Merge #756 into sdk602patch0626 from refs/changes/756/head
author邓雪英 <1731678236@qq.com>
Thu, 22 Aug 2024 02:08:38 +0000 (02:08 +0000)
committersnickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
Thu, 22 Aug 2024 02:08:38 +0000 (02:08 +0000)
Code review from 邓雪英

* refs/changes/756/head: (4 commits squashed)

  - CAT1的TCP文件传输

  - Merge branch &#39;sdk602patch0626&#39; of https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230 into sdk602patch0626

  - 修改文件名

  - 删除文件名

Signed-off-by: d15521469561 <1731678236@qq.com>
Reviewed-by: snickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
Merged-by: snickersun@163.com <accounts_62b90f7fcf51ade33b6f628e@mail.teambition.com>
link: https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230/change/756
12 files changed:
cat1modem/src/cat1Service.py
cat1modem/src/checkota.py
cat1modem/src/main.py
cat1modem/src/main_init.py [new file with mode: 0644]
cat1modem/src/pyversion.txt [new file with mode: 0644]
cat1modem/src/tcpService.py [new file with mode: 0644]
code/sdk/application/brandy/brandy_standard/thread_pri_init.c
code/sdk/drivers/peripheral/slip/cat1Service/CMakeLists.txt
code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.h
code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.cpp [new file with mode: 0644]
code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.h [new file with mode: 0644]
code/sdk/drivers/peripheral/utils/custom_utils_at_cmd.c

index 4c1d05a..c650c5d 100644 (file)
@@ -209,6 +209,7 @@ class Cat1Service:
     STA = 1 # SLIP_OUTER
 
     def __init__(self, uart=UART.UART4, mode=AP):
+        
         self.__uart = uart
         self.__mode = mode
         self.__message = ''
@@ -267,11 +268,7 @@ class Cat1Service:
         self.msg_nums_old = 0
         self.china_mobile_init = 0
         self.factory_status = 0
-        sms_get = sms.getSaveLoc()
-        if(sms_get != -1):
-            sms_lacv = sms_get[0][0]
-            if sms_lacv != 'SM': #每次开机设置一下短信的存储位置
-                sms.setSaveLoc('SM', 'SM', 'SM')
+        
         return None
 
     def __socket_init(self):
@@ -889,20 +886,21 @@ class Cat1Service:
         
         print("__Socket_UDP_noreply send msg {}".format(msg))
         self.__err = 0
-        self.__sock.sendto(msg,server_addr)
-
+        data_size = self.__sock.sendto(msg,server_addr)
+        print("self.__sock data_size {}".format(data_size))
         self.__wait_resp = 0
         return 0
 
     # socket通信(UDP)模块
     def __Socket_Thread(self):
+        data = b""
         while True:
             try:
                 print("recv====")
                 data=self.__sock.recv(1024)
-                print(data)
+                print("data:{}".format(data))
             except Exception as recverr:
-                print(recverr)
+                print("recverr:{}\r\n".format(recverr))
                 if "110" in str(recverr):
                     self.__err = 1
                     # if self.__wait_resp == 1:
@@ -911,7 +909,7 @@ class Cat1Service:
                     utime.sleep(1)
                     self.__sock = self.__socket_reinit()
                 
-            else :
+            if data:
                 value = self.__unpack_tlv_format(data.decode())
                 if value != -1:
                     print('mode: {0}, recv {1} bytes, Data: {2}'.format (value[0],len(data), value[2]))
index a788a41..6b6efd7 100644 (file)
@@ -39,41 +39,41 @@ def set_version_to_json_config(app_type,keyvalue):
     config_data = ql_fs.read_json(CONFIG_JSON)
     config_data.update( {str(get_versionkeyname_by_py(app_type)):keyvalue})
     ql_fs.touch(CONFIG_JSON, config_data)
-    fota_log.info("{}={}".format(get_versionkeyname_by_py(app_type),keyvalue))
-    fota_log.info("{}".format(config_data))
+    print("{}={}".format(get_versionkeyname_by_py(app_type),keyvalue))
+    print("{}".format(config_data))
 
 def get_version_from_json_config(app_type):
     config_data = ql_fs.read_json(CONFIG_JSON)
     keyvalue = config_data.get( get_versionkeyname_by_py(app_type),get_default_versionvalue_by_py(app_type))
-    fota_log.info("{}={}".format(get_versionkeyname_by_py(app_type),keyvalue))
+    print("{}={}".format(get_versionkeyname_by_py(app_type),keyvalue))
     return keyvalue
 
 def result(args):
-    fota_log.info('download status:',args[0],'download process:',args[1])
+    printf('download status:',args[0],'download process:',args[1])
 
 def check_fota():
     modem_ver = modem.getDevFwVersion()    
     imei = modem.getDevImei()
     url =  "http://icfota.snicker.com.cn:8089/fd230ota.jsp?product=FD230&pkgver={0}&imei={1}".format(modem_ver,imei)
     response = request.get(url)
-    fota_log.info(url)
+    printf(url)
     data = response.json()
     if(data['UptoDate'] == False):
-        fota_log.info("Need update python application")
+        printf("Need update python application")
         fota_obj = fota()  # 创建Fota对象
-        fota_log.info("httpDownload...")
+        printf("httpDownload...")
         srcurl = data['url']
         #差分升级方式
         # res = fota_obj.httpDownload(url1="http://www.example.com/fota.bin",callback=result)    
         # mini fota方式
-        fota_log.info("{},{}".format("{}/dfota_1.bin".format(srcurl),"{}/dfota_2.bin".format(srcurl)))
+        printf("{},{}".format("{}/dfota_1.bin".format(srcurl),"{}/dfota_2.bin".format(srcurl)))
         res = fota_obj.httpDownload(url1="{}/dfota_1.bin".format(srcurl),url2="{}/dfota_2.bin".format(srcurl),callback=result)    
         #差分升级FTP方式  
         #res = fota_obj.httpDownload(url1="ftp://user:password@ip:port/fota.bin",callback=result) #其中user,password,ip,port需要填写具体使用的FTP服务器信息
         if res != 0:
-            fota_log.error("httpDownload error")
+            printf("httpDownload error")
             return
-        fota_log.info("wait httpDownload update...")
+        printf("wait httpDownload update...")
     else:
         print("No need update python application")
     
@@ -86,11 +86,11 @@ def do_app_update_internal(app_type):
         response = request.get(url)
         print(url)
         data = response.json()
-        if(data['UptoDate'] == False):
+        if data['UptoDate'] == False:
             print("Need update python application {}".format(data["appcount"]))        
             for app_update in data["apps"]:
                 srcurl = app_update['url']
-                fota_log.info("run start...")
+                printf("run start...")
                 targetpyname = app_update['OtaPackageName']
                 version = app_update['OtaPackageVersion']
                 tmpfile_path = "/usr/.updater/{}".format(targetpyname)
@@ -113,6 +113,7 @@ def do_app_update_internal(app_type):
         print("nonetwork:{}".format(e))
 
 if __name__ == '__main__':
+    print("check ota start!!!!!!!!!!")
     set_version_to_json_config(CURRENT_APP_TYPE,PROJECT_VERSION)
     stage, state = checkNet.waitNetworkReady(1)
     if stage == 3 and state == 1:
index 5cbf4cb..a72e1dc 100644 (file)
@@ -1,51 +1,13 @@
 import example
-import osTimer
-import ql_fs
-import log
-
-PROJECT_VERSION = "PY_MAIN_V3"
-CONFIG_JSON="/usr/system_config.json"
-CURRENT_APP_TYPE="pymain"
-
-
-# 设置日志输出级别
-log.basicConfig(level=log.INFO)
-cat1service_log = log.getLogger("pymain")
-
-
-def get_versionkeyname_by_py(app_type):
-    return str("{}version".format(app_type))
-
-def get_default_versionvalue_by_py(app_type):
-    if (app_type == "pymain"):
-        return "PY_MAIN_V2"
-    elif (app_type == "pyota"):
-        return  "PY_OTA_V2"
-    elif (app_type == "pysrv"):
-        return  "PY_SRV_V2"
-
-#如果没有configfile则创建它
-if not ql_fs.path_exists(CONFIG_JSON):
-    data = {str(get_versionkeyname_by_py(CURRENT_APP_TYPE)):get_default_versionvalue_by_py(CURRENT_APP_TYPE)}
-    ql_fs.touch(CONFIG_JSON,data)
-
-def set_version_to_json_config(app_type,keyvalue):
-    config_data = ql_fs.read_json(CONFIG_JSON)
-    config_data.update( {str(get_versionkeyname_by_py(app_type)):keyvalue})
-    ql_fs.touch(CONFIG_JSON, config_data)
-    cat1service_log.info("{}={}".format(get_versionkeyname_by_py(app_type),keyvalue))
-    cat1service_log.info("{}".format(config_data))
-
-set_version_to_json_config(CURRENT_APP_TYPE,PROJECT_VERSION)
+main_flag = 1
+try:
+    from usr.tcpService import TcpService
+    example.exec('/usr/main_init.py')
+    print("启动成功!!!!!\r\n")
+except Exception as e:
+    main_flag = 0
+    print("启动失败!!!!!\r\n")
     
-def checkota_cb(arg):
-    print("start checkota!!")
-    example.exec('/usr/checkota.py')
-# 创建os定时器
-timer = osTimer()
-# 启动定时器,参数依次为时间、是否循环、回调函数  定时器超时的时间(单位ms)
-# 开机delay 20秒后执行一次ota升级
-timer.start(20000,0,checkota_cb)  
 
-example.exec('/usr/cat1Service.py')
+
 
