串列埠(流資料)協議封裝,拆包解析
阿新 • • 發佈:2019-02-07
功能:
對資料進行封包,加入校驗,簡單加密
2.主要解析及返回資料
使用說明:
1.主函式呼叫初始化函式wifi_buff_init()
2.串列埠中斷呼叫add_message_queue()
3.主函式迴圈處理analyze_queue()
解釋說明:
此協議固定協議長度為12
加密碼0x03f7
4個幀頭 48 45 53 5a
校驗2個位元組
型別2個位元組
可以自定義各種資料型別
資料長度2個位元組
表示12位元組後的使用者資料長度
版本2個位元組
自定義預留引數
(都是低位元組在前)
這些都是預留開發用,實際中可以不用
基本資料包:
48 45 53 5a 31 05 00 00 00 00 00 00
效果:
wifi_data_tran.h
#ifndef _WIFI_DATA_TRAN #define _WIFI_DATA_TRAN /************************************************* com:未知科技 作者:何少 編寫時間:2017-10-27 1.新增wifi_data_tran檔案 功能: 對資料進行封包,加入校驗,簡單加密 2.主要解析及返回資料 使用說明: 1.主函式呼叫初始化函式wifi_buff_init() 2.串列埠中斷呼叫add_message_queue() 3.主函式迴圈處理analyze_queue() 解釋說明: 此協議固定協議長度為12 加密碼0x03f7 4個幀頭 48 45 53 5a 校驗2個位元組 型別2個位元組 資料長度2個位元組 版本2個位元組 (都是低位元組在前) 這些都是預留開發用,實際中可以不用 基本資料包: 48 45 53 5a 31 05 00 00 00 00 00 00 **************************************************/ #define _PROTOCOL_HEAD 12 //固定協議頭長度 #define USER_DATA 30 //使用者資料長度 #define HANDLE_DATA 20 #define RX_TX_LEN 20 //接收與傳送資料長度 extern unsigned char volatile wifi_queue_buff[_PROTOCOL_HEAD + USER_DATA]; //資料包 extern unsigned char wifi_queue_buf_len; extern volatile unsigned char *queue_out; //出隊指標 extern unsigned short queue_all_len; //當前佇列長度 extern unsigned char wifi_rx_buff[_PROTOCOL_HEAD+RX_TX_LEN]; //接收到的正確資料包 extern unsigned char wifi_tx_buff[_PROTOCOL_HEAD+RX_TX_LEN]; //傳送的資料包 extern unsigned char handle_buff[HANDLE_DATA]; //接收到的資料 extern unsigned char wifi_rx_buff_len; //接收的資料包長度 extern unsigned char wifi_tx_buff_len; //傳送資料包長度 extern unsigned char wifiwork_state; //模組工作狀態 /***************************************************************************** 函式名稱 : wifi_buff_init 功能描述 : wifi所有資料初始化 輸入引數 : 返回引數 : *****************************************************************************/ void wifi_buff_init(void); /***************************************************************************** 函式名稱 : analyze_queue 功能描述 : 分解佇列 輸入引數 : 返回引數 : *****************************************************************************/ void analyze_queue(void); /***************************************************************************** 函式名稱 : add_message_queue 功能描述 : 新增資料到資料包 輸入引數 : 返回引數 : *****************************************************************************/ void add_message_queue(unsigned char value); /***************************************************************************** 函式名稱 : get_queue_data 功能描述 : 新增資料到資料包 輸入引數 : 返回引數 : *****************************************************************************/ unsigned char get_queue_data(void); /***************************************************************************** 函式名稱 : get_check_sum 功能描述 : 計算校驗和 輸入引數 : pack:資料來源指標 pack_len:計算校驗和長度 返回引數 : 校驗和 *****************************************************************************/ unsigned short check_sum(unsigned char *pack, unsigned short pack_len); /***************************************************************************** 函式名稱 : analyze_message_queue 功能描述 : 分析資料包 輸入引數 : 返回引數 : *****************************************************************************/ void analyze_message_queue(unsigned char len); /***************************************************************************** 函式名稱 : handle_set_ 功能描述 : 處理設定指令 輸入引數 : 返回引數 : *****************************************************************************/ void handle_set(unsigned char len); /***************************************************************************** 函式名稱 : handle_led 功能描述 : 事件處理 輸入引數 : 函式名,處理引數 返回引數 : *****************************************************************************/ void handle_led(void (*fun)(),unsigned char n); /***************************************************************************** 函式名稱 : set_tx_data 功能描述 : 設定傳送資料 輸入引數 : 要傳送的資料 返回引數 : *****************************************************************************/ void set_tx_data(unsigned char buf[],unsigned short len); /***************************************************************************** 函式名稱 : take_data 功能描述 : 提取接收到的資料 輸入引數 : 返回引數 : *****************************************************************************/ void take_data(void); /***************************************************************************** 函式名稱 : wifi_uart_write_data 功能描述 : 向wifi uart寫入連續資料 輸入引數 : in:傳送快取指標 len:資料傳送長度 返回引數 : 無 *****************************************************************************/ void _wifi_uart_write_data(unsigned char *in, unsigned short len); /***************************************************************************** 函式名稱 : mymemcpy 功能描述 : 記憶體拷貝 輸入引數 : dest:目標地址 src:源地址 count:資料拷貝數量 返回引數 : src:資料處理完後的源地址 *****************************************************************************/ void *my_memcpy(void *dest, const void *src, unsigned short count); #endif
wifi_data_tran.c
/************************************************* com:未知科技 作者:何少 編寫時間:2017-10-27 1.新增wifi_data_tran檔案 功能: 對資料進行封包,加入校驗,簡單加密 2.主要解析及返回資料 使用說明: 1.主函式呼叫初始化函式wifi_buff_init() 2.串列埠中斷呼叫add_message_queue() 3.主函式迴圈處理analyze_queue() 解釋說明: 此協議固定協議長度為12 加密碼0x03f7 4個幀頭 48 45 53 5a 校驗2個位元組 型別2個位元組 可以自定義各種資料型別 資料長度2個位元組 表示12位元組後的使用者資料長度 版本2個位元組 自定義預留引數 (都是低位元組在前) 這些都是預留開發用,實際中可以不用 基本資料包: 48 45 53 5a 31 05 00 00 00 00 00 00 **************************************************/ #include "wifi_data_tran.h" #include "sys.h" #include "stdio.h" /*******************************************************/ unsigned char volatile wifi_queue_buff[_PROTOCOL_HEAD + USER_DATA]; //資料包 unsigned char wifi_queue_buf_len; unsigned short queue_all_len; unsigned char wifi_rx_buff[_PROTOCOL_HEAD+RX_TX_LEN]; //接收到的正確資料包 unsigned char wifi_tx_buff[_PROTOCOL_HEAD+RX_TX_LEN]; //傳送的資料包 unsigned char handle_buff[HANDLE_DATA]; unsigned char wifi_rx_buff_len; unsigned char wifi_tx_buff_len; volatile unsigned char *queue_out; //出隊指標 unsigned char wifiwork_state; //wifi模組工作狀態 /***************************************************************************** 函式名稱 : wifi_buff_init 功能描述 : wifi所有資料初始化 輸入引數 : 返回引數 : *****************************************************************************/ void wifi_buff_init() { queue_out=wifi_queue_buff; //初始化出隊指標 queue_all_len=0; //隊列當前長度 wifi_rx_buff_len=0; //接收命令快取 wifi_tx_buff_len=0; //傳送命令快取 } /***************************************************************************** 函式名稱 : get_queue_data 功能描述 : 新增資料到資料包 輸入引數 : 返回引數 : *****************************************************************************/ unsigned char get_queue_data(void) { unsigned char value; if(queue_all_len > 0) { //有資料 if(queue_out >= (unsigned char *)(wifi_queue_buff + sizeof(wifi_queue_buff))) //出隊指標要小於資料佇列總長度 { //資料已經到末尾 queue_out = (unsigned char *)(wifi_queue_buff); //重新指向陣列頭 } value = *queue_out ++; //出隊 queue_all_len --; //佇列資料-1 } return value; } /***************************************************************************** 函式名稱 : add_message_queue 功能描述 : 新增資料到資料包 輸入引數 : unsigned char value 返回引數 : *****************************************************************************/ void add_message_queue(unsigned char value) { if(wifi_queue_buf_len<(_PROTOCOL_HEAD + USER_DATA)) //隊列當前資料長度小於佇列快取總長度 { wifi_queue_buff[wifi_queue_buf_len++]=value; //新增到佇列 queue_all_len++; // } else { wifi_queue_buf_len=0; //佇列快取索引重新開始 wifi_queue_buff[wifi_queue_buf_len++]=value; queue_all_len++; //佇列長度 } } /***************************************************************************** 函式名稱 : analyze_queue 功能描述 : 分解佇列,在主函式裡面迴圈 輸入引數 : 返回引數 : *****************************************************************************/ void analyze_queue(void) { short data_len=0; //索引 short rx_value_len=0; //接收包長度 int i; while((wifi_rx_buff_len < sizeof(wifi_queue_buff)) && queue_all_len > 0) //接收包長度小於佇列快取長度,佇列資料要大於0 { u8 r=wifi_rx_buff[wifi_rx_buff_len ++] = get_queue_data(); //printf("%c",r); } if(wifi_rx_buff_len<12) return; //資料包小於12(最短資料包) while((wifi_rx_buff_len - data_len) >= 12) { if(wifi_rx_buff[data_len] != 0x48) { data_len ++; continue; } printf("\r\n H ok\r\n"); if(wifi_rx_buff[data_len + 1] != 0x45) { data_len ++; continue; } printf("\r\n E ok\r\n"); if(wifi_rx_buff[data_len + 2] != 0x53) { data_len += 2; continue; } printf("\r\n S ok\r\n"); if(wifi_rx_buff[data_len + 3] != 0x5a) { data_len += 3; continue; } printf("\r\n 5a ok\r\n"); rx_value_len = wifi_rx_buff[data_len + 9] * 0x100 + wifi_rx_buff[data_len + 8] + 12; //使用者資料+標準資料(幀頭資料) if(rx_value_len > sizeof(wifi_rx_buff)) { data_len += 4; continue; } printf("\r\n 長度 ok\r\n"); if((wifi_rx_buff_len - data_len) < rx_value_len) { break; } printf("\r\n 資料長度:%d ok\r\n",rx_value_len); //資料接收完成 if(check_sum((unsigned char *)wifi_rx_buff + data_len,rx_value_len) != wifi_rx_buff[data_len + 5] * 0x100 + wifi_rx_buff[data_len + 4]) { //校驗出錯 data_len += 4; continue; } printf("\r\n 校驗 ok\r\n"); #if 1//1為test //打印出正確的接收到的協議 printf("recv:%d:",data_len); for(i=0; i<rx_value_len; i++) { printf("%x ",wifi_rx_buff[data_len + i]); } printf("\r\n"); #endif analyze_message_queue(rx_value_len); //處理資料包 data_len += rx_value_len; } wifi_rx_buff_len -= data_len; if(wifi_rx_buff_len > 0 && data_len>0) { my_memcpy(wifi_rx_buff,wifi_rx_buff + data_len,wifi_rx_buff_len); } } /***************************************************************************** 函式名稱 : get_check_sum 功能描述 : 計算校驗和 輸入引數 : pack:資料來源指標 pack_len:計算校驗和長度 返回引數 : 校驗和 *****************************************************************************/ unsigned short check_sum(unsigned char *pack, unsigned short pack_len) { unsigned short i; unsigned short check_sum = 0; for(i = 0; i < pack_len; i ++) { if(i==4 || i==5) { pack ++; continue; // 避開校驗位; } check_sum += *pack++; } return (check_sum + 0x03f7); } /***************************************************************************** 函式名稱 : analyze_message_queue 功能描述 : 分析資料包 輸入引數 : 返回引數 : *****************************************************************************/ void analyze_message_queue(unsigned char len) { switch(wifi_rx_buff[6]+wifi_rx_buff[7]*0x100) { } } /***************************************************************************** 函式名稱 : handle_set_ 功能描述 : 處理指令 輸入引數 : 返回引數 : *****************************************************************************/ void handle_set(unsigned char len) { //unsigned char buf[]={0x01,0x02,0x03,0x04,0x05}; //要傳送的資料 take_data(); //提取資料 } /***************************************************************************** 函式名稱 : handle_led 功能描述 : 事件處理 輸入引數 : 返回引數 : *****************************************************************************/ void handle_led(void (*fun)(),unsigned char n) { fun(n); } /***************************************************************************** 函式名稱 : set_tx_data 功能描述 : 設定傳送資料 輸入引數 : 要傳送的資料 返回引數 : *****************************************************************************/ void set_tx_data(unsigned char buf[],unsigned short len) { unsigned char i; unsigned short buf_len = len; //傳送資料的長度 unsigned short buf_sum; //傳送資料的總和 char state_re[]={0x48,0x45,0x53,0x5A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //標準返回資料頭 wifi_tx_buff_len=12; for(i=0;i<wifi_tx_buff_len;i++) //資料頭 wifi_tx_buff[i]=state_re[i]; for(i=0;i<buf_len;i++) //所有資料和 buf_sum+=buf[i]; buf_sum+=0x0531+buf_len; //協議頭+校驗和+資料長度 wifi_tx_buff[4]=buf_sum&0x00ff; //校驗和 wifi_tx_buff[5]=buf_sum>>8; wifi_tx_buff[8]=buf_len&0x00ff; //資料和 wifi_tx_buff[9]=buf_len>>8; for(i=0;i<buf_len;i++) //所有資料 wifi_tx_buff[wifi_tx_buff_len+i]=buf[i]; _wifi_uart_write_data((unsigned char *)wifi_tx_buff, wifi_tx_buff_len+buf_len); //指令傳送 } /***************************************************************************** 函式名稱 : take_data 功能描述 : 提取接收到資料 輸入引數 : 返回引數 : *****************************************************************************/ void take_data(void) { unsigned short data_len = wifi_rx_buff[8]+wifi_rx_buff[9]*0x100; //接收到資料長度 unsigned char i; for(i=0;i<data_len;i++) //提取出資料 handle_buff[i]=wifi_rx_buff[12+i]; } /***************************************************************************** 函式名稱 : wifi_uart_write_data 功能描述 : 向wifi uart寫入連續資料 輸入引數 : in:傳送快取指標 len:資料傳送長度 返回引數 : 無 *****************************************************************************/ void _wifi_uart_write_data(unsigned char *in, unsigned short len) { if((NULL == in) || (0 == len)) { return; } printf("send:"); while(len --) { printf("%c",*in); in ++; } printf("\r\n"); } /***************************************************************************** 函式名稱 : mymemcpy 功能描述 : 記憶體拷貝 輸入引數 : dest:目標地址 src:源地址 count:資料拷貝數量 返回引數 : src:資料處理完後的源地址 *****************************************************************************/ void *my_memcpy(void *dest, const void *src, unsigned short count) { unsigned char *pdest = (unsigned char *)dest; const unsigned char *psrc = (const unsigned char *)src; unsigned short i; if(dest == NULL || src == NULL) { return NULL; } /* 此判斷是保證未被轉移的源資料不會被轉移操作所汙染; */ if((pdest <= psrc) || (pdest > psrc + count)) { for(i = 0; i < count; i ++) { pdest[i] = psrc[i]; } } else { for(i = count; i > 0; i --) { pdest[i - 1] = psrc[i - 1]; } } return dest; }