initial commit
This commit is contained in:
169
common/xbuf/xbuf.c
Executable file
169
common/xbuf/xbuf.c
Executable file
@@ -0,0 +1,169 @@
|
||||
#include "xbuf.h"
|
||||
#include "errno.h"
|
||||
#include "hlog.h"
|
||||
|
||||
#define TAG "TAG_XBUF"
|
||||
|
||||
|
||||
uint32_t xbuf_init(xbuf_handler *hdlr)
|
||||
{
|
||||
iobuffer_init(&hdlr->read_io);
|
||||
return OK;
|
||||
}
|
||||
|
||||
uint32_t xbuf_deinit(xbuf_handler *hdlr)
|
||||
{
|
||||
iobuffer_deinit(&hdlr->read_io);
|
||||
return OK;
|
||||
}
|
||||
|
||||
uint32_t xbuf_put(xbuf_handler *hdlr, const char *data, const uint32_t sz)
|
||||
{
|
||||
if ( OK == iobuffer_appendData(&hdlr->read_io, data, sz) )
|
||||
{
|
||||
return xbuf_flush(hdlr);
|
||||
}
|
||||
return NG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint32_t xbuf_flush(xbuf_handler *hdlr)
|
||||
{
|
||||
kpacket *packet = (kpacket*)hdlr->read_io.iodata;
|
||||
//hlogd("xbuf_flush len:%d magic:%x %d %d",packet->tlv.L, packet->tlv.magic,hdlr->read_io.size,sizeof(kpacket));
|
||||
while ( hdlr->read_io.size >= sizeof(kpacket) + packet->tlv.L ) /* 粘包 或 包不齐处理 */
|
||||
{
|
||||
if ( packet->tlv.magic == OS_PACKET_MAGIC && kpacket_calc_checksum(packet) == packet->tlv.checksum ){
|
||||
{ /* 如果 注册了type 处理 */
|
||||
for ( uint16_t i=0; i< hdlr->ev_list_sz; i++ ){
|
||||
//hlogd("xbuf_flush len:%d magic:%x",packet->tlv.T, hdlr->ev_list[i].event);
|
||||
if ( hdlr->ev_list[i].event == packet->tlv.T ){
|
||||
hdlr->ev_list[i].on_event(packet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ /* 增加未注册type的, packet 处理*/
|
||||
if ( hdlr->on_packet )
|
||||
{
|
||||
hdlr->on_packet(packet);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
hloge("invalid %s magic:0x%x, calc_checksum:%x %x, V:%s", __func__, packet->tlv.magic, kpacket_calc_checksum(packet), packet->tlv.checksum,packet->tlv.V);
|
||||
}
|
||||
/* 删除packet占用的内存,后面的数据将前移到0位置 */
|
||||
iobuffer_erase(&hdlr->read_io, 0, sizeof(kpacket) + packet->tlv.L);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************ for tester ************************************/
|
||||
/* 应用层四步
|
||||
**
|
||||
** 一, 声明枚举指令 和 回调函数
|
||||
** 二, 填写 packet_event 的 ev_list
|
||||
** 三, 通过xbuf_init注册到xbuf
|
||||
** 四, 收数xbuf_put到xbuf, 自动回调
|
||||
**/
|
||||
|
||||
/* 第一步 */
|
||||
enum{
|
||||
CMD_SYNC = 0x0001, /* 握手指令 */
|
||||
};
|
||||
|
||||
static uint32_t on_sync(const kpacket *packet){
|
||||
hlogw("%s magic:0x%x, type:%x, extend:%u, len:%u, payload:%s", __func__, packet->tlv.magic, packet->tlv.T, packet->offset, packet->tlv.L, packet->tlv.V);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static packet_event s_ev_list[]={
|
||||
{CMD_SYNC, on_sync},
|
||||
};
|
||||
|
||||
|
||||
/* 第二步 */
|
||||
|
||||
static xbuf_handler handler = {
|
||||
.ev_list = s_ev_list,
|
||||
.ev_list_sz = sizeof(s_ev_list)/sizeof(s_ev_list[0]),
|
||||
};
|
||||
|
||||
/* 第三和四步 */
|
||||
|
||||
static uint32_t kpacket_recv(char *data, uint32_t max_sz);
|
||||
void xbuf_test()
|
||||
{
|
||||
xbuf_init(&handler);
|
||||
|
||||
{
|
||||
/* 用iobuffer */
|
||||
for ( uint32_t i=0; i<10; i++ )
|
||||
{
|
||||
if ( iobuffer_freesize(&handler.read_io) < 1024 ) /* 如果预期接收的数据不小于1024大小(也可是256/512字节点), 那么扩容一下, 随协议来定*/
|
||||
{
|
||||
iobuffer_reserve(&handler.read_io, 1024 + handler.read_io.size); /* 小于1024了申请多些内存 */
|
||||
}
|
||||
|
||||
/*第一种: 直接读到xbuf的iobuffer, 减少一次内存拷贝 */
|
||||
uint32_t read_cnt = kpacket_recv(handler.read_io.iodata + handler.read_io.size, iobuffer_freesize(&handler.read_io));
|
||||
if ( read_cnt > 0 )
|
||||
{
|
||||
handler.read_io.size += read_cnt;
|
||||
kpacket *packet = (kpacket*)handler.read_io.iodata;
|
||||
hlogd("xbuf_test read_cnt:%u %s",read_cnt, packet->tlv.V);
|
||||
xbuf_flush(&handler); /*将自动回调对应的on_type*/
|
||||
}
|
||||
//hlogd("xbuf_test i:%u",i);
|
||||
}
|
||||
hlogd("xbuf_test end");
|
||||
}
|
||||
|
||||
|
||||
xbuf_deinit(&handler);
|
||||
}
|
||||
|
||||
|
||||
/* 串口, rndis 等的接收*/
|
||||
static uint32_t kpacket_recv(char *data, uint32_t max_sz)
|
||||
{
|
||||
/*******这段为模拟发送端发送的数据 ,即接收*******/
|
||||
static uint32_t i;
|
||||
char str[128]; /* 没必要memset 或 ={0}, sprintf 会补 0 */
|
||||
sprintf(str, "{\"sync\":\"i m :%u\"}", i++);
|
||||
|
||||
uint32_t size = strlen(str) + 1; /*+1 for '\0'*/
|
||||
|
||||
|
||||
kpacket *packet = kpacket(CMD_SYNC, size);
|
||||
kpacket_put_string(packet, str);
|
||||
kpacket_checksum(packet); /* 生成 crc16 */
|
||||
|
||||
hlogd("%s magic:0x%x, calc_checksum:%x %x, V:%s", __func__, packet->tlv.magic, kpacket_calc_checksum(packet), packet->tlv.checksum, packet->tlv.V);
|
||||
#if 0
|
||||
send(packet, sizeof(kpacket)+packet->tlv.L); /* 发给接收端数据 */
|
||||
#endif
|
||||
|
||||
/*********************end***********************/
|
||||
|
||||
/******* 这段为接收端数据拷贝到目标中data, 如iobuffer.iodata *******/
|
||||
#if 0
|
||||
recv_cnt = recv(data, max_sz); /* 发给接收端数据 */
|
||||
#else
|
||||
int32_t recv_cnt = sizeof(kpacket) + packet->tlv.L;
|
||||
memcpy(data, packet, recv_cnt);
|
||||
#endif
|
||||
|
||||
kpacket_dec(packet);/* 释放kpacket */
|
||||
|
||||
return recv_cnt;
|
||||
}
|
||||
/************************************end************************************/
|
||||
|
||||
|
||||
84
common/xbuf/xbuf.h
Executable file
84
common/xbuf/xbuf.h
Executable file
@@ -0,0 +1,84 @@
|
||||
/*************************************************
|
||||
File name : xbuf.h
|
||||
Module :
|
||||
Author : amir
|
||||
Version : 0.1
|
||||
Created on : 2024-04-27
|
||||
Description : buf for protocol transmission
|
||||
协议间传输
|
||||
Modify History:
|
||||
1. Date: Author: Modification:
|
||||
*************************************************/
|
||||
|
||||
#ifndef __XBUF__
|
||||
#define __XBUF__
|
||||
#include <stdint.h>
|
||||
#include "kpacket.h"
|
||||
#include "iobuffer.h"
|
||||
|
||||
typedef struct{
|
||||
uint16_t event;
|
||||
uint32_t (*on_event)(const kpacket *packet);
|
||||
}packet_event;
|
||||
|
||||
|
||||
typedef struct{
|
||||
|
||||
/**
|
||||
* @brief 当接收完整一包kpacket, 触发回调
|
||||
*
|
||||
* @param [in] box, box的地址.
|
||||
*
|
||||
*
|
||||
*/
|
||||
void (*on_packet)(const kpacket *packet);
|
||||
|
||||
packet_event *ev_list;
|
||||
uint16_t ev_list_sz;
|
||||
|
||||
|
||||
/* private data*/
|
||||
iobuffer read_io;
|
||||
/* 高阶应用
|
||||
* 1. iobuffer_iobuffer_reserve(&read_io, 4096); // 设置iobuffer的缓冲大小
|
||||
* 2. recv(read_io.iodata, read_io.capacity - read_io.size); xbuf_flush(); // 直接将数据读到iobuffer里,并尝试触发回调
|
||||
**/
|
||||
|
||||
|
||||
}xbuf_handler;
|
||||
|
||||
|
||||
uint32_t xbuf_init(xbuf_handler *hdlr);
|
||||
|
||||
|
||||
uint32_t xbuf_deinit(xbuf_handler *hdlr);
|
||||
|
||||
/**
|
||||
* @brief 入数据处理, 满足包条件时触发on_packet回调
|
||||
*
|
||||
* @param [in] hdlr, 外部保存的xbuf_handler.
|
||||
* @param [in] data, 入数.
|
||||
* @param [in] sz, 入数长度.
|
||||
* @note 成长返回OK, 返回NG内存不足--查一下read_io的capacity和size.
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t xbuf_put(xbuf_handler *hdlr, const char *data, const uint32_t sz);
|
||||
|
||||
|
||||
/**
|
||||
* @brief 尝试主动触发回调
|
||||
*
|
||||
* @param [in] hdlr, 外部保存的xbuf_handler.
|
||||
* @note 成长返回OK, 返回NG内存不足--查一下read_io的capacity和size.
|
||||
*
|
||||
*/
|
||||
|
||||
uint32_t xbuf_flush(xbuf_handler *hdlr);
|
||||
|
||||
|
||||
void xbuf_test();
|
||||
|
||||
|
||||
#endif /* __XBUF__ */
|
||||
|
||||
Reference in New Issue
Block a user