diff --git a/cat1modem/src/main_init.py b/cat1modem/src/main_init.py
new file mode 100644 (file)
index 0000000..5c9846a
--- /dev/null
@@ -0,0 +1,78 @@
+import example
+import osTimer
+import ql_fs
+import log
+import sms
+from misc import Power
+ota_flag = 0
+try:
+    from usr.EventMesh import eventMesh
+    from usr.telecom_dmp import telecomDmpCb
+    from usr.china_mobile_dmp import chinamobileCb
+    import usr.checkota
+    from usr.cat1Service import cat1service
+    ota_flag = 1
+    print("检测文件成功!!!!!!!\r\n")
+except Exception as e:
+    print("检测文件失败!!!!!!!{}\r\n".format(e))
+    ota_flag = 0
+tmp_dir = ql_fs.path_exists("/usr/TmpPyFile") #临时存放的文件夹
+if tmp_dir == True:
+    try:
+        ql_fs.rmdirs("/usr/TmpPyFile")
+        print("移除 TmpPyFile 成功!!!!!!!{}\r\n".format(e))
+    except Exception as e:
+        print("移除 TmpPyFile 失败!!!!!!!{}\r\n".format(e))
+
+sms_get = sms.getSaveLoc()
+if(sms_get != -1):
+    sms_lacv = sms_get[0][0]
+    if sms_lacv != 'SM': #每次开机设置一下短信的存储位置
+        sms.setSaveLoc('SM', 'SM', 'SM')
+
+PROJECT_VERSION = "PY_MAIN_V3"
+CONFIG_JSON="/usr/system_config.json"
+CURRENT_APP_TYPE="pymain"
+
+
+# 设置日志输出级别
+log.basicConfig(level=log.INFO)
+cat1service_log = log.getLogger("pymain")
+
+
+def get_versionkeyname_by_py(app_type):
+    return str("{}version".format(app_type))
+
+def get_default_versionvalue_by_py(app_type):
+    if (app_type == "pymain"):
+        return "PY_MAIN_V2"
+    elif (app_type == "pyota"):
+        return  "PY_OTA_V2"
+    elif (app_type == "pysrv"):
+        return  "PY_SRV_V2"
+
+#如果没有configfile则创建它
+if not ql_fs.path_exists(CONFIG_JSON):
+    data = {str(get_versionkeyname_by_py(CURRENT_APP_TYPE)):get_default_versionvalue_by_py(CURRENT_APP_TYPE)}
+    ql_fs.touch(CONFIG_JSON,data)
+
+def set_version_to_json_config(app_type,keyvalue):
+    config_data = ql_fs.read_json(CONFIG_JSON)
+    config_data.update( {str(get_versionkeyname_by_py(app_type)):keyvalue})
+    ql_fs.touch(CONFIG_JSON, config_data)
+    cat1service_log.info("{}={}".format(get_versionkeyname_by_py(app_type),keyvalue))
+    cat1service_log.info("{}".format(config_data))
+
+set_version_to_json_config(CURRENT_APP_TYPE,PROJECT_VERSION)
+    
+
+def checkota_cb(arg):
+    print("start checkota!!")
+    example.exec('/usr/checkota.py')
+# 创建os定时器
+
+timer = osTimer()
+# 启动定时器,参数依次为时间、是否循环、回调函数  定时器超时的时间(单位ms)
+# 开机delay 20秒后执行一次ota升级
+timer.start(20000,0,checkota_cb)  
+print("checkota py end!!")
diff --git a/cat1modem/src/pyversion.txt b/cat1modem/src/pyversion.txt
new file mode 100644 (file)
index 0000000..99b3fb0
--- /dev/null
@@ -0,0 +1 @@
+PY_SRV_V11
\ No newline at end of file
diff --git a/cat1modem/src/tcpService.py b/cat1modem/src/tcpService.py
new file mode 100644 (file)
index 0000000..3238fc2
--- /dev/null
@@ -0,0 +1,694 @@
+from misc import Power
+import usocket
+import log
+import utime
+import audio
+from machine import UART
+import _thread
+from queue import Queue
+from machine import Pin
+from machine import ExtInt
+import dataCall
+import voiceCall
+import net
+import uping
+import example
+import osTimer
+import sim
+import modem
+import utime
+import checkNet
+import atcmd
+import fota
+import request
+import ql_fs
+import pm
+import sms
+import binascii
+import ujson
+import uos
+import slip
+
+CAT1_SERVICE_HEAD = "FE"
+
+
+
+CAT1_REPLAY_STATE="00"
+CAT1_CREAT_DIR_FAILE= "01"
+CAT1_CREAT_DIR_OK= "02"
+CAT1_NO_REPLAY_OTA_OK= "03"
+CAT1_WRITE_FILE_SUCC= "04"
+CAT1_WRITE_FILE_ERROR = "05"
+CAT1_CRC_ERROR = "06"
+CAT1_SEND_HEAD_ERR = "07"
+CAT1_OTA_TIMEOUT_BLE_NO_REPLAY = "08"
+CAT1_CREAT_FILE_ERROR = "09"
+CAT1_CREAT_FILE_SUCC = "0A"
+CAT1_ALLPY_FILE_TRANSFER_END = "0B"
+CAT1_REPLAY_OTA_SUCC = "0C"
+CAT1_REPLAY_OTA_FALIE = "0D"
+CAT1_REPLAY_FILE_SIZE_OK = "0E"
+CAT1_REPLAY_FILE_SIZE_ERR = "0F"
+CAT1_REPLAY_OTA_END_FAILE = "10" #升级完之后 CAT1回复升级失败
+
+CAT1_NEED_UPDATE_OTA = "11" #提示用户强制升级
+
+BLE_STOP_OTA = 0 #结束OTA升级
+BLE_START_OTA = 1 #ble 开始发送OTA标识 -》   CAT1
+BLE_START_SEND_SINGLE_FILE_INFO= 2 #//ble 开始发送单个文件信息 -> CAT1 创建单个文件名
+BLE_START_SEND_FILE_DATA= 3 #//BLE开始发送文件数据额 ----》CAT1 接收文件数据写文件
+BLE_START_OTA_FAILE = 4 #BLE 发送OTA失败 取消文件传输
+BLE_START_OTA_SUCC = 5 #//BLE 发送OTA成功标识
+BLE_START_SEND_ALLFILE_FINESH = 6 #/所有PY文件传输完成
+BLE_START_SEND_SINGLE_FINESH = 7 #//单个文件传输完成
+BLE_START_ERROR_INFO = 255 #/发送错误信息结束进程
+
+# 创建gpio对象
+gpioWakeBT = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_DISABLE, 1)
+# 设置输入输出模式
+gpioWakeBT.set_dir(Pin.OUT)
+
+# 设置引脚电平
+gpioWakeBT.write(0)
+FILE_TRANSFER_TIMEOUT=60  #超时时间 60s没有收到BLE的发送数据就结束了
+class TcpServiceInit:
+    AP = 0  # SLIP_INNER
+    STA = 1 # SLIP_OUTER
+
+    def __init__(self, uart=UART.UART4, mode=AP):
+        self.__uart = uart
+        self.__mode = mode
+        self.Cat1FileState = 0
+        self.Cat1FileReplayBle = 0
+        self.Cat1TimeCount = 0
+        self.Cat1PyFileTimout = FILE_TRANSFER_TIMEOUT
+        self.Cat1FileTransTimer = osTimer()
+        self.Cat1OtaTimeOut = osTimer()
+        self.crc_err = 0
+        self.allPyRecvFlag = 0
+        self.ota_state =0
+        self.ota_bstate =0
+        self.fileNameTmp = ""
+        self.fileNameList = []
+        self.fileSizeList = []
+        self.fileSize = 0
+        self.updateTimer = osTimer()
+        self.updateTimerCount = 0
+        self.updateTimerFlag = 0
+        self.sock = None
+        
+        slip.destroy()
+        ret = slip.construct(self.__uart,self.__mode, 0)
+        if ret != 0:
+            print('slip netif construct fail')
+            return None
+        
+        self.__sock_file = None
+        self.__sock_file = self.__socket_file_init()
+        self.__thread_file = _thread.start_new_thread(self.__Socket_File_Thread, ())
+        print("ftp_Service :{}\r\n".format(self.__sock_file))
+    # 封装tlv数据包
+    def __pack_tlv_format(self, head, content):
+        head1 = head
+        content1 = content
+        if len(content1) == 0 or len(content1) > 9999 or len(head1) != 2:
+            print('illegal pack tlv content file')
+            return -1
+        len_str ='%04d' % len(content1)
+        tlv_pack = CAT1_SERVICE_HEAD+head1+len_str+content1
+        return tlv_pack
+    # 解码tlv数据包
+    def __unpack_tlv_format(self, msg):
+        print('__unpack_tlv_format file {}\r\n'.format(msg))
+        msg_tmp = str(msg)[2:]#这是去除head FE
+        tag = msg_tmp[0:2]
+        length = msg_tmp[2:6]
+        value = msg_tmp[6:]
+        len_str ='%04d' % len(value)
+        if len(value) == 0 or len(value) > 9999 or len(tag) != 2 or len_str != msg_tmp[2:6]:
+            print('__unpack_tlv_format err file')
+            return -1
+        print('__unpack_tlv_format: {} {} {}\r\n'.format(tag,length,value))
+        unpack = (tag,length,value)
+        return unpack
+    def __socket_init(self):
+       
+        # 创建一个socket实例
+        self.sock = usocket.socket(usocket.AF_INET, usocket.SOCK_STREAM)
+        self.sock.setsockopt(usocket.SOL_SOCKET, usocket.SO_REUSEADDR, 1)
+        return self.sock
+
+    def __socket_file_init(self): #文件传输Socket
+        self.sock = usocket.socket(usocket.AF_INET, usocket.SOCK_DGRAM, usocket.TCP_CUSTOMIZE_PORT)
+        self.sock.setsockopt(usocket.SOL_SOCKET, usocket.SO_REUSEADDR, 1)
+        # 绑定IP
+        bind_addr = ('172.16.1.2', 5001) 
+        self.sock.bind(bind_addr)
+        self.sock.settimeout(10)
+        return self.sock
+    def __socket_file_reinit(self):
+        print("self.__sock_file reinit:{}\r\n".format(self.__sock_file))
+        if self.__sock_file != None:
+            self.sock.close()
+        return self.__socket_file_init()
+    
+    def __Socket_UDP_file_noreply(self, head, content):
+        head1 = head
+        content1 = content
+        gpioWakeBT.write(1)
+        utime.sleep_ms(2)
+        gpioWakeBT.write(0)
+        utime.sleep_ms(20)
+        # 消息处理
+        msg = self.__pack_tlv_format(head1,content1)
+        if msg == -1: #无效数据
+            return 0
+        # 向服务端发送消息
+        server_addr = ('172.16.1.5',1001) #服务端口也需要更改
+        
+        print("__Socket_UDP_file_noreply send msg {}".format(msg))
+        try:
+            data_size = self.__sock_file.sendto(msg,server_addr)
+            print("self.__sock_file data_size {}".format(data_size))
+        except Exception as e:
+            print("self.__sock_file error {}".format(e))
+        return 0
+    # py文件传输
+    # //py文件传输
+    # // {"Code":1} 开始OTA
+    # // {"Code":2,"fileName":"cat1Service.py","fileSize":123435} fileCode: 文件ID fileName:文件名称 fileSize:文件大小
+    # // {"Code":3,"head+datalen+data+CRC":"数据"} // Code: 2开始发送文件数据
+    # // {"Code":4} BLE 主动发送OTA失败
+    # // {"Code":5} BLE 主动发送OTA成功
+    # // {"Code":6} BLE 所有PY文件传输完成
+    # // {"Code":7} BLE 单个文件传输完成
+    def __Socket_File_Thread(self):
+        while True:
+            try:
+                print(" __Socket_File_Thread recv====22222")
+                data=self.__sock_file.recv(1024*10)
+                if not data:
+                    print("__Socket_File_Thread data null:\r\n")
+                else:
+                    self.file_data(data.decode('uft-8'))
+                    # print("__Socket_File_Thread  end:{}\r\n".format(data.decode()))
+
+            except Exception as e:
+                print("__Socket_File_Thread:e{}\r\n".format(e))
+                self.__sock_file = self.__socket_file_reinit()
+            # print("End __Socket_File_Thread Thread")
+    
+    def cat1FileTimerCb(self,*argc):
+        print("timer test\r\n")
+        if self.Cat1PyFileTimout > 0:
+            self.Cat1PyFileTimout-=1
+        if self.Cat1PyFileTimout == 0:
+            self.Cat1PyFileTimout = 0
+            self.Cat1FileState = 0
+            self.deleteTmpFile()
+            self.deleteUsrTmpFile()
+            self.__Socket_UDP_file_noreply(CAT1_OTA_TIMEOUT_BLE_NO_REPLAY,"ota error") #结束文件接收不完整的
+            self.Cat1FileTransTimer.stop() #//关闭定时器
+            pass
+
+    def crc_cal(self,msg):
+        bytes_data = msg.encode('utf-8')
+        hex_data = binascii.hexlify(bytes_data)
+        hex_data = hex_data.decode()
+        # print("hex_data:{}\r\n".format(hex_data))
+        data = hex_data
+        crcValue = 0
+        j = 0
+        i = 0
+        json_state = 0
+        crcbuf = 0
+        print("len(data) :{}\r\n".format(len(data)))
+        data_len = len(str(data))
+        try:
+            if data_len % 2 != 0: 
+                json_state = 0
+                return [json_state,crcbuf]
+        except Exception as e:
+            json_state = 0
+            print("不合法的的十六进制数据!!\r\n")
+
+        for i in range(data_len):
+            if j >= data_len:
+                break
+            try:
+                decimal_number = int(str(data[j:j+2]), 16)
+                
+                crcValue=crcValue+decimal_number
+                crcValue = crcValue&0xff
+            except Exception as e:
+                print("不合法的的十六进制数据!!\r\n")
+            j+=2
+        
+        crcbuf = crcValue%256
+        crcbuf = 256-crcbuf
+        crcbuf = crcbuf%256
+        
+        print("crcbuf:{}\r\n".format(crcbuf))
+        return [json_state,"%02x"%(crcbuf)]
+    #删除临时创建的文件夹
+    def deleteTmpFile(self):
+        tmp_dir = ql_fs.path_exists("/usr/TmpPyFile")
+        if tmp_dir == True:
+            ql_fs.rmdirs("/usr/TmpPyFile")
+
+    #删除usr临时创建的文件夹
+    def deleteUsrTmpFile(self):
+        return
+        tmp_dir = ql_fs.path_exists("/usr/UsrTmpPyFile")
+        if tmp_dir == True:
+            ql_fs.rmdirs("/usr/UsrTmpPyFile")              
+
+    def file_data(self,data):
+        mk_dir_state = 0
+        print("data!!!!!{}\r\n".format(len(data)))
+        if self.updateTimerFlag == 0:
+            self.updateTimerFlag = 1
+            self.updateTimer.stop()
+        msg = {}
+        json_state = 0
+        try:
+            msg = ujson.loads(data)
+            json_state = 1
+        except Exception as e:
+            
+            json_state = 0
+        
+        # print("msg type msg {} {}\r\n".format(msg,type(data)))
+        if "Code" in msg and json_state == 1 :
+            
+            Code = int(msg["Code"])
+            print("Code {} self.Cat1FileState:{}\r\n".format(Code,self.Cat1FileState))
+            if Code == BLE_STOP_OTA: #OTA失败
+                self.allPyRecvFlag = 0
+                self.Cat1FileState = 0
+                self.Cat1FileTransTimer.stop()
+                self.deleteTmpFile()
+                self.deleteUsrTmpFile()
+                pass
+            elif Code == BLE_START_OTA: #BLE 开始OTA cat1创建临时文件夹记录传输的文件数据 文件名
+                self.ota_state =0
+                self.ota_bstate =0
+                self.allPyRecvFlag = 0
+                self.fileNameList = []
+                self.fileSizeList = []
+                print("BLE_START_OTA {} \r\n".format(BLE_START_OTA))
+                self.allPyRecvFlag = 0
+                self.Cat1FileState = 0
+                self.deleteUsrTmpFile()
+                self.Cat1OtaTimeOut.stop()
+                check_dir = ql_fs.path_exists("/usr/TmpPyFile")
+                mk_dir_state = 0
+                if check_dir == True:
+                    try:
+                        self.deleteTmpFile()
+                    except Exception as e:
+                        print("移除失败!!!!\r\n")
+                check_dir = ql_fs.path_exists("/usr/TmpPyFile")      
+                if check_dir == False: #文件夹不存在 创建目录文件夹
+                    try:
+                        ql_fs.mkdirs("/usr/TmpPyFile") 
+                        mk_dir_state = 1
+                        print("创建临时文件 创建成功!!!!\r\n")
+                    except Exception as e:
+                        mk_dir_state = 0
+                        print("创建临时文件失败没有内存!!!!\r\n")
+                else: #已经存在目录了
+                   mk_dir_state = 1 
+                print("创建成功!!!!{}\r\n".format(mk_dir_state))
+                if mk_dir_state == 0:
+                    self.__Socket_UDP_file_noreply(CAT1_CREAT_DIR_FAILE,"creat dir error!")
+                else:
+                    self.Cat1FileState = 1
+                    self.fileNameList = []
+                    self.fileSizeList = []
+                    self.Cat1PyFileTimout = FILE_TRANSFER_TIMEOUT #超时时间10s
+                    self.Cat1FileTransTimer.stop()
+                    self.Cat1FileTransTimer.start(1000,1,self.cat1FileTimerCb)
+                    self.__Socket_UDP_file_noreply(CAT1_CREAT_DIR_OK,"creat dir success!")
+                    
+
+            elif Code == BLE_START_SEND_SINGLE_FILE_INFO and self.Cat1FileState == 1: #包含文件名 文件大小 
+                print("BLE_START_SEND_SINGLE_FILE_INFO {} \r\n".format(BLE_START_SEND_SINGLE_FILE_INFO))
+                self.Cat1PyFileTimout = FILE_TRANSFER_TIMEOUT #超时时间60s
+                # {"Code":1,"fileName":"testpy.py","fileSize":1040}
+                # print("msg {}\r\n".format(msg))
+                self.fileNameTmp = str(msg["fileName"])
+                self.fileSize = msg["fileSize"]
+                self.fileNameList = msg["fileNameList"]
+                # self.fileSizeList.append({"fileName":self.fileNameTmp,"fileSize":int(self.fileSize)})
+                path = "/usr/TmpPyFile/{}".format(self.fileNameTmp)
+                print("self.fileNameTmp {} self.fileSize:{} self.fileNameList:{} self.fileSizeList:{}\r\n".format(self.fileNameTmp,self.fileSize,self.fileNameList,self.fileSizeList))
+                check_touch = ql_fs.path_exists("/usr/TmpPyFile/{}".format(self.fileNameTmp))
+                if check_touch == True:
+                    try:
+                        uos.remove("/usr/TmpPyFile/{}".format(self.fileNameTmp))
+                    except Exception as e:
+                        print("移除文件失败\r\n")
+                    try:
+                        with open(path,"w+") as fd:
+                            fd.write("")
+                        fd.close()  #关闭文件流
+                        self.__Socket_UDP_file_noreply(CAT1_CREAT_FILE_SUCC,"1creat file or dir success!")
+                    except Exception as e:
+                        print("创建文件失败\r\n")
+                        self.__Socket_UDP_file_noreply(CAT1_CREAT_FILE_ERROR,"1creat file or dir err!")
+                else:
+                    try:
+                        print("self.fileNameTmp 111111{}\r\n".format(self.fileNameTmp))
+                        with open(path,"w+") as fd:
+                            fd.write("")
+                        fd.close()  #关闭文件流
+                        self.crc_err = 0
+                        print("self.fileNameTmp {}\r\n".format(self.fileNameTmp))
+                        self.__Socket_UDP_file_noreply(CAT1_CREAT_FILE_SUCC,"2creat file or dir success!")
+                    except Exception as e:
+                        self.__Socket_UDP_file_noreply(CAT1_CREAT_FILE_ERROR,"2creat file or dir err!")
+                        print("创建文件失败\r\n")
+
+            elif Code == BLE_START_SEND_FILE_DATA and self.Cat1FileState == 1: #文件数据
+                self.Cat1PyFileTimout = FILE_TRANSFER_TIMEOUT #超时时间10s
+                print("BLE_START_SEND_FILE_DATA {} self.fileNameTmp:{}\r\n".format(BLE_START_SEND_FILE_DATA,self.fileNameTmp))
+                # {"Code":2,"data":"89ggjdggsjgdj"}
+                if len(self.fileNameTmp) == 0: #文件名不能为空
+                    return
+                data = msg["data"]
+                if len(data) == 0:
+                    return
+                print(" (data):{}\r\n".format(len(data)))
+                tmpdata = str(data)
+                head = tmpdata[0:2] #FE 
+                if head != "FE" and len(tmpdata) <= 8: #必须大于8 FE+012C+DATA+crc(一个字节89)
+                    print("head {}\r\n".format(head))
+                    self.__Socket_UDP_file_noreply(CAT1_SEND_HEAD_ERR,"head error!")
+                    return
+                datalen = str(tmpdata[2:6]) #012c
+                datalen = int("0x" + datalen, 16) #转换成十进制数
+                data_buf = tmpdata[6:] # 数据
+                data_buf = data_buf[:-2]  #最后两个往前的数据
+                crc = tmpdata[-2:] # 最后两个字符是 crc 一个字节
+                print("crc ===!111111:{} {} len:{} {}\r\n".format(crc,type(crc),datalen,len(str(data_buf))))
+                if len(str(data_buf)) == 0 or len(str(data_buf)) != datalen: #数据为空
+                    self.__Socket_UDP_file_noreply(CAT1_WRITE_FILE_ERROR,"crc error or data null!")
+                    return
+                crclist=self.crc_cal(data_buf)
+                newcrc = crclist[1]
+                news = crclist[0]
+                if len(str(crc)) == 0:
+                    self.__Socket_UDP_file_noreply(CAT1_CRC_ERROR,"crc error!")
+                    return
+                decnumCrcCal = int("0x" + str(newcrc), 16) #转换成十进制数
+                decnumCrc = int("0x" + str(crc), 16) #转换成十进制数
+                print("crc:{} newcrc:{}\r\n".format(crc,newcrc,decnumCrc,decnumCrcCal))
+                if decnumCrcCal != decnumCrc and news == 0:
+                    print("newcrc is not === crc crc校验出错不一致\r\n")
+                    self.__Socket_UDP_file_noreply(CAT1_CRC_ERROR,"crc error!")
+                    return
+                data = str(data_buf)
+                path = "/usr/TmpPyFile/{}".format(str(self.fileNameTmp))
+                print("py path:{} self.fileNameTmp:{}\r\n".format(path,self.fileNameTmp))
+                try:
+                    with open(path,"a") as fd:
+                        fd.write(data)
+                    fd.close() #关闭文件流
+                    self.__Socket_UDP_file_noreply(CAT1_WRITE_FILE_SUCC,"write file success!")
+                    print("写文件成功!!!!!\r\n")
+                except Exception as e:
+                    self.__Socket_UDP_file_noreply(CAT1_WRITE_FILE_ERROR,"write file error!")
+                    print("写文件失败没有内存!!!!!\r\n")
+            elif Code == BLE_START_OTA_FAILE and self.Cat1FileState == 1: #取消文件传输 OTA失败 移除目录文件
+                print("BLE_START_OTA_FAILE {} \r\n".format(BLE_START_OTA_FAILE))
+                self.allPyRecvFlag = 0
+                self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"OTA FAILE")
+                self.Cat1FileState = 0
+                self.Cat1FileTransTimer.stop()
+                self.deleteTmpFile()
+                self.deleteUsrTmpFile()
+                pass
+            elif Code == BLE_START_SEND_ALLFILE_FINESH and self.Cat1FileState == 1: #全部文件传输完成
+                
+                tmp_dir = ql_fs.path_exists("/usr/TmpPyFile")
+                if tmp_dir == True:
+                    filenamesList = uos.listdir("/usr/TmpPyFile")
+                    list1 = sorted(filenamesList)
+                    list2 = sorted(self.fileNameList)
+                    print("filenamesList:{} self.fileNameList:{} {}{}\r\n".format(filenamesList,self.fileNameList,type(filenamesList),type(self.fileNameList)))
+                    if list1 != list2: #传输的文件列表和BLE不一致说明有文件没有传输完成不再重启CAT1
+                        self.deleteTmpFile()
+                        self.Cat1FileState = 0
+                        print("self.Cat1PyFile444!!!:{}\r\n".format(self.Cat1FileState))
+                        self.Cat1FileTransTimer.stop()
+                        self.deleteUsrTmpFile()
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"ota end faile!")
+                        return
+                    
+                    try:
+                        copy_state = 1
+                        compare_flag = 1
+                        copy_flag = 0
+                        filenamesList = uos.listdir("/usr/TmpPyFile")
+                        for tmp in filenamesList: #将传输的文件 copy到usr目录下
+                            print("filenamesList for :{}\r\n".format(filenamesList))
+                            dst_path = "/usr/{}".format(tmp) #目标目录文件
+                            if ql_fs.path_exists(dst_path) == True:
+                                try:
+                                    copy_flag = 1
+                                    uos.remove(dst_path)
+                                except Exception as e:
+                                    print("移除文件失败!!!!!\r\n")
+                            try:
+                                copy_flag = 1
+                                ql_fs.touch(dst_path,"")
+                            except Exception as e:
+                                print("创建文件失败!!!!!\r\n")
+
+                            if copy_flag == 0:
+                                print("创建文件失败!!!!!copy_flag\r\n")
+                                copy_state = 0
+                                break
+                            src_path = "/usr/TmpPyFile/{}".format(tmp) #源目录文件
+                            ret = False
+                            file_size = 0
+                            
+                            try:
+                                ret = ql_fs.file_copy(dst_path,src_path) 
+                                print("copy ret!!!!!:{}\r\n".format(ret))
+                                if ret == True:
+                                    dstfile_size = ql_fs.path_getsize(dst_path)
+                                    srcfile_size = ql_fs.path_getsize(src_path)
+
+                                    print("copy dstfile_size:{} srcfile_size:{}\r\n".format(dstfile_size,srcfile_size))
+                                    if dstfile_size != srcfile_size:
+                                        compare_flag = 0
+                                        break
+                                    else: #拷贝完之后比较大小一致移除文件
+                                        try:
+                                            compare_flag = 1
+                                            uos.remove(src_path)
+                                            filenamesList = uos.listdir("/usr/TmpPyFile")
+                                            print("remove filenamesList :{}\r\n".format(filenamesList))
+                                        except Exception as e:
+                                            print("copy file \r\n")
+                                else:
+                                    compare_flag = 0
+                                    break
+                                
+                            except Exception as e:
+                                print("copy file \r\n")
+                                
+                            
+                        if copy_state == 0 or compare_flag == 0 : #比较失败 或者copy失败没有内存了
+                            self.deleteUsrTmpFile()
+                            self.deleteTmpFile()
+                            self.Cat1FileState = 0
+                            self.Cat1FileTransTimer.stop()
+                            self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"ota faile!22") #传输文件完之后最后提示是否成功失败
+                            return
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_SUCC,"ota success!") #传输文件完之后最后提示是否成功失败
+                        self.deleteTmpFile()
+                        self.Cat1FileState = 0
+                        self.Cat1FileTransTimer.stop()
+                        print("重启 auto:\r\n")
+                        self.Cat1OtaTimeOut.stop()
+                        self.Cat1TimeCount = 0
+                        self.ota_state = 1
+                        self.allPyRecvFlag = 1 #所有的py文件接收完成
+                        self.Cat1OtaTimeOut.start(5000,0,self.otaTimeOut)
+                    except Exception as e:
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"ota faile!33") #传输文件完之后最后提示是否成功失败
+                        self.deleteUsrTmpFile()
+                        self.deleteTmpFile()
+                        self.Cat1FileState = 0
+                        self.Cat1FileTransTimer.stop()
+                else:
+                    if self.ota_state == 1:
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_SUCC,"ota success!") #传输文件完之后最后提示是否成功失败
+                        pass
+                    else:
+                        self.deleteTmpFile()
+                        self.Cat1FileState = 0
+                        self.Cat1FileTransTimer.stop()
+                        self.deleteUsrTmpFile()
+                        print("cat1 ota\r\n")
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"ota end faile!")
+
+            
+            elif Code == BLE_START_OTA_SUCC and self.Cat1FileState == 1:
+                if self.allPyRecvFlag == 0: #没有接收完成就发送OTA成功的标识
+                    self.deleteTmpFile()
+                    self.deleteUsrTmpFile()
+                    self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"ota end faile!")
+                    return
+                tmp_dir = ql_fs.path_exists("/usr/TmpPyFile")
+                if tmp_dir == True:
+                    filenamesList = uos.listdir("/usr/TmpPyFile")
+                    list1 = sorted(filenamesList)
+                    list2 = sorted(self.fileNameList)
+                    print("filenamesList:{} self.fileNameList:{} {}{}\r\n".format(filenamesList,self.fileNameList,type(filenamesList),type(self.fileNameList)))
+                    if list1 != list2: #传输的文件列表和BLE不一致说明有文件没有传输完成不再重启CAT1
+                        self.deleteTmpFile()
+                        self.Cat1FileState = 0
+                        print("self.Cat1PyFile444!!!:{}\r\n".format(self.Cat1FileState))
+                        self.Cat1FileTransTimer.stop()
+                        self.deleteUsrTmpFile()
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"ota end faile!")
+                        return
+                    
+                    try:
+                        copy_state = 1
+                        compare_flag = 1
+                        copy_flag = 0
+                        filenamesList = uos.listdir("/usr/TmpPyFile")
+                        for tmp in filenamesList: #将传输的文件 copy到usr目录下
+                            print("filenamesList for :{}\r\n".format(filenamesList))
+                            dst_path = "/usr/{}".format(tmp) #目标目录文件
+                            if ql_fs.path_exists(dst_path) == True:
+                                try:
+                                    copy_flag = 1
+                                    uos.remove(dst_path)
+                                except Exception as e:
+                                    print("移除文件失败!!!!!\r\n")
+                            try:
+                                copy_flag = 1
+                                ql_fs.touch(dst_path,"")
+                            except Exception as e:
+                                print("创建文件失败!!!!!\r\n")
+
+                            if copy_flag == 0:
+                                print("创建文件失败!!!!!copy_flag\r\n")
+                                copy_state = 0
+                                break
+                            src_path = "/usr/TmpPyFile/{}".format(tmp) #源目录文件
+                            ret = False
+                            file_size = 0
+                            
+                            try:
+                                ret = ql_fs.file_copy(dst_path,src_path) 
+                                print("copy ret!!!!!:{}\r\n".format(ret))
+                                if ret == True:
+                                    dstfile_size = ql_fs.path_getsize(dst_path)
+                                    srcfile_size = ql_fs.path_getsize(src_path)
+
+                                    print("copy dstfile_size:{} srcfile_size:{}\r\n".format(dstfile_size,srcfile_size))
+                                    if dstfile_size != srcfile_size:
+                                        compare_flag = 0
+                                        break
+                                    else: #拷贝完之后比较大小一致移除文件
+                                        try:
+                                            compare_flag = 1
+                                            uos.remove(src_path)
+                                            filenamesList = uos.listdir("/usr/TmpPyFile")
+                                            print("remove filenamesList :{}\r\n".format(filenamesList))
+                                        except Exception as e:
+                                            print("copy file \r\n")
+                                else:
+                                    compare_flag = 0
+                                    break
+                                
+                            except Exception as e:
+                                print("copy file \r\n")
+                                
+                            
+                        if copy_state == 0 or compare_flag == 0 : #比较失败 或者copy失败没有内存了
+                            self.deleteUsrTmpFile()
+                            self.deleteTmpFile()
+                            self.Cat1FileState = 0
+                            self.Cat1FileTransTimer.stop()
+                            self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"ota faile!22") #传输文件完之后最后提示是否成功失败
+                            return
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_SUCC,"ota success!") #传输文件完之后最后提示是否成功失败
+                        self.deleteTmpFile()
+                        self.Cat1FileState = 0
+                        self.Cat1FileTransTimer.stop()
+                        print("重启 auto:\r\n")
+                        self.Cat1OtaTimeOut.stop()
+                        self.Cat1TimeCount = 0
+                        self.ota_bstate = 1
+                        self.Cat1OtaTimeOut.start(10000,0,self.otaTimeOut)
+                    except Exception as e:
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"ota faile!33") #传输文件完之后最后提示是否成功失败
+                        self.deleteUsrTmpFile()
+                        self.deleteTmpFile()
+                        self.Cat1FileState = 0
+                        self.Cat1FileTransTimer.stop()
+                else:
+                    if self.ota_bstate == 1:
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_SUCC,"ota success!") #传输文件完之后最后提示是否成功失败
+                        pass
+                    else:
+                        self.deleteTmpFile()
+                        self.Cat1FileState = 0
+                        self.Cat1FileTransTimer.stop()
+                        self.deleteUsrTmpFile()
+                        print("cat1 ota\r\n")
+                        self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_FALIE,"ota end faile!")
+
+            elif Code == BLE_START_SEND_SINGLE_FINESH and self.Cat1FileState == 1: #单个文件传输完成
+                print("BLE_START_SEND_SINGLE_FINESH {} self.fileNameTmp:{}\r\n".format(BLE_START_SEND_SINGLE_FINESH,self.fileNameTmp))
+                self.Cat1PyFileTimout = FILE_TRANSFER_TIMEOUT #超时时间10s
+                tmp_dir = ql_fs.path_exists("/usr/TmpPyFile")
+                if tmp_dir == True:
+                    tmp_file = ql_fs.path_exists("/usr/TmpPyFile/{}".format(self.fileNameTmp))
+                    if tmp_file == True: #文件存在
+                        file_size = ql_fs.path_getsize("/usr/TmpPyFile/{}".format(self.fileNameTmp))
+                        print("file size :file_size:{} self.fileSize:{}\r\n".format(file_size,self.fileSize))
+                        if self.fileSize != file_size: #文件大小不一致 传输出错
+                            self.__Socket_UDP_file_noreply(CAT1_REPLAY_FILE_SIZE_ERR,"file size err") #结束文件接收不完整的
+                            pass
+                        else:
+                            self.__Socket_UDP_file_noreply(CAT1_REPLAY_FILE_SIZE_OK,"file size ok") #结束文件接收完整的
+                            pass
+                    else:
+                        self.__Socket_UDP_file_noreply(CAT1_CREAT_FILE_ERROR,"creat file or dir err!")
+                        pass
+                else:
+                    self.__Socket_UDP_file_noreply(CAT1_CREAT_DIR_FAILE,"creat file or dir error!")
+                    pass
+
+
+            else:
+                if self.Cat1FileState == 0:
+                    if self.Cat1FileReplayBle == 1:
+                        return
+                    self.Cat1FileReplayBle = 1
+                    self.__Socket_UDP_file_noreply(CAT1_REPLAY_OTA_SUCC,"reset start!") #结束文件接收不完整的
+                    print("错误信息!!!!!\r\n")
+                    self.Cat1FileState == 0
+                    self.Cat1FileTransTimer.stop() #//关闭定时器
+                    self.Cat1PyFileTimout = 0
+                    self.fileNameList=[]
+                    self.deleteTmpFile()
+                    self.deleteUsrTmpFile()
+                    
+
+    def otaTimeOut(self,*argc):
+        print("重启成功!!!!!!!!\r\n")
+        Power.powerRestart()
+
+TcpService = TcpServiceInit()
+
+
index 2c3062d..a28102f 100755 (executable)
 #include "cat1_server.h"\r
 #endif\r
 \r
