From 8a383b8715fc07145fdc3f3e3dbe6ecd93f72989 Mon Sep 17 00:00:00 2001 From: guowenxue <guowenxue@gmail.com> Date: Sun, 07 Jun 2020 00:06:57 +0800 Subject: [PATCH] update tlv_server program, add TLV parser support --- prj1_tlv/tlv_server.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 108 insertions(+), 2 deletions(-) diff --git a/prj1_tlv/tlv_server.c b/prj1_tlv/tlv_server.c index 73cb6e4..43251b6 100644 --- a/prj1_tlv/tlv_server.c +++ b/prj1_tlv/tlv_server.c @@ -20,6 +20,8 @@ #include "logger.h" #include "proc.h" #include "socket.h" +#include "tlv_pack.h" +#include "crc-itu-t.h" #define PROG_VERSION "1.0.0" @@ -39,7 +41,7 @@ struct list_head list; /* all client buffer saved in a list */ } cli_buf_t; - +static int parser_tlvpack(cli_buf_t *cli_buf); static void term_socket_client(int epollfd, int fd, struct list_head *buf_list); static void banner(void) @@ -275,9 +277,11 @@ } else { + cli_buf->bytes += rv; log_dbg("socket[%d] receive %d bytes data\n", fd, rv); - logger_dump(LOG_LEVEL_INFO, cli_buf->buf, rv); } + + parser_tlvpack(cli_buf); } } @@ -289,6 +293,108 @@ return 0; } +static int parser_tlvpack(cli_buf_t *cli_buf) +{ + int i; + int left_bytes; + unsigned short crc16; + tlv_pack_t *tlv_pack; + + if( !cli_buf ) + { + log_err("Invalid input arguments\n"); + return -1; + } + + log_info("start to parser client buffer %d bytes data:\n", cli_buf->bytes); + logger_dump(LOG_LEVEL_INFO, cli_buf->buf, cli_buf->bytes); + + if( cli_buf->bytes < TLV_MIN_SIZE ) + { + log_warn("TLV packet bytes less than min. size\n"); + return -2; + } + +PARSER_AGAIN: + for(i=0; i<cli_buf->bytes; i++) + { + if( PACK_HEADER == (unsigned char )cli_buf->buf[i] ) + { + log_dbg("found TLV packet header on [%d]\n", i); + left_bytes = cli_buf->bytes - i; + + if(left_bytes < TLV_MIN_SIZE) + { + log_warn("TLV packet bytes less than min. size\n"); + memmove(cli_buf->buf, &cli_buf->buf[i], left_bytes); + cli_buf->bytes = left_bytes; + break; + } + + tlv_pack = (tlv_pack_t *) &cli_buf->buf[i]; + log_info("header: 0x%02x tag: 0x%02x len: 0x%02x\n", tlv_pack->header, tlv_pack->tag, tlv_pack->len); + + if(tlv_pack->len > left_bytes ) + { + log_err("TLV packet not integrated, continue to receive left data\n"); + memmove(cli_buf->buf, &cli_buf->buf[i], left_bytes); + cli_buf->bytes = left_bytes; + break; + } + + if( tlv_pack->len > TLV_MAX_SIZE ) + { + log_err("TLV packet length more than max. length, maybe found wrong header?\n"); + + /* skip current header */ + left_bytes -= 1; + memmove(cli_buf->buf, &cli_buf->buf[i+1], left_bytes); + cli_buf->bytes = left_bytes; + goto PARSER_AGAIN; + } + + crc16 = crc_itu_t(MAGIC_CRC, (unsigned char *)&cli_buf->buf[i], tlv_pack->len-2); + if( crc16 != bytes_to_ushort((unsigned char *)&cli_buf->buf[i+tlv_pack->len-2], 2) ) + { + log_err("TLV packet CRC check error, maybe found wrong header?\n"); + + /* skip current header */ + left_bytes -= 1; + memmove(cli_buf->buf, &cli_buf->buf[i+1], left_bytes); + cli_buf->bytes = left_bytes; + + goto PARSER_AGAIN; + } + + if( tlv_pack->tag == TAG_SN ) + { + log_nrml("Found SN TLV data:\n"); + dump_buf(tlv_pack->data, tlv_pack->len-TLV_FIXED_SIZE); + } + else if( tlv_pack->tag == TAG_TEMP ) + { + log_nrml("Found temperature TLV data:\n"); + dump_buf(tlv_pack->data, tlv_pack->len-TLV_FIXED_SIZE); + } + else if( tlv_pack->tag == TAG_TIME ) + { + log_nrml("Found date time TLV data:\n"); + dump_buf(tlv_pack->data, tlv_pack->len-TLV_FIXED_SIZE); + } + + left_bytes -= tlv_pack->len; + memmove(cli_buf->buf, &cli_buf->buf[i+tlv_pack->len], left_bytes); + cli_buf->bytes = left_bytes; + + log_info("left %d bytes data:\n", cli_buf->bytes); + logger_dump(LOG_LEVEL_INFO, cli_buf->buf, cli_buf->bytes); + goto PARSER_AGAIN; + } + } + + return 0; +} + static void term_socket_client(int epollfd, int fd, struct list_head *buf_list) { cli_buf_t *buf, *tmp; -- Gitblit v1.9.1