更新cat1 蓝牙通讯协议解析,同时支持旧版和新版协议。 197/1 197/head 199/target/1
authorSnickerSun <snickersun@163.com>
Thu, 30 May 2024 04:52:32 +0000 (12:52 +0800)
committerSnickerSun <snickersun@163.com>
Thu, 30 May 2024 06:39:38 +0000 (14:39 +0800)
code/sdk/drivers/peripheral/slip/cat1Service/cat1_server.cpp
code/sdk/drivers/peripheral/slip/cat1Service/pyscript/V3/checkota.py [moved from code/sdk/drivers/peripheral/slip/cat1Service/pyscript/checkota.pyV3 with 100% similarity]
code/sdk/drivers/peripheral/slip/cat1Service/pyscript/V6/cat1Service.py [new file with mode: 0644]

index 5f60e4b..fbd35c6 100644 (file)
@@ -83,80 +83,99 @@ enum UDP_COMMAND_HEAD {
     UDP_MSG_GET_TELECON_DMP_TIMESEC = 0x14,//获取本地保存的注册的时间戳
     UDP_MSG_RECV_CAT1_SMS_CONTENT = 0x15,//接收信息内容数据
 };
+static uint8_t g_msg_format_type = 0;// 0: old format , 1: new format
 
-
-static uint8_t get_header_cmd_from_uint16_hexstr(uint16_t value)
+static uint8_t get_int8_from_ascii_char( uint8_t ascii)
 {
 
-    uint8_t *p_value = (uint8_t *)&value;
-    uint16_t intvalue = 0;
-    uint8_t * p_intvalue = (uint8_t *)&intvalue;
-    for (int i= 0 ; i<2;i++)
-    {
+        char* tmpt =NULL;
         uint8_t tmp=0;
-        switch (p_value[i])
+        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;
         }
-        p_intvalue[i] = tmp;   
-    }
-    uint8_t ret = (p_intvalue[1]&0x0F) | ((p_intvalue[0]&0x0F)<<4);
+    //    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; 
 }
 
@@ -173,14 +192,21 @@ static uint8_t get_header_cmd_from_uint16_hexstr(uint16_t value)
 //     "6",     // smart config mode
 // };
 #define RESP_STATUS_OFSET  2
-#define MAX_TCP_MSG_BUFFER_LEN (512+8)
+#define MAX_CMD_MSG_BUFFER_LEN 512
+#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;
-    int length;
-    char buffer[512];
+    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)
 
@@ -203,6 +229,43 @@ static uint8_t g_time_sync_retry_time = 0;
 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_s(tx_buffer,1,"%1X", 0xF);
