From bc4a622140b0d4c639dd93b66851e95bc9230375 Mon Sep 17 00:00:00 2001 From: hcj <1224667075@qq.com> Date: Fri, 26 Jul 2024 16:39:29 +0800 Subject: [PATCH] =?utf8?q?=E5=A2=9E=E5=8A=A0=202AE6=E6=96=87=E4=BB=B6?= =?utf8?q?=E4=BC=A0=E8=BE=93=20=E5=A2=9E=E5=8A=A0=E8=87=AA=E5=AE=9A?= =?utf8?q?=E4=B9=89=E8=A1=A8=E7=9B=98=E6=96=87=E4=BB=B6=E4=BC=A0=E8=BE=93?= =?utf8?q?=20=E4=BF=AE=E5=A4=8D=E9=80=9A=E8=AE=AF=E5=BD=95=E4=B8=8D?= =?utf8?q?=E6=98=BE=E7=A4=BA=E5=A4=9A=E4=B8=AA=E7=94=B5=E8=AF=9DBUG?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../nativeui/bluetooth/src/BluetoothModel.cpp | 12 +- .../nativeui/phone/src/phoneaddressmodel.cpp | 25 +- .../nativeui/set_dial/include/SetDialModel.h | 3 +- .../nativeui/set_dial/src/SetDialModel.cpp | 38 ++ .../service/ble_service/blemoder/bletest.cpp | 10 + .../service/ble_service/blemoder/bletest.h | 2 + .../service/ble_service/bleservice/bleEvent.c | 609 +++++++++++++----- .../service/ble_service/bleservice/bleEvent.h | 6 +- .../ble_service/bleservice/bleService.c | 57 +- .../ble_service/bleservice/bleService.h | 1 + 10 files changed, 586 insertions(+), 177 deletions(-) diff --git a/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothModel.cpp index 896ca215c..7ea5b313e 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/bluetooth/src/BluetoothModel.cpp @@ -972,12 +972,12 @@ void BluetoothModel::BtGapAclStateChangedHandle(gap_acl_state_t state, unsigned // 回调:ACL连接状态上报 void GapAclStateChangedCallback(const bd_addr_t *bdAddr, gap_acl_state_t state, unsigned int reason) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "bt GapAclStateChangedCallback state %d, reason %x succ or err", state, reason); - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "addr: %02x%02x%02x%02x%02x%02x", + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "bt GapAclStateChangedCallback state %d, reason %x succ or err", state, reason); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "addr: %02x%02x%02x%02x%02x%02x", bdAddr->addr[5], bdAddr->addr[4], bdAddr->addr[3], /* mac下标 0 1 2 3 4 5 */ bdAddr->addr[2], bdAddr->addr[1], bdAddr->addr[0]); /* mac下标 0 1 2 3 4 5 */ if ((gap_get_device_class(bdAddr) & 0x200) != 0) { - WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "GapAclStateChangedCallback: Mobile Phone Device"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GapAclStateChangedCallback: Mobile Phone Device"); return; } GraphicService::GetInstance()->PostGraphicEvent( @@ -1412,8 +1412,14 @@ void BtA2dpDeInit(void) a2dp_snk_deregister_callbacks(&g_a2dp_snk_callbacks); } +static void sample_gap_state_changed_callback(const int transport, const int status) +{ + printf("gap_state_changed_callback transport: %d status: %d\n", transport, status); +} + void BtInitCallBacks(void) { + g_btGapCallBacks.state_change_callback=sample_gap_state_changed_callback; g_btGapCallBacks.discovery_result_callback = BtGapDiscoveryResultCallback; g_btGapCallBacks.discovery_state_changed_callback = BtGapDiscoveryStateChangedCallback; g_btGapCallBacks.acl_state_changed_callbak = GapAclStateChangedCallback; diff --git a/code/sdk/application/wearable/fd230app/nativeui/phone/src/phoneaddressmodel.cpp b/code/sdk/application/wearable/fd230app/nativeui/phone/src/phoneaddressmodel.cpp index e2ae148d1..d29a4bb52 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/phone/src/phoneaddressmodel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/phone/src/phoneaddressmodel.cpp @@ -86,21 +86,27 @@ namespace OHOS printf("号码: %s\r\n",addressbook_t.Contact_t[j].phone_number_t[i].number); // addressbook_t.Contact_t[j].phone_number_t[i].number=phonen_name; offset=offset+phonen_len+1; - } - for(int i=0;i AREA_LEN) + { + addressbook_t.Contact_t[j].phone_number_t[i].affiliating_area[AREA_LEN]='\0'; + memcpy(addressbook_t.Contact_t[j].phone_number_t[i].affiliating_area,&buf[offset+1],AREA_LEN); + }else{ + memcpy(addressbook_t.Contact_t[j].phone_number_t[i].affiliating_area,&buf[offset+1],add); + } + printf("归属地: %s\r\n",addressbook_t.Contact_t[j].phone_number_t[i].affiliating_area); // addressbook_t.Contact_t[j].phone_number_t[i].affiliating_area=add_buf; + offset=offset+add+1; uint8_t yun = buf[offset]; // char *yun_buf=(char *)malloc(sizeof(char)*yun+1); - memset(addressbook_t.Contact_t[j].phone_number_t[i].operator_t,0,yun+1); + memset(addressbook_t.Contact_t[j].phone_number_t[i].operator_t,0,OPERATOR_LEN); if(yun > OPERATOR_LEN) { addressbook_t.Contact_t[j].phone_number_t[i].operator_t[OPERATOR_LEN]='\0'; @@ -112,7 +118,10 @@ namespace OHOS // addressbook_t.Contact_t[j].phone_number_t[i].operator_t=yun_buf; offset=offset+yun+1; + + } + } //fclose(fp); // if(buf) @@ -292,12 +301,12 @@ namespace OHOS { //buf[offset]=strlen(addressbook_t.Contact_t[i].phone_number_t[j].affiliating_area)+1; memcpy(&buf[offset],addressbook_t.Contact_t[i].phone_number_t[j].affiliating_area,AREA_LEN); - printf("写入运营商: %s\r\n",&buf[offset]); + printf("写入所属地: %s\r\n",&buf[offset]); offset=offset+AREA_LEN; //buf[offset]=strlen(addressbook_t.Contact_t[i].phone_number_t[j].operator_t)+1; memcpy(&buf[offset],addressbook_t.Contact_t[i].phone_number_t[j].operator_t,OPERATOR_LEN); - printf("写入所属地: %s\r\n",&buf[offset]); + printf("写入运营商: %s\r\n",&buf[offset]); offset=offset+OPERATOR_LEN; } } diff --git a/code/sdk/application/wearable/fd230app/nativeui/set_dial/include/SetDialModel.h b/code/sdk/application/wearable/fd230app/nativeui/set_dial/include/SetDialModel.h index ea6abd2e3..b316c61f4 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/set_dial/include/SetDialModel.h +++ b/code/sdk/application/wearable/fd230app/nativeui/set_dial/include/SetDialModel.h @@ -26,7 +26,6 @@ #ifndef SET_DIAL_MODEL_H #define SET_DIAL_MODEL_H #include "AppViewIDs.h" -#include "UiConfig.h" #include "SetDialInfo.h" namespace OHOS @@ -56,8 +55,10 @@ namespace OHOS int GetAllDialIDs(char *allidStr); bool readDialfile(); bool saveDialfile(); + std::string GetSaveDir(int Id); private: + void CreateDirectoryIfNotExists(const std::string &path); void LoadAllDialFromRam(void); void LoadAllDialFromFs(void); void LoadAllDialFromDefult(void); diff --git a/code/sdk/application/wearable/fd230app/nativeui/set_dial/src/SetDialModel.cpp b/code/sdk/application/wearable/fd230app/nativeui/set_dial/src/SetDialModel.cpp index 0080f3aaa..f86a8386d 100644 --- a/code/sdk/application/wearable/fd230app/nativeui/set_dial/src/SetDialModel.cpp +++ b/code/sdk/application/wearable/fd230app/nativeui/set_dial/src/SetDialModel.cpp @@ -30,6 +30,8 @@ #include #include #include "NativeAbility.h" +#include "UiConfig.h" +#include namespace OHOS { // 定义特殊Id @@ -283,6 +285,42 @@ namespace OHOS } } + void SetDialModel::CreateDirectoryIfNotExists(const std::string &path) + { + struct stat info; + if (stat(path.c_str(), &info) != 0) + { + if (mkdir(path.c_str(), 0755) != 0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Could not create directory %s. Errno: %d", path.c_str(), errno); + } + else + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Created directory: %s", path.c_str()); + } + } + else if (info.st_mode & S_IFDIR) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Directory already exists: %s", path.c_str()); + } + } + + std::string SetDialModel::GetSaveDir(int Id) + { + // 首先检查Id是否在0~4的范围内 + if (Id < 0 || Id > 4) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Error: Id must be between 0 and 4."); + return ""; // 或者返回一个空字符串 + } + CreateDirectoryIfNotExists(std::string(APP_CUSTOM_DIAL_PATH)); + std::string folderPath = std::string(APP_CUSTOM_DIAL_PATH) + "/" + std::to_string(Id); // 修复这一行 + CreateDirectoryIfNotExists(folderPath); // 确保目录存在 + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Directory is %s", folderPath.c_str()); + + return folderPath; // 返回目录路径 + } + /*加载所有表盘*/ void SetDialModel::LoadAllDial() { diff --git a/code/sdk/application/wearable/service/ble_service/blemoder/bletest.cpp b/code/sdk/application/wearable/service/ble_service/blemoder/bletest.cpp index 3ae47e602..c924afd53 100644 --- a/code/sdk/application/wearable/service/ble_service/blemoder/bletest.cpp +++ b/code/sdk/application/wearable/service/ble_service/blemoder/bletest.cpp @@ -530,7 +530,17 @@ void get_sedent_param( msg_sedent_set_param_info_t * data) return; } +void ble_get_dial_path(char * buf,uint16_t id) +{ + char *path= (char*)OHOS::SetDialModel::GetInstance().GetSaveDir(id).c_str(); + memcpy(buf,path,strlen(path)+1); + return; +} + +// void ble_save_dial_() +// { +// } void ble_set_dial_by_id(uint16_t id) { diff --git a/code/sdk/application/wearable/service/ble_service/blemoder/bletest.h b/code/sdk/application/wearable/service/ble_service/blemoder/bletest.h index 4d0bbffb5..fb3f477f9 100644 --- a/code/sdk/application/wearable/service/ble_service/blemoder/bletest.h +++ b/code/sdk/application/wearable/service/ble_service/blemoder/bletest.h @@ -218,6 +218,8 @@ void Set_oxygen_cmd(msg_get_spo2_set_param_info_t *data); void Get_oxygen_cmd(msg_get_spo2_set_param_info_t *data); //////////////////////表盘相关//////////////////////////// +void ble_get_dial_path(char * buf,uint16_t id); + void ble_set_dial_by_id(uint16_t id); uint16_t ble_get_dial_id(void); diff --git a/code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.c b/code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.c index 8a11c87d1..e3033394e 100644 --- a/code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.c +++ b/code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.c @@ -51,6 +51,48 @@ extern "C" { #define AI_TXT_BUF_MAX_LEN 1024*3 //json解析失败 + +uint32_t packdataLen = 0; +uint32_t totalDataLen = 0; +uint8_t totalpack = 0; +uint8_t cmd_data[17]; +uint8_t *recvData; +#include "los_memory.h" + +#define MAX_BLE_MSG_PACKAGE_LEN (1024*5) //包缓存最大5k +#define BLE_MSG_TMP_FILE_NAME "/user/userdata/ble_tmp_buf_%04X" +typedef struct +{ + int handle; + int data_len ; + int totalDataLen; + int buffer_to_file; //1 buffer to file , 0 buffer to ram + int decode_type; //1 with header , 2 no header + FILE *tmpfilehandle;// 如果buffer to file , 则在此保存handle + msg_header_t cmd_header; + uint8_t *data;//if buffer_to_file is 1, than data is the filename , else data is the ram buffer. + uint8_t crcvalue; + uint8_t lrcvalue; //计算crc用的临时变量 + uint8_t lrcvalue2; //计算crc用的临时变量 + uint32_t last_timestamp;// last package receive time + uint8_t receive_file_flag;//1 接收文件 0 不接收文件 + file_recv_stat_t file_recv_stat; + uint8_t last_data_sample[5]; //专门给文件传输过程中重复包判定用。目前只是取前5个字节,实际应该再做优化算法。 + uint16_t last_data_size;//专门给传输过程中重复包判定用,记录上一个包的长度,至少长度相同才有判断重复的必要。同时也可以作为少于5个字节的包的判定依据。 +} ble_read_data; + +#define MAX_HANDLE_NUM 10 +//LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) +//根据特征值分开组合读取的数据,并处理 +static ble_read_data handle_l[MAX_HANDLE_NUM]={0}; + +errcode_t cancel_recv_file(ble_read_data *buffer_handle); + + + + +uint8_t ble_dial_file_count=0; +uint8_t ble_dial_file_index=0; uint8_t *bigDataBuf = NULL;//大数据buf uint8_t bigDataBufLen=0; bool sendbigDataBufState = false;//发送大数据表示不要被其他指令打断 @@ -61,6 +103,12 @@ static uint16_t data_len = 0; ble_recv_data_info_t ble_recv_data; static uint8_t TRANSMIT_DATA; static osTimerId_t BR_TRANSFER_timer=NULL; +static uint8_t timer_flie_type=0; +static uint32_t timer_flie_flag=0; +ble_read_data* ble_read_timer_p=NULL; + + + #if 1 #include "app_msg_manager.h" @@ -96,6 +144,7 @@ static const char* getHandlname(uint16_t handle) if (data2ae3Cmd == handle) return "data2ae3Cmd"; if (data2ae4Cmd == handle) return "data2ae4Cmd"; if (data2ae5Cmd == handle) return "data2ae5Cmd"; + if (data2ae6Cmd == handle) return "data2ae6Cmd"; //if (data2ae2Cmd == handle) return "data2ae2Cmd"; return "unknown handle"; @@ -114,7 +163,22 @@ static errcode_t get_file_recv_file_path(char* input_filename ,uint32_t input_si return ERRCODE_SUCC; } +static errcode_t get_custom_dial_file_path(uint16_t id,uint32_t input_size, char* output_file_path , uint32_t max_output_size) +{ + if( id >=5 || output_file_path == NULL) + { + return ERRCODE_FAIL; + } + char name[64]={0}; + ble_get_dial_path(name,id); + + int ret = sprintf_s(output_file_path,max_output_size,"%s",name); + if (ret < 0) + return ERRCODE_FAIL; + return ERRCODE_SUCC; + +} static errcode_t get_dial_file_path(char* input_dialname ,uint32_t input_size, char* output_file_path , uint32_t max_output_size) { if(input_dialname == NULL || output_file_path == NULL) @@ -336,51 +400,6 @@ void send_big_data(uint8_t flag, char *data, uint16_t datalen, uint32_t total, u } - - - - -uint32_t packdataLen = 0; -uint32_t totalDataLen = 0; -uint8_t totalpack = 0; -uint8_t cmd_data[17]; -uint8_t *recvData; -#include "los_memory.h" - -#define MAX_BLE_MSG_PACKAGE_LEN (1024*5) //包缓存最大5k -#define BLE_MSG_TMP_FILE_NAME "/user/userdata/ble_tmp_buf_%04X" -typedef struct -{ - int handle; - int data_len ; - int totalDataLen; - int buffer_to_file; //1 buffer to file , 0 buffer to ram - int decode_type; //1 with header , 2 no header - FILE *tmpfilehandle;// 如果buffer to file , 则在此保存handle - msg_header_t cmd_header; - uint8_t *data;//if buffer_to_file is 1, than data is the filename , else data is the ram buffer. - uint8_t crcvalue; - uint8_t lrcvalue; //计算crc用的临时变量 - uint8_t lrcvalue2; //计算crc用的临时变量 - uint32_t last_timestamp;// last package receive time - uint8_t receive_file_flag;//1 接收文件 0 不接收文件 - file_recv_stat_t file_recv_stat; - uint8_t last_data_sample[5]; //专门给文件传输过程中重复包判定用。目前只是取前5个字节,实际应该再做优化算法。 - uint16_t last_data_size;//专门给传输过程中重复包判定用,记录上一个包的长度,至少长度相同才有判断重复的必要。同时也可以作为少于5个字节的包的判定依据。 -} ble_read_data; - -#define MAX_HANDLE_NUM 10 -//LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus) -//根据特征值分开组合读取的数据,并处理 -static ble_read_data handle_l[MAX_HANDLE_NUM]={0}; - -errcode_t cancel_recv_file(ble_read_data *buffer_handle); - - - - - - //发送训练状态[app发起的运动] void sendtraningstatedata(uint8_t state ,uint16_t time) { @@ -441,7 +460,12 @@ void sendtraningdata(msg_get_train_data_info_t *data) cJSON_free(jsonString); } -//发送AI录音准备就绪国内/国外标识:0:国内版本 1:国外版本 +//发送AI录音准备就绪国内/ +/*使用模型: +0:文心一言 +1:ChatGPT +2:KIMI +3:豆包*/ void send_AI_is_ready(uint8_t type) { @@ -993,7 +1017,7 @@ void sendBindInfor(uint8_t *data) ret = gap_ble_pair_remote_device(&phone_addr); - printf("gap_ble_pair_remote_device ret:%x ",ret); + printf("gap_ble_pair_remote_device ret:%x \r\n",ret); bond = 0x02;//手表与该手机绑定过 value[17] = bond;// value[18] = Calculate_CRC(value,18); @@ -1492,6 +1516,7 @@ static void jsonCheck_alarm(uint8_t *buf)//json 解析闹钟数据 } cJSON_Delete(root); + ble_AlarmClock_refresh(); printf("alarmCount %d\n",alarmCount); } @@ -3537,7 +3562,7 @@ static void GetHrGetParamCmd(uint16_t cmd,uint8_t *data,uint16_t len,uint8_t *to value[18] = heart_param.remind_on;// value[19] = heart_param.max_min;// value[20] = heart_param.heart;// - + printf("%d %d %d %d ",value[17],value[18],value[19],value[20]); value[21] = Calculate_CRC(value,21); @@ -4769,7 +4794,6 @@ void type2AE3Data(ble_read_data *buffer_handle,uint8_t *cmd_buf ,uint8_t *data,u case GET_SPECIF_TYPE_FILE_CMD://获取指定类型文件目录 case AI_IS_READ_DATA_CMD: case SYN_HEART_HISTORY_DATA_CMD://同步心率历史数据 - //heartDataCmd(cmd,data,datalen,totaldata,crcvalue); case SYN_SPO2_HISTORY_DATA_CMD://同步血氧历史数据 case SYN_STEP_HISTORY_DATA_CMD: //同步步数历史数据 case SYN_FAT_BURN_HISTORY_DATA_CMD://同步燃脂时间数据 @@ -4933,7 +4957,7 @@ bool Read_Health_BIN_file_buf_send_bin_Data(uint8_t day, uint16_t num,uint16_t i fseek(fp, 0, SEEK_SET); // 将文件指针移回文件开头 buf = (char *)ym_malloc(sizeof(char)*num+1); - if(buf==NULL)return false; + if(buf==NULL){fclose(fp); return false;} uint32_t pack=1; if(file_size%num==0) @@ -5504,7 +5528,216 @@ errcode_t ble_reply_msg(uint8_t msg_cmdtype,uint8_t msg_cmdid,uint8_t replydata) return ble_reply_msgarr(msg_cmdtype,msg_cmdid,&replydata,1); } +static uint32_t last_package_id=0; +static void ble_transfer_Timer_CallBack(int data) +{ + timer_flie_flag--; + + if(timer_flie_flag==0) + { + if(timer_flie_type==1) + { + TRANSMIT_DATA=TRANS_OTA_FAIL; + } + else if (timer_flie_type==3) + { + TRANSMIT_DATA=TRANS_DIAL_FAIL; + } + else + { + TRANSMIT_DATA=TRANS_FREE; + } + + ble_read_timer_p->receive_file_flag = 0; + + if (ble_read_timer_p->file_recv_stat.recv_file_stat != 2) //已经下载完毕的文件,没有必要cancel了。 + { + + if (ble_read_timer_p->file_recv_stat.file!=NULL) + { + fclose(ble_read_timer_p->file_recv_stat.file); + ble_read_timer_p->file_recv_stat.file = NULL; + } + if (ble_read_timer_p->file_recv_stat.file_name != NULL) + { + free(ble_read_timer_p->file_recv_stat.file_name); + ble_read_timer_p->file_recv_stat.file_name=NULL; + } + ble_read_timer_p->file_recv_stat.recv_file_stat = -1; + + ble_read_timer_p=NULL; + + ble_reply_cmd(FILE_RECV_REPLY_STAT_CMD,0);//接收失败 + } + CustomEventPublish(TOPIC_EVENT_BLE_TRANSMIT,&TRANSMIT_DATA,1); + + if(BR_TRANSFER_timer) + { + osTimerStop(BR_TRANSFER_timer); + osTimerDelete(BR_TRANSFER_timer); + BR_TRANSFER_timer = NULL; + } + + } +} +uint8_t OTA_FILE_value=0; + +errcode_t decode_ota_data(ble_read_data *buffer_handle,uint8_t *data,uint16_t datalen,uint8_t crcvalue) +{ + uint32_t package_id=0; + memcpy_s(&package_id,4,&data[11],4); + printf("package_id: %d \r\n",package_id); + + // for(int i=0 ;i<17;i++) + // { + // printf(" 0x%02X",data[i]); + // } + // printf("\r\n"); + + data=data+sizeof(msg_header_t); + datalen-=18; + if(Check_CRC(data,datalen,crcvalue)) + { + + if(package_id==0) + { + last_package_id=package_id; + if((buffer_handle->file_recv_stat.recv_file_stat <= 0) && buffer_handle->file_recv_stat.file == NULL ) + { + buffer_handle->file_recv_stat.lrcvalue = 0; + if (buffer_handle->file_recv_stat.file_type == 1) + { + buffer_handle->file_recv_stat.file = fopen("/update/update.fwpkg","w+"); + printf("create file /update/update.fwpkg %X\n",buffer_handle->file_recv_stat.file); + + }else{ + char filepath[128]={0}; + if (get_file_recv_file_path(buffer_handle->file_recv_stat.file_name,strlen(buffer_handle->file_recv_stat.file_name),filepath,sizeof(filepath)) == ERRCODE_SUCC) + { + buffer_handle->file_recv_stat.file = fopen(filepath,"w+"); + printf("create file %s %X\n",filepath,buffer_handle->file_recv_stat.file); + }else{ + printf("create file %s error %X\n",buffer_handle->file_recv_stat.file_name,buffer_handle->file_recv_stat.file); + } + } + if (buffer_handle->file_recv_stat.file == NULL) + { + printf("6185 buffer_handle->file_recv_stat.file \n"); + return ERRCODE_FAIL; + } + size_t writtensize = fwrite(data,1,datalen,buffer_handle->file_recv_stat.file); + if(writtensize == datalen) + { + timer_flie_flag=10; + + buffer_handle->file_recv_stat.lrcvalue = calculate_lrc(data,datalen,buffer_handle->file_recv_stat.lrcvalue); + buffer_handle->file_recv_stat.received_size += datalen; + printf("handle_recv_file received_size %d\n",buffer_handle->file_recv_stat.received_size); + OTA_FILE_value= ((float) buffer_handle->file_recv_stat.received_size / (float)buffer_handle->file_recv_stat.file_size) *100; + + + }else{ + printf("handle_recv_file write file failed! ret %d != %d\n",writtensize,datalen); + return ERRCODE_FAIL; + } + + + buffer_handle->file_recv_stat.recv_file_stat = 1; + ////////////////创建文件传输超时定时器////////////////// + uint32_t tick; + osStatus_t retTimer; + if(BR_TRANSFER_timer!=NULL) + { + osTimerDelete(BR_TRANSFER_timer); + BR_TRANSFER_timer = NULL; + } + timer_flie_type=buffer_handle->file_recv_stat.file_type; + ble_read_timer_p=buffer_handle; + timer_flie_flag=10; + + BR_TRANSFER_timer = osTimerNew((osTimerFunc_t)ble_transfer_Timer_CallBack, osTimerPeriodic, NULL, NULL); + tick =1000;// osMs2Tick(1000); + retTimer = osTimerStart(BR_TRANSFER_timer, tick); + if (retTimer != osOK && BR_TRANSFER_timer != NULL) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"StartCallTimer osTimerStart failed, ret = %lx!!", retTimer); + osTimerDelete(BR_TRANSFER_timer); + BR_TRANSFER_timer = NULL; + return ERRCODE_FAIL; + } + } + /////////////////////////////////////////////////////////// + } + else if ((last_package_id+1)==package_id) + { + last_package_id=package_id; + if (buffer_handle->file_recv_stat.file == NULL) + { + printf("6194 buffer_handle->file_recv_stat.file \n"); + return ERRCODE_FAIL; + } + //写入文件 + size_t writtensize = fwrite(data,1,datalen,buffer_handle->file_recv_stat.file); + if(writtensize == datalen) + { + timer_flie_flag=10; + + buffer_handle->file_recv_stat.lrcvalue = calculate_lrc(data,datalen,buffer_handle->file_recv_stat.lrcvalue); + buffer_handle->file_recv_stat.received_size += datalen; + printf("handle_recv_file received_size %d\n",buffer_handle->file_recv_stat.received_size); + OTA_FILE_value= ((float) buffer_handle->file_recv_stat.received_size / (float)buffer_handle->file_recv_stat.file_size) *100; + + + }else{ + printf("handle_recv_file write file failed! ret %d != %d\n",writtensize,datalen); + return ERRCODE_FAIL; + } + //检查文件是否写完 + if(buffer_handle->file_recv_stat.file_size == buffer_handle->file_recv_stat.received_size) + { + if (buffer_handle->file_recv_stat.file!=NULL) + { + fclose(buffer_handle->file_recv_stat.file); + buffer_handle->file_recv_stat.file = NULL; + } + if (buffer_handle->file_recv_stat.file_name != NULL) + { + free(buffer_handle->file_recv_stat.file_name); + buffer_handle->file_recv_stat.file_name=NULL; + } + buffer_handle->file_recv_stat.recv_file_stat = 2; + buffer_handle->receive_file_flag = 0; + printf("handle_recv_file received success \n"); + + if(BR_TRANSFER_timer) + { + osTimerStop(BR_TRANSFER_timer); + osTimerDelete(BR_TRANSFER_timer); + BR_TRANSFER_timer = NULL; + } + + ble_reply_cmd(OTA_FILE_SUCC_CMD,1);//接收成功 + } + + } + else if (last_package_id==package_id) + { + uint32_t replydata=0xffffffff; + printf("包重复\r\n"); + //ble_reply_msgarr(6,4,&replydata,4); + } + else if (last_package_id!=package_id) + { + uint32_t replydata= last_package_id+1; + ble_reply_msgarr(6,4,&replydata,4); + } + return ERRCODE_SUCC; + } + else + { + return ERRCODE_FAIL; + } +} @@ -5667,6 +5900,7 @@ errcode_t decode_mp3_json(ble_read_data *buffer_handle) } } + errcode_t decode_dial_info(ble_read_data *buffer_handle) { @@ -5689,28 +5923,46 @@ errcode_t decode_dial_info(ble_read_data *buffer_handle) // dialinfo.dial_count = pdialinfo->dial_count; dialinfo.dial_uid = pdialinfo->dial_uid; - dialinfo.file_name_len = pdialinfo->file_name_len; - // dialinfo.file_type = pdialinfo->file_type; - - if (dialinfo.file_name_len < 0 || dialinfo.file_name_len >255) - { - printf("file name len should in [0,255] \n"); - return ERRCODE_FAIL; + if(dialinfo.dial_uid<=4) + { + msg_recv_custom_dial_info_t *custom_dial_info=(msg_recv_custom_dial_info_t*)data; + printf("custom_dial_info %d %d %d %d", + custom_dial_info->dial_uid, + custom_dial_info->battery, + custom_dial_info->time, + custom_dial_info->time_font); + ble_dial_file_count=*(data+sizeof(msg_recv_custom_dial_info_t)); + printf(" custom_dial file_count %d\r\n",ble_dial_file_count); + } - char * filename = malloc(dialinfo.file_name_len); - uint8_t file_count = data[sizeof(msg_recv_dial_info_t)+dialinfo.file_name_len]; - if (filename == NULL) + else { - printf("file name malloc failed filename_len %d\n",dialinfo.file_name_len); - return ERRCODE_FAIL; + dialinfo.file_name_len = pdialinfo->file_name_len; + // dialinfo.file_type = pdialinfo->file_type; + + if (dialinfo.file_name_len < 0 || dialinfo.file_name_len >255) + { + printf("file name len should in [0,255] \n"); + return ERRCODE_FAIL; + } + char * filename = malloc(dialinfo.file_name_len); + ble_dial_file_count= data[sizeof(msg_recv_dial_info_t)+dialinfo.file_name_len]; + if (filename == NULL) + { + printf("file name malloc failed filename_len %d\n",dialinfo.file_name_len); + return ERRCODE_FAIL; + } + memcpy_s(filename,dialinfo.file_name_len,data+sizeof(msg_recv_dial_info_t),dialinfo.file_name_len); + buffer_handle->file_recv_stat.file_name = filename; + + printf(" dial name = %s, dial file count = %d \n", + filename, + ble_dial_file_count + ); + free(filename); + } - memcpy_s(filename,dialinfo.file_name_len,data+sizeof(msg_recv_dial_info_t),dialinfo.file_name_len); - buffer_handle->file_recv_stat.file_name = filename; - - printf(" dial name = %s, dial file count = %d \n", - filename, - file_count - ); + buffer_handle->file_recv_stat.received_size = 0; buffer_handle->file_recv_stat.lrcvalue = 0; buffer_handle->receive_file_flag = 0; @@ -5719,7 +5971,7 @@ errcode_t decode_dial_info(ble_read_data *buffer_handle) TRANSMIT_DATA=TRANS_DIAL_TRANSMITTING; CustomEventPublish(TOPIC_EVENT_BLE_TRANSMIT,&TRANSMIT_DATA,1); - free(filename); + return ERRCODE_SUCC; } @@ -5745,6 +5997,9 @@ errcode_t decode_single_dial_info(ble_read_data *buffer_handle) msg_recv_single_dial_info_t *pdialinfo=(msg_recv_single_dial_info_t*)data; dialinfo.dial_count = pdialinfo->dial_count; + + ble_dial_file_index= dialinfo.dial_count; + dialinfo.dial_uid = pdialinfo->dial_uid; dialinfo.file_name_len = pdialinfo->file_name_len; dialinfo.file_type = pdialinfo->file_type; @@ -5822,10 +6077,22 @@ static errcode_t install_dial(void) } printf("dial_basename %s\n",dial_basename); char dialbin_filepath[128]={0}; - if (get_dial_file_path(dial_basename,strlen(dial_basename),dialbin_filepath,sizeof(dialbin_filepath)) != ERRCODE_SUCC) + if(ble_dial_uid>=5) { - return ERRCODE_FAIL; + if (get_dial_file_path(dial_basename,strlen(dial_basename),dialbin_filepath,sizeof(dialbin_filepath)) != ERRCODE_SUCC) + { + return ERRCODE_FAIL; + } } + else + { + if (get_custom_dial_file_path(ble_dial_uid,strlen(dial_basename),dialbin_filepath,sizeof(dialbin_filepath)) != ERRCODE_SUCC) + { + return ERRCODE_FAIL; + } + } + + printf("dialbin_filepath %s\n",dialbin_filepath); char lzma_filepath[128]={0}; if (get_file_recv_file_path(lzmapkgname,strlen(lzmapkgname),lzma_filepath,sizeof(lzma_filepath)) != ERRCODE_SUCC) @@ -5840,10 +6107,22 @@ static errcode_t install_dial(void) char *namebuf= strtok(lzmapkgname,"."); - install_Register_dial(namebuf,ble_dial_uid); + if(ble_dial_uid>=5) + { + install_Register_dial(namebuf,ble_dial_uid); + + ble_set_dial_by_id(ble_dial_uid); + + } + else + { - ble_set_dial_by_id(ble_dial_uid); + install_Register_dial(namebuf,ble_dial_uid); + ble_set_dial_by_id(ble_dial_uid); + } + + //安装完后删除表盘 printf("remove %s\r\n",lzma_filepath); @@ -5955,11 +6234,14 @@ void decode_file_checksum(ble_read_data *buffer_handle) { //ble_set_dial_by_id(ble_dial_uid); - TRANSMIT_DATA= TRANS_DIAL_SUCC; - CustomEventPublish(TOPIC_EVENT_BLE_TRANSMIT,&TRANSMIT_DATA,1); - + if(ble_dial_uid>=5 || ble_dial_file_index==ble_dial_file_count) + { + TRANSMIT_DATA= TRANS_DIAL_SUCC; + CustomEventPublish(TOPIC_EVENT_BLE_TRANSMIT,&TRANSMIT_DATA,1); //0504 - ble_reply_cmd(DIAL_INSTALL_REPY_CMD,1); + ble_reply_cmd(DIAL_INSTALL_REPY_CMD,1); + } + // ble_reply_cmd(GET_TRANS_END_CMD,1); @@ -6117,6 +6399,85 @@ void type2AE0Data(ble_read_data *buffer_handle) } } +// +void type2AE6Data(ble_read_data *buffer_handle,uint8_t *cmd_buf ,uint8_t *data,uint16_t datalen,uint8_t *totaldata,uint8_t crcvalue) +{ + uint16_t cmd = cmd_buf[1]*256+cmd_buf[2]; + #ifdef BLE_LOG + + #endif + printf("typeHexOneData:0x%04X\r\n",cmd); + // uint8_t typeID = cmd_buf[2]; + switch (cmd) + { + case OTA_FILE_MSG_CMD : + { + if (decode_ota_json( buffer_handle) == ERRCODE_SUCC) + { + ble_reply_cmd(OTA_FILE_MSG_CMD,1); + }else{ + ble_reply_cmd(OTA_FILE_MSG_CMD,2); + } + } + break; + + case DIAL_COLLECT_FILE_CMD : + { + if (decode_dial_info( buffer_handle) == ERRCODE_SUCC) + { + ble_reply_cmd(DIAL_COLLECT_FILE_CMD,1); + }else{ + ble_reply_cmd(DIAL_COLLECT_FILE_CMD,2); + } + break; + } + + case DIAL_SINGEL_FILE_CMD : + { + if (decode_single_dial_info(buffer_handle) == ERRCODE_SUCC) + { + ble_reply_cmd(DIAL_SINGEL_FILE_CMD,1); + + }else{ + ble_reply_cmd(DIAL_SINGEL_FILE_CMD,2); + + } + break; + } + case MP3_FILE_CMD : + { + if (decode_mp3_json( buffer_handle) == ERRCODE_SUCC) + { + ble_reply_cmd(MP3_FILE_CMD,1); + }else{ + ble_reply_cmd(MP3_FILE_CMD,2); + } + } + break; + // case OTA_FILE_DATA_CMD : + // { + // if (decode_ota_data( buffer_handle,data,datalen, crcvalue) == ERRCODE_SUCC) + // { + + // }else{ + // ble_reply_cmd(OTA_FILE_DATA_CMD,0); + // } + // } + + case OTA_FILE_SUCC_CMD : + { + decode_file_checksum(buffer_handle); + break; + } + + case OTA_FILE_FAIL_CMD : + break; + default: + break; + } +} + + void dumpHeader(msg_header_t *msgheader) @@ -6151,94 +6512,20 @@ errcode_t check_header(msg_header_t *header ) return ERRCODE_FAIL; } } -static uint8_t timer_flie_type=0; -static uint32_t timer_flie_flag=0; -ble_read_data* ble_read_timer_p=NULL; + errcode_t cancel_recv_file(ble_read_data *buffer_handle) { - buffer_handle->receive_file_flag = 0; - - if (buffer_handle->file_recv_stat.recv_file_stat != 2) //已经下载完毕的文件,没有必要cancel了。 + if(BR_TRANSFER_timer) { - - if (buffer_handle->file_recv_stat.file!=NULL) - { - fclose(buffer_handle->file_recv_stat.file); - buffer_handle->file_recv_stat.file = NULL; - } - if (buffer_handle->file_recv_stat.file_name != NULL) - { - free(buffer_handle->file_recv_stat.file_name); - buffer_handle->file_recv_stat.file_name=NULL; - } - buffer_handle->file_recv_stat.recv_file_stat = -1; - - if(BR_TRANSFER_timer) - { - timer_flie_flag=1; - } - - ble_reply_cmd(FILE_RECV_REPLY_STAT_CMD,0);//接收失败 + timer_flie_flag=1; } + ble_reply_cmd(FILE_RECV_REPLY_STAT_CMD,0);//接收失败 + return ERRCODE_SUCC; } - -static void ble_transfer_Timer_CallBack(int data) -{ - timer_flie_flag--; - - if(timer_flie_flag==0) - { - if(timer_flie_type==1) - { - TRANSMIT_DATA=TRANS_OTA_FAIL; - } - else if (timer_flie_type==3) - { - TRANSMIT_DATA=TRANS_DIAL_FAIL; - } - else - { - TRANSMIT_DATA=TRANS_FREE; - } - - ble_read_timer_p->receive_file_flag = 0; - - if (ble_read_timer_p->file_recv_stat.recv_file_stat != 2) //已经下载完毕的文件,没有必要cancel了。 - { - - if (ble_read_timer_p->file_recv_stat.file!=NULL) - { - fclose(ble_read_timer_p->file_recv_stat.file); - ble_read_timer_p->file_recv_stat.file = NULL; - } - if (ble_read_timer_p->file_recv_stat.file_name != NULL) - { - free(ble_read_timer_p->file_recv_stat.file_name); - ble_read_timer_p->file_recv_stat.file_name=NULL; - } - ble_read_timer_p->file_recv_stat.recv_file_stat = -1; - - ble_read_timer_p=NULL; - - ble_reply_cmd(FILE_RECV_REPLY_STAT_CMD,0);//接收失败 - } - CustomEventPublish(TOPIC_EVENT_BLE_TRANSMIT,&TRANSMIT_DATA,1); - - if(BR_TRANSFER_timer) - { - osTimerStop(BR_TRANSFER_timer); - osTimerDelete(BR_TRANSFER_timer); - BR_TRANSFER_timer = NULL; - } - - } -} -uint8_t OTA_FILE_value=0; - uint8_t get_OTA_recv_value() { return OTA_FILE_value; @@ -6441,6 +6728,8 @@ void bleLongRecvData(ble_read_data *buffer_handle,uint8_t *data, uint16_t data_s case 0x04: type2AE0Data(buffer_handle); break; + case 0x06: + type2AE6Data(buffer_handle,buf_cmd,data,data_size,totalData,crcvalue); default: break; } @@ -6472,11 +6761,15 @@ errcode_t combine_data_internal(ble_read_data *buffer_handle,uint8_t *totalData, { - if(buffer_handle->receive_file_flag == 1) + if(buffer_handle->receive_file_flag == 1 ) { //接收文件 + if(buffer_handle->handle==data2ae6Cmd) + return decode_ota_data( buffer_handle,totalData,event_size,totalData[event_size-1]); + else return handle_recv_file(buffer_handle,totalData,event_size); } + msg_header_t *header = (msg_header_t*)totalData; //第一帧 if (event_size > sizeof(msg_header_t) && check_header(header) == ERRCODE_SUCC ) diff --git a/code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.h b/code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.h index abd584dcf..b04903a91 100644 --- a/code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.h +++ b/code/sdk/application/wearable/service/ble_service/bleservice/bleEvent.h @@ -800,7 +800,11 @@ bool get_ctkd_flag(void); #define OTA_FILE_MSG_CMD 0x0601 #define OTA_FILE_DATA_CMD 0x0602 #define OTA_FILE_SUCC_CMD 0x0603 -#define OTA_FILE_FAIL_CMD 0x0604 +#define OTA_FILE_FAIL_CMD 0x0604 +///////////// +#define DIAL_COLLECT_FILE_CMD 0x0605 +#define DIAL_SINGEL_FILE_CMD 0x0606 +#define MP3_FILE_CMD 0x0607 #ifdef __cplusplus } diff --git a/code/sdk/application/wearable/service/ble_service/bleservice/bleService.c b/code/sdk/application/wearable/service/ble_service/bleservice/bleService.c index 4e0ea4fc5..997050cb9 100644 --- a/code/sdk/application/wearable/service/ble_service/bleservice/bleService.c +++ b/code/sdk/application/wearable/service/ble_service/bleservice/bleService.c @@ -49,6 +49,9 @@ extern "C" { /* Gatt service UUID */ #define BLE_SERVICE_UUID 0x18e0 /* Gatt Characteristic UUID */ +//自定义 ota 文件传输特征值 +#define BLE_ZHIHUI_OTA_ID 0x2ae6 + #define BLE_CHARACTERISTIC_RECV_ID 0x2ae5 #define BLE_CHARACTERISTIC_SNED_SHORT_ID 0x2ae3 @@ -114,6 +117,7 @@ uint16_t data2ae2Cmd = 0;//read uint16_t data2ae1Cmd = 0;//安卓消息来电 uint16_t data2ae0Cmd = 0;//OTA +uint16_t data2ae6Cmd = 0;//自定义OTA void get_phone_addr(bd_addr_t *addr) { @@ -131,6 +135,7 @@ enum{ BLE_CHARACTERISTIC_SNED_OTA_ID_PROPERTIES = GATT_CHARACTER_PROPERTY_BIT_WRITE|GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP, BLE_CHARACTERISTIC_SNED_ANDRIOD_ID_PROPERTIES = GATT_CHARACTER_PROPERTY_BIT_WRITE|GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP, BLE_CHARACTERISTIC_READ_BATTERY_ID_PROPERTIES = GATT_CHARACTER_PROPERTY_BIT_READ|GATT_CHARACTER_PROPERTY_BIT_NOTIFY, + BLE_ZHIHUI_OTA_ID_ID_PROPERTIES=GATT_CHARACTER_PROPERTY_BIT_WRITE|GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP, }; static uint8_t ble_adv_falg = 0; static bool g_custom_ble_init_flag = false; @@ -379,6 +384,35 @@ static void srv_ble_add_chart_decr_ota(uint8_t server_id,uint16_t srv_handle) // ALIPAY_PRINT_ERR(0, "gatts_add_descriptor fail, ret:%u.\r\n", ret); } } + +//自定义 ota 文件传输协议 +static void srv_ble_add_chart_decr_Zhihui_ota(uint8_t server_id,uint16_t srv_handle) +{ + errcode_t ret = 0; + static uint8_t ota_val[] = {0x00, 0x00}; + gatts_add_chara_info_t character; + gatts_add_desc_info_t descriptor; + bts_data_to_uuid_len2(BLE_ZHIHUI_OTA_ID, &character.chara_uuid); + character.permissions = GATT_ATTRIBUTE_PERMISSION_READ; + character.properties = BLE_ZHIHUI_OTA_ID_ID_PROPERTIES; + character.value_len = (uint16_t)sizeof(ota_val); + character.value = ota_val; + + ret = gatts_add_characteristic(server_id, srv_handle, &character); + if (ret != ERRCODE_SUCC) { + // ALIPAY_PRINT_ERR(0, "gatts_add_characteristic fail, ret:%u.\r\n", ret); + } + bts_data_to_uuid_len2(BLE_UUID_USER_CHARACTERISTIC_CONF, &descriptor.desc_uuid); + descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_WRITE|GATT_ATTRIBUTE_PERMISSION_READ; + descriptor.value_len = (uint16_t)sizeof(ota_val); + descriptor.value = ota_val; + + ret = gatts_add_descriptor(server_id, srv_handle, &descriptor); + if (ret != ERRCODE_SUCC) { + // ALIPAY_PRINT_ERR(0, "gatts_add_descriptor fail, ret:%u.\r\n", ret); + } +} + //用于adnriod发送消息添加特征值和描述符 static void srv_ble_add_chart_decr_andriod(uint8_t server_id,uint16_t srv_handle) { @@ -767,6 +801,8 @@ static void svr_ble_bt_gatts_service_add_cb(uint8_t server_id, bt_uuid_t *uuid, srv_ble_add_chart_decr_short_cmd(server_id,srv_handle); srv_ble_add_chart_decr_long_cmd(server_id,srv_handle); srv_ble_add_chart_decr_recv_cmd(server_id,srv_handle); + srv_ble_add_chart_decr_Zhihui_ota(server_id,srv_handle); + gatts_start_service(server_id, srv_handle); } if (ble_gatts_cmp_uuid(uuid, &hid_service_uuid) == true){ @@ -822,15 +858,24 @@ static void svr_ble_bt_gatts_characteristic_add_cb(uint8_t server_id, bt_uuid_t bt_uuid_t hid_report_uuid_2a4d = {0}; bts_data_to_uuid_len2(BLE_UUID_REPORT, &hid_report_uuid_2a4d); - bt_uuid_t alipay_report_uuid = {0}; - bts_data_to_uuid_len2(ALIPAYY_CHARACTERISTIC_ID, &alipay_report_uuid); + bt_uuid_t hid_report_uuid_2ae6 = {0}; + bts_data_to_uuid_len2(BLE_ZHIHUI_OTA_ID, &hid_report_uuid_2ae6); + + // bt_uuid_t alipay_report_uuid = {0}; + // bts_data_to_uuid_len2(ALIPAYY_CHARACTERISTIC_ID, &alipay_report_uuid); - if(ble_gatts_cmp_uuid(uuid, &alipay_report_uuid)) + // if(ble_gatts_cmp_uuid(uuid, &alipay_report_uuid)) + // { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " alipay_handle %d\r\n",result->value_handle); + // alipay_handle = result->value_handle; + // } + if(ble_gatts_cmp_uuid(uuid, &hid_report_uuid_2ae6)) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " alipay_handle %d\r\n",result->value_handle); - alipay_handle = result->value_handle; + if(data2ae6Cmd==0) + { + data2ae6Cmd=result->value_handle; + } } - if(ble_gatts_cmp_uuid(uuid, &chara_uuid_data_2ae5)) { if(g_ble_server_handle == 0) diff --git a/code/sdk/application/wearable/service/ble_service/bleservice/bleService.h b/code/sdk/application/wearable/service/ble_service/bleservice/bleService.h index 6a10f936d..6bcfa2b7d 100644 --- a/code/sdk/application/wearable/service/ble_service/bleservice/bleService.h +++ b/code/sdk/application/wearable/service/ble_service/bleservice/bleService.h @@ -22,6 +22,7 @@ extern uint16_t data2ae4Cmd; extern uint16_t data2ae5Cmd; extern uint16_t data2ae1Cmd;//安卓消息来电 extern uint16_t data2ae0Cmd;//OTA +extern uint16_t data2ae6Cmd;//自定义OTA extern uint16_t ble_nus_max_data_len; extern uint16_t alipay_handle; extern uint16_t g_ble_conn_id; -- 2.17.1