#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************************************/