+    // sprintf_s(tx_buffer+1,1,"%1X", cmd&0xF);
+    // sprintf_s(tx_buffer+4,4,"%04d", content_length);
+    // sprintf_s(tx_buffer+6,MAX_CMD_MSG_BUFFER_LEN,"%s",content);
+    // printf("pack_tlv_format_old %04d , %s\n",content_length,content);
+    sprintf(tx_buffer,"%1X", 0xF);
+    sprintf(tx_buffer+1,"%1X", cmd&0xF);
+    sprintf(tx_buffer+2,"%04d", content_length);
+    sprintf(tx_buffer+6,"%s",content);
+
+    // for (int i = 0 ; i<content_length+6;i++ )
+    // {
+    //     printf("tx[%d]=%c(%02X) ",i,tx_buffer[i],tx_buffer[i]);
+    // }
+    // printf("\n");
+    
+    return content_length+6;
+}
+
 static struct tcp_msg_t *unpack_tlv_format(char *rx_buffer, int length)
 {
     char temp[8]={0};
@@ -218,22 +281,37 @@ static struct tcp_msg_t *unpack_tlv_format(char *rx_buffer, int length)
 static int pack_tlv_format(char *tx_buffer, uint8_t cmd, char *content)
 {
     int content_length = (int)strlen(content);
-    if( content == NULL || content_length > MAX_TCP_MSG_BUFFER_LEN ) {
+    if( content == NULL || content_length > MAX_CMD_MSG_BUFFER_LEN ) {
         return -1;
     }
-    struct tcp_msg_t *msg = (struct tcp_msg_t *)tx_buffer;
-    sprintf((char*)(&msg->head), "%02X", 0xFE);
-    sprintf((char*)(&msg->cmd), "%02X", cmd);
-    sprintf((char*)(&msg->length), "%04d", (unsigned char)content_length);
-    sprintf(&tx_buffer[4], "%04d", content_length);
-    strcpy(msg->buffer, content);
-    return strlen(content)+8;
+    // printf("pack_tlv_format %04d , %s\n",content_length,content);
+    // sprintf_s(tx_buffer,2,"%02X", 0xFE);
+    // sprintf_s(tx_buffer+2,2,"%02X", cmd);
+    // sprintf_s(tx_buffer+4,4,"%04d", content_length);
+    // sprintf_s(tx_buffer+8,MAX_CMD_MSG_BUFFER_LEN,"%s",content);
+    sprintf(tx_buffer,"%02X", 0xFE);
+    sprintf(tx_buffer+2,"%02X", cmd);
+    sprintf(tx_buffer+4,"%04d", content_length);
+    sprintf(tx_buffer+8,"%s",content);
+    // for (int i = 0 ; i<content_length+8;i++ )
+    // {
+    //     printf("tx[%d]=%c(%02X) ",i,tx_buffer[i],tx_buffer[i]);
+    // }
+    // printf("\n");
+    return content_length+8;
 }
 
 static void udp_send_response(char *tx_buffer, uint8_t cmd, char *content)
 {
     // remain lock using
-    int len = pack_tlv_format(tx_buffer, cmd, content);
+    int len = 0;
+    if(g_msg_format_type == 1)
+    {
+       len = pack_tlv_format(tx_buffer, cmd, content);
+    }else{
+       len = pack_tlv_format_old(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 *)&sourceAddr, sizeof(sourceAddr));
@@ -607,30 +685,34 @@ void cat1_call_sms_send(char* phonenum,char* sms_txtdata)
         memset_s(msg_tmp,len_smstxt,0,len_smstxt);
         sprintf_s(msg_tmp,len_smstxt,"%s,%s",phonenum,sms_txtdata);
         udp_send_msg_toCat1(UDP_CMD_SEND_SMS,msg_tmp);
+        free(msg_tmp);
     }
 }
 
 static char* phonenum =NULL;
     
 //来电
-int cat1_handle_call_incomming(struct tcp_msg_t *msg)
+int cat1_handle_call_incomming(char * msg)
 {
     if(phonenum!=NULL)
     {
         free(phonenum);
         phonenum=NULL;
     }
-    phonenum = (char*)malloc(strlen(msg->buffer));
+    int phonenumlen = strlen(msg)+1;
+    phonenum = (char*)malloc(phonenumlen);
     if(phonenum==NULL)
     return 0;
 
-    strcpy(phonenum,msg->buffer);
+    strncpy(phonenum,msg,phonenumlen-1);
+    phonenum[phonenumlen-1]='\0';
     WEARABLE_LOGI(WEARABLE_LOG_MODULE_MAIN_SERVICE,"cat1 incomming call %s\n",phonenum);
 
     incomingcall_event_sendmsg_toUI(phonenum);
     //声音
     //uapi_cat1_start_volte_voice();
-    
+    //由于incomingcall_event_sendmsg_toUI中的参数是char* 在其他地方会使用。因此要保留内存存在,只能在更新时刷新。
+    // free(phonenum);
 
 
     return 1;
@@ -638,15 +720,13 @@ int cat1_handle_call_incomming(struct tcp_msg_t *msg)
 
 void test_call_incomming(void)
 {
-    struct tcp_msg_t msg;
-    strcpy(msg.buffer,"10086");
-    cat1_handle_call_incomming(&msg);
+    cat1_handle_call_incomming("10086");
 }
 
-int cat1_handle_networ_msg(struct tcp_msg_t *msg)
+int cat1_handle_networ_msg(char *msg)
 {
     // WEARABLE_LOGI(WEARABLE_LOG_MODULE_MAIN_SERVICE,"cat1 cat1_handle_networ_msg %s\n",msg->buffer);
-    if(decodeNetStat(msg->buffer) == 0)
+    if(decodeNetStat(msg) == 0)
     {
         runtime_status_t * runtime = get_device_runtime_status();
         OHOS::ConfigModel::GetInstance()->Setimei(runtime->cat1_runtime.imei);
@@ -656,7 +736,7 @@ int cat1_handle_networ_msg(struct tcp_msg_t *msg)
     return 1;
 }
 
-int cat1_handle_version_msg(struct tcp_msg_t *msg)
+int cat1_handle_version_msg(char *msg)
 {
    
     // WEARABLE_LOGI(WEARABLE_LOG_MODULE_MAIN_SERVICE,"cat1 cat1_handle_networ_msg %s\n",msg->buffer);
@@ -666,7 +746,7 @@ int cat1_handle_version_msg(struct tcp_msg_t *msg)
 // pyVer,PY_SRV_V4,modemVer,EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_BETA0312
 // imei:860132060352796,sim:0,oper:-1,signal:99,net:([99, 0, 0, 0], [0, 0, 0, 0, 0])
     
-    if(decodeVersion(msg->buffer) == 0)
+    if(decodeVersion(msg) == 0)
     {
         runtime_status_t * runtime = get_device_runtime_status();
         OHOS::ConfigModel::GetInstance()->SetpyVer(runtime->cat1_runtime.pyVer);
@@ -679,20 +759,19 @@ int cat1_handle_version_msg(struct tcp_msg_t *msg)
 
 
 
-int cat1_handle_sms(struct tcp_msg_t *msg)
+int cat1_handle_sms(char *msg)
 {
-    char* smsmsg=msg->buffer;
     // WEARABLE_LOGI(WEARABLE_LOG_MODULE_MAIN_SERVICE,"cat1 cat1_handle_sms %s\n",smsmsg);
-    if (decodeSMS(smsmsg) ==0 )
+    if (decodeSMS(msg) ==0 )
     {
         //添加到消息列表里
     }
     return 1;
 }
 
-int cat1_handle_timesync(struct tcp_msg_t *msg)
+int cat1_handle_timesync(char *timesync)
 {
-    char* timesync=msg->buffer;
+   
     // WEARABLE_LOGI(WEARABLE_LOG_MODULE_MAIN_SERVICE,"cat1 cat1_handle_timesync %s\n",timesync);
 
     // ('24/03/01 07:15:36 8 0', 1709277336, 0)
@@ -806,7 +885,7 @@ void restart_time_sync(void)
     }
         
 }
-int cat1_handle_call_connected(struct tcp_msg_t *msg)
+int cat1_handle_call_connected(void)
 {
     
     WEARABLE_LOGI(WEARABLE_LOG_MODULE_MAIN_SERVICE,"cat1 call connected\n");
@@ -817,7 +896,7 @@ int cat1_handle_call_connected(struct tcp_msg_t *msg)
     return 1;
 }
 //来电挂断处理
-int cat1_handle_call_disconnected(struct tcp_msg_t *msg)
+int cat1_handle_call_disconnected(void)
 {
     WEARABLE_LOGI(WEARABLE_LOG_MODULE_MAIN_SERVICE,"cat1 call disconnected\n");
     //TODO:  关闭声音
@@ -901,92 +980,108 @@ void get_regist_time_toCat1(void)//设置电信入库功能开关->CAT1
 static int udp_packet_parse(char *rx_buffer, int len)
 {
 
-    struct tcp_msg_t *msg = unpack_tlv_format(rx_buffer, len);
-    int index = 0;
-    // if(  msg->head[1] != UDP_WIFI_STATUS ) { // ota only status check
-    //     return 1;
-    // }
-    uint8_t cmd = get_header_cmd_from_uint16_hexstr(msg->cmd);
-
-    uint8_t *p_header = (uint8_t *)&msg->head;
-    if (( *p_header == 'F' || *p_header == 'f') && (*(p_header+1) == 'E' || *(p_header+1) == 'e'))
+    int index = 0; 
+    if (len <6 || rx_buffer == NULL)
     {
-
-    }else{
-        printf("msg format error!\n");
+        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]);
 
-    if( msg != NULL ) {
-        switch (cmd) {
-            case UDP_MSG_COMMING_CALL:
-                           index = cat1_handle_call_incomming(msg);
-                break;
-            case UDP_CMD_GET_RECV_NETWORKSTAT:
-                index = cat1_handle_networ_msg(msg);
-                break;
-            case UDP_CMD_GET_TIME:
-                           index = cat1_handle_timesync(msg);
-                break;
-            case UDP_MSG_CALL_CONNECTED:
-                           index = cat1_handle_call_connected(msg);
-                break;
-            case UDP_MSG_CALL_DISCONNECTED:
-                           index = cat1_handle_call_disconnected(msg);
-                break;
-            case UDP_CMD_CAT1_OTA_UPDATE:
-                PRINT("CAT1_OTA_UPDATE reply %s\n",msg->buffer);
-                break;
-            case UDP_MSG_REPLY:
-                PRINT("UDP_MSG_REPLY reply %s!!!!!!!\n",msg->buffer);
-                //"BOOTUP,pyVer,PY_SRV_V4,modemVer,EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_BETA0312"
-                // VER:xxxxx
-                // ICCID:xxxxxx
-                if(strstr(msg->buffer,"BOOTUP")!=NULL)
-                {
-                    cat1_handle_version_msg(msg);
-                    restart_time_sync();
-                    cat1_getsignal();
-                    #ifdef SUPPORT_TELECOM_DMP //是否开启电信入库功能
-                        set_telecom_dmp_switch_toCat1(1);
-                        get_software_version_toCat1();
-                        get_sim_iccid_toCat1();
-                        get_regist_time_toCat1();
-                    #endif
-                }
-                break;
-            case UDP_MSG_GET_TELECON_DMP_TIMESEC:
-                #ifdef SUPPORT_TELECOM_DMP
-                    save_regist_time_toBle(msg->buffer);
-                #endif
-                break;
-            case UDP_CMD_GET_CAT1VER:
-                index = cat1_handle_version_msg(msg);
-                break;
-            case UDP_CMD_MSG_ATCMD:
-                PRINT("ATCMD reply : %s\n", msg->buffer);
-                break;
-            case UDP_MSG_SAVE_SIM_ICCID:
-                #ifdef SUPPORT_TELECOM_DMP
-                    save_sim_iccid_toBle(msg->buffer);
+    }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 %x,bufferlen %d , buffer %s \n",cmd,msg_buffer_len,msg_buffer);
+    switch (cmd) {
+        case UDP_MSG_COMMING_CALL:
+            index = cat1_handle_call_incomming(msg_buffer);
+            break;
+        case UDP_CMD_GET_RECV_NETWORKSTAT:
+            index = cat1_handle_networ_msg(msg_buffer);
+            break;
+        case UDP_CMD_GET_TIME:
+            index = cat1_handle_timesync(msg_buffer);
+            break;
+        case UDP_MSG_CALL_CONNECTED:
+            index = cat1_handle_call_connected();
+            break;
+        case UDP_MSG_CALL_DISCONNECTED:
+            index = cat1_handle_call_disconnected();
+            break;
+        case UDP_CMD_CAT1_OTA_UPDATE:
+            PRINT("CAT1_OTA_UPDATE reply %s\n",msg_buffer);
+            break;
+        case UDP_MSG_REPLY:
+            PRINT("UDP_MSG_REPLY reply %s!!!!!!!\n",msg_buffer);
+            //"BOOTUP,pyVer,PY_SRV_V4,modemVer,EG810MCNLAR06A01M08_VOLTE_OCPU_QPY_BETA0312"
+            // VER:xxxxx
+            // ICCID:xxxxxx
+            if(strstr(msg_buffer,"BOOTUP")!=NULL)
+            {
+                cat1_handle_version_msg(msg_buffer);
+                restart_time_sync();
+                cat1_getsignal();
+                if(g_msg_format_type == 0) break;
+                #ifdef SUPPORT_TELECOM_DMP //是否开启电信入库功能
+                    set_telecom_dmp_switch_toCat1(1);
+                    get_software_version_toCat1();
+                    get_sim_iccid_toCat1();
+                    get_regist_time_toCat1();
                 #endif
-                break;
-            case UDP_MSG_RECV_CAT1_SMS_CONTENT://接收单条短信内容
-            case UDP_MSG_SMS:
-                           index = cat1_handle_sms(msg);
-                break;
-                   default:
-                           PRINT("error message: %s\n", rx_buffer);
-                index = 1;
-                break;
-        }
-        // if (index > 0) //需要反馈的指令才返回OK
-            // udp_send_msg_toCat1( msg->head[1], "OK");
-    } else {
-        PRINT("wrong format msg and exit\n");
-        index = 1;
+            }
+            break;
+        case UDP_MSG_GET_TELECON_DMP_TIMESEC:
+            #ifdef SUPPORT_TELECOM_DMP
+                save_regist_time_toBle(msg_buffer);
+            #endif
+            break;
+        case UDP_CMD_GET_CAT1VER:
+            index = cat1_handle_version_msg(msg_buffer);
+            break;
+        case UDP_CMD_MSG_ATCMD:
+            PRINT("ATCMD reply : %s\n", msg_buffer);
+            break;
+        case UDP_MSG_SAVE_SIM_ICCID:
+            #ifdef SUPPORT_TELECOM_DMP
+                save_sim_iccid_toBle(msg_buffer);
+            #endif
+            break;
+        case UDP_MSG_RECV_CAT1_SMS_CONTENT://接收单条短信内容
+        case UDP_MSG_SMS:
+            index = cat1_handle_sms(msg_buffer);
+            break;
+        default:
+            PRINT("error message: %s\n", rx_buffer);
+            index = 1;
+            break;
     }
     
+    
+    // if (index > 0) //需要反馈的指令才返回OK
+        // udp_send_msg_toCat1( msg->head[1], "OK");
+
+    
     return index;
 }
 
@@ -1076,19 +1171,6 @@ void cat1_server_task(void *pvParameters)
 }
 
 
-
-
-#if 0
-void wifi_status()
-{
-    char tx_buffer[128] = {0};
-    int index = resolve_msg_wifi_status(NULL);
-    char *head = "FF";
-    int len = pack_tlv_format(tx_buffer, head, msg_wifi_status[index]);
-    PRINT("wifi_status len = %d, msg = [%s]\n",len, tx_buffer);
-}
-#endif
-
 #include "osal_msgqueue.h"
 #include "thread_init.h"
 #include "soc_osal.h"
diff --git a/code/sdk/drivers/peripheral/slip/cat1Service/pyscript/V6/cat1Service.py b/code/sdk/drivers/peripheral/slip/cat1Service/pyscript/V6/cat1Service.py
new file mode 100644 (file)
index 0000000..4bd9cd6
--- /dev/null
@@ -0,0 +1,625 @@
+# Copyright (c) Quectel Wireless Solution, Co., Ltd.All Rights Reserved.
+#  
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#  
+#     http://www.apache.org/licenses/LICENSE-2.0
+#  
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+
+# net.getNetMode()
+# (0, '460', '11', 7)
+
+# net.getSignal(1)
+# ([99, 99, 255, 255], [-84, -117, -15, 255, -3])
+
+# net.nitzTime()
+# ('24/02/26 11:17:42 8 0', 1708946262, 0)
+
+
+import usocket
+import log
+import utime
+import slip
+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
+PROJECT_NAME = "Cat1SlipUDPService"
+PROJECT_VERSION = "PY_SRV_V6"
+CONFIG_JSON="/usr/system_config.json"
+CURRENT_APP_TYPE="pysrv"
+
+
+# 设置日志输出级别
+log.basicConfig(level=log.INFO)
+cat1service_log = log.getLogger("cat1service")
+
+lpm_fd = pm.create_wakelock("system_lock", len("system_lock"))
+pm.autosleep(1)
+pm.wakelock_lock(lpm_fd)
+cat1service_log.info("create_wakelock {}".format(pm.get_wakelock_num()))
+
+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))
+
+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))
+    cat1service_log.info("{}={}".format(get_versionkeyname_by_py(app_type),keyvalue))
+    return keyvalue
+
+set_version_to_json_config(CURRENT_APP_TYPE,PROJECT_VERSION)
+    
+
+audio.set_qdai_cfg(1,0,0,1,0,0,1,1)
+
+# GPIO21 - 引脚 86   KP_MKOUT1   唤醒主控
+# GPIO22 - 引脚 87   KP_MKIN     被主控唤醒
+
+# GPIOn - GPIO号,int类型,点此查看GPIO引脚编号与物理引脚的映射关系。
+
+# direction - 输入输出模式,int类型,IN - 输入模式,OUT - 输出模式。
+
+# pullMode - 上下拉模式,int类型,说明如下:
+# PULL_DISABLE - 浮空模式
+# PULL_PU - 上拉模式
+# PULL_PD - 下拉模式
+
+# level - 引脚电平,int类型,0 - 设置引脚为低电平, 1- 设置引脚为高电平。
+# recvDataPin = Pin(Pin.GPIO22, Pin.IN, Pin.PULL_PU, 0)
+def ExtIntfun(args):
+        # cat1service_log.info('### interrupt  {} ###'.format(args)) # args[0]:gpio号 args[1]:上升沿或下降沿
+        if args[1] == 0:
+            cat1service_log.info("disable autosleep")
+            # pm.autosleep(0)
+            pm.wakelock_lock(lpm_fd)
+        elif args[1] == 1:
+            cat1service_log.info("enable autosleep")
+            pm.wakelock_unlock(lpm_fd)
+            # pm.autosleep(1)
+        # cat1service_log.info("recvDataPin={}".format(recvDataPin.read()))
+extint = ExtInt(ExtInt.GPIO22, ExtInt.IRQ_RISING_FALLING, ExtInt.PULL_DISABLE, ExtIntfun)
+extint.enable()
+
+
+# 创建gpio对象
+gpioWakeBT = Pin(Pin.GPIO21, Pin.OUT, Pin.PULL_DISABLE, 1)
+# 设置输入输出模式
+gpioWakeBT.set_dir(Pin.OUT)
+
+# 设置引脚电平
+gpioWakeBT.write(0)
+
+UDP_CMD_GET_CAT1VER = '0'  #获取 Cat1 版本号
+UDP_CMD_DIAL_NUMB = '1'              #拨打电话
+UDP_CMD_HUNGUP = '2'               #挂断电话
+UDP_CMD_ANSWER = '3'            #接听电话
+UDP_CMD_CAT1_OTA_UPDATE = '4'       #触发Cat1 OTA升级,mcu提供url
+UDP_CMD_SEND_SMS = '5'         #发送SMS短信,mcu提供电话号及短信内容
+UDP_CMD_GET_TIME = '6'               #获取Cat1 时间 ,YYYYMMDD HHmmss zone
+UDP_CMD_GET_RECV_NETWORKSTAT = '7'      #获取Cat1 信号信息,VOLTE信息,信号强度,SIM卡状态  // 内容同UDP_CMD_GET_NETWORKSTAT,CAT主动发给MCU
+UDP_MSG_SMS = '8'           #  CAT1接收到的SMS信息给MCU,包含电话号及短信内容
+UDP_CMD_ATCMD = '9'           # 执行AT指令
+UDP_MSG_CALL_CONNECTED = 'A'       #  CAT1 电话接听消息
+UDP_MSG_CALL_DISCONNECTED = 'B'        #  CAT1 电话挂断消息
+UDP_MSG_COMMING_CALL = 'C'       #  CAT1 来电消息,包含电话号
+UDP_MSG_REPLY = 'F'         # 返回值 
+
+
+
+def result(args):
+    print('download status:',args[0],'download process:',args[1])
+def download_fota_img( srcurl ):
+    fota_obj = fota()  # 创建Fota对象
+    cat1service_log.info("httpDownload... {} , {}".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:
+        cat1service_log.error("httpDownload error")
+        
+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)
+    cat1service_log.info(url)
+    data = response.json()
+    if(data['UptoDate'] == False):
+        cat1service_log.info("Need update python application")
+        srcurl = data['url']
+        #差分升级方式
+        # res = fota_obj.httpDownload(url1="http://www.example.com/fota.bin",callback=result)    
+        # mini fota方式
+        return srcurl
+    else:
+        cat1service_log.info("No need update python application")
+        return ""
+
+class Cat1Service:
+    AP = 0  # SLIP_INNER
+    STA = 1 # SLIP_OUTER
+
+    def __init__(self, uart=UART.UART4, mode=AP):
+        self.__uart = uart
+        self.__mode = mode
+        self.__message = ''
+        self.__err = 0
+        self.__net_connected = 0
+        self.__value = None
+        self.__wait_resp = 0
+        self.__waiting_netstat = 0
+        slip.destroy()
+        print('slip uart={0}'.format (self.__uart))
+
+        ret = slip.construct(self.__uart, self.__mode, 0)
+        if ret != 0:
+            print('slip netif construct fail')
+            return None
+        print('slip network card create success')
+        self.__queue = Queue(1)
+        self.__sock = self.__socket_init()
+        self.__threadid = _thread.start_new_thread(self.__Socket_Thread, ())
+        return None
+
+    def __socket_init(self):
+        # 创建一个socket实例
+        sock = usocket.socket(usocket.AF_INET, usocket.SOCK_DGRAM, usocket.TCP_CUSTOMIZE_PORT)
+        sock.setsockopt(usocket.SOL_SOCKET, usocket.SO_REUSEADDR, 1)
+        # 绑定IP
+        bind_addr = ('172.16.1.2', 5000)
+        sock.bind(bind_addr)
+        sock.settimeout(10)
+        return sock
+
+    def __socket_reinit(self):
+        return self.__socket_init()
+    
+    def bootup_msg_to_bt(self):
+        modem_ver = modem.getDevFwVersion() 
+        self.reply_cmd('FF',"BOOTUP@pyVer:{}@modemVer:{}".format(PROJECT_VERSION,modem_ver))
+
+    def btmcu_cmd_handler(self,cmd,parm):
+        print("btmcu_cmd_handler cmd {0} , args {1}".format(cmd,parm))
+        if cmd == "F0":
+            print(cmd)
+            # UDP_CMD_GET_CAT1VER
+            modem_ver = modem.getDevFwVersion() 
+            self.reply_cmd('F0',"pyVer:{}@modemVer:{}".format(PROJECT_VERSION,modem_ver))
+        elif cmd == "F1":
+            print("{}{}".format(cmd,parm))
+            # UDP_CMD_DIAL_NUMB
+            voiceCall.callStart(parm)
+        elif cmd == "F2":
+            print(cmd)
+            # UDP_CMD_HUNGUP
+            voiceCall.callEnd()
+        elif cmd == "F3":
+            print(cmd)
+            # UDP_CMD_ANSWER
+            voiceCall.callAnswer()
+        elif cmd == "F4":
+            print(cmd)
+            result = check_fota()
+            if result == "":
+                self.reply_cmd('F4',"no need update!")
+            else:
+                self.reply_cmd('F4',"start ota {} please wait...".format(result))
+            download_fota_img(result)
+        elif cmd == "F5":
+            print(cmd)
+            # UDP_CMD_SEND_SMS
+        elif cmd == "F6":
+            print(cmd)
+            # UDP_CMD_GET_TIME
+            time=utime.localtime()
+            zone=utime.getTimeZone()
+            #(2024, 3, 2, 18, 31, 32, 5, 62),8
+            # 返回当前时间戳,参数为元组
+            # timestamp = utime.mktime(time)
+            # cat1service_log.info(timestamp)
+            self.reply_cmd('F6',"{0}@{1}".format(time,zone))
+        elif cmd == "F7":
+            print(cmd)
+            # UDP_CMD_GET_RECV_NETWORKSTAT
+            simstat = sim.getStatus()
+            imei = modem.getDevImei()
+            netstat = "0,10,0,10"
+            netstat_ = net.getState()
+            if netstat_ != -1 :
+                netstat = "{},{},{},{}".format(netstat_[0][0],netstat_[0][3],netstat_[1][0],netstat_[1][3])
+            # ([voice_state, voice_lac, voice_cid, voice_rat, voice_reject_cause, voice_psc], [data_state, data_lac, data_cid, data_rat, data_reject_cause, data_psc])
+            operator =  net.operatorName()
+            signal = net.csqQueryPoll()
+            print("imei:{0},sim:{1},oper:{2},signal:{3},net:{4}".format(imei,simstat,operator,signal,netstat))
+            self.reply_cmd('F7',"imei:{0}@sim:{1}@oper:{2}@signal:{3}@net:{4}".format(imei,simstat,operator,signal,netstat))
+        elif cmd == "F9":
+            print("{},{}".format(cmd,parm))
+            # UDP_CMD_ATCMD
+            # net.setModemFun(0)
+            # net.setModemFun(1)
+            resp=bytearray(50)
+            ret=atcmd.sendSync("{}\r\n".format(parm),resp,'',10)
+            if ret == 0:
+                print("reply:{},ret:{}".format(resp.decode(),ret))
+                self.reply_cmd('F9',"{}".format(resp.decode()))
+            else:
+                print("cmd error ret:{}".format(ret))
+                self.reply_cmd('F9',"{}".format("at error"))
+
+
+    # 来电提醒
+    def notifyIncomingcall(self, incomming_numb):
+        self.clear_remain()
+        __head = 'FC'
+        self.__message = str(incomming_numb)
+        self.__Socket_UDP(__head, self.__message)
+        # if self.__err == 1 or self.__value[2] != 'OK':
+        #     return -1
+        return 0
+
+    # 电话接听消息
+    def notifyConnecteCall(self):
+        self.clear_remain()
+        __head = 'FA'
+        self.__message = '0'       
+        self.__Socket_UDP(__head, self.__message)
+        # if self.__err == 1 or self.__value[2] != 'OK':
+        #     return -1
+        return 0
+
+    # 电话拒接消息
+    def notifyDisconnectCall(self):
+        self.clear_remain()
+        __head = 'FB'
+        self.__message = '0'       
+        self.__Socket_UDP(__head, self.__message)
+        # if self.__err == 1 or self.__value[2] != 'OK':
+        #     return -1
+        return 0
+    
+    def wait_network_ready(self):
+        if(self.__waiting_netstat == 1):
+            return 0
+        self.__waiting_netstat = 1
+        stage, state = checkNet.waitNetworkReady(30)
+        pm.wakelock_unlock(lpm_fd)
+        if stage == 3 and state == 1:
+            print('Network connection successful.')
+            self.set_network_config()
+            self.__net_connected = 1
+            self.__waiting_netstat = 0
+            return 0
+        else:
+            print('Network connection failed, stage={}, state={}'.format(stage, state))
+            self.reset_network_config()
+            self.__net_connected = 0
+            self.__waiting_netstat = 0
+            return -1
+
+    # 查询网卡状态
+    def timesync(self,_timesync):
+        self.clear_remain()
+        self.__message = str(_timesync)
+        self.__Socket_UDP('FD', self.__message)
+        return 0
+    
+       # 查询网卡版本信息
+    def version(self):
+        self.clear_remain()
+        self.__Socket_UDP('F5', '0')
+        if self.__err == 1:
+            return -1
+        return self.__value[2]
+    
+    def reply_timesync(self,_timesync):
+        self.clear_remain()
+        self.__message = str(_timesync)
+        self.__Socket_UDP_noreply('FD', self.__message)
+        return 0
+
+    def reply_cmd(self,cmd,_timesync):
+        self.clear_remain()
+        self.__message = str(_timesync)
+        self.__Socket_UDP_noreply(cmd, self.__message)
+        return 0
+    
+    def clear_remain(self):
+        if self.__queue.empty() == False:
+            self.__queue.get()
+        self.__err = 0
+        self.__value = None
+    #添加路由信息
+    def router_add(self, ip='192.168.4.1', mask='255.255.255.0'):
+        self.ip = ip
+        self.mask = mask
+        return slip.router_add(self.ip, self.mask)
+
+    # 获取slip的网络配置
+    def ipconfig(self):
+        return slip.ipconfig()
+
+       # 设置dns服务器
+    def set_dns(self, pri_dns='8.8.8.8', sec_dns='114.114.114.114'):
+        self.pri_dns = pri_dns
+        self.sec_dns = sec_dns
+        return slip.set_dns(self.pri_dns,self.sec_dns)
+    
+       # 设置默认网卡
+    def set_default_NIC(self, ip_str):
+        self.ip_str = ip_str
+        return slip.set_default_netif(self.ip_str)
+    
+    def reset_network_config(self):
+        if (self.__net_connected == 0):
+            print("skip reset_network_config")
+            return 0
+        Info = dataCall.getInfo(1,0)
+        print("Info{}".format(Info))
+        default_NIC_ip = Info[2][2]    # 假设默认网卡ip地址为10.10.1.1,请根据实际情况更改
+        segment_ip = '172.16.4.0'      # 假设ap模式网段范围是[192.168.4.0 ~ 192.168.4.255],请根据实际情况更改
+        mask = '255.255.255.0'          # 假设子网掩码为255.255.255.0,请根据实际情况更改
+        # 配置默认网卡,通过默认网卡进行网络转发
+        cat1service.set_default_NIC(default_NIC_ip)
+        print("default_NIC_ip {0} segment_ip {1}".format(default_NIC_ip,segment_ip))
+        #添加路由规则,只有该网段IP才进行转发
+        cat1service.router_add(segment_ip, mask)
+
+        pri_dns = '8.8.8.8'             # 假设DNS首选地址为8.8.8.8,请根据实际情况更改
+        sec_dns = '114.114.114.114'     # 假设DNS备选地址为114.114.114.114,请根据实际情况更改
+        # 配置网卡DNS服务器
+        cat1service.set_dns(pri_dns, sec_dns)
+        # 网卡IP信息查询
+        cat1service.ipconfig()
+
+    def set_network_config(self):
+        if (self.__net_connected == 1) :
+            print("skip set_network_config")
+            return 0
+        Info = dataCall.getInfo(1,0)
+        print("Info{}".format(Info))
+        default_NIC_ip = Info[2][2]    # 假设默认网卡ip地址为10.10.1.1,请根据实际情况更改
+        segment_ip = '172.16.1.0'      # 假设ap模式网段范围是[192.168.4.0 ~ 192.168.4.255],请根据实际情况更改
+        mask = '255.255.255.0'          # 假设子网掩码为255.255.255.0,请根据实际情况更改
+        # 配置默认网卡,通过默认网卡进行网络转发
+        cat1service.set_default_NIC(default_NIC_ip)
+        print("default_NIC_ip {0} segment_ip {1}".format(default_NIC_ip,segment_ip))
+        #添加路由规则,只有该网段IP才进行转发
+        cat1service.router_add(segment_ip, mask)
+
+        pri_dns = '8.8.8.8'             # 假设DNS首选地址为8.8.8.8,请根据实际情况更改
+        sec_dns = '114.114.114.114'     # 假设DNS备选地址为114.114.114.114,请根据实际情况更改
+        # 配置网卡DNS服务器
+        cat1service.set_dns(pri_dns, sec_dns)
+        # 网卡IP信息查询
+        cat1service.ipconfig()
+
+    # 释放slip网卡
+    def stop(self):
+        slip.destroy()
+        return 0
+
+
+    # 封装tlv数据包
+    def __pack_tlv_format(self, head, content):
+        self.head = head
+        self.content = content
+        if len(self.content) == 0 or len(self.content) > 9999 or len(self.head) != 2:
+            print('illegal pack tlv content')
+            return -1
+        len_str ='%04d' % len(self.content)
+        tlv_pack = self.head+len_str+self.content
+        return tlv_pack
+
+    # 解码tlv数据包
+    def __unpack_tlv_format(self, msg):
+        self.msg = str(msg)
+        tag = self.msg[0:2]
+        length = self.msg[2:6]
+        value = self.msg[6:]
+        len_str ='%04d' % len(value)
+        if len(value) == 0 or len(value) > 9999 or len(tag) != 2 or len_str != self.msg[2:6]:
+            print('illegal unpack tlv content')
+            return -1
+        unpack = (tag,length,value)
+        return unpack
+
+    # socket通信(UDP)模块
+    def __Socket_UDP(self, head, content):
+        try:
+            self.head = head
+            self.content = content
+            gpioWakeBT.write(1)
+            utime.sleep_ms(2)
+            gpioWakeBT.write(0)
+            utime.sleep_ms(20)
+            # 消息处理
+            msg = self.__pack_tlv_format(self.head, self.content)
+
+            # 向服务端发送消息
+            server_addr = ('172.16.1.5',1000)
+            print("send msg {}".format(msg))
+            self.__err = 0
+            self.__sock.sendto(msg,server_addr)
+            self.__wait_resp = 1
+            # data = self.__queue.get()
+            self.__wait_resp = 0
+            # return data
+            return 1
+        except Exception as error:
+            print(error)
+        return 0
+    
+    def __Socket_UDP_noreply(self, head, content):
+        self.head = head
+        self.content = content
+        gpioWakeBT.write(1)
+        utime.sleep_ms(2)
+        gpioWakeBT.write(0)
+        utime.sleep_ms(20)
+        # 消息处理
+        msg = self.__pack_tlv_format(self.head, self.content)
+        # 向服务端发送消息
+        server_addr = ('172.16.1.5',1000)
+        print("send msg {}".format(msg))
+        self.__err = 0
+        self.__sock.sendto(msg,server_addr)
+        self.__wait_resp = 0
+        return 0
+
+    # socket通信(UDP)模块
+    def __Socket_Thread(self):
+        while True:
+            try:
+                print("recv====")
+                data=self.__sock.recv(1024)
+                print(data)
+            except Exception as recverr:
+                print(recverr)
+                if "110" in str(recverr):
+                    self.__err = 1
+                    if self.__wait_resp == 1:
+                        self.__queue.put('0')
+                else:
+                    utime.sleep(1)
+                    self.__sock = self.__socket_reinit()
+                
+            else :
+                value = self.__unpack_tlv_format(data.decode())
+                print('mode: {0}, recv {1} bytes, Data: {2}'.format (value[0],len(data), value[2]))
+                if value[0] == 'FF':
+                    self.btmcu_cmd_handler(value[0],value[2])
+                else:
+                    self.__value = value
+                    self.__queue.put('1')
+                    self.btmcu_cmd_handler(value[0],value[2])
+                print("End else Thread")
+
+        print("End Socket Thread")
+
+
+
+
+# UDP_CMD_GET_CAT1VER = '0',  // 获取 Cat1 版本号
+# UDP_CMD_DIAL_NUMB = '1',               //  拨打电话
+# UDP_CMD_HUNGUP = '2',                 //  挂断电话
+# UDP_CMD_ANSWER = '3',            //  接听电话
+# UDP_CMD_CAT1_OTA_UPDATE = '4',       // 触发Cat1 OTA升级,mcu提供url
+# UDP_CMD_SEND_SMS = '5',               // 发送SMS短信,mcu提供电话号及短信内容
+# UDP_CMD_GET_TIME = '6',               // 获取Cat1 时间 ,YYYYMMDD HHmmss zone
+# UDP_CMD_GET_NETWORKSTAT = '7',               //获取Cat1 信号信息,VOLTE信息,信号强度,SIM卡状态
+# 下文进行系统配置
+print("Cat1Service start")
+
+cat1service = Cat1Service()
+
+
+
+#voice call callback function
+def voice_callback(args):
+    if args[0] == 10:
+        print('voicecall incoming call, PhoneNO: ', args[6])
+        # gpioWakeBT.write(1)
+        cat1service.notifyIncomingcall(args[6])
+    elif args[0] == 11:
+        print('voicecall connected, PhoneNO: ', args[6])
+        cat1service.notifyConnecteCall()
+    elif args[0] == 12:
+        print('voicecall disconnect')
+        cat1service.notifyDisconnectCall()
+    elif args[0] == 13:
+        print('voicecall is waiting, PhoneNO: ', args[6])
+    elif args[0] == 14:
+        print('voicecall dialing, PhoneNO: ', args[6])
+    elif args[0] == 15:
+        print('voicecall alerting, PhoneNO: ', args[6])
+    elif args[0] == 16:
+        print('voicecall holding, PhoneNO: ', args[6])
+
+#电话消息反馈
+voiceCall.setCallback(voice_callback)
+
+
+def checknet_cb(arg):
+    print("start checktime!!")
+    _thread.start_new_thread(cat1service.wait_network_ready, ())
+    # time=utime.localtime()
+    # zone=utime.getTimeZone()
+    #(2024, 3, 2, 18, 31, 32, 5, 62),8
+    # cat1service.timesync("{0},{1}".format(time,zone))
+
+timer = osTimer()
+# checknet_cb(())
+timer.start(30000,1,checknet_cb)  
+
+def bootupmsg_cb(arg):
+    cat1service.bootup_msg_to_bt()
+    
+
+delaybootupmsg_timer = osTimer()
+delaybootupmsg_timer.start(1000,0,bootupmsg_cb)
+
+# def checkpin_cb(arg):
+#     cat1service_log.info("recvDataPin={}".format(recvDataPin.read()))
+
+# timerCheckRevPin = osTimer()
+# timerCheckRevPin.start(1000,1,checkpin_cb)  
+
+
+# while True:
+#     utime.sleep(5)
+
+
+# uping.ping("172.16.1.5")
+   # 获取网卡当前工作状态
+
+# gpioWakeBT.write(1)
+# utime.sleep(1)
+
+# timesync = net.nitzTime()
+# cat1service.timesync(timesync)