+#ifdef SUPPORT_CAT1_TCP_SERVICE\r
+#include "cat1_tcpServer.h"\r
+#endif\r
+\r
 #ifdef ENABLE_SLIP\r
 #include "uart_slip.h"\r
 #endif\r
@@ -452,6 +456,9 @@ uapi_pm_remove_sleep_veto(PM_ID_DEBUG);
 #ifdef SUPPORT_CAT1_SERVICE\r
     cat1_server_init();\r
 #endif\r
+#if SUPPORT_CAT1_TCP_SERVICE\r
+    cat1_tcp_server_init();\r
+#endif\r
 \r
     uapi_blesrv_service_init();\r
     \r
index 04fe4ea..832e742 100644 (file)
@@ -20,6 +20,7 @@ set(SOURCES
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_at_cmd.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_server_hal.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_server.cpp
+${CMAKE_CURRENT_SOURCE_DIR}/cat1_tcpServer.cpp
 ${CMAKE_CURRENT_SOURCE_DIR}/cat1_ctl.cpp
 )
 
@@ -53,6 +54,7 @@ set(MAIN_COMPONENT
 
 set(PUBLIC_DEFINES
 SUPPORT_CAT1_SERVICE
+SUPPORT_CAT1_TCP_SERVICE
 SUPPORT_AT_CAT1
 )
 
index c150295..218df94 100644 (file)
@@ -13,7 +13,9 @@
 extern "C" {
 #endif /* __cplusplus */
 #endif /* __cplusplus */
-
+#include <stdio.h>
+#include <string.h>
+#include "errcode.h"
 /*send cmd msg to cat1**/
 void cat1_ota_update(char *url);
 void cat1_call_hungup(void);
diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.cpp b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.cpp
new file mode 100644 (file)
index 0000000..218e416
--- /dev/null
@@ -0,0 +1,1047 @@
+/* BSD Socket API Example
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+#include <dirent.h>
+#include "lwip/ip.h"
+#include "lwip/netif.h"
+#include "lwip/init.h"
+#include "lwip/inet_chksum.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include <lwip/netdb.h>
+// #include <netinet/in.h>
+#include "lwip/inet.h"
+#include <stdio.h>
+// #include <string.h>
+// #include <sys/param.h>
+#include <string.h>
+
+#include "../../../../../open_source/openharmony/third_party/cJSON/cJSON.h"
+#include "ConfigModelC.h"
+#include "ConfigModel.h"
+#include "wearable_log.h"
+#include "custom_runtime.h"
+#include "osal_timer.h"
+#include "lwip/apps/sntp.h"
+
+#include <sys/time.h>
+
+#include "bletest.h"
+#include "custom_utils.h"
+#include "custom_runtime.h"
+#include "bleANCS.h"
+#include "cat1_tcpServer.h"
+
+#ifdef __cplusplus
+
+extern "C" {
+
+#endif /* __cplusplus */
+
+
+
+#include "errcode.h"
+#include "errno.h"
+#include "uart_slip.h"
+#include "cat1_server.h"
+#include "cat1_server_hal.h"
+#include "cat1_ctl.h"
+#include "tcxo.h"
+#include "custom_utils.h"
+#include "cmsis_os.h"
+
+static uint8_t g_skip_cat1_service_udp_transfer = 0;
+
+#define PEER_IP "172.16.1.2"
+#define PEER_PORT 5001
+#define SERVER_IP "172.16.1.5"
+#define PORT 1001
+
+
+/** 0: old format 1字节cmd, 1: new format 2字节cmd */
+static uint8_t g_msg_format_type = 0;
+
+static char ble_buffer[20] = {0};
+
+#define CAT1_PY_PATH "/system/cat1ota" //存放需要升级的py文件路径
+#define CAT1_REPLYA_FILE_SIZE_FUN 1  //是否需要CAT1回复文件大小一致传输完单个文件是否与SIZE大小匹配比较
+static osTimerId_t file_transfer_timer=NULL;
+static uint8_t timerOut_count = 0;
+#define DEFAULT_MAX_FILE_COUNT  20 //最大文件个数 按照20个 可更改
+#define DEFAULT_MAX_FILE_NAME_SIZE  64 //文件名最大限制字符
+
+#define DEFAULT_TIMEOUT_TIME 10 //间隔超时时间10s
+#define DEFAULT_TIMEOUT_COUNT (60/DEFAULT_TIMEOUT_TIME) //10s倒计时 计时6次总共是1分钟
+
+#define READ_FILE_DATA_MAX_SIZE 400 // 一次读文件数据最大的size 数据长度不包含头 长度 CRC位
+#define CAT1_FILE_DATA_HEAD "FE" //数据头'FE'
+#define CAT1_FILE_DATA_LEN_CHA "0000" //数据LEN'FE'
+#define CAT1_FILE_DATA_CRC_CHA "00" //数据CRC'FE'
+
+#define DATA_HEAD_SIZE 2 //头的字符大小
+#define DATA_ACTUAL_LEN_BIT 4 //实际数据的长度
+#define DATA_CRC_SZIE 2 //CRC 字符个数
+
+#define DATA_TOTAL_LEN (DATA_HEAD_SIZE+DATA_ACTUAL_LEN_BIT+READ_FILE_DATA_MAX_SIZE+DATA_CRC_SZIE+2+200) //最大一包的数据总长度  200 {"Code":1,"fileName":"",file}
+#define DATA_MIN_HEAD_LEN (DATA_HEAD_SIZE+DATA_ACTUAL_LEN_BIT)  
+
+#define FAILE_COUNT 10 //失败次数
+
+#define RESP_STATUS_OFSET  2
+#define MAX_CMD_MSG_BUFFER_LEN DATA_TOTAL_LEN
+#define MAX_TCP_MSG_BUFFER_LEN (MAX_CMD_MSG_BUFFER_LEN+8)
+#pragma pack(push)
+#pragma pack(1)
+struct tcp_msg_t {
+    uint16_t head;
+    uint16_t cmd;
+    uint32_t length;
+    char buffer[MAX_CMD_MSG_BUFFER_LEN];
+};
+struct tcp_msg_old_t {
+    uint8_t head;
+    uint8_t cmd;
+    uint32_t length;
+    char buffer[MAX_CMD_MSG_BUFFER_LEN];
+};
+#pragma pack(pop)
+
+
+static int g_listen_sock = 0;
+struct sockaddr_in filesourceAddr = {0};
+static osTimerId_t g_timer_time_sync = NULL;
+#ifdef USE_CAT1_SLEEP_TIMER
+static osTimerId_t g_timer_cat1_sleep = NULL;
+#endif
+static uint8_t g_time_synced = 0;
+#define MAX_TIME_SYNC_RETRY_TIME 5
+static uint8_t g_time_sync_retry_time = 0;
+
+
+#define  PY_SRV_VER_4 "PY_SRV_V4"
+#define  PY_SRV_VER_5 "PY_SRV_V5"
+#define  PY_SRV_VER_6 "PY_SRV_V6"
+
+static uint8_t g_py_ver = 4;
+
+
+static struct tcp_msg_old_t *unpack_tlv_format_old(char *rx_buffer, int length)
+{
+    char temp[8]={0};
+    struct tcp_msg_old_t *msg = (struct tcp_msg_old_t *)rx_buffer;
+    strncpy(temp, (char *)&msg->length, 4);
+    temp[4] = '\0';
+    msg->length = atoi(temp);
+
+    if( length != msg->length+6 ) return NULL;
+    return msg;
+}
+
+static int pack_tlv_format_old(char *tx_buffer, uint8_t cmd, char *content)
+{
+    int content_length = (int)strlen(content);
+    if( content == NULL || content_length > MAX_CMD_MSG_BUFFER_LEN) {
+        return -1;
+    }
+    sprintf(tx_buffer,"%s",content);
+    return 0;
+}
+
+static struct tcp_msg_t *unpack_tlv_format(char *rx_buffer, int length)
+{
+    char temp[8]={0};
+    struct tcp_msg_t *msg = (struct tcp_msg_t *)rx_buffer;
+    strncpy(temp, (char *)&msg->length, 4);
+    temp[4] = '\0';
+    msg->length = atoi(temp);
+
+    if( length != msg->length+8 ) return NULL;
+    return msg;
+}
+
+static int pack_tlv_format(char *tx_buffer, uint8_t cmd, char *content)
+{
+    
+    int content_length = (int)strlen(content);
+    if(content_length > MAX_CMD_MSG_BUFFER_LEN || content == NULL)
+    {
+        printf("content data error: content_length %d %s\r\n",content_length,content);
+        return -1;
+    }
+    sprintf(tx_buffer,"%s",content);
+    return content_length+8;
+}
+
+
+
+
+static void udp_send_response(char *tx_buffer, uint8_t cmd, char *content)
+{
+    // remain lock using
+    int len = 0;
+    len = pack_tlv_format(tx_buffer, cmd, content);
+    // printf("msg_format_type %d  \n",g_msg_format_type,len);
+    int err = 0;
+    if( len > 0 ) {
+        err = sendto(g_listen_sock, tx_buffer, len, 0, (struct sockaddr *)&filesourceAddr, sizeof(filesourceAddr));
+        if (err < 0) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Error occured during sending: errno %d\n", errno);
+               }
+    } else {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Error occured unkown send data\n");
+    }
+}
+#include "uart_porting.h"
+void ble_tcp_send_msg_toCat1(uint8_t cmd,char *content)
+{
+    if (!uapi_cat1_get_power_stat())
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Error cat1 poweroff skipp send data\n");
+        return ;
+    }
+    uapi_cat1_wakeup_cat1(1);
+    // uart_port_register_irq(UART_BUS_0);
+    osal_irq_enable(UART_1_IRQN);
+
+    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( filesourceAddr.sin_port != 0 ) {
+        
+        udp_send_response(station_tx_buffer, cmd, content);
+    }
+    uapi_cat1_wakeup_cat1(0);
+}
+
+
+
+
+
+static uint32_t read_size=0; //实际读的文件数据大小
+static char data_arr[DATA_TOTAL_LEN] = {0}; //数据arr
+static uint8_t file_count = 0;//需要升级的文件个数
+static long size; //实际文件大小
+static uint8_t cat1_ota_flag = 0x00; //BLE传输文件状态
+static uint8_t allfiletransEnd = 0; //所有文件传输完成
+static uint8_t otaCount = 0;//ota发送标识计时 10次默认是失败传输文件失败
+static uint8_t noreplayCount = 0;//CAT1没有回复计数累加 10次
+static char fileNameList[DEFAULT_MAX_FILE_COUNT][DEFAULT_MAX_FILE_NAME_SIZE]; //文件列表
+static FILE *fp = NULL; 
+static uint8_t creat_file_err = 0; //CAT1创建文件失败次数
+static uint8_t file_size_err = 0;//两边文件大小不一致错误count
+static uint8_t data_crc_err = 0;//CRC两边不一致
+static uint8_t write_data_err = 0;//CAT1写文件失败
+static uint8_t ota_flag = 0;//OTA标识
+static uint8_t transferFlag = 0;//是否在传输文件
+static uint8_t count = 0;//文件累加
+static uint8_t curfilecount = 0;//当前第几个文件用于重复发送当前文件信息
+
+
+//py文件传输
+// {"Code":1} 开始OTA
+// {"Code":2,"fileName":"cat1Service.py","fileSize":123435} fileCode: 文件ID fileName:文件名称 fileSize:文件大小
+// {"Code":3,"head+datalen+data+CRC":"数据"} // Code: 2开始发送文件数据
+// {"Code":4} BLE 主动发送OTA失败
+// {"Code":5} BLE 主动发送OTA成功
+// {"Code":6} BLE 所有PY文件传输完成
+// {"Code":7} BLE 单个文件传输完成
+void cat1_ota_send_data(uint8_t Code,char *fileName,uint32_t fileSize,char *data){
+    cJSON *dataJSON = cJSON_CreateObject();
+    cJSON *arrayJSON = cJSON_CreateArray();
+    char *json_format = NULL;
+    uint8_t i = 0;
+    switch (Code)
+    {
+        case BLE_STOP_OTA: // 停止OTA
+            cJSON_AddNumberToObject(dataJSON,"Code",BLE_STOP_OTA);
+            json_format = cJSON_PrintUnformatted(dataJSON);
+            printf("cat1_ota_send_data zero %s\r\n",json_format);
+            cJSON_Delete(dataJSON);
+            ble_tcp_send_msg_toCat1(BLE_STOP_OTA,json_format);
+            cJSON_free(json_format);
+            break;
+
+        case BLE_START_OTA: // BLE 开始OTA cat1需要创建临时的目录存放传输的文件内容
+            cJSON_AddNumberToObject(dataJSON,"Code",BLE_START_OTA);
+            json_format = cJSON_PrintUnformatted(dataJSON);
+            printf("cat1_ota_send_data first %s\r\n",json_format);
+            cJSON_Delete(dataJSON);
+            ble_tcp_send_msg_toCat1(BLE_START_OTA,json_format);
+            cJSON_free(json_format);
+            break;
+        case BLE_START_SEND_SINGLE_FILE_INFO: 
+            for(i = 0;i < file_count;i++)
+            {
+                printf("cat1_ota_send_data fileNameList[i]:%s\r\n",fileNameList[i]);
+                if(strlen(fileNameList[i]) != 0){
+                    cJSON_AddStringToObject(arrayJSON,"fileNameList",fileNameList[i]);
+                }
+            }
+            cJSON_AddItemToObject(dataJSON,"fileNameList",arrayJSON); //文件列表 所有需要传输的文件名集合
+            cJSON_AddNumberToObject(dataJSON,"Code",BLE_START_SEND_SINGLE_FILE_INFO);
+            cJSON_AddStringToObject(dataJSON,"fileName",fileName); //文件名
+            cJSON_AddNumberToObject(dataJSON,"fileSize",fileSize); //文件大小
+            json_format = cJSON_PrintUnformatted(dataJSON);
+            printf("cat1_ota_send_data one:%s\r\n",json_format);
+            cJSON_Delete(dataJSON);
+            ble_tcp_send_msg_toCat1(BLE_START_SEND_SINGLE_FILE_INFO,json_format);
+            cJSON_free(json_format);
+            break;
+        case BLE_START_SEND_FILE_DATA:  //start file transfer
+            cJSON_AddNumberToObject(dataJSON,"Code",BLE_START_SEND_FILE_DATA);
+            cJSON_AddStringToObject(dataJSON,"data",(char *)data); // FE 头 0012c 文件长度 + data+crc
+            json_format = cJSON_PrintUnformatted(dataJSON);
+            // printf("start cat1_ota_send_data json_format:%s %d\r\n",data,strlen(data));
+            cJSON_Delete(dataJSON);
+            printf("cat1_ota_send_data two:\r\n");
+            ble_tcp_send_msg_toCat1(BLE_START_SEND_FILE_DATA,json_format);
+            cJSON_free(json_format);
+            break;
+        // case BLE_START_OTA_FAILE: //OTA失败
+           
+        //     cJSON_AddNumberToObject(dataJSON,"Code",BLE_START_OTA_FAILE);
+        //     json_format = cJSON_PrintUnformatted(dataJSON);
+        //     printf("cat1_ota_send_data three:%s\r\n",json_format);
+        //     cJSON_Delete(dataJSON);
+        //     ble_tcp_send_msg_toCat1(BLE_START_OTA_FAILE,json_format);
+        //     cJSON_free(json_format);
+        //     break;
+        // case BLE_START_OTA_SUCC: // OTA成功
+        //     cJSON_AddNumberToObject(dataJSON,"Code",BLE_START_OTA_SUCC);
+        //     json_format = cJSON_PrintUnformatted(dataJSON);
+        //     printf("cat1_ota_send_data four:%s\r\n",json_format);
+        //     cJSON_Delete(dataJSON);
+        //     ble_tcp_send_msg_toCat1(BLE_START_OTA_SUCC,json_format);
+        //     cJSON_free(json_format);
+        //     break;
+        case BLE_START_SEND_ALLFILE_FINESH: //all file transfer end
+            cJSON_AddNumberToObject(dataJSON,"Code",BLE_START_SEND_ALLFILE_FINESH);
+            json_format = cJSON_PrintUnformatted(dataJSON);
+            printf("cat1_ota_send_data five:%s\r\n",json_format);
+            cJSON_Delete(dataJSON);
+            ble_tcp_send_msg_toCat1(BLE_START_SEND_ALLFILE_FINESH,json_format);
+            cJSON_free(json_format);
+            break;
+        case BLE_START_SEND_SINGLE_FINESH:
+            cJSON_AddNumberToObject(dataJSON,"Code",BLE_START_SEND_SINGLE_FINESH);
+            json_format = cJSON_PrintUnformatted(dataJSON);
+            printf("cat1_ota_send_data single:%s\r\n",json_format);
+            cJSON_Delete(dataJSON);
+            ble_tcp_send_msg_toCat1(BLE_START_SEND_SINGLE_FINESH,json_format);
+            cJSON_free(json_format);
+            break;
+
+        case BLE_START_ERROR_INFO: //连续发送十次都没有回复 当前传输py文件
+            cJSON_AddNumberToObject(dataJSON,"Code",BLE_START_ERROR_INFO);
+            json_format = cJSON_PrintUnformatted(dataJSON);
+            printf("cat1_ota_send_data five:%s\r\n",json_format);
+            cJSON_Delete(dataJSON);
+            ble_tcp_send_msg_toCat1(BLE_START_ERROR_INFO,json_format);
+            cJSON_free(json_format);
+            break;
+
+        default:
+            break;
+    }
+    
+}
+
+static uint8_t cat1_file_crc(const char *str,int len) {
+    uint8_t lrcValue = 0x00;
+    for(int i = 0; i < len; i++)
+    {
+        lrcValue =lrcValue+ str[i];
+        // printf("%02x ",lrcValue);
+    }
+    uint8_t crcbuf  = 0x00;
+    crcbuf = lrcValue%256; //s = "Hello, World! 8f"
+    crcbuf = 256-crcbuf;
+    crcbuf = crcbuf%256;
+    return crcbuf;
+}
+
+void send_dir_info(void); //发送目录文件信息
+void send_cur_pack_data(void);//发送当前包的数据
+void send_curfile_info_data(void);//发送单个文件信息 包含文件名 文件大小 需要传输的文件列表
+void send_singlefile_end_cmd(void);//发送单个文件数据结束命令
+void send_allfile_finesh_cmd(void);//发送所有文件传输完成命令
+static void stop_cat1_ota(void){ //停止 CAT1 ota 清标识
+    printf("stop_cat1_ota!!!!!!\r\n");
+    if(file_transfer_timer){
+        osTimerStop(file_transfer_timer);
+        osTimerDelete(file_transfer_timer);
+        file_transfer_timer = NULL;
+    }
+    otaCount = 0;
+    allfiletransEnd = 0;
+    timerOut_count = 0;
+    noreplayCount = 0;
+    ota_flag = 0;
+    transferFlag = 0;
+    write_data_err = 0;
+    data_crc_err = 0;
+    creat_file_err = 0;
+    file_size_err=0;
+    count = 0;
+    curfilecount = 0;
+    memset(data_arr,'\0',DATA_TOTAL_LEN);
+    file_count = 0;
+    size=0;
+    cat1_ota_flag = BLE_STOP_OTA;
+    for(uint8_t i=0;i<DEFAULT_MAX_FILE_COUNT;i++){
+        strcpy(fileNameList[i],"");
+    }
+    
+    if(fp != NULL){ //防止打开文件没有关闭
+        printf("file is not close!\r\n");
+        fclose(fp);
+        fp = NULL;
+    }
+}
+
+static void  cat1_file_Timer_CallBack(int data_tmp)
+{
+    if(cat1_ota_flag == BLE_STOP_OTA){
+        stop_cat1_ota();
+        return;
+    }
+    if(timerOut_count > 0){
+        timerOut_count--;
+    }
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"timerOut_count = !!%d cat1_ota_flag:%d\r\n",timerOut_count,cat1_ota_flag);
+    if(timerOut_count==0){
+        if(cat1_ota_flag == BLE_START_OTA || cat1_ota_flag == BLE_START_SEND_ALLFILE_FINESH
+        || cat1_ota_flag == BLE_START_SEND_FILE_DATA  || cat1_ota_flag == BLE_START_SEND_SINGLE_FILE_INFO
+        ||cat1_ota_flag == BLE_START_SEND_SINGLE_FINESH){ //如果发送创建文件没有回复 累加十次结束发送
+            noreplayCount+=1;
+            if(noreplayCount >= DEFAULT_TIMEOUT_COUNT){
+                noreplayCount = 0;
+                stop_cat1_ota();
+                return;
+            }else{  //
+                if(cat1_ota_flag == BLE_START_OTA){
+                    send_dir_info(); //再次发送目录文件信息
+                }else if(cat1_ota_flag == BLE_START_SEND_SINGLE_FILE_INFO){
+                    send_curfile_info_data();
+                }else if(cat1_ota_flag == BLE_START_SEND_FILE_DATA){ //发送一包超过10s CAT1没有回复继续上一包的数据
+                    send_cur_pack_data();
+                }else if(cat1_ota_flag == BLE_START_SEND_SINGLE_FINESH){ //单个文件传输完成
+                    send_singlefile_end_cmd();
+                }else if(cat1_ota_flag == BLE_START_SEND_ALLFILE_FINESH){ //所有文件传输完成
+                    send_allfile_finesh_cmd();
+                }
+                
+            }
+        }
+    }
+   
+}
+//读目录文件信息
+void send_dir_info(void)
+{
+    if(file_count == 0){ //目录下没有文件
+        return;
+    }
+    
+    cat1_ota_flag = BLE_START_OTA;
+    timerOut_count = DEFAULT_TIMEOUT_TIME;
+    cat1_ota_send_data(BLE_START_OTA,NULL,0,NULL);
+    
+}
+void read_dir(void){
+    
+    struct dirent *entry;
+    
+    for (int i = 0; i < DEFAULT_MAX_FILE_COUNT; i++) {
+        strcpy(fileNameList[i],"");
+    }
+    DIR *dir = opendir(CAT1_PY_PATH); // 打开文件夹
+    if (dir == NULL) {
+        printf("opendir");
+        return;
+    }
+
+    file_count = 0;
+    count = 0;
+    while ((entry = readdir(dir)) != NULL) {
+        // 跳过'.'和'..'目录
+        if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
+            printf("%s\n", entry->d_name); // 输出文件名
+            //0 1 2
+            if(file_count >= DEFAULT_MAX_FILE_COUNT){
+                break;
+            }
+            snprintf(fileNameList[file_count],DEFAULT_MAX_FILE_NAME_SIZE,"%s",entry->d_name);
+            // memcpy_s(fileNameList+file_count,DEFAULT_MAX_FILE_NAME_SIZE,entry->d_name,strlen(entry->d_name));
+            printf("fileNameList[file_count] %s\r\n",fileNameList[file_count]);
+            file_count+=1;
+        }
+    }
+    closedir(dir); // 关闭文件夹
+    if(file_count == 0){ //目录下没有文件
+        return;
+    }
+    allfiletransEnd = 1;
+    transferFlag = 1; //文件传输标识 1正在OTA py 2OTA失败
+    ota_flag = 1;
+    send_dir_info();
+    noreplayCount = 0;
+    uint32_t tick;
+    osStatus_t retTimer;
+    if(file_transfer_timer == NULL){
+        file_transfer_timer = osTimerNew((osTimerFunc_t)cat1_file_Timer_CallBack, osTimerPeriodic, NULL, NULL);
+        tick = 1000;// osMs2Tick(1000);
+        retTimer = osTimerStart(file_transfer_timer, tick);
+        if (retTimer != osOK && file_transfer_timer != NULL) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"StartCallTimer osTimerStart failed, ret = %lx!!", retTimer);
+            osTimerDelete(file_transfer_timer);
+            file_transfer_timer = NULL;
+        }
+    }
+}
+
+void send_curfile_info_data(void)
+{
+    cat1_ota_flag = BLE_START_SEND_SINGLE_FILE_INFO;
+    timerOut_count = DEFAULT_TIMEOUT_TIME;
+    if(strlen(fileNameList[curfilecount])  && size != 0){
+        cat1_ota_send_data(BLE_START_SEND_SINGLE_FILE_INFO,fileNameList[curfilecount],size,NULL);
+    }
+        
+}
+void send_allfile_finesh_cmd(void)
+{
+    cat1_ota_flag = BLE_START_SEND_ALLFILE_FINESH;
+    timerOut_count = DEFAULT_TIMEOUT_TIME;
+    cat1_ota_send_data(BLE_START_SEND_ALLFILE_FINESH,NULL,0,NULL);
+}
+
+void read_file_info_data(void){
+    if(file_count <= 0){
+        return;
+    }
+    while (1)
+    {
+        if(count < file_count){
+            size = 0;
+            if(count >= file_count){
+                cat1_ota_flag = BLE_START_SEND_ALLFILE_FINESH;
+                timerOut_count = DEFAULT_TIMEOUT_TIME;
+                cat1_ota_send_data(BLE_START_SEND_ALLFILE_FINESH,NULL,0,NULL);
+                break;
+            }
+            if(strlen(fileNameList[count])==0){ //空的文件 2 count = 0 count = 1
+                count+=1;
+                continue;
+            }
+            curfilecount = count;
+            printf("count:%d file_count:%d\r\n",count,file_count);
+            struct dirent *entry;
+            char file_path[DEFAULT_MAX_FILE_NAME_SIZE]={0};
+            memset(file_path,0,DEFAULT_MAX_FILE_NAME_SIZE);
+            sprintf_s(file_path,DEFAULT_MAX_FILE_NAME_SIZE,"%s/%s",CAT1_PY_PATH,fileNameList[curfilecount]);
+            
+            count+=1;
+            fp = fopen(file_path, "rb");
+            if(fp != NULL){
+                fseek(fp, 0, SEEK_END);
+                size = ftell(fp);
+                fseek(fp, 0, SEEK_SET);
+                noreplayCount = 0;
+                send_curfile_info_data();
+                break;
+            }
+        }else{
+            cat1_ota_flag = BLE_START_SEND_ALLFILE_FINESH;
+            timerOut_count = DEFAULT_TIMEOUT_TIME;
+            cat1_ota_send_data(BLE_START_SEND_ALLFILE_FINESH,NULL,0,NULL);
+            break;
+        }
+    }
+}
+//开始发送数据
+void send_cur_pack_data(void){
+    int data_len = 0;
+    uint8_t crcvalue = 0x00;
+    cat1_ota_flag = BLE_START_SEND_FILE_DATA;
+    timerOut_count=DEFAULT_TIMEOUT_TIME;
+    char head_data[10]={0};
+    memset(head_data, '\0', sizeof(head_data));
+    if(strlen(data_arr+6) != 0  && read_size != 0 ){ //FE 012C
+        if(head_data[0] != 'F' && head_data[1] != 'E'){
+            data_len+=snprintf(head_data+data_len,sizeof(head_data)-data_len,"%s","FE");
+        }else{
+            data_len+=snprintf(head_data+data_len,sizeof(head_data)-data_len,"%s",CAT1_FILE_DATA_HEAD);
+        }
+
+        data_len+=snprintf(head_data+data_len,sizeof(head_data)-data_len,"%04x",read_size);
+        memcpy_s(data_arr,6,head_data,6);
+        crcvalue = cat1_file_crc(data_arr+6,read_size);
+        data_len+=read_size;
+        data_len+=snprintf(data_arr+data_len,sizeof(data_arr)-data_len,"%02x",crcvalue);
+        
+        cat1_ota_send_data(BLE_START_SEND_FILE_DATA,NULL,0,data_arr); 
+    }
+}
+void send_singlefile_end_cmd(void)
+{
+    cat1_ota_flag = BLE_START_SEND_SINGLE_FINESH;
+    timerOut_count=DEFAULT_TIMEOUT_TIME;
+    cat1_ota_send_data(BLE_START_SEND_SINGLE_FINESH,NULL,0,NULL);
+}
+void send_file_pack_data(void) 
+{
+    if(fp == NULL){
+        return;
+    }
+    noreplayCount=0;
+    memset(data_arr, '\0', sizeof(data_arr));
+    read_size = fread(data_arr+6,1,READ_FILE_DATA_MAX_SIZE,fp);
+    printf("strlen(data_arr) %d read_size:%d\r\n",strlen(data_arr+6),read_size);
+    if(read_size != 0){
+        send_cur_pack_data();
+    }else{ //文件内容读完下一个文件内容读取
+        fclose(fp);
+        fp = NULL;
+        #if CAT1_REPLYA_FILE_SIZE_FUN
+            send_singlefile_end_cmd();
+        #else
+            read_file_info_data();//下一个文件
+        #endif
+        
+    }
+    
+}
+
+
+void send_data_case(uint8_t mode){
+    
+    noreplayCount = 0;
+    switch (mode)
+    {
+        case READ_DIR_INFO: //读文件目录信息
+            read_dir();
+            break;
+        case READ_FILE_DATA_INFO://收到CAT1回复开始发送文件信息
+            read_file_info_data();
+            break;
+        case CREAT_FILE_FAILE:
+            send_curfile_info_data();
+            break;
+        case SEND_PACK_DATA_INFO://分包发送数据
+            send_file_pack_data();
+            break;
+        case DATA_CRC_ERROR://CRC错误
+        case FILE_DATA_HEAD_ERR: //文件内容的数据头不对 需要重新发送 
+        case WRITE_FILE_DATA_FAILE: //写文件失败
+            send_cur_pack_data();
+            break;
+        
+        default:
+            break;
+    }
+}
+void start_cat1_ota(void){
+    stop_cat1_ota();
+    send_data_case(READ_DIR_INFO); //开始OTA 就开始升级py文件
+}
+void Cat1_OTA(uint8_t ota_state)
+{    
+    switch (ota_state)
+    {
+        case BLE_START_OTA:
+            start_cat1_ota();
+            break;
+        case BLE_STOP_OTA:
+            stop_cat1_ota();
+            cat1_ota_send_data(BLE_STOP_OTA,NULL,0,NULL);
+            break;
+        default:
+            break;
+    }
+}
+//
+uint8_t Get_Cat1_OTA_Flag(void) 
+{    
+    return cat1_ota_flag;
+}
+#define BOOTMSG_HEADER_STR "BOOTUP"
+#define BOOTMSG_HEADER_STR_LEN strlen(BOOTMSG_HEADER_STR)
+#define NETSTAT_HEADER_STR "imei:"
+#define NETSTAT_HEADER_STR_LEN strlen(NETSTAT_HEADER_STR)
+#define VERMSG_HEADER_STR "pyVer"
+#define VERMSG_HEADER_STR_LEN strlen(VERMSG_HEADER_STR)
+#define MSG_SPLIT_CHAR ","
+#define MSG_SPLIT_CHAR2 "@"
+
+
+
+static uint8_t get_int8_from_ascii_char( uint8_t ascii)
+{
+
+        char* tmpt =NULL;
+        uint8_t tmp=0;
+        switch (ascii)
+        {
+            case '0':
+                tmp = 0;
+                tmpt="0";
+                break;
+            case '1':
+                tmp = 1;
+                tmpt="1";
+                break;
+            case '2':
+                tmp = 2;
+                tmpt="2";
+                break;
+            case '3':
+                tmp = 3;
+                tmpt="3";
+                break;
+            case '4':
+                tmp = 4;
+                tmpt="4";
+                break;
+            case '5':
+                tmp = 5;
+                tmpt="5";
+                break;
+            case '6':
+                tmp = 6;
+                tmpt="6";
+                break;
+            case '7':
+                tmp = 7;
+                tmpt="7";
+                break;
+            case '8':
+                tmp = 8;
+                tmpt="8";
+                break;
+            case '9':
+                tmp = 9;
+                tmpt="9";
+                break;
+            case 'A':
+            case 'a':
+                tmp = 0xA;
+                tmpt="A";
+                break;
+            case 'B':
+            case 'b':
+                tmp = 0xB;
+                tmpt="B";
+                break;
+            case 'C':
+            case 'c':
+                tmp = 0xC;
+                tmpt="C";
+                break;
+            case 'D':
+            case 'd':
+                tmp = 0xD;
+                tmpt="D";
+                break;
+            case 'E':
+            case 'e':
+                tmp = 0xE;
+                tmpt="E";
+                break;
+            case 'F':
+            case 'f':
+                tmp = 0xF;
+                tmpt="F";
+                break;
+            default:
+                tmp = 0x0;
+                tmpt="0";
+                break;
+        }
+    //    printf("%s\n",tmpt);
+       return tmp;   
+}
+static uint8_t get_header_cmd_from_uint16_hexstr(char* int16_value)
+{
+    uint8_t * p_intvalue = (uint8_t *)int16_value;
+    uint8_t low = get_int8_from_ascii_char(p_intvalue[1]);
+    uint8_t high = get_int8_from_ascii_char(p_intvalue[0]);
+    uint8_t ret = ((low&0x0F) | (high&0x0F)<<4);
+    return ret; 
+}
+static int udp_packet_parse(char *rx_buffer, int len)
+{
+
+    int index = 0; 
+    if (len <6 || rx_buffer == NULL)
+    {
+        printf("len < 6 , format error !\n");
+        return -1;
+    }
+    uint8_t header0 = rx_buffer[0];
+    uint8_t header1 = rx_buffer[1];
+    if (( header0 == 'F' || header0 == 'f') && (header1== 'E' || header1 == 'e'))
+    {
+        g_msg_format_type = 1;
+    }else{
+        // printf("msg format error or old msg format!\n");
+        g_msg_format_type = 0;
+    }
+    printf("g_msg_format_type %d\n",g_msg_format_type);
+    char * msg_buffer = NULL;
+    int msg_buffer_len = 0;
+    uint16_t cmd = 0;
+    if (g_msg_format_type == 1)
+    {
+        struct tcp_msg_t *msg = unpack_tlv_format(rx_buffer, len);
+        msg_buffer = msg->buffer;
+        msg_buffer_len = msg->length;
+        cmd = get_header_cmd_from_uint16_hexstr(&rx_buffer[2]);
+
+    }else{
+        struct tcp_msg_old_t *msg = unpack_tlv_format_old(rx_buffer, len);
+        msg_buffer = msg->buffer;
+        msg_buffer_len = msg->length;
+        cmd = get_int8_from_ascii_char(rx_buffer[1]);
+    }
+    printf("cmd! %d",cmd);
+    noreplayCount = 0;
+    if(cat1_ota_flag == BLE_STOP_OTA) //只有在传输文件才生效
+    {
+        return 0;
+    } 
+    switch (cmd)
+    {
+        case CAT1_REPLAY_CREAT_DIR_FAILE: //cat1:创建临时文件夹失败
+            write_data_err = 0;
+            file_size_err=0;
+            data_crc_err = 0;
+            creat_file_err+=1;
+            if(creat_file_err >= FAILE_COUNT){ //创建十次都出错不创建结束当前的升级
+                creat_file_err=0;
+                stop_cat1_ota();
+                break;
+            }
+            send_data_case(READ_DIR_INFO); //再发一下
+            break;
+        case CAT1_REPLAY_CREAT_DIR_OK: //CAT1创建文件成功开始发送文件标识和文件信息 读文件夹文件信息 回复OK 
+            write_data_err = 0;
+            data_crc_err = 0;
+            creat_file_err = 0;
+            file_size_err=0;
+            send_data_case(READ_FILE_DATA_INFO);
+            break;
+        case CAT1_REPLAY_CREAT_FILE_SUCC:
+        case CAT1_REPLAY_WRITE_FILE_SUCC:
+            printf("CAT1_REPLAY_WRITE_FILE_SUCC! %d",cmd);
+            write_data_err = 0;
+            data_crc_err = 0;
+            creat_file_err = 0;
+            file_size_err=0;
+            send_data_case(SEND_PACK_DATA_INFO);
+            break;
+        case CAT1_REPLAY_WRITE_FILE_ERROR:  //CAT1 写文件内容失败了
+            file_size_err = 0;
+            data_crc_err = 0;
+            creat_file_err = 0;
+            write_data_err+=1;
+            if(write_data_err >= FAILE_COUNT){
+                write_data_err = 0;
+                stop_cat1_ota();
+                break;
+            }
+            printf("CAT1_REPLAY_WRITE_FILE_ERROR! %d",cmd);
+            send_data_case(WRITE_FILE_DATA_FAILE);
+            break;
+        case CAT1_REPLAY_CRC_ERROR:   
+            write_data_err = 0;
+            file_size_err = 0;
+            creat_file_err = 0;    
+            data_crc_err+=1;
+            if(data_crc_err >= FAILE_COUNT){ //连续十次CRC都出错就结束进程
+                data_crc_err = 0;
+                stop_cat1_ota();
+                break;
+            }
+            send_data_case(DATA_CRC_ERROR);
+            break;
+        
+        case CAT1_REPLAY_SEND_HEAD_ERR: //发送的头不对 不是FF
+            write_data_err = 0;
+            data_crc_err = 0;
+            creat_file_err = 0;
+            file_size_err = 0;
+            send_data_case(FILE_DATA_HEAD_ERR);
+            break;
+        case CAT1_REPLAY_CREAT_FILE_ERROR:
+            write_data_err = 0;
+            data_crc_err = 0;
+            file_size_err = 0;
+            creat_file_err+1;
+            if(creat_file_err >= FAILE_COUNT){
+                creat_file_err = 0;
+                stop_cat1_ota();
+                break;
+            }
+            send_data_case(CREAT_FILE_FAILE);
+            break;
+        case CAT1_REPLAY_OTA_SUCC: //ota 成功失败与否 收到CAT1的回复就停止计时器
+            stop_cat1_ota();
+            //添加GUI
+            break;
+        case CAT1_REPLAY_OTA_FALIE:
+            stop_cat1_ota();
+            break;
+        case CAT1_REPLAY_FILE_SIZE_OK: //文件大小发送和接收的一致
+            read_file_info_data();
+            break;
+        case CAT1_REPLAY_FILE_SIZE_ERR://文件大小发送和接收的不一致
+            file_size_err+=1;
+            if(file_size_err >= FAILE_COUNT){
+                file_size_err = 0;
+                stop_cat1_ota();
+                break;
+            }
+            send_curfile_info_data();
+            break;
+        case CAT1_OTA_TIMEOUT_BLE_NO_REPLAY:
+        case CAT1_REPLAY_OTA_ERR: //提示用户是否重新升级 最后校验文件出错
+            stop_cat1_ota();
+            break;
+        default:
+            break;
+    }
+    // printf("cmd %x,bufferlen %d , buffer %s \n",cmd,msg_buffer_len,msg_buffer);
+    return index;
+}
+
+static int udp_socket_file_init()
+{
+    int addr_family;
+    int ip_protocol;
+    int opt = 1;
+    struct sockaddr_in destAddr;
+    char addr_str[128];
+
+    // destAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+    destAddr.sin_addr.s_addr = inet_addr(SERVER_IP);
+    destAddr.sin_family = AF_INET;
+    destAddr.sin_port = htons(PORT);
+    addr_family = AF_INET;
+    ip_protocol = IPPROTO_IP;
+    inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1);
+
+    int listen_sock = socket(addr_family, SOCK_DGRAM, ip_protocol);
+    if (listen_sock < 0) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Unable to create socket: errno %d\n", errno);
+        return -1;
+    }
+    setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
+
+    int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
+    if (err != 0) {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Socket unable to bind: errno %d\n", errno);
+        return -1;
+    }
+    
+    filesourceAddr.sin_addr.s_addr = inet_addr(PEER_IP);
+    filesourceAddr.sin_family = AF_INET;
+    filesourceAddr.sin_port = htons(PEER_PORT);
+
+    return listen_sock;
+}
+#include "cmsis_os2.h"
+extern osStatus_t osDelay(uint32_t ticks);
+#define cat1_msleep(ms) osDelay(ms) /* osDelay(1) : 1ms */
+void cat1_server_file_task(void *pvParameters)
+{
+    char rx_buffer[512];
+    char tx_buffer[256];
+    int index;
+    socklen_t addrLen = sizeof(filesourceAddr);
+    while (1) {
+        if( g_listen_sock > 0 ) close(g_listen_sock);
+        g_listen_sock = udp_socket_file_init();
+        if( g_listen_sock < 0 ) {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"socket init fail and retry\n");
+            // vTaskDelay(1000/portTICK_RATE_MS);
+            cat1_msleep(1000);
+            continue;
+        }
+        
+        while (1) {
+
+            // printf("recv ENTER\r\n");
+            
+                       memset(rx_buffer, 0, sizeof(rx_buffer));
+            int len = recvfrom(g_listen_sock, rx_buffer, sizeof(rx_buffer) - 1, 0, (struct sockaddr *)&filesourceAddr, &addrLen);
+            // Error occured during receiving
+            printf("file recv len:%d rx_buffer:%s\r\n",len,rx_buffer);
+            if (len < 0) {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"recv failed: errno %d\n", errno);
+                break;
+            } else if (len == 0) {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Connection closed\n");
+                break;
+            }
+            // Data received
+            rx_buffer[len] = '\0'; // Null-terminate whatever we received and treat like a string
+            // WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"Received %d bytes, rx_buffer: %s\n", len, rx_buffer);
+            index = udp_packet_parse(rx_buffer, len);
+            // if( index >= 0 ) {
+            //     udp_send_response(tx_buffer, rx_buffer, "OK"/* msg_wifi_resp[index]*/);
+            // }
+
+            #ifndef USE_CAT1_SLEEP_TIMER
+            uapi_cat1_remove_cat1_vote(); //中断会添加休眠投票,此处代表已经收到cat1的消息,可以移除投票进入休眠了。
+            #endif
+        }
+       }
+       
+}
+
+
+#include "osal_msgqueue.h"
+#include "thread_init.h"
+#include "soc_osal.h"
+#include "common_def.h"
+#include "los_printf.h"
+
+#define CAT1_SERVICE_TASK_SIZE       (0x800*5)
+#define CAT1_SERVICE_TASK_PRIO       5
+
+errcode_t cat1_tcp_server_init(void)
+{
+    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"cat1_tcp_server_init !\r\n");
+    app_task_definition_t taskcfg={0};
+    taskcfg.create_queue_handle = NULL;
+    taskcfg.attr.name="cat1_service_file";
+    taskcfg.attr.priority = TASK_PRIORITY_APP;
+    taskcfg.attr.stack_size = CAT1_SERVICE_TASK_SIZE;
+    taskcfg.func = cat1_server_file_task;
+    taskcfg.use_mem = USE_EXTEND_MEM;
+    
+    errcode_t ret=uapi_create_osThread_custom(&taskcfg);
+    if(ret != ERRCODE_SUCC)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"create cat1_service_file failed %d!\r\n",ret);
+        return ERRCODE_FAIL;
+    }
+    return ERRCODE_SUCC;
+}
+
+#ifdef __cplusplus
+
+}
+
+#endif /* __cplusplus */
diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.h b/code/sdk/drivers/peripheral/slip/cat1Service/cat1_tcpServer.h
new file mode 100644 (file)
index 0000000..0b2caf5
--- /dev/null
@@ -0,0 +1,75 @@
+/* BSD Socket API Example
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+#ifndef __CAT1_SERVER_FILE_H
+#define __CAT1_SERVER_FILE_H
+#include <stdio.h>
+#include <string.h>
+#include "errcode.h"
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+typedef enum Ble_send_file_mode { //BLE 发送文件模式
+    READ_DIR_INFO = 0,// BLE读目录文件 重新发送收到CAT1回复
+    READ_FILE_DATA_INFO = 1, //读文件信息 重新发送收到CAT1回复
+    SEND_PACK_DATA_INFO= 2, //发送当前数据包数据信息 重新发送收到CAT1回复
+    DATA_CRC_ERROR= 3, //CRC出错 重新发送收到CAT1回复
+    FILE_DATA_HEAD_ERR = 4, //发送的头不一致 重新发送收到CAT1回复
+    CREAT_FILE_FAILE = 5, //创建文件出错 重新发送收到CAT1回复
+    WRITE_FILE_DATA_FAILE = 6, //写文件数据出错重新发送
+} Ble_send_file_mode;
+
+typedef enum Ble_send_state { //BLE 发送文件传输状态
+    BLE_STOP_OTA = 0,//结束OTA升级
+    BLE_START_OTA = 1, //ble 开始发送OTA标识 -》   CAT1
+    BLE_START_SEND_SINGLE_FILE_INFO= 2, //ble 开始发送单个文件信息 -> CAT1 创建单个文件名
+    BLE_START_SEND_FILE_DATA= 3, //BLE开始发送文件数据额 ----》CAT1 接收文件数据写文件
+    BLE_START_OTA_FAILE = 4, //CAT 发送OTA失败 取消文件传输 //预留
+    BLE_START_OTA_SUCC = 5, //BLE 发送OTA成功标识 //预留
+    BLE_START_SEND_ALLFILE_FINESH = 6, //所有PY文件传输完成
+    BLE_START_SEND_SINGLE_FINESH = 7, //单个文件传输完成
+    BLE_START_ERROR_INFO = 255, //发送错误信息结束进程
+} Ble_send_state;
+typedef enum cat1_replay_state { //手表CAT1回复的状态
+    CAT1_REPLAY_STATE=0x00,
+    CAT1_REPLAY_CREAT_DIR_FAILE= 0x01, //创建文件失败没有内存或者异常出错
+    CAT1_REPLAY_CREAT_DIR_OK= 0x02, //创建文件成功
+    CAT1_REPLAY_NO_OTA_OK= 0x03,
+    CAT1_REPLAY_WRITE_FILE_SUCC= 0x04, //写文件成
+    CAT1_REPLAY_WRITE_FILE_ERROR = 0x05,//写文件失败
+    CAT1_REPLAY_CRC_ERROR = 0x06, //CAT1回复CRC错误
+    CAT1_REPLAY_SEND_HEAD_ERR = 0x07,
+    CAT1_OTA_TIMEOUT_BLE_NO_REPLAY = 0x08,//CAT1超时没有收到
+    CAT1_REPLAY_CREAT_FILE_ERROR = 0x09,//创建文件失败
+    CAT1_REPLAY_CREAT_FILE_SUCC = 0x0A,//创建文件成功
+    CAT1_REPLAY_ALLPY_FILE_TRANSFER_END = 0x0B, //所有的py文件传输完成
+    CAT1_REPLAY_OTA_SUCC = 0x0C, //ble 发送OTA到CAT1 cat1 回复成功的标识
+    CAT1_REPLAY_OTA_FALIE = 0x0D, //ble 发送OTA到CAT1 cat1 回复失败的标识
+    CAT1_REPLAY_FILE_SIZE_OK = 0x0E, //BLE单个文件传输完成 文件大小一致
+    CAT1_REPLAY_FILE_SIZE_ERR = 0x0F, //BLE单个文件传输完成 文件大小不一致
+    CAT1_REPLAY_OTA_ERR = 0x10, //所有文件传输完成之后CAT1校验文件是否成功
+
+    CAT1_NEED_UPDATE_OTA = 0x11, //CAT1回复需要强制升级 因为py运行出错了
+} cat1_replay_state;
+errcode_t cat1_tcp_server_init(void);
+void ble_tcp_send_msg_toCat1(uint8_t cmd,char *content);
+void cat1_ota_send_data(uint8_t Code,char *fileName,uint32_t fileSize,char *data);
+//ota_state:
+//BLE_START_OTA  开始OTA
+//BLE_STOP_OTA  停止OTA
+void Cat1_OTA(uint8_t ota_state);
+//获取CAT1 OTA升级状态 返回 BLE_STOP_OTA 不在升级状态 其他在升级状态中
+uint8_t Get_Cat1_OTA_Flag(void);
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+#endif
index 0ec208d..60322f0 100644 (file)
@@ -8,6 +8,7 @@
 #include "debug_print.h"
 #include "custom_runtime.h"
 #include "ConfigModelC.h"
+#include "cat1_tcpServer.h"
 #ifdef SUPPORT_A5133_SERVICE
 #include "service/a5133_service.h"
 #endif
@@ -908,8 +909,16 @@ static uint32_t custom_get_aging_data(uint8_t *para, uint32_t paraLen, char *str
     uapi_get_file_data("user/userdata/aging_test.bin",aging_data,4);
     return ERRCODE_SUCC;
 }
-
-
+static uint32_t custom_cat1_start_ota_pyupdate(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    Cat1_OTA(BLE_START_OTA);
+    return ERRCODE_SUCC;
+}
+static uint32_t custom_cat1_stop_ota_pyupdate(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+    Cat1_OTA(BLE_STOP_OTA);
+    return ERRCODE_SUCC;
+}
 #ifdef SUPPORT_A5133_SERVICE
 
 
@@ -1171,6 +1180,9 @@ static const at_cmd_table_t g_custom_utils_cmd[] = {
     {(char *)"AT^GETCYWEEACTIVE", custom_get_cywee_active_state, (char *)" "},
     {(char *)"AT^AGINGTEST", custom_aging_test, (char *)" "},
     {(char *)"AT^GETAGING", custom_get_aging_data, (char *)" "},
+    
+    {(char *)"AT^CAT1STARTOTAPY", custom_cat1_start_ota_pyupdate, (char *)" "},
+    {(char *)"AT^CAT1STOPOTAPY", custom_cat1_stop_ota_pyupdate, (char *)" "},
     {(char *)"AT^VIBTEST", custom_vibrator_test, (char *)" "},
 #ifdef SUPPORT_A5133_SERVICE
     {(char *)"AT^A5133SENDDATA", custom_a5133_send_msg, (char *)" "},
@@ -1178,7 +1190,7 @@ static const at_cmd_table_t g_custom_utils_cmd[] = {
    
     
 #endif
-      { (char *)"AT^CALL_BT_ENTRY_ADRESSBOOK",      PBAP_ENTRY_ADDRESS, (char *)" " },
+    { (char *)"AT^CALL_BT_ENTRY_ADRESSBOOK",      PBAP_ENTRY_ADDRESS, (char *)" " },
     { (char *)"AT^CALL_BT_CONNECT_PBAP",      PBAP_CONNECT, (char *)" " },
     { (char *)"AT^PBAP_PULL",      PBAP_PULL, (char *)" " },
     { (char *)"AT^PBAP_LS",      PBAP_LS, (char *)" " },