From: hcj <1224667075@qq.com> Date: Thu, 10 Jul 2025 06:44:09 +0000 (+0800) Subject: 增加 modem 升级方式 X-Git-Url: http://git.snicker.com.cn/css/static/gitweb.css?a=commitdiff_plain;h=f43cd3dc52ab602b7f80fc4ac410d2340a276549;p=mirrors%2FFD230.git 增加 modem 升级方式 --- diff --git a/cat1modem/fd230/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944_20250710-1429.zip b/cat1modem/fd230/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944_20250710-1429.zip new file mode 100644 index 000000000..f153a28f5 --- /dev/null +++ b/cat1modem/fd230/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944_20250710-1429.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b98532e83e5f83c7b86d43e923091987eb3517bacf6fc5bc24c3ed9d88ad4d9 +size 11630097 diff --git a/cat1modem/fd230/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944.zip b/cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944.zip similarity index 100% rename from cat1modem/fd230/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944.zip rename to cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944.zip diff --git a/cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944.zip:Zone.Identifier b/cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944.zip:Zone.Identifier new file mode 100644 index 000000000..e69de29bb diff --git a/cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944_20250709-1731.zip b/cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944_20250709-1731.zip new file mode 100644 index 000000000..065abd4c3 --- /dev/null +++ b/cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944_20250709-1731.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:82324c00dd851ace1c45e65886849fe39d7d356573b965ce90b66ff123b0c6d7 +size 11630066 diff --git a/cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944_20250710-1429.zip b/cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944_20250710-1429.zip new file mode 100644 index 000000000..f153a28f5 --- /dev/null +++ b/cat1modem/fd230/bak/EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_TEST0630_20250630-1944_20250710-1429.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b98532e83e5f83c7b86d43e923091987eb3517bacf6fc5bc24c3ed9d88ad4d9 +size 11630097 diff --git a/cat1modem/src/cat1Service.py b/cat1modem/src/cat1Service.py index b8f0a8b98..deed26916 100644 --- a/cat1modem/src/cat1Service.py +++ b/cat1modem/src/cat1Service.py @@ -53,6 +53,7 @@ import sms from usr.EventMesh import eventMesh +from usr.httpota import httpota # from usr.telecom_dmp import telecomDmpCb # from usr.china_mobile_dmp import chinamobileCb from usr.china_mobile_ai_regulation import aiRegulation @@ -78,7 +79,7 @@ sms.setCallback(msg_cb)#sms注册回调 CAT1_SERVICE_HEAD = 'FE' #固定head PROJECT_NAME = "Cat1SlipUDPService" -PROJECT_VERSION = "PY_SRV_V18" +PROJECT_VERSION = "PY_SRV_V19" CONFIG_JSON="/usr/system_config.json" CURRENT_APP_TYPE="pysrv" @@ -183,7 +184,7 @@ UDP_MSG_CALL_CONNECTED = 'A' # CAT1 电话接听消息 UDP_MSG_CALL_DISCONNECTED = 'B' # CAT1 电话挂断消息 UDP_MSG_COMMING_CALL = 'C' # CAT1 来电消息,包含电话号 UDP_MSG_REPLY = 'F' # 返回值 - +UDP_MSG_OTA = 'D' # 返回值 class Cat1Service: AP = 0 # SLIP_INNER @@ -299,6 +300,7 @@ class Cat1Service: else: self.reply_cmd('0F',"callcmd_success") else: + print("get_volte_switch NO") self.reply_cmd('0F',"callcmd_fail") elif cmd == "02": clog.info(cmd) @@ -395,6 +397,13 @@ class Cat1Service: voiceCall.startDtmf(str(parm),100) #100ms 持续时间 100-1000 elif cmd == "1A": eventMesh.publish("set_volte_switch",int(parm)) + elif cmd == "1B": + print("fota {}".format(str(parm).split("and")[0])) + print("fota {}".format(str(parm).split("and")[-1])) + # httpota = httpota() + httpota.run( str(parm).split("and")[0], str(parm).split("and")[-1]) + # eventMesh.publish("set_volte_switch",int(parm)) + # UDP_MSG_OTA elif cmd == "AC":# if self.ack_sem==1: self.ack_sem=0 diff --git a/cat1modem/src/httpota.py b/cat1modem/src/httpota.py new file mode 100644 index 000000000..1f7ff897c --- /dev/null +++ b/cat1modem/src/httpota.py @@ -0,0 +1,43 @@ +#远程升级 + +import fota +import utime +import log +import checkNet + +import app_fota +from misc import Power +import modem +import ujson +import request +import ql_fs +import checkNet +import sys + +#远程升级 +import uos + + +# 设置日志输出级别 + +class httpota: + def __init__(self): + print("httpota init") + + + def run(url_1,url_2): + print("httpDownload...{}".format(url_1)) + print("httpDownload...{}".format(url_2)) + # format(str(url_2))) + fota_obj = fota() # 创建Fota对象 + # res = fota_obj.httpDownload(str(url_1),str(url_2)) + res = fota_obj.httpDownload(url1="{}".format(url_1),url2="{}".format(url_2)) + if res != 0: + print.error("httpDownload error") + return + print("wait httpDownload update...") + utime.sleep(2) + # Power.powerRestart() + +# httpota = httpota() +# httpota.run("http://snicker.com.cn:8089/FD230/V18-V19OTA") \ No newline at end of file diff --git a/cat1modem/src/main.py b/cat1modem/src/main.py index ab14d8bf5..a5bea573d 100644 --- a/cat1modem/src/main.py +++ b/cat1modem/src/main.py @@ -6,7 +6,7 @@ from machine import UART log.basicConfig(level=log.INFO) # 设置输出到debug口 uart = UART(UART.UART0, 115200, 8, 0, 1, 0) -log.set_output(uart) +# log.set_output(uart) clog = log.getLogger("cat1") main_flag = 1 diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/cat1Service.py b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/cat1Service.py index c631c75a5..d0b727137 100755 --- a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/cat1Service.py +++ b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/cat1Service.py @@ -52,10 +52,10 @@ import pm import sms from usr.EventMesh import eventMesh - +from usr.httpota import httpota # from usr.telecom_dmp import telecomDmpCb # from usr.china_mobile_dmp import chinamobileCb - +from usr.china_mobile_ai_regulation import aiRegulation # 设置日志输出级别 log.basicConfig(level=log.INFO) clog = log.getLogger("cat1") @@ -78,7 +78,7 @@ sms.setCallback(msg_cb)#sms注册回调 CAT1_SERVICE_HEAD = 'FE' #固定head PROJECT_NAME = "Cat1SlipUDPService" -PROJECT_VERSION = "PY_SRV_V18" +PROJECT_VERSION = "PY_SRV_V19" CONFIG_JSON="/usr/system_config.json" CURRENT_APP_TYPE="pysrv" @@ -183,7 +183,7 @@ UDP_MSG_CALL_CONNECTED = 'A' # CAT1 电话接听消息 UDP_MSG_CALL_DISCONNECTED = 'B' # CAT1 电话挂断消息 UDP_MSG_COMMING_CALL = 'C' # CAT1 来电消息,包含电话号 UDP_MSG_REPLY = 'F' # 返回值 - +UDP_MSG_OTA = 'D' # 返回值 class Cat1Service: AP = 0 # SLIP_INNER @@ -218,7 +218,7 @@ class Cat1Service: self.iccid_data = "" self.software_version = "" self.deletSmsTimer = osTimer() - + self.china_mobile_ai_init = 0 self.volte_switch = 1 #默认是开启VOLTE通话功能 eventMesh.subscribe("set_dmp_change_mode",self.set_dmp_change_mode) eventMesh.subscribe("get_dmp_change_mode",self.get_dmp_change_mode) @@ -299,6 +299,7 @@ class Cat1Service: else: self.reply_cmd('0F',"callcmd_success") else: + print("get_volte_switch NO") self.reply_cmd('0F',"callcmd_fail") elif cmd == "02": clog.info(cmd) @@ -395,6 +396,13 @@ class Cat1Service: voiceCall.startDtmf(str(parm),100) #100ms 持续时间 100-1000 elif cmd == "1A": eventMesh.publish("set_volte_switch",int(parm)) + elif cmd == "1B": + print("fota {}".format(str(parm).split("and")[0])) + print("fota {}".format(str(parm).split("and")[-1])) + # httpota = httpota() + httpota.run( str(parm).split("and")[0], str(parm).split("and")[-1]) + # eventMesh.publish("set_volte_switch",int(parm)) + # UDP_MSG_OTA elif cmd == "AC":# if self.ack_sem==1: self.ack_sem=0 @@ -408,8 +416,6 @@ class Cat1Service: pass elif cmd == "14":# pass - - pass def set_volte_switch(self,event,msg): #设置VOLTE开关 @@ -808,12 +814,19 @@ class Cat1Service: eventMesh.publish("set_network_state",1) # telecomDmpCb.telecom_dmp_power_on_init() if 1: #CHINA_MOBILE_DM_FUN_ENABLE == 1: - if eventMesh.publish("get_dmp_change_mode") > 1: + if eventMesh.publish("get_dmp_change_mode") == 2: eventMesh.publish("set_network_state",1) if self.china_mobile_init == 1: return self.china_mobile_init = 1 + #移动入库的初始化 # chinamobileCb.china_mobile_init() + if eventMesh.publish("get_dmp_change_mode") == 3: + if self.china_mobile_ai_init == 1: + return + self.china_mobile_ai_init = 1 + eventMesh.publish("set_network_state",1) + aiRegulation.AIRegulation_init() def cat1_reply_iccid_to_ble(self,event,msg): ICCID_DATA = str("ICCID:")+str(msg) diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/china_mobile_ai_regulation.py b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/china_mobile_ai_regulation.py new file mode 100644 index 000000000..9cd4bf9a8 --- /dev/null +++ b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/china_mobile_ai_regulation.py @@ -0,0 +1,416 @@ +#AI 纳管对接文件 +import modem +import request +import utime +import osTimer +import ql_fs +from machine import RTC +from misc import Power +import uos +import ujson +import urandom +from usr.EventMesh import eventMesh +HEARBEAT_REPORT_TIMER_CONFIG = 60*60*12#60*60*12 #心跳上报时间间隔12小时可更改做测试 +REALY_TIME_COUNT = 60*60# #开启1小时实时定时器 +HEART_REPORT_ERROR_TIMER = 60 #心率上报错误定时器检测 按照1分钟检查 +PRODUCTID = "1927646275585744898" #产品ID +PRODUCTKEY = "iijgiGiTolCblSFE" #产品KEY 平台创建产品是生成的 +HEART_REPORT_ERR_MAX_NUM = 30 #连续上报错误次数最大值 30 网络异常或者哪里报错了 重启设备 可根据实际的用户的需求更改次数 +REPORT_MODE = 1 #上报方式 1 24小时内一定上报一次 2 12小时后上报一次 +class AIRegulation: + #定义全局变量 + def __init__(self): + self.timerStart = osTimer() + self.timerStartReportHr = osTimer() + self.productId = PRODUCTID + self.productKey = PRODUCTKEY + self.deviceId = "" #设备ID + self.deviceSecret = "" #设备私钥 + self.config_data = {} + self.getDevInforErrCount = 0 #获取设备信息错误次数累计 + self.report_state = 0 #超过24小时清0 + self.TimeSec = 0 #上报的时间戳 + self.startTimerState = 0 + self.software_version = "" + self.imei_new = "" + self.init_flag = 0 + self.net_work_state = 0 + self.dev_mac = "" + eventMesh.subscribe("get_dev_version",self.get_dev_version) + eventMesh.subscribe("set_dev_version",self.set_dev_version) + eventMesh.subscribe("get_dev_mac",self.get_dev_mac) + eventMesh.subscribe("set_dev_mac",self.set_dev_mac) + eventMesh.subscribe("get_network_state",self.get_network_state)#订阅消息 + eventMesh.subscribe("set_network_state",self.set_network_state)#订阅消息 + self.report_err_count = 0 #上报错误次数 30次 + + def set_network_state(self,event,msg): + self.net_work_state=int(msg) + + def get_network_state(self,event,msg): + return self.net_work_state + + def set_dev_version(self,event,msg): + self.software_version=str(msg) + + def get_dev_version(self,event,msg): + return self.software_version + def get_dev_mac(self,event,msg): + return self.dev_mac + def set_dev_mac(self,event,msg): + self.dev_mac = str(msg) + #要或者设备的mac 和设备的固件版本号 + + #读取存储设备的设备参数 包含设备imei 设备ID和设备私钥 同一个设备设备ID和设备私钥不变 + def read_dev_storage_param(self): + + IMEI = modem.getDevImei() #获取IMEI号 + result_ok = 0 #返回结果状态 + IFEXIST = ql_fs.path_exists("/usr/cm_ai_regulation.json") # + if IFEXIST == True: #文件存在 + fileSize = ql_fs.path_getsize('usr/cm_ai_regulation.json') + if fileSize == 0: + result_ok = 0 + print("设备信息配置文件不存在\r\n") + return result_ok + else: + try: + with open("/usr/cm_ai_regulation.json","r",encoding='utf-8') as fd: + try: + self.config_data = ujson.load(fd) #转换成json格式 + if len(self.config_data) != 0: + if "deviceId" in self.config_data:# + self.deviceId = str(self.config_data["deviceId"]) #设备ID + + #存在 + if "deviceSecret" in self.config_data: + self.deviceSecret = str(self.config_data["deviceSecret"]) + #存在 + if "TimeSec" in self.config_data: + self.TimeSec = self.config_data["TimeSec"] + if "IMEI" in self.config_data: + self.imei_new = self.config_data["IMEI"] + if str(self.imei_new) != str(IMEI): #设备IMEI不一样也要重新获取 + self.config_data["IMEI"] = str(IMEI) + self.write_config_msg_file(self.config_data) + result_ok = 0 + return result_ok + + if len(str(self.deviceId)) != 0 or len(str(self.deviceSecret)) != 0: + result_ok = 1 + else: #m没有存储数据 需要从平台上获取设备信息 + result_ok = 0 + except Exception as error: + print("配置文件的内容不是json格式 保存数据的时候格式不对\r\n") + result_ok = 0 + except Exception as error: + print("打开配置文件失败\r\n") + result_ok = 0 + else: + print("配置文件不存在!!!!\r\n") + result_ok = 0 + + print("cm_ai_regulation result_ok: {} self.config_data:{}\r\n".format(result_ok,self.config_data)) + return result_ok + #写文件信息 + def write_config_msg_file(self,msg): + + print("cm_ai_regulation msg:{}\r\n".format(msg)) + with open("/usr/cm_ai_regulation.json",'w+',encoding="utf-8") as fd: + ujson.dump(msg,fd) + def get_dev_info(self): #是否需要获取设备信息 + request_result = 0 + netWorkState = eventMesh.publish("get_network_state") + if netWorkState == 0: #网络异常 + request_result = 0 + return request_result + url = "https://ivs.chinamobiledevice.com:11443/v2/customer/device/secret/info" + #获取设备ID和设备私钥 + get_dev_storage = self.read_dev_storage_param() #返回1说明已经获取过设备信息 不需要再重新获取了只有 + if get_dev_storage == 0: #还没有获取设备信息需要获取一遍 + #获取设备设备信息地址 + IMEI = modem.getDevImei() #获取IMEI号 + + headers_T ={"Content-Type":"application/json"} + config_data ={ + "deviceNoType":"IMEI", + "deviceNo":str(IMEI), + "productKey":str(self.productKey), + "productId":str(self.productId), + } + print("ujson.dumps(config_data):{}".format(ujson.dumps(config_data))) + + result_json = "" + response = 0 + try: + response = request.post(url, data=ujson.dumps(config_data),headers =headers_T) + if response.status_code == 200: #服务器响应成功并返回数据 + try: + content = response.content + c = next(content) + result_json = ujson.loads(c) + print("response.json:{}".format(ujson.loads(c))) + code = "" + message = "" + success = False + if "code" in result_json: + code = result_json["code"] + if "message" in result_json: + message = result_json["message"] + if "success" in result_json: + success = result_json["success"] + if code == "200" and message == "成功" and success == True: + if "data" in result_json: + data_json = result_json["data"] + if "deviceId" in data_json: + self.deviceId = data_json["deviceId"] + if "deviceSecret" in data_json: + self.deviceSecret = data_json["deviceSecret"] + + if len(self.deviceId) != 0 or len(self.deviceSecret) != 0: #获取设备信息成功 保存数据 用做心跳上报 + request_result = 1 + self.config_data["deviceId"] = str(self.deviceId) + self.config_data["deviceSecret"] = str(self.deviceSecret) + IMEI = modem.getDevImei() #获取IMEI号 + self.config_data["IMEI"] = str(IMEI) + self.write_config_msg_file(self.config_data) + # { + # "code":"200", + # "message":"成功", + # "success": true, + # "data":{ + # "deviceId":"xxx", + # "deviceNo":"xxx", + # "productId":"xxx", + # "deviceSecret":"xxx" + # } + # } + else: + request_result = 0 + print("后台返回数据json字段里面没有data字段\r\n") + else: + request_result = 0 + print("后台返回数据失败 可能是设备没有加入产品或者产品私钥或者产品ID对不上\r\n") + except Exception as e: #不是json格式 + print("not json data:{}".format(e)) + request_result = 0 + else: + print("未响应 或者网络异常连接不上后台\r\n") + request_result = 0 + except Exception as e: + print("response error:{}".format(e)) + request_result = 0 + else: + request_result = 1 + return request_result + + #上报心跳数据 + def report_hr_data(self): #设备ID 设备私钥不为空才可以上报 + result_s = 0 + netWorkState = eventMesh.publish("get_network_state") + if netWorkState == 0: #网络异常 + result_s = 0 + return result_s + if len(str(self.deviceId)) != 0 and len(str(self.deviceSecret)) != 0: + + ######################################################### + # { + # "deviceId":"1927659130106658817", + # "deviceSecret":"xmvlRHbEaKPtCqHt", + # "productId":"1927646275585744898", + # "productKey":"iijgiGiTolCblSFE", + # "params": { + # "innerIp": [ + # "127.0.0.1" + # ], + # "netSpeed": "0Mbps", + # "netType": "4G", + # "platform": "RTOS", + # "sdkVersion": "ai_http_1.0", + # "firmwareVersion": "0.0.5.2", + # "imei": "860132060564184", + # "cmei": "", + # "mac": "" + # } + # } + IMEI = modem.getDevImei() #获取IMEI号 + tmp_mac = "" + if len(self.dev_mac) != 0: + tmp_mac = self.dev_mac.replace(':', '-') #将传过来的字符里面的:转换成- + #数据格式内容 + data_json = { + "deviceId":str(self.deviceId), #设备ID + "deviceSecret":str(self.deviceSecret), #设备私钥 + "productId":str(self.productId), #产品ID + "productKey":str(self.productKey), #产品私钥 + "params": { + "innerIp": [ + "127.0.0.1" + ], + "netSpeed": "0Mbps", + "netType": "4G", + "platform": "RTOS", + "sdkVersion": "ai_http_1.0", + "firmwareVersion":str(self.software_version), #设备固件版本号 + "imei": str(IMEI), #设备IMEI号 + "cmei": "", + "mac": str(tmp_mac) #设备MAC地址 + } + } + url = "https://ivs.chinamobiledevice.com:11443/v2/customer/device/report" #post请求上报数据心跳地址 + #获取设备ID和设备私钥 + try: + headers_T ={"Content-Type":"application/json"} #应用是json格式 + response = request.post(url, data=ujson.dumps(data_json),headers =headers_T) #post请求数据 + if response.status_code == 200: #服务器响应成功并返回数据 + try: + content = response.content + c = next(content) + result_json = ujson.loads(c) #将字符串转换成json格式 + print("response.json:{}".format(result_json)) + code = "" + message = "" + success = False + if "code" in result_json: + code = result_json["code"] + if "message" in result_json: + message = result_json["message"] + if "success" in result_json: + success = result_json["success"] + if code == "200" and message == "成功" and success == True: #上报成功返回 + date_tmp = utime.localtime() + time_tmp = utime.mktime(date_tmp) #获取当前时间戳 用于下次时间判断上报心跳数据 + print("date_tmp :{} time_tmp:{}\r\n".format(date_tmp,time_tmp)) + self.report_state = 1 #表示上报成功 置标志1 12小时之内不清0 12小时之后再次上报清零 + self.TimeSec = str(time_tmp) + self.config_data["TimeSec"] = str(time_tmp) + IMEI = modem.getDevImei() #获取IMEI号 + self.config_data["IMEI"] = str(IMEI) + self.write_config_msg_file(self.config_data) + # { + # "code":"200", + # "message":"成功", + # "success": true, + # "data":{ + # "deviceId":"xxx", + # "protocolTypeTime":"xxx" + # } + # } + result_s = 1 + else: + result_s = 0 + except Exception as e: #不是json格式 + print("response:{}".format(e)) + result_s = 0 + else: + result_s = 0 + except Exception as e: + print("response:{}".format(e)) + result_s = 0 + if REPORT_MODE == 1: #上报方式1 + if result_s == 1: #当前上报数据成功 开启下一个上报心跳数据定时器 + date_tmp = utime.localtime() + time_tmp = utime.mktime(date_tmp) + random_integer = urandom.randint(-15, 15) #两个时间戳相减大于24小时啧清0 + timerStart_init = HEARBEAT_REPORT_TIMER_CONFIG*1000+random_integer*1000*60 + print("timerStart_init {} random_integer:{}\r\n".format(timerStart_init,random_integer)) + self.timerStartReportHr.start(timerStart_init,0,self.timerStartReportHrCbOne)#重新开始 单次定时器 + else: #上报方式2 + if self.startTimerState == 0: + self.startTimerState = 1 + self.open_report_start_timer() + else: + result_s = 2 + self.AIRegulation_init() #重新初始化 + return result_s + return result_s + def timerStartReportHrCbOne(self,*argc): + reportStatus = self.report_hr_data() #上报心跳数据接口函数 + print("timerStartReportHrCbOne {}\r\n".format(reportStatus)) + if reportStatus == 0: #当前上报失败 开启1分钟的定时器检测 + self.timerStart.stop() + self.report_err_count = 0 + self.timerStart.start(HEART_REPORT_ERROR_TIMER*1000,1,self.oneMinTimerStartCb)#重新开始 + else: + self.timerStart.stop() + + def oneMinTimerStartCb(self,*argc): + reportStatus = self.report_hr_data() + print("oneMinTimerStartCb {}\r\n".format(reportStatus)) + if reportStatus != 0: # + self.timerStart.stop() + else: + self.report_err_count+=1 + if self.report_err_count >= HEART_REPORT_ERR_MAX_NUM: + self.report_err_count = 0 + self.timerStart.stop() + Power.powerRestart() #重启设备 可能网络异常或者哪里出错了 + + def timerStartReportHrCb(self,*argc): #上报心跳定时器回调 + date_tmp = utime.localtime() + time_tmp = utime.mktime(date_tmp) + random_integer = urandom.randint(-15, 15) #-15 - +15上报时间随机值分钟单位 *60*1000 + data = RTC().datetime() + year = data[0] + month = data[1] + day = data[2] + + if self.report_state == 1: #上报过一次 就等下一个12小时再上报一次 + #当前时间大于上次记录时间加上12小时就上报一次 + next_alarm_time = utime.localtime(int(self.TimeSec)) + old_month = next_alarm_time[1] + old_day = next_alarm_time[2] + old_year = next_alarm_time[0] + # if 1: + # if old_year != year or old_month != month or old_day != day: + # self.report_state = 0 + # self.report_hr_data() + + # else: + if (time_tmp >= self.TimeSec + HEARBEAT_REPORT_TIMER_CONFIG*1000 + random_integer*60*1000) or (old_year != year or old_month != month or old_day != day): #or old_year != year or old_month != month or old_day != day: #上次上报时间戳+12小时时间戳 大于当前时间戳 上报一次 或者年 月 日不一致也上报一次 + self.report_state = 0 + self.report_hr_data() + else: #确保12小时之内上报一次 每一个小时上 + self.report_hr_data()#上报一次心跳数据 + + def open_report_start_timer(self): #1小时的定时器 + self.timerStartReportHr.start(REALY_TIME_COUNT*1000,1,self.timerStartReportHrCb)#1小时定时 + + def timerStartCb(self,*argc):#获取设备信息定时器回调 + getDevInfoState = self.get_dev_info() + if getDevInfoState == 0:# + self.getDevInforErrCount+=1 + if self.getDevInforErrCount >= 20: + self.getDevInforErrCount = 0 + self.timerStart.stop() + else: + self.getDevInforErrCount = 0 + self.timerStart.stop() + self.report_hr_data()#上报一次心跳数据 + + def AIRegulation_init(self):#AI 纳管 初始化 获取完设备数据后立马上报心跳数据 + status = eventMesh.publish("get_factory_status") + if status == None: + status = 0 + print("get_factory_status:{}\r\n".format(status)) + if status == 0:#恢复出厂或者新的机器需要清空不必要的数据 + if self.init_flag == 0:#只初始化一次 + IFEXIST = ql_fs.path_exists("/usr/cm_ai_regulation.json") + if IFEXIST == True: + uos.remove("/usr/cm_ai_regulation.json") + self.init_flag = 1 + self.report_state = 0 + self.getDevInforErrCount = 0 + self.report_err_count = 0 + self.timerStartReportHr.stop() + + self.startTimerState = 0 + getDevInfoState = self.get_dev_info() + if getDevInfoState == 0:#开机获取失败了再等30s重新获取 获取二十次都失败就等下次重启设备获取 + self.timerStart.stop() + self.timerStart.start(30*1000,1,self.timerStartCb)#重新开始 开机10分钟内没有获取到设备信息就不获取了需要手动重启设备 + else: #设备开机获取设备信息成功 立马上报一次心跳数据 + self.report_hr_data()#上报一次心跳数据 + +aiRegulation = AIRegulation() + diff --git a/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/httpota.py b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/httpota.py new file mode 100644 index 000000000..1f7ff897c --- /dev/null +++ b/code/sdk/build/config/target_config/brandy/mk_fs_image/fd230/fs/user/system/cat1ota/httpota.py @@ -0,0 +1,43 @@ +#远程升级 + +import fota +import utime +import log +import checkNet + +import app_fota +from misc import Power +import modem +import ujson +import request +import ql_fs +import checkNet +import sys + +#远程升级 +import uos + + +# 设置日志输出级别 + +class httpota: + def __init__(self): + print("httpota init") + + + def run(url_1,url_2): + print("httpDownload...{}".format(url_1)) + print("httpDownload...{}".format(url_2)) + # format(str(url_2))) + fota_obj = fota() # 创建Fota对象 + # res = fota_obj.httpDownload(str(url_1),str(url_2)) + res = fota_obj.httpDownload(url1="{}".format(url_1),url2="{}".format(url_2)) + if res != 0: + print.error("httpDownload error") + return + print("wait httpDownload update...") + utime.sleep(2) + # Power.powerRestart() + +# httpota = httpota() +# httpota.run("http://snicker.com.cn:8089/FD230/V18-V19OTA") \ No newline at end of file diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt b/code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt index b4b5f30f4..f6c4c68c5 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt +++ b/code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt @@ -19,6 +19,7 @@ set(PRIVATE_HEADER set(SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/dev_authentication.cpp ${CMAKE_CURRENT_SOURCE_DIR}/http_cat1.cpp +${CMAKE_CURRENT_SOURCE_DIR}/http_cat1_ota.cpp ${CMAKE_CURRENT_SOURCE_DIR}/cat1_at_cmd.cpp ${CMAKE_CURRENT_SOURCE_DIR}/cat1_server_hal.cpp @@ -30,6 +31,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/cat1_ws.cpp + ) set(COMPONENT_PUBLIC_CCFLAGS diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_at_cmd.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_at_cmd.cpp index d184439c0..825668649 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_at_cmd.cpp +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_at_cmd.cpp @@ -653,6 +653,36 @@ static uint32_t stopwstest(uint8_t *para, uint32_t paraLen, char *strCommonCmd) } +// static uint32_t sendfotaurl(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +// { +// UNUSED(strCommonCmd); +// uint8_t argv[PPG_MAX_ARGC][PPG_MAX_ARGV_LEN] = { 0 }; +// uint32_t argc = 0; +// printf("ai_msg\n"); +// int ret = ConvertCmdToParam(para, paraLen, argv, &argc); +// if (ret != PPG_SUCCESS) { +// printf("CAT1TEST ATCMD Convert Command Failed\n"); +// return ERRCODE_FAIL; +// } +// // send_fota_url(" and "); +// return 0; +// } + +static uint32_t sendfotaurl(uint8_t *para, uint32_t paraLen, char *strCommonCmd) +{ + UNUSED(strCommonCmd); + uint8_t argv[PPG_MAX_ARGC][PPG_MAX_ARGV_LEN] = { 0 }; + uint32_t argc = 0; + printf("ai_msg\n"); + int ret = ConvertCmdToParam(para, paraLen, argv, &argc); + if (ret != PPG_SUCCESS) { + printf("CAT1TEST ATCMD Convert Command Failed\n"); + return ERRCODE_FAIL; + } + star_http_ota_updata(); + return 0; +} + static const at_cmd_table_t g_cat1_cmd[] = { @@ -689,6 +719,8 @@ static const at_cmd_table_t g_cat1_cmd[] = { { (char *)"AT^STARTTTS", starttts, (char *)"1" }, { (char *)"AT^SENDTTTS", sendttstxt, (char *)"1" }, { (char *)"AT^STOPTEST", stopwstest, (char *)"1" }, + { (char *)"AT^OTAHTTP", sendfotaurl, (char *)"1" }, + }; diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.cpp index ea949f93d..0c50a3eb1 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.cpp +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.cpp @@ -95,6 +95,8 @@ enum UDP_COMMAND_HEAD { UDP_MSG_SEND_VOLTE_SWITCH = 0x1A,//VOLTE开关 + UDP_MSG_SEND_OTA= 0x1B,//OTA 升级 + UDP_MSG_WATCH_REPLY_ACK = 0xAC,// // UDP_MSG_WATCH_REPLY_HANGUP = 0x21,// }; @@ -395,11 +397,11 @@ void udp_send_msg_toCat1(uint8_t cmd,char *content) osal_msleep(50); } - if (g_skip_cat1_service_udp_transfer == 1) - { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP," g_skip_cat1_service_udp_transfer \n"); - return ; - } + // if (g_skip_cat1_service_udp_transfer == 1) + // { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP," g_skip_cat1_service_udp_transfer \n"); + // return ; + // } char station_tx_buffer[MAX_TCP_MSG_BUFFER_LEN] = {0}; if( sourceAddr.sin_port != 0 ) { @@ -1402,6 +1404,21 @@ void send_volte_switch_toCat1(void)//发送VOLTE->CAT1 sprintf_s((char *)send_str,5, "%d", volte); udp_send_msg_toCat1(UDP_MSG_SEND_VOLTE_SWITCH,send_str); } + +void send_fota_url(char *buf)//发送VOLTE->CAT1 +{ + // if(strlen(buf)>128) + // { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"strlen(buf)>128\n"); + // } + // char send_str[128] = {0}; + // sprintf_s((char *)send_str,128, "%s", buf); + + udp_send_msg_toCat1(UDP_MSG_SEND_OTA,buf); + + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ok!\n"); +} + bool get_volte_switch(void)// { bool volte = OHOS::ConfigModel::GetInstance()->GetVoLTE_Call(); diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.h b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.h index 8d7ece835..f2963d362 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.h +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.h @@ -64,6 +64,10 @@ uint8_t set_call_hungup_flag(uint8_t data); void cat1_call_hungup_timer(void); +void send_fota_url(char *buf); + +void star_http_ota_updata(void); + #ifdef __cplusplus #if __cplusplus } diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.cpp index a21c3d6e1..708637eb5 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.cpp +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.cpp @@ -442,7 +442,7 @@ static void stop_cat1_ota(void){ //停止 CAT1 ota 清标识 } } if(fp != NULL){ //防止打开文件没有关闭 - printf("file is not close!\r\n"); + printf("file is not lwip_close!\r\n"); fclose(fp); fp = NULL; } @@ -1162,7 +1162,7 @@ static int tcp_socket_file_init() void re_connect(void) { // socklen_t addrLen = sizeof(filesourceAddr); - // close(g_listen_sock); + // lwip_close(g_listen_sock); // // while (1) // { // int connret=connect(g_listen_sock, (struct sockaddr *)&filesourceAddr,addrLen); @@ -1200,8 +1200,8 @@ void cat1_server_file_task(void *pvParameters) } if( g_listen_sock > 0 ) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"close(g_listen_sock)\n"); - close(g_listen_sock); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"lwip_close(g_listen_sock)\n"); + lwip_close(g_listen_sock); } if(is_need_udp_updata==0) @@ -1271,7 +1271,7 @@ void cat1_server_file_task(void *pvParameters) break; // continue; } else if (len == 0) { - WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Connection closed\n"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Connection lwip_closed\n"); break; // continue; } diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp index 4da61b191..e293a59c8 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp +++ b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_ws.cpp @@ -1082,8 +1082,21 @@ bool chat_result_analysis(char *buf) // } } + } + if(strcmp("end",type_str)==0) + { + char end_str_chat[128]={0}; + + if(strlen(content_str)>0) + { + memset_s(end_str_chat,128,0,128); + memcpy_s(end_str_chat,128,end_str_chat,strlen(end_str_chat)); + ble_set_ai_Answer_str(end_str_chat,2); + } } + + cJSON_Delete(root); return true; } @@ -1907,7 +1920,9 @@ void bk_websocket_tts(void *data) { // uapi_start_asr(); // uapi_start_tts_single_txt("2025英超夏季转会窗分阶段开启第一阶段2025å¹´6月1日至2025å¹´6月11日凌晨2:00北京时间第二阶段常规夏窗2025å¹´6月16日至2025å¹´9月2日凌晨2:00北京时间本贴将持续更新2025年夏窗以曼联转会相关为主的新闻和消息。"); } + tts_break=0; + // uapi_start_tts_single(); char* tts_recv_buf=(char *)malloc(1024*4); @@ -2028,6 +2043,10 @@ int32_t uapi_tts_paly_stop(void) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"uapi_tts_paly_init\n"); + tts_break=1; + AIStreamFlush(); + send_msg_data_into_Ai_msg_queue((uint8_t *)"tts_recv_buf",13,201); + int32_t ret = ERRCODE_FAIL; int32_t argc = 1; uint8_t *argv = (uint8_t *)"stop"; @@ -2035,6 +2054,7 @@ int32_t uapi_tts_paly_stop(void) ret = VoiceCallVolteSample(argc, (const char **)&argv); } + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"ret %d ",ret); @@ -2057,6 +2077,8 @@ void chat_server_deinit(void) void tts_server_deinit(void) { send_websocket_message(tts_client,(uint8_t *)"WS_CLOSE",strlen("WS_CLOSE"),WS_CLOSE); + + } diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.h b/code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.h index 6d91265c4..82522523b 100644 --- a/code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.h +++ b/code/sdk/drivers/peripheral/slip/cat1Service/dev_authentication.h @@ -33,6 +33,9 @@ void dev_authentication_MSG_put(const char *data,uint32_t len,dev_authentication void aut_active(void);//设备激活; void aut_login(void);//设备激活; +void system_init(void); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/http_cat1_ota.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/http_cat1_ota.cpp new file mode 100644 index 000000000..4f176d36d --- /dev/null +++ b/code/sdk/drivers/peripheral/slip/cat1Service/http_cat1_ota.cpp @@ -0,0 +1,253 @@ +#include "lwip/apps/http_client.h" + + +#include + +#include "bletest.h" +#include "custom_utils.h" +#include "custom_runtime.h" +#include "bleANCS.h" +#include "cat1_tcpServer.h" +#include "custom_utils.h" +#include "broadcast_feature.h" +#include "cmsis_os2.h" +#include "cat1_ctl.h" +#include "wearable_log.h" +#include "lwip/apps/httpd.h" +#include "dev_authentication.h" +#include "SystemUpdateModel.h" + +#include "bts_br_gap.h" +#include "custom_utils.h" +#include "cat1_server.h" + + +// http://iot.api.thisiot.com/ota/task?deviceId=281106010103&sourceVersion=PY19_1 +// http://iot.api.thisiot.com/ota/task?deviceId=281106010103&sourceVersion=PY19_2 +#if 1 +#define CAT1_HTTP_JSON_SERVER_NAME "iot.api.thisiot.com"//"test.app.api.thisiot.com"//获取升级服务器 +#define CAT1_PORT (80)//(443)//http端口号 +// #define POST_URL "http://test.iot.api.thisiot.com/ota/update-result"//上报url +#define CAT1_JSON_URL "http://iot.api.thisiot.com/ota/task?deviceId=%s&sourceVersion=%s"//获取升级url +#else + +#define CAT1_HTTP_JSON_SERVER_NAME "snicker.com.cn"//"test.app.api.thisiot.com"//获取升级服务器 +#define CAT1_PORT "snicker.com.cn"//"//升级包服务器 +#define PORT (8089)//(443)//http端口号 +#define CAT1_JSON_URL "http://snicker.com.cn:8089/fd230otanew.jsp?product=FD230&imei=%s&pkgver=%s"//获取升级url +#endif + +#ifdef SINGLE_USER_PARTITION +#define UPDATAJSONPATH "/user/update/cat1_ota.json"//获取升级的得到的json +#else +#define UPDATAJSONPATH "/update/ota_start_.json"//获取升级的得到的json +#endif + +osSemaphoreId_t get_done_sem; + +static uint32_t put_srv_res=0; + +static void read_http_get_ota_url_file(char *out_put_url); + + +static httpc_connection_t settings = {0}; + + + static err_t httpc_download_headers_done_ui(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "httpc_download_headers_done_ui hdrlen %d, file len %d\r\n",hdr_len,content_len); + // file_total_len = content_len; + return 0; + } + static err_t httpc_download_file_recv_ui(httpc_state_t *connection, u32_t rx_len,u32_t rx_total_len) + { + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "httpc_download_file_recv_ui recv %d bytes total received %d filelen %d\r\n",rx_len,rx_total_len,file_total_len); + return 0; + } + + static void httpc_download_result_data_put(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "httpc_download_result_ui"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"httpc_download_result , httpc_result_t %d, rx_content_len %d , srv_res %d, err %d\n", + httpc_result,rx_content_len,srv_res,err); + // if(srv_res==200) + { + put_srv_res=srv_res; + + (void)osSemaphoreRelease(get_done_sem); + //激活成功 + } + return ; + } + + +uint32_t http_get_ota_url(char *out_put_url,char *pkgver) +{ + + memset_s(&settings,sizeof(settings),0,sizeof(settings)); + settings.use_proxy=0; + + uint8_t *otadatapath =(uint8_t *)UPDATAJSONPATH; + + settings.result_fn=httpc_download_result_data_put; + settings.file_rx_fn = httpc_download_file_recv_ui; + settings.headers_done_fn = httpc_download_headers_done_ui; + + unsigned char deviceId[20] = {0}; + memset(deviceId,0,6); + bluetooth_get_local_addr(&deviceId[0],6); + char deviceId_temp[20] = {0}; + sprintf(deviceId_temp,"%02X%02x%02X%02x%02X%02x",deviceId[5],deviceId[4],deviceId[3],deviceId[2],deviceId[1],deviceId[0]); + + char CAT1_JSON_URL_BUF[256]={0}; + sprintf(CAT1_JSON_URL_BUF,CAT1_JSON_URL,deviceId_temp,pkgver); + + httpc_state_t* connection=NULL; + err_t rett= httpc_get_file_dns_to_disk( + CAT1_HTTP_JSON_SERVER_NAME, + CAT1_PORT, + CAT1_JSON_URL_BUF, + &settings, + NULL, + (const char*) otadatapath, + &connection); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"custom_start_ota_download %d \r\n",rett); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "use_put"); + + if(rett==0) + { + get_done_sem = osSemaphoreNew(1, 0, NULL); + + osSemaphoreAcquire(get_done_sem, 1000*30); + + if(put_srv_res==200) + { + read_http_get_ota_url_file(out_put_url); + } + + + osSemaphoreDelete(get_done_sem); + + + return put_srv_res; + } + else + { + return rett; + } +} + + +static void read_http_get_ota_url_file(char *out_put_url) +{ + + FILE * fp = fopen(UPDATAJSONPATH,"rb+"); + if(fp==NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "open fail"); + return; + } + char *buf=(char *)malloc(1024); + memset((void*)buf,0,1024); + int ret =fread(buf,1,1024,fp); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "httpc_download_result_ui %d %s\r\n",ret,buf); + if(ret==0) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "fread %d",ret); + fclose(fp); + free(buf); + return; + } + fclose(fp); + + char *p=buf; + + while (*p!='{' && *p !='\0') + { + p++; + } + cJSON *root = cJSON_Parse(p); + // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, " %s",new_buf); + free(buf); + + if(root==NULL) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "httpc_download_result_ui JSON_parse_fail"); + } + else if(root!=NULL) + { + + int code=cJSON_GetObjectItem(root, "code")->valueint; + char *msg_json = cJSON_GetObjectItem(root, "msg")->valuestring; + + int success=cJSON_GetObjectItem(root, "success")->valueint; + + if(code==20007) + { + cJSON *data=cJSON_GetObjectItem(root, "data"); + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, ""); + + if(data!=NULL) + { + cJSON *downloadFileVo=cJSON_GetObjectItem(data, "downloadFileVo"); + + if(downloadFileVo!=NULL) + { + char *uri = cJSON_GetObjectItem(downloadFileVo, "url")->valuestring; + WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "uri %s",uri); + sprintf((char *)out_put_url,"%s",uri); + } + char* targetVersion=cJSON_GetObjectItem(data,"targetVersion")->valuestring; + } + + } + cJSON_Delete(root); + } +} + + +// +// http://snicker.com.cn:8089/FD230/PY_SRV_V19/dfota_2.bin + +void star_http_ota_updata(void) +{ + int ret=0; + char buf_1[256]={0}; + ret = http_get_ota_url(buf_1,"PY19_1"); + for (int i = 0; i <3; i++) + { + ret = http_get_ota_url(buf_1,"PY19_1"); + if(ret==200) + break; + } + if(ret!=200) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ret!=200 PY19_1"); + return; + } + char buf_2[256]={0}; + http_get_ota_url(buf_2,"PY19_2"); + for (int i = 0; i <3; i++) + { + ret = http_get_ota_url(buf_2,"PY19_2"); + if(ret==200) + break; + } + if(ret!=200) + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ret!=200 PY19_2"); + return; + } + + char * send_buf=(char *) malloc(strlen(buf_1)+strlen(buf_2)+40); + memset(send_buf,0,strlen(buf_1)+strlen(buf_2)+40); + + sprintf(send_buf,"%s and %s",buf_1,buf_2); + // sprintf(send_buf,"%s and %s","http://snicker.com.cn:8089/FD230/PY_SRV_V19/dfota_1.bin","http://snicker.com.cn:8089/FD230/PY_SRV_V19/dfota_2.bin"); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s ",send_buf); + + send_fota_url(send_buf); + + free(send_buf); +} +// http_get_ota_url() \ No newline at end of file