#include "errcode.h"\r
\r
#include "bletest.h"\r
-\r
+#include "custom_utils.h"\r
#define DEBUG_TEST (0)\r
#define CRC_CHECK_ERR 0 //crc校验失败\r
#define JSON_CHECK_OK 1 //json解析成功\r
}\r
\r
bool bigDataBufState=false;//大数据传输状态\r
-static bool Check_CRC(uint8_t *data,uint16_t len,uint8_t crcvalue)//计算20byte的的校验位\r
+/**\r
+ * 计算crc时的求和函数,可以递归,从而实现多段数据的组合计算\r
+*/\r
+static uint8_t calculate_lrc(uint8_t *data,uint16_t len,uint8_t _lrcValue)\r
{\r
- uint8_t crcbuf = 0;\r
- uint8_t lrcValue = 0x00;\r
+ uint8_t lrcValue = _lrcValue;\r
if(data == NULL)\r
{\r
return false; \r
lrcValue =lrcValue+ data[i];\r
// printf("%02x ",data[i]);\r
}\r
- //"{\"pn\":\"iPhone\",\"tp\":1}";\r
- \r
+ return lrcValue;\r
+}\r
+\r
+/***\r
+ * 根据求和后的数据计算crc 值 \r
+*/\r
+static uint8_t get_crc_from_lrc(uint8_t lrcValue)\r
+{\r
+ uint8_t crcbuf = 0;\r
crcbuf = lrcValue%256;\r
crcbuf = 256-crcbuf;\r
crcbuf = crcbuf%256;\r
+ return crcbuf;\r
+}\r
+\r
+static bool Check_CRC(uint8_t *data,uint16_t len,uint8_t crcvalue)//计算20byte的的校验位\r
+{\r
+ uint8_t crcbuf = 0;\r
+ uint8_t lrcValue = 0x00;\r
+ if(data == NULL)\r
+ {\r
+ return false; \r
+ }\r
+ lrcValue = calculate_lrc(data,len,0x00);\r
+ \r
+ crcbuf = get_crc_from_lrc(lrcValue);\r
+\r
WEARABLE_LOGI(WEARABLE_LOG_MODULE_APP, "Check_CRC ret:0x%x len:%d\r\n",crcbuf,len);\r
\r
if(crcbuf == crcvalue)\r
{\r
uint8_t crcbuf = 0;\r
uint8_t lrcValue = 0x00;\r
- for(uint16_t i = 17; i < len; i++)\r
- {\r
- lrcValue =lrcValue+ data[i];\r
- }\r
- // printf("Calculate_CRC:%x,len:%d",lrcValue,len);\r
- crcbuf = lrcValue%256;\r
- crcbuf = 256-crcbuf;\r
- crcbuf = crcbuf%256;\r
+ lrcValue = calculate_lrc(data+17,len-17,0x00);\r
+ crcbuf = get_crc_from_lrc(lrcValue);\r
return crcbuf;\r
}\r
-static uint8_t cal_sum(uint8_t *data,uint16_t len)//计算20byte\r
-{\r
- uint8_t lrcValue = 0x00;\r
- for(uint16_t i = 0; i < len; i++)\r
- {\r
- lrcValue =lrcValue+ data[i];\r
- }\r
- return lrcValue;\r
-}\r
+\r
static uint8_t Calculate_CRC_Big(uint8_t *data,uint16_t len)//计算20byte\r
{\r
uint8_t crcbuf = 0;\r
uint8_t lrcValue = 0x00;\r
- for(uint16_t i = 0; i < len; i++)\r
- {\r
- lrcValue =lrcValue+ data[i];\r
- }\r
- crcbuf = lrcValue%256;\r
- crcbuf = 256-crcbuf;\r
- crcbuf = crcbuf%256;\r
+ lrcValue = calculate_lrc(data,len,0x00);\r
+ crcbuf = get_crc_from_lrc(lrcValue);\r
return crcbuf;\r
}\r
+\r
static cJSON *cjson_json_tmp = NULL;\r
//发送ble数据\r
errcode_t sendBleData(uint8_t *buf,uint16_t len)\r
\r
ym_free(buf); // 释放内存空间\r
}\r
+\r
+\r
+\r
+\r
+\r
+\r
+uint32_t packdataLen = 0;\r
+uint32_t totalDataLen = 0;\r
+uint8_t totalpack = 0;\r
+uint8_t cmd_data[17];\r
+uint8_t *recvData;\r
+#include "los_memory.h"\r
+\r
+\r
+#if USE_PROTOCOL_EN_DE_BY_SNICKER\r
+#define MAX_BLE_MSG_PACKAGE_LEN (1024*5) //包缓存最大5k\r
+#define BLE_MSG_TMP_FILE_NAME "/user/userdata/ble_tmp_buf_%04X"\r
+typedef struct \r
+{\r
+ int handle;\r
+ int data_len ;\r
+ int totalDataLen;\r
+ int buffer_to_file; //1 buffer to file , 0 buffer to ram\r
+ int decode_type; //1 with header , 2 no header\r
+ FILE *tmpfilehandle;// 如果buffer to file , 则在此保存handle\r
+ msg_header_t cmd_header;\r
+ uint8_t *data;//if buffer_to_file is 1, than data is the filename , else data is the ram buffer.\r
+ uint8_t crcvalue;\r
+ uint8_t lrcvalue; //计算crc用的临时变量\r
+ uint32_t last_timestamp;// last package receive time\r
+ uint8_t receive_file_flag;//1 接收文件 0 不接收文件\r
+ file_recv_stat_t file_recv_stat;\r
+} ble_read_data;\r
+\r
+#define MAX_HANDLE_NUM 10\r
+//LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus)\r
+//根据特征值分开组合读取的数据,并处理\r
+static ble_read_data handle_l[MAX_HANDLE_NUM]={0};\r
+\r
+errcode_t cancel_recv_file(ble_read_data *buffer_handle);\r
+\r
+\r
+#else\r
+\r
+typedef struct \r
+{\r
+ uint8_t *data;\r
+ int handle;\r
+ int data_len ;\r
+ int totalDataLen;\r
+ uint8_t cmd_data[17];\r
+ uint8_t crcvalue;\r
+} ble_read_data;\r
+\r
+#define MAX_HANDLE_NUM 10\r
+//LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus)\r
+//根据特征值分开组合读取的数据,并处理\r
+static ble_read_data handle_l[MAX_HANDLE_NUM]={0};\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
//发送训练状态[app发起的运动]\r
void sendtraningstatedata(uint8_t state ,uint16_t time)\r
{\r
void getUserInfo(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *totalData,uint8_t crcvalue)//\r
{\r
\r
- // 用户数据同步死机,暂时跳过 by Snicker\r
- return;\r
-\r
+ // 用户数据同步死机,\r
uint8_t value[19];\r
memset(value,0,19);\r
uint32_t tmp = 1;\r
}\r
}\r
//撤销当前文件传输 1 OTA 2MP3 3表盘 3天气 5闹钟\r
+#if USE_PROTOCOL_EN_DE_BY_SNICKER\r
+static void RemoveFileCmd(ble_read_data *buffer_handle,uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *totaldata,uint8_t crcvalue)\r
+#else\r
static void RemoveFileCmd(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *totaldata,uint8_t crcvalue)\r
+#endif\r
{\r
uint8_t value[19];\r
memset(value,0,19);\r
value[17] = 1; //\r
value[18] = Calculate_CRC(value,18);\r
sendBleData(value,19);\r
+\r
+ #if USE_PROTOCOL_EN_DE_BY_SNICKER\r
+ cancel_recv_file(buffer_handle);\r
+ #endif \r
}else\r
{\r
value[17] = 0;\r
*totaldata:总的数据内容 包含包头和校验预览做接口是用 如果要计算totaldata的长度直接是len+17+1 就是加上包头和校验和\r
crcvalue;数据的校验和 不包含包头和校验和的计算结果\r
*/\r
+#if USE_PROTOCOL_EN_DE_BY_SNICKER\r
+void type2AE3Data(ble_read_data *buffer_handle,uint8_t *cmd_buf ,uint8_t *data,uint16_t datalen,uint8_t *totaldata,uint8_t crcvalue)\r
+#else\r
void type2AE3Data(uint8_t *cmd_buf ,uint8_t *data,uint16_t datalen,uint8_t *totaldata,uint8_t crcvalue)\r
+#endif\r
{\r
uint16_t cmd = cmd_buf[1]*256+cmd_buf[2];\r
- printf("typeHexOneData:0x%x\r\n",cmd);\r
+ printf("typeHexOneData:0x%04X\r\n",cmd);\r
// uint8_t typeID = cmd_buf[2];\r
switch (cmd)\r
{\r
GetSwitchMessCmd(cmd,data,datalen,totaldata,crcvalue);\r
break;\r
case REVOKE_CURR_FILE_TRANS_CMD://撤销文件传输\r
- RemoveFileCmd(cmd,data,datalen,totaldata,crcvalue);\r
+ #if USE_PROTOCOL_EN_DE_BY_SNICKER\r
+ RemoveFileCmd(buffer_handle,cmd,data,datalen,totaldata,crcvalue);\r
+ #endif\r
break;\r
case GET_SPECIF_TYPE_FILE_CMD://获取指定类型文件目录 \r
- RemoveFileCmd(cmd,data,datalen,totaldata,crcvalue);\r
+ GetFileTypeCmd(data,datalen); //\r
break;\r
case DELETE_SPECIF_TYPE_FILE_CMD://删除指定类型的所有文件\r
DeleteFileTypeCmd(cmd,data,datalen,totaldata,crcvalue);\r
\r
}\r
\r
-//长数据解析\r
-void bleLongRecvData(uint8_t *data, uint16_t data_size,uint8_t *buf_cmd,uint8_t *totalData,uint8_t crcvalue)//buf_cmd 指令前17个字节数据\r
-{\r
- uint8_t type=buf_cmd[1];\r
- printf("type:%d %d data_size:%d data:%x crcvalue:%x\r\n",buf_cmd[0],type,data_size,data,crcvalue);\r
- switch (type)\r
- {\r
- case 0x02://获取手机信息\r
- type2AE4Data(buf_cmd,data,data_size,totalData,crcvalue);\r
- break;\r
- case 0x01:\r
- type2AE3Data(buf_cmd,data,data_size,totalData,crcvalue);\r
- break;\r
- case 0x03://\r
- type2AE1Data(buf_cmd,data,data_size,totalData,crcvalue);\r
- break;\r
- case 0x04:\r
- type2AE0Data(buf_cmd,data,data_size,totalData,crcvalue);\r
- break;\r
- default:\r
- break;\r
- }\r
-}\r
bool creatMessageDir(void)//创建消息文件夹\r
{\r
struct stat info;\r
}\r
}\r
\r
-static ota_file_struct_t g_ota_file_stat={0};\r
+void bleRecvANCSData(uint8_t *data, uint16_t data_size,uint8_t *buf_cmd,uint8_t *totalData,uint8_t crcvalue)//buf_cmd 指令前17个字节数据\r
+{\r
+ uint8_t type = buf_cmd[1];\r
+ printf("type:%d %d data_size:%d data:%d crcvalue:%x\r\n",buf_cmd[0],type,data_size,data[0],crcvalue);\r
+ switch (type)\r
+ {\r
+ case 0x03://\r
+ type2AE1Data(buf_cmd,data,data_size,totalData,crcvalue);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
\r
-errcode_t ota_json_file_save(uint8_t *data,uint16_t datalen)\r
+#if USE_PROTOCOL_EN_DE_BY_SNICKER\r
+\r
+\r
+/**\r
+ * less than 20bytes msg reply\r
+*/\r
+errcode_t ble_reply_msgarr(uint8_t msg_cmdtype,uint8_t msg_cmdid,uint8_t *replydata,uint16_t replydata_len)\r
{\r
+\r
+ //发送校验失败\r
+\r
+ if (replydata_len > 20)\r
+ {\r
+ printf("datalen is larger than 20, please send with other api !\n");\r
+ return ERRCODE_FAIL;\r
+ }\r
+ uint16_t replybuflen=sizeof(msg_header_t)+replydata_len+1;\r
+ uint8_t *replybuf=malloc(replybuflen);\r
+ if(replybuf != NULL)\r
+ {\r
+ msg_header_t *reply_cmd_header=(msg_header_t*)replybuf;\r
+ reply_cmd_header->direction = MSG_DIRECTION_SEND;\r
+ reply_cmd_header->cmdtype =msg_cmdtype;\r
+ reply_cmd_header->cmdid = msg_cmdid;\r
+ reply_cmd_header->package_count = 1;\r
+ reply_cmd_header->package_index = 1;\r
+ reply_cmd_header->package_len = replydata_len;\r
+ reply_cmd_header->total_data_len = replydata_len;\r
+ memcpy_s(replybuf+sizeof(msg_header_t),replydata_len,replydata,replydata_len); \r
+ uint8_t crc_value = Calculate_CRC( replybuf, replybuflen - 1);\r
+ replybuf[ replybuflen - 1 ] = crc_value ; //CRC\r
+ errcode_t ret = sendBleData(replybuf,replybuflen);\r
+ printf("ble_reply_msgarr cmdtype %02X cmdid %02X package %d/%d , len %d,total len %d , data[0] %02X crc %02X\n",\r
+ reply_cmd_header->cmdtype,\r
+ reply_cmd_header->cmdid,\r
+ reply_cmd_header->package_index,\r
+ reply_cmd_header->package_count,\r
+ reply_cmd_header->package_len,\r
+ reply_cmd_header->total_data_len,\r
+ (replybuf+sizeof(msg_header_t))[0],\r
+ crc_value\r
+ );\r
+ free(replybuf);\r
+ return ret;\r
+ }else{\r
+ return ERRCODE_MALLOC;\r
+ }\r
+}\r
+\r
+errcode_t ble_reply_cmdarr(uint16_t msg_cmd,uint8_t *replydata,uint16_t replydata_len)\r
+{\r
+\r
+ uint8_t cmdtype = (uint8_t)((msg_cmd&0xFF00)>>8);\r
+ uint8_t cmdid = (uint8_t)(msg_cmd&0x00FF);\r
+ \r
+ return ble_reply_msgarr(cmdtype,cmdid,replydata,replydata_len);\r
+\r
+}\r
+errcode_t ble_reply_cmd(uint16_t msg_cmd,uint8_t replydata)\r
+{\r
+ uint8_t cmdtype = (uint8_t)((msg_cmd&0xFF00)>>8);\r
+ uint8_t cmdid = (uint8_t)(msg_cmd&0x00FF);\r
+ printf("msg_cmd %04X cmdtype %02X cmdid %02X\n",msg_cmd,cmdtype,cmdid);\r
+ return ble_reply_msg(cmdtype,cmdid,replydata);\r
+}\r
+errcode_t ble_reply_msg(uint8_t msg_cmdtype,uint8_t msg_cmdid,uint8_t replydata)\r
+{\r
+ return ble_reply_msgarr(msg_cmdtype,msg_cmdid,&replydata,1);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+errcode_t decode_ota_json(ble_read_data *buffer_handle)\r
+{\r
+\r
+ uint8_t *data = buffer_handle->data+sizeof(msg_header_t);\r
+ uint16_t datalen = buffer_handle->totalDataLen;\r
printf("ota_json_file_save %s\n",data);\r
\r
/**\r
cJSON* ota_type_json = cJSON_GetObjectItem(root, "type");\r
if(ota_type_json != NULL && cJSON_IsNumber(ota_type_json))\r
{\r
- g_ota_file_stat.ota_type = ota_type_json->valueint;\r
+ buffer_handle->file_recv_stat.file_type = ota_type_json->valueint;\r
}\r
\r
cJSON* ota_name_json = cJSON_GetObjectItem(root, "name");\r
if ( ota_name_json != NULL && cJSON_IsString(ota_name_json)) {\r
- g_ota_file_stat.ota_name = ota_name_json->valuestring;\r
+ buffer_handle->file_recv_stat.file_name = ota_name_json->valuestring;\r
}\r
\r
cJSON* ota_size_json = cJSON_GetObjectItem(root, "size");\r
if(ota_size_json != NULL && cJSON_IsNumber(ota_size_json))\r
{\r
- g_ota_file_stat.ota_size = ota_size_json->valueint;\r
+ buffer_handle->file_recv_stat.file_size = ota_size_json->valueint;\r
}\r
cJSON* ota_major_json = cJSON_GetObjectItem(root, "major");\r
if(ota_major_json != NULL && cJSON_IsNumber(ota_major_json))\r
{\r
- g_ota_file_stat.ota_major = ota_major_json->valueint;\r
+ buffer_handle->file_recv_stat.ota_major = ota_major_json->valueint;\r
}\r
cJSON* ota_mid_json = cJSON_GetObjectItem(root, "mid");\r
if(ota_mid_json != NULL && cJSON_IsNumber(ota_mid_json))\r
{\r
- g_ota_file_stat.ota_mid = ota_mid_json->valueint;\r
+ buffer_handle->file_recv_stat.ota_mid = ota_mid_json->valueint;\r
}\r
cJSON* ota_minor_json = cJSON_GetObjectItem(root, "minor");\r
if(ota_minor_json != NULL && cJSON_IsNumber(ota_minor_json))\r
{\r
- g_ota_file_stat.ota_minor = ota_minor_json->valueint;\r
+ buffer_handle->file_recv_stat.ota_minor = ota_minor_json->valueint;\r
}\r
cJSON* ota_isforced_json = cJSON_GetObjectItem(root, "isForced");\r
if(ota_isforced_json != NULL && cJSON_IsNumber(ota_isforced_json))\r
{\r
- g_ota_file_stat.ota_isforced = ota_isforced_json->valueint;\r
+ buffer_handle->file_recv_stat.ota_isforced = ota_isforced_json->valueint;\r
}\r
cJSON_Delete(root);\r
\r
printf(" ota_type= %d, ota_name=%s, ota_size=%d, ota_major=%d, ota_mid=%d, ota_minor=%d, ota_isforced=%d \n",\r
- g_ota_file_stat.ota_type,\r
- g_ota_file_stat.ota_name,\r
- g_ota_file_stat.ota_size,\r
- g_ota_file_stat.ota_major,\r
- g_ota_file_stat.ota_mid,\r
- g_ota_file_stat.ota_minor,\r
- g_ota_file_stat.ota_isforced\r
+ buffer_handle->file_recv_stat.file_type,\r
+ buffer_handle->file_recv_stat.file_name,\r
+ buffer_handle->file_recv_stat.file_size,\r
+ buffer_handle->file_recv_stat.ota_major,\r
+ buffer_handle->file_recv_stat.ota_mid,\r
+ buffer_handle->file_recv_stat.ota_minor,\r
+ buffer_handle->file_recv_stat.ota_isforced\r
);\r
+ buffer_handle->file_recv_stat.received_size = 0;\r
+ buffer_handle->file_recv_stat.lrcvalue = 0;\r
+ buffer_handle->receive_file_flag = 1;\r
+ return ERRCODE_SUCC;\r
+ }else{\r
+ buffer_handle->receive_file_flag = 0; \r
+ return ERRCODE_FAIL;\r
+ }\r
+}\r
\r
+void decode_file_checksum(ble_read_data *buffer_handle)\r
+{\r
+\r
+ uint8_t msg_crc = get_crc_from_lrc(buffer_handle->lrcvalue);\r
+ if (msg_crc == buffer_handle->crcvalue)\r
+ {\r
+ uint8_t file_crc = get_crc_from_lrc(buffer_handle->file_recv_stat.lrcvalue);\r
+ uint8_t crc_recv = buffer_handle->data[sizeof(msg_header_t)];\r
+ if (file_crc == crc_recv)\r
+ {\r
+ ble_reply_cmd(FILE_CHECKSUM_RECV_CMD,1);\r
+ do_custom_cmd_service_check_msg(CUSTOM_CMD_MSG_TYPE_STARTOTA,NULL,0);\r
+ }else{\r
+ ble_reply_cmd(FILE_CHECKSUM_RECV_CMD,2);\r
+ }\r
+ }else{\r
+ ble_reply_cmd(FILE_CHECKSUM_RECV_CMD,0);\r
}\r
- return ERRCODE_SUCC;\r
+ \r
}\r
\r
-void type2AE0Data(uint8_t *buf_cmd,uint8_t *data,uint16_t datalen,uint8_t *totalData,uint8_t crcvalue)\r
+void type2AE0Data(ble_read_data *buffer_handle)\r
{\r
- uint16_t typeID = buf_cmd[1]*256 +buf_cmd[2];\r
- printf("type2AE0Data typeID:0x%x datalen %d\r\n",typeID,datalen);\r
- bool checkcrc = Check_CRC(data,datalen,crcvalue);\r
+ uint16_t typeID = buffer_handle->cmd_header.cmdtype*256 + buffer_handle->cmd_header.cmdid;\r
+ printf("type2AE0Data typeID:0x%x datalen %d\r\n",typeID,buffer_handle->totalDataLen);\r
+ bool checkcrc = (get_crc_from_lrc(buffer_handle->lrcvalue) == buffer_handle->crcvalue);\r
if( checkcrc == true )\r
{\r
switch (typeID) //ID\r
{\r
case OTA_FILE_RECV_CMD://\r
- ota_json_file_save( data, datalen);\r
+ {\r
+ if (decode_ota_json( buffer_handle) == ERRCODE_SUCC)\r
+ {\r
+ ble_reply_cmd(OTA_FILE_RECV_CMD,1);\r
+ }else{\r
+ ble_reply_cmd(OTA_FILE_RECV_CMD,2);\r
+ } \r
+ }\r
+ break;\r
+ case MP3_FILE_RECV_CMD:\r
+\r
+ break;\r
+ case DIAL_FILE_RECV_CMD:\r
+ break;\r
+ case FILE_CHECKSUM_RECV_CMD:\r
+ decode_file_checksum(buffer_handle);\r
+ break;\r
+ case EPO_DATA_RECV_CMD:\r
break;\r
+ case SINGLE_DIAL_FILE_RECV_CMD:\r
+ break;\r
+ default:\r
+ break; \r
}\r
\r
}else{\r
}\r
\r
}\r
-void bleRecvANCSData(uint8_t *data, uint16_t data_size,uint8_t *buf_cmd,uint8_t *totalData,uint8_t crcvalue)//buf_cmd 指令前17个字节数据\r
-{\r
- uint8_t type = buf_cmd[1];\r
- printf("type:%d %d data_size:%d data:%d crcvalue:%x\r\n",buf_cmd[0],type,data_size,data[0],crcvalue);\r
- switch (type)\r
- {\r
- case 0x03://\r
- type2AE1Data(buf_cmd,data,data_size,totalData,crcvalue);\r
- break;\r
- default:\r
- break;\r
- }\r
-}\r
-\r
-uint32_t packdataLen = 0;\r
-uint32_t totalDataLen = 0;\r
-uint8_t totalpack = 0;\r
-uint8_t cmd_data[17];\r
-uint8_t *recvData;\r
-#include "los_memory.h"\r
\r
\r
-#if USE_PROTOCOL_EN_DE_BY_SNICKER\r
-#define MAX_BLE_MSG_PACKAGE_LEN (1024*5) //包缓存最大5k\r
-typedef struct \r
-{\r
- uint8_t *data;\r
- int handle;\r
- int data_len ;\r
- int totalDataLen;\r
- msg_header_t cmd_header;\r
- uint8_t crcvalue;\r
-} ble_read_data;\r
-\r
-#define MAX_HANDLE_NUM 10\r
-//LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus)\r
-//根据特征值分开组合读取的数据,并处理\r
-static ble_read_data handle_l[MAX_HANDLE_NUM]={0};\r
-\r
void dumpHeader(msg_header_t *msgheader)\r
{\r
printf("dumpHeader(%d) direction %02X, type %02X, id %02X, package_count %d, total_data_len %d,package_index %d , package_len %d\n",\r
);\r
}\r
\r
+errcode_t check_header(msg_header_t *header )\r
+{\r
+ if( (header->direction == MSG_DIRECTION_RECV) \r
+ && (header->cmdtype > 0 && header->cmdtype <= 6 )\r
+ && (header->cmdid > 0 && header->cmdid <= 0x50 )\r
+ )\r
+ {\r
+ // 这个是合理的值,可以当做header来处理\r
+ dumpHeader(header);\r
+ return ERRCODE_SUCC;\r
+ }else{\r
+ //非header\r
+ // printf("not first package , no header!\n");\r
+ return ERRCODE_FAIL;\r
+ }\r
+}\r
+errcode_t cancel_recv_file(ble_read_data *buffer_handle)\r
+{\r
+\r
+ buffer_handle->receive_file_flag = 0;\r
+\r
+ if (buffer_handle->file_recv_stat.recv_file_stat != 2) //已经下载完毕的文件,没有必要cancel了。\r
+ {\r
+\r
+ if (buffer_handle->file_recv_stat.file!=NULL)\r
+ {\r
+ fclose(buffer_handle->file_recv_stat.file);\r
+ buffer_handle->file_recv_stat.file = NULL;\r
+ }\r
+ buffer_handle->file_recv_stat.recv_file_stat = -1;\r
+ ble_reply_cmd(FILE_RECV_REPLY_STAT_CMD,0);//接收失败\r
+ }\r
+ return ERRCODE_SUCC;\r
+}\r
+errcode_t handle_recv_file(ble_read_data *buffer_handle,uint8_t *data, uint16_t event_size)\r
+{\r
+\r
+ if( event_size == 0 || data == NULL ) return ERRCODE_FAIL;\r
+ \r
+\r
+ printf("handle_recv_file %d\n",event_size);\r
+\r
+ //第一帧要创建文件\r
+ if(buffer_handle->file_recv_stat.recv_file_stat <= 0 && buffer_handle->file_recv_stat.file == NULL)\r
+ {\r
+ buffer_handle->file_recv_stat.lrcvalue = 0;\r
+ if (buffer_handle->file_recv_stat.file_type == 1)\r
+ {\r
+ buffer_handle->file_recv_stat.file = fopen("/update/update.fwpkg","w+");\r
+ printf("create file /update/update.fwpkg %X\n",buffer_handle->file_recv_stat.file);\r
+ }else{\r
+ buffer_handle->file_recv_stat.file = fopen(buffer_handle->file_recv_stat.file_name,"w+");\r
+ printf("create file %s %X\n",buffer_handle->file_recv_stat.file_name,buffer_handle->file_recv_stat.file);\r
+ }\r
+ if (buffer_handle->file_recv_stat.file == NULL)\r
+ {\r
+ return ERRCODE_FAIL;\r
+ }\r
+ buffer_handle->file_recv_stat.recv_file_stat = 1;\r
+ }\r
+\r
+ if (buffer_handle->file_recv_stat.file == NULL)\r
+ {\r
+ return ERRCODE_FAIL;\r
+ }\r
+ //写入文件\r
+ size_t writtensize = fwrite(data,1,event_size,buffer_handle->file_recv_stat.file);\r
+ if(writtensize == event_size)\r
+ {\r
+ buffer_handle->file_recv_stat.lrcvalue = calculate_lrc(data,event_size,buffer_handle->file_recv_stat.lrcvalue);\r
+ buffer_handle->file_recv_stat.received_size += event_size;\r
+ printf("handle_recv_file received_size %d\n",buffer_handle->file_recv_stat.received_size);\r
+\r
+ }else{\r
+ printf("handle_recv_file write file failed! ret %d != %d\n",writtensize,event_size);\r
+ return ERRCODE_FAIL;\r
+ }\r
+\r
+ //检查文件是否写完\r
+ if(buffer_handle->file_recv_stat.file_size == buffer_handle->file_recv_stat.received_size )\r
+ {\r
+ if (buffer_handle->file_recv_stat.file!=NULL)\r
+ {\r
+ fclose(buffer_handle->file_recv_stat.file);\r
+ buffer_handle->file_recv_stat.file = NULL;\r
+ }\r
+ buffer_handle->file_recv_stat.recv_file_stat = 2;\r
+ buffer_handle->receive_file_flag = 0;\r
+ printf("handle_recv_file received success \n");\r
+ ble_reply_cmd(FILE_RECV_REPLY_STAT_CMD,1);//接收成功\r
+ }\r
+\r
+ return ERRCODE_SUCC;\r
+}\r
+\r
+//长数据解析\r
+void bleLongRecvData(ble_read_data *buffer_handle,uint8_t *data, uint16_t data_size,uint8_t *buf_cmd,uint8_t *totalData,uint8_t crcvalue)//buf_cmd 指令前17个字节数据\r
+{\r
+ uint8_t type=buf_cmd[1];\r
+ printf("type:%d %d data_size:%d data:%x crcvalue:%x\r\n",\r
+ buffer_handle->cmd_header.cmdtype,\r
+ buffer_handle->cmd_header.cmdid,\r
+ data_size,\r
+ data,\r
+ crcvalue);\r
\r
+ switch (type)\r
+ {\r
+ case 0x02://获取手机信息\r
+ type2AE4Data(buf_cmd,data,data_size,totalData,crcvalue);\r
+ break;\r
+ case 0x01:\r
+ type2AE3Data(buffer_handle,buf_cmd,data,data_size,totalData,crcvalue);\r
+ break;\r
+ case 0x03://\r
+ type2AE1Data(buf_cmd,data,data_size,totalData,crcvalue);\r
+ break;\r
+ case 0x04:\r
+ type2AE0Data(buffer_handle);\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+/// @brief 解码收到的msg\r
+/// @param buffer_handle \r
+/// @return \r
+static errcode_t handle_ble_msg(ble_read_data *buffer_handle)\r
+{\r
+\r
+ if(buffer_handle->buffer_to_file == 0)\r
+ {\r
+ bleLongRecvData(buffer_handle,buffer_handle->data+sizeof(msg_header_t),buffer_handle->totalDataLen,(uint8_t*)(&buffer_handle->cmd_header),NULL,buffer_handle->crcvalue);\r
+\r
+ }else{\r
+ //处理缓存成文件的 \r
+ printf("handle ble msg file buffer! not implement\n");\r
+ }\r
+ return ERRCODE_SUCC;\r
+}\r
/*****\r
* 组包函数\r
* 组包校验完成,在分发给对应的handler去解码协议。\r
errcode_t combine_data_internal(ble_read_data *buffer_handle,uint8_t *totalData, uint16_t event_size)\r
{\r
\r
- msg_header_t *header = (msg_header_t*)totalData;\r
- dumpHeader(header);\r
- buffer_handle->cmd_header.direction = header->direction;\r
- buffer_handle->cmd_header.cmdtype = header->cmdtype;\r
- buffer_handle->cmd_header.cmdid = header->cmdid;\r
- buffer_handle->cmd_header.package_count = header->package_count;\r
- buffer_handle->cmd_header.total_data_len = header->total_data_len;\r
- buffer_handle->cmd_header.package_len = header->package_len;\r
- buffer_handle->cmd_header.package_index = header->package_index;\r
\r
- //第一帧\r
- if (buffer_handle->cmd_header.package_index == 1)\r
+ if(buffer_handle->receive_file_flag == 1)\r
{\r
+ //接收文件\r
+ return handle_recv_file(buffer_handle,totalData,event_size);\r
+ }\r
+ msg_header_t *header = (msg_header_t*)totalData; \r
+ //第一帧\r
+ if (event_size > sizeof(msg_header_t) && check_header(header) == ERRCODE_SUCC )\r
+ {\r
+ buffer_handle->cmd_header.direction = header->direction;\r
+ buffer_handle->cmd_header.cmdtype = header->cmdtype;\r
+ buffer_handle->cmd_header.cmdid = header->cmdid;\r
+ buffer_handle->cmd_header.package_count = header->package_count;\r
+ buffer_handle->cmd_header.total_data_len = header->total_data_len;\r
+ buffer_handle->cmd_header.package_len = header->package_len;\r
+ buffer_handle->cmd_header.package_index = header->package_index;\r
//如果有历史数据,没有被清空,可能是历史错误数据,则清空内存。\r
if (buffer_handle->data!=NULL && buffer_handle->data_len > 0)\r
{\r
free(buffer_handle->data);\r
buffer_handle->data = NULL;\r
- buffer_handle->data_len = 0;\r
}\r
+ if (buffer_handle->tmpfilehandle!=NULL && buffer_handle->data_len>0)\r
+ {\r
+ fclose(buffer_handle->tmpfilehandle);\r
+ buffer_handle->tmpfilehandle = NULL;\r
+ }\r
+ buffer_handle->data_len = 0;\r
+ buffer_handle->crcvalue = 0;\r
+ buffer_handle->lrcvalue = 0;\r
+ buffer_handle->buffer_to_file = 0;\r
+ buffer_handle->decode_type = 0;\r
+ buffer_handle->tmpfilehandle = NULL;\r
+ uint32_t timestamp_ble=0;\r
+ uapi_get_timestampe_ms(×tamp_ble);\r
+ buffer_handle->last_timestamp = timestamp_ble;\r
buffer_handle->totalDataLen = buffer_handle->cmd_header.total_data_len;\r
if (buffer_handle->totalDataLen > MAX_BLE_MSG_PACKAGE_LEN || buffer_handle->totalDataLen <= 0 )\r
{\r
printf("package is too lardge (%d) than (%d) or too small !\n",buffer_handle->totalDataLen,MAX_BLE_MSG_PACKAGE_LEN);\r
return ERRCODE_FAIL;\r
}\r
- buffer_handle->data = malloc(buffer_handle->totalDataLen);\r
+ if(buffer_handle->totalDataLen+sizeof(msg_header_t)+1 > MAX_BLE_MSG_PACKAGE_LEN)\r
+ {\r
+ //如果总长度超过限定大小,则写入文件做缓存。\r
+ buffer_handle->buffer_to_file = 1;\r
+ int filelen = strlen(BLE_MSG_TMP_FILE_NAME);\r
+ buffer_handle->data = malloc(filelen);\r
+ if (buffer_handle->data== NULL) \r
+ {\r
+ return ERRCODE_MALLOC;\r
+ }\r
+ //生成临时文件名\r
+ sprintf_s((char*)buffer_handle->data,filelen,BLE_MSG_TMP_FILE_NAME,buffer_handle->handle);\r
+ buffer_handle->tmpfilehandle = fopen((const char*)buffer_handle->data,"w+");\r
+ printf("create ble protocol tmpfile %s handle %X\n",buffer_handle->data,buffer_handle->tmpfilehandle);\r
+ if (buffer_handle->tmpfilehandle != NULL)\r
+ {\r
+ //写buffer到文件\r
+ size_t ret =fwrite(totalData,1,event_size,buffer_handle->tmpfilehandle);\r
+ buffer_handle->lrcvalue = calculate_lrc(totalData+sizeof(msg_header_t),header->package_len,0x00);\r
+ printf("write %d to buffer file!\n",ret);\r
+ }\r
+ buffer_handle->data_len += event_size;\r
+ \r
+ }else{\r
+ //如果长度在限定大小之内。则写入内存中缓存。\r
+ buffer_handle->buffer_to_file = 0;\r
+ buffer_handle->data = malloc(buffer_handle->totalDataLen+sizeof(msg_header_t)+1);\r
+ if (buffer_handle->data== NULL) \r
+ {\r
+ return ERRCODE_MALLOC;\r
+ }\r
+ //创建缓存开始存储包数据\r
+ if(buffer_handle->cmd_header.package_len >0)\r
+ {\r
+ memcpy_s(buffer_handle->data,buffer_handle->totalDataLen+sizeof(msg_header_t)+1,totalData,event_size);\r
+ buffer_handle->lrcvalue = calculate_lrc(totalData+sizeof(msg_header_t),header->package_len,0x00);\r
+ buffer_handle->data_len += event_size;\r
+ }\r
+\r
+ //单一包\r
+ if(event_size == sizeof(msg_header_t)+buffer_handle->totalDataLen+1)\r
+ {\r
+ buffer_handle->crcvalue = totalData[event_size-1];\r
+ }\r
+ } \r
+ \r
+ }else{\r
+ //处理第二包以后的数据\r
+\r
+ //经过第一包处理,仍然data==NULL证明第一帧就是错的,要退出解析。\r
if (buffer_handle->data== NULL) \r
{\r
return ERRCODE_MALLOC;\r
}\r
- }\r
- //经过第一包处理,仍然data==NULL证明第一帧就是错的,要退出解析。\r
- if (buffer_handle->data== NULL) \r
- {\r
- return ERRCODE_MALLOC;\r
- }\r
- //创建缓存开始存储包数据\r
- if(buffer_handle->cmd_header.package_len >0)\r
- {\r
-\r
-\r
+ //此处是最后一帧 event_size = (buffer_handle->totalDataLen-buffer_handle->data_len) + 1\r
+ if (event_size == (buffer_handle->totalDataLen + sizeof(msg_header_t) + 1 -buffer_handle->data_len ))\r
+ {\r
+ if(buffer_handle->buffer_to_file == 1)\r
+ {\r
+ fwrite(totalData,1,event_size,buffer_handle->tmpfilehandle);\r
+ \r
+ }else{\r
+ memcpy_s(buffer_handle->data+buffer_handle->data_len,buffer_handle->totalDataLen,totalData,event_size);\r
+ \r
+ }\r
+ buffer_handle->lrcvalue = calculate_lrc(totalData,event_size,buffer_handle->lrcvalue);\r
+ buffer_handle->data_len += event_size; \r
+ }else if (event_size < (buffer_handle->totalDataLen + sizeof(msg_header_t) + 1 - buffer_handle->data_len)) //中间帧\r
+ {\r
+ if(buffer_handle->buffer_to_file == 1)\r
+ {\r
+ fwrite(totalData,1,event_size,buffer_handle->tmpfilehandle);\r
+ \r
+ }else{\r
+ memcpy_s(buffer_handle->data+buffer_handle->data_len,(buffer_handle->totalDataLen + sizeof(msg_header_t) + 1 - buffer_handle->data_len),totalData,event_size);\r
+ \r
+ }\r
+ buffer_handle->lrcvalue = calculate_lrc(totalData,event_size,buffer_handle->lrcvalue);\r
+ buffer_handle->data_len += event_size; \r
+ }else{ //异常帧\r
+ printf("error event_size %d , should <= %d\n",event_size, (buffer_handle->totalDataLen + sizeof(msg_header_t) + 1 - buffer_handle->data_len) );\r
+ \r
+ }\r
+ \r
}\r
//如果包完整接收,进行crc校验\r
- if(buffer_handle->data_len == buffer_handle->totalDataLen)\r
+ if( (buffer_handle->totalDataLen + sizeof(msg_header_t) + 1 ) == buffer_handle->data_len )\r
{\r
+ //我们认为最后一个包,应该不包含其他包,因此其最后一位,应当就是crc值,因此可直接获取crc值\r
+ buffer_handle->crcvalue = buffer_handle->data[buffer_handle->data_len - 1];//获取crc\r
+ //最后一位校验位清0,方便字符串处理\r
+ buffer_handle->data[buffer_handle->data_len - 1] = 0;\r
\r
+ //缓存到文件的,处理方法会不同因此单独解决\r
+ if(buffer_handle->buffer_to_file == 1)\r
+ {\r
+ //先关闭临时文件,然后把文件名给协议解析函数即可。\r
+ if (buffer_handle->tmpfilehandle != NULL)\r
+ {\r
+ fclose(buffer_handle->tmpfilehandle);\r
+ buffer_handle->tmpfilehandle=NULL;\r
+ }\r
+ }\r
+ // #define COMMON_CRC_MSG \r
+ //通用回复crc校验结果,不是所有指令都一致,暂时取消,在每个指令内部进行回复\r
+ #ifdef COMMON_CRC_MSG \r
+ if (get_crc_from_lrc(buffer_handle->lrcvalue) != buffer_handle->crcvalue)\r
+ {\r
+ //发送校验失败\r
+ ble_reply_msg(buffer_handle->cmd_header.cmdtype,buffer_handle->cmd_header.cmdid,0);\r
\r
+ }else \r
+ #endif \r
+ {\r
+ //协议解析指令\r
+ handle_ble_msg(buffer_handle);\r
+ }\r
+ //所有操作都完成,要释放 data \r
+ if(buffer_handle->data != NULL)\r
+ {\r
+ free(buffer_handle->data);\r
+ buffer_handle->data=NULL;\r
+ }\r
+ \r
}\r
return ERRCODE_SUCC;\r
}\r
\r
+\r
+\r
void bleDataRecv(uint8_t *totalData, uint16_t event_size,uint16_t handle)\r
{\r
\r
return;\r
}\r
printf("bleDataRecv handle:%d\r\n",handle); \r
-\r
+ int last_unused_handle_index = -1;\r
+ int handle_index_found = -1;\r
for(int i = 0;i<MAX_HANDLE_NUM;i++)\r
- {\r
- if(handle_l[i].handle == 0)//第一次用 \r
+ { \r
+ if(handle_l[i].handle == 0 && last_unused_handle_index == -1)\r
{\r
- handle_l[i].handle = handle; \r
+ last_unused_handle_index = i; \r
}\r
if(handle_l[i].handle == handle)\r
{\r
//找到当前handle的缓存数据 ,进行组包\r
- combine_data_internal(&handle_l[i],totalData,event_size);\r
+ handle_index_found = i;\r
+ break;\r
}\r
}\r
+ //如果没找到已经用到的handle_l,就用第一个空的handle_l\r
+ if(last_unused_handle_index >=0 && handle_index_found == -1)\r
+ {\r
+ handle_index_found = last_unused_handle_index; \r
+ }\r
+\r
+ if(handle_index_found>=0)\r
+ {\r
+ printf("handle_index_found:index %d addr %X\r\n",handle_index_found,&handle_l[handle_index_found]); \r
+ handle_l[handle_index_found].handle = handle;\r
+ combine_data_internal(&handle_l[handle_index_found],totalData,event_size);\r
+ }\r
+ else\r
+ printf("no empty handle_l found! skip this msg!\n");\r
+\r
+ \r
}\r
\r
void free_ble_data(void)//以防断开蓝牙没有释放数据类型\r
\r
}\r
#else \r
-typedef struct \r
+\r
+\r
+\r
+//长数据解析\r
+void bleLongRecvData(uint8_t *data, uint16_t data_size,uint8_t *buf_cmd,uint8_t *totalData,uint8_t crcvalue)//buf_cmd 指令前17个字节数据\r
{\r
- uint8_t *data;\r
- int handle;\r
- int data_len ;\r
- int totalDataLen;\r
- uint8_t cmd_data[17];\r
- uint8_t crcvalue;\r
-} ble_read_data;\r
+ uint8_t type=buf_cmd[1];\r
+ printf("type:%d %d data_size:%d data:%x crcvalue:%x\r\n",buf_cmd[0],type,data_size,data,crcvalue);\r
+\r
+ switch (type)\r
+ {\r
+ case 0x02://获取手机信息\r
+ type2AE4Data(buf_cmd,data,data_size,totalData,crcvalue);\r
+ break;\r
+ case 0x01:\r
+ type2AE3Data(buf_cmd,data,data_size,totalData,crcvalue);\r
+ break;\r
+ case 0x03://\r
+ type2AE1Data(buf_cmd,data,data_size,totalData,crcvalue);\r
+ break;\r
+ case 0x04:\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+}\r
+\r
\r
-#define MAX_HANDLE_NUM 10\r
-//LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus)\r
-//根据特征值分开组合读取的数据,并处理\r
-static ble_read_data handle_l[MAX_HANDLE_NUM]={0};\r
void bleDataRecv(uint8_t *totalData, uint16_t event_size,uint16_t handle)\r
{\r
\r