重构ble通讯协议接收代码,增加 ota文件接收,实现ota升级能力 173/1 173/head 174/target/1
authorSnickerSun <snickersun@163.com>
Thu, 16 May 2024 12:32:51 +0000 (20:32 +0800)
committerSnickerSun <snickersun@163.com>
Thu, 16 May 2024 12:32:51 +0000 (20:32 +0800)
code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.c
code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.h
code/sdk/drivers/peripheral/utils/custom_cmd_service.c
code/sdk/drivers/peripheral/utils/custom_utils.h

index 675585c..a6c7ce1 100644 (file)
@@ -39,7 +39,7 @@ extern "C" {
 #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
@@ -221,10 +221,12 @@ void cameram_data(void)//拍照发送数据 调用这个接口即可
 }\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
@@ -234,11 +236,33 @@ static bool Check_CRC(uint8_t *data,uint16_t len,uint8_t crcvalue)//计算20byte
                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
@@ -256,38 +280,20 @@ static uint8_t Calculate_CRC(uint8_t *data,uint16_t len)//计算20byte
 {\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
@@ -347,6 +353,73 @@ void send_big_data(uint8_t flag, char *data, int datalen, int total, uint32_t Pa
 \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
@@ -1883,9 +1956,7 @@ void GetWeatherCmd(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *totalData,ui
 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
@@ -2488,7 +2559,11 @@ static void GetSwitchMessCmd(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *to
     }\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
@@ -2508,6 +2583,10 @@ static void RemoveFileCmd(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *total
         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
@@ -3913,10 +3992,14 @@ len 就是data的长度
 *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
@@ -3945,10 +4028,12 @@ void type2AE3Data(uint8_t *cmd_buf ,uint8_t *data,uint16_t datalen,uint8_t *tota
             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
@@ -4431,29 +4516,6 @@ void getPhoneInfo_test(void)
 \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
@@ -4729,10 +4791,101 @@ void type2AE1Data(uint8_t *buf_cmd,uint8_t *data,uint16_t datalen,uint8_t *total
     }\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
@@ -4757,67 +4910,114 @@ errcode_t ota_json_file_save(uint8_t *data,uint16_t datalen)
         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
@@ -4825,45 +5025,8 @@ void type2AE0Data(uint8_t *buf_cmd,uint8_t *data,uint16_t datalen,uint8_t *total
     }\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
@@ -4878,7 +5041,148 @@ void dumpHeader(msg_header_t *msgheader)
     );\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
@@ -4887,58 +5191,179 @@ void dumpHeader(msg_header_t *msgheader)
 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(&timestamp_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
@@ -4952,19 +5377,37 @@ void bleDataRecv(uint8_t *totalData, uint16_t event_size,uint16_t handle)
         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
@@ -4980,20 +5423,34 @@ void free_ble_data(void)//以防断开蓝牙没有释放数据类型
     \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
index 7321c58..cc5d552 100644 (file)
@@ -95,11 +95,15 @@ void cameram_send_data(void);
 #define FIND_PHONE_CMD 0x0501 //同步睡眠历史数据
 
 
-#define USE_PROTOCOL_EN_DE_BY_SNICKER 0
+#define USE_PROTOCOL_EN_DE_BY_SNICKER 1
 
 #if USE_PROTOCOL_EN_DE_BY_SNICKER
+
+
 #define MSG_DIRECTION_RECV 0x73
-#define MSG_DIRECTION_SEND 0x71
+#define MSG_DIRECTION_SEND 0x72
+
+#define MAX_INTERVAL_MS_BETWEEN_2_CMD 50  // 50ms 在一个分包里,如果多个指令间超过50ms,则认为分包失败
 
 /*******************data structure*************************/
 
@@ -132,6 +136,12 @@ typedef struct
     uint8_t  crc; //校验位 数据包后最后一位
 }msg_data_t;
 
+
+errcode_t ble_reply_cmd(uint16_t msg_cmd,uint8_t replydata);
+errcode_t ble_reply_cmdarr(uint16_t msg_cmd,uint8_t *replydata,uint16_t replydata_len);
+errcode_t ble_reply_msg(uint8_t msg_cmdtype,uint8_t msg_cmdid,uint8_t replydata);
+errcode_t ble_reply_msgarr(uint8_t msg_cmdtype,uint8_t msg_cmdid,uint8_t *replydata,uint16_t replydata_len);
+
 #endif
 #pragma pack(1)
 typedef struct
@@ -537,6 +547,13 @@ typedef struct
 
 /****************OTA******************************************/
 #define OTA_FILE_RECV_CMD 0x0420
+#define MP3_FILE_RECV_CMD 0x0421
+#define DIAL_FILE_RECV_CMD 0x0422
+#define FILE_CHECKSUM_RECV_CMD 0x0423
+#define SINGLE_DIAL_FILE_RECV_CMD 0x0424
+#define EPO_DATA_RECV_CMD 0x0425
+#define FILE_RECV_REPLY_STAT_CMD 0x0520
+
 
 /***********************长指令>20字节****************************************/
 /*******************TYPE+ID**********************/
@@ -647,14 +664,20 @@ typedef struct
 
 typedef struct 
 {
-    uint8_t ota_type;
-    uint32_t ota_size;
+    uint8_t file_type; //1 ota file , 2 mp3 file , 3 dial file, 7 epo file
+    uint32_t file_size;
     uint8_t ota_major;
     uint8_t ota_mid;
     uint8_t ota_minor;
-    uint8_t ota_isforced;
-    char    *ota_name;
-}ota_file_struct_t;
+    uint8_t ota_isforced;    
+    char* file_name;
+    FILE* file;
+    uint32_t received_size;
+    uint8_t lrcvalue;//crc 校验算子
+    int recv_file_stat; //0 not start , 1 reciving , -1 error or stop , 2 success
+} file_recv_stat_t;
+
+
 
         
 
@@ -662,9 +685,9 @@ typedef struct
 
 void revBleOldData(uint8_t *buf, uint16_t event_size,uint16_t handle);//协议接收client下发的数据接口
 //02类型的指令数据
-void type2AE3Data(uint8_t *cmd_buf ,uint8_t *data,uint16_t datalen,uint8_t *totaldata,uint8_t crcvalue);//对不同指令ID进行区分
+// void type2AE3Data(uint8_t *cmd_buf ,uint8_t *data,uint16_t datalen,uint8_t *totaldata,uint8_t crcvalue);//对不同指令ID进行区分
 void type2AE1Data(uint8_t *buf_cmd,uint8_t *data,uint16_t datalen,uint8_t *totalData,uint8_t crcvalue);
-void type2AE0Data(uint8_t *buf_cmd,uint8_t *data,uint16_t datalen,uint8_t *totalData,uint8_t crcvalue);
+// void type2AE0Data(uint8_t *buf_cmd,uint8_t *data,uint16_t datalen,uint8_t *totalData,uint8_t crcvalue);
 void type2AE4Data(uint8_t *buf_cmd,uint8_t *data,uint16_t datalen,uint8_t *totalData,uint8_t crcvalue);
 void type2AE5Data(uint8_t *buf_cmd,uint8_t *data,uint16_t datalen,uint8_t *totalData,uint8_t crcvalue);
 
index 41bba13..ee0be8c 100644 (file)
@@ -125,8 +125,11 @@ static void custom_cmd_service_check_task(void const *arg)
                 UnbindSucessCmd(1);//1确认解绑
                 uapi_delete_files();
                 uapi_reboot_device();
-             }
-             break;
+            }
+            break;
+        case CUSTOM_CMD_MSG_TYPE_STARTOTA:
+            uaip_cmd_update_request();
+            break;
         default:
             PRINT("Unknown CUSTOM_CMD_MSG cmd 0x%02X \r\n", mail.cmd);
             break;
index 4fe064a..3827aa1 100644 (file)
@@ -156,6 +156,7 @@ uint32_t uapi_calendar_store_date(void);
 #define CUSTOM_CMD_MSG_TYPE_CHANGE_CALL_VOLUME 0x03
 #define CUSTOM_CMD_MSG_TYPE_REMOVE_CAT1VOTE 0x04
 #define CUSTOM_CMD_MSG_TYPE_RESTORE_FACTORY_SETTING 0x05
+#define CUSTOM_CMD_MSG_TYPE_STARTOTA 0x06
 
 errcode_t uapi_custom_cmd_service_init(void);
 void do_custom_cmd_service_check_msg(int cmd, void *params, int paramlen);