From: 孙春阳 Date: Thu, 18 Sep 2025 13:57:24 +0000 (+0800) Subject: 雷鸟兼容EG810的配置,cat1固件选择w9的固件,并更新cat1Service.py X-Git-Tag: leiniao_debug_1.0.0_20250922_020716~52 X-Git-Url: http://git.snicker.com.cn/css/static/gitweb.css?a=commitdiff_plain;h=53d21133d531481ddeccf7297986ac0fdf420e7e;p=mirrors%2FFD230.git 雷鸟兼容EG810的配置,cat1固件选择w9的固件,并更新cat1Service.py 优化ppp协议响应速度 --- diff --git a/cat1modem/src/LeiNiao/cat1Service.py b/cat1modem/src/LeiNiao/cat1Service.py new file mode 100644 index 000000000..476be0ea2 --- /dev/null +++ b/cat1modem/src/LeiNiao/cat1Service.py @@ -0,0 +1,1121 @@ +# 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 +import sms +import ujson + +from usr.EventMesh import eventMesh + +from usr.httpota import httpota +from usr.telecom_dmp import telecomDmpCb +from usr.china_mobile_dmp import chinamobileCb + +from usr.china_mobile_ai_regulation import aiRegulation +# 设置日志输出级别 +log.basicConfig(level=log.INFO) +clog = log.getLogger("cat1") + +def msg_cb(args): + index = args[1] + storage = args[2] + sms_data = sms.getSaveLoc() + if sms_data == -1: + return + sms_max = sms_data[0][2] + if index != -1: + eventMesh.publish("send_singal_data_toBle",index) + + if index >= sms_max-1:#删除短信 + eventMesh.publish("delete_sms_event")#删除短信 + +sms.setCallback(msg_cb)#sms注册回调 + +CAT1_SERVICE_HEAD = 'FE' #固定head + +PROJECT_NAME = "Cat1SlipUDPService" +PROJECT_VERSION = "PY_SRV_V21" +CONFIG_JSON="/usr/system_config.json" +CURRENT_APP_TYPE="pysrv" + + + + + + +#设置通话音量 +voiceCall.setVolume(10) +clog.info("voice call volume {}".format(voiceCall.getVolume())) +lpm_fd = pm.create_wakelock("system_lock", len("system_lock")) +# pm.autosleep(1) +pm.wakelock_lock(lpm_fd) +clog.info("create_wakelock {}".format(pm.get_wakelock_num())) +telecomTimerCount = 0 +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_V14" + elif (app_type == "pysrv"): + return "PY_SRV_V16" + +#如果没有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): + try : + 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) + clog.info("{}={}".format(get_versionkeyname_by_py(app_type),keyvalue)) + clog.info("{}".format(config_data)) + except Exception as e: + clog.error("set_version_to_json_config") + +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)) + clog.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): + # clog.info('### interrupt {} ###'.format(args)) # args[0]:gpio号 args[1]:上升沿或下降沿 + if args[1] == 0: + clog.info("disable autosleep") + # pm.autosleep(0) + pm.wakelock_lock(lpm_fd) + elif args[1] == 1: + clog.info("enable autosleep") + pm.wakelock_unlock(lpm_fd) + # pm.autosleep(1) + # clog.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' # 返回值 +UDP_MSG_OTA = 'D' # 返回值 + +class Cat1Service: + AP = 0 # SLIP_INNER + STA = 1 # SLIP_OUTER + + def __init__(self, uart=UART.UART2, 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() + clog.info('slip uart={0}'.format (self.__uart)) + + ret = slip.construct(self.__uart, self.__mode, 0) + if ret != 0: + clog.error('slip netif construct fail') + return None + clog.info('slip network card create success') + # self.__queue = Queue(1) + self.__sock = self.__socket_init() + self.__threadid = _thread.start_new_thread(self.__Socket_Thread, ()) + self.telecom_init_flag = 0 + self.telecomTimer = osTimer() + eventMesh.subscribe("cat1_reply_iccid_to_ble",self.cat1_reply_iccid_to_ble) + eventMesh.subscribe("cat1_reply_timesec_to_ble",self.cat1_reply_timesec_to_ble) + + self.iccid_data = "" + self.software_version = "" + self.deletSmsTimer = osTimer() + self.china_mobile_ai_init = 0 + self.volte_switch = 1 #默认是开启VOLTE通话功能 + eventMesh.subscribe("set_dmp_change_mode",self.set_dmp_change_mode) + eventMesh.subscribe("get_dmp_change_mode",self.get_dmp_change_mode) + eventMesh.subscribe("delete_sms_event",self.delete_sms_event) + eventMesh.subscribe("remove_all_sms_cb", self.remove_all_sms_cb)# + eventMesh.subscribe("send_sms_max_to_Ble",self.send_sms_max_to_Ble) + eventMesh.subscribe("get_all_sms_data",self.get_all_sms_data) #获取所有的短信内容 + eventMesh.subscribe("send_singal_data_toBle",self.send_singal_data_toBle) + eventMesh.subscribe("delete_sms_single_data",self.delete_sms_single_data) + + eventMesh.subscribe("get_factory_status",self.get_factory_status) + eventMesh.subscribe("set_factory_status",self.set_factory_status) + eventMesh.subscribe("send_dmp_cm_address_toBLE",self.send_dmp_cm_address_toBLE) + eventMesh.subscribe("set_volte_switch",self.set_volte_switch) + eventMesh.subscribe("get_volte_switch",self.get_volte_switch) + eventMesh.publish("delete_sms_event") + + + self.telecom_dmp_switch = 0 + + self.send_data = [] + self.code_old = 0 + self.code_old_num = 1 + self.tmp_data = [] + self.total_num = 0 + # + self.msg_nums = 0 + self.msg_nums_old = 0 + self.china_mobile_init = 0 + self.factory_status = 0 + self.send_data_q = Queue(100) + self.ack_sem=0 + _thread.start_new_thread(self.Socket_SEND_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(None) + return sock + + def __socket_reinit(self): + return self.__socket_init() + + def bootup_msg_to_bt(self): + modem_ver = modem.getDevFwVersion() + self.reply_cmd('0F',"BOOTUP@pyVer:{}@modemVer:{}".format(PROJECT_VERSION,modem_ver)) + self.reply_cmd('0F',"VOLUME:{}".format(voiceCall.getVolume())) + + def btmcu_cmd_handler(self,cmd,parm): + + # cmd = "" + # cmd_tmp= int(cmd_data)#将十进制数转换成int 再转换成十六进制 + # cell_data = hex(cmd_tmp) + # decimal_number = int(cell_data, 16) + # cmd = "%02x"%(decimal_number) # 使用两位表示,不足前面补0 + clog.info(cmd) # 输出: 07 + clog.info("btmcu_cmd_handler cmd {0} , args {1}".format(cmd,parm)) + if cmd == "00": + clog.info(cmd) + # UDP_CMD_GET_CAT1VER + modem_ver = modem.getDevFwVersion() + self.reply_cmd('00',"pyVer:{}@modemVer:{}".format(PROJECT_VERSION,modem_ver)) + elif cmd == "01": + # UDP_CMD_DIAL_NUMB + if eventMesh.publish("get_volte_switch") == 1: #只有BLE开了VOLTE才允许打电话 + ret = voiceCall.callStart(str(parm)) + # if ret != 0: + # ret = voiceCall.callStart(str(parm)) + clog.info("ret={} {} {}".format(ret,cmd,parm)) + if ret != 0: + self.reply_cmd('0F',"callcmd_fail") + else: + self.reply_cmd('0F',"callcmd_success") + else: + print("get_volte_switch NO") + self.reply_cmd('0F',"callcmd_fail") + elif cmd == "02": + clog.info(cmd) + # UDP_CMD_HUNGUP + ret = voiceCall.callEnd() + if ret != 0: + ret = voiceCall.callEnd() + if ret != 0: + self.reply_cmd('0F',"callend_fail") + else: + self.reply_cmd('0F',"callend_success") + elif cmd == "03": + clog.info(cmd) + # UDP_CMD_ANSWER + ret = voiceCall.callAnswer() + if ret != 0: + ret = voiceCall.callAnswer() + if ret != 0: + self.reply_cmd('0F',"callanswer_fail") + else: + self.reply_cmd('0F',"callanswer_success") + elif cmd == "04": + clog.info(cmd) + elif cmd == "05": + clog.info(cmd) + # UDP_CMD_SEND_SMS + elif cmd == "06": + clog.info(cmd) + # UDP_CMD_GET_TIME + time=utime.localtime() + zone=utime.getTimeZone() + #(2024, 3, 2, 18, 31, 32, 5, 62),8 + # 返回当前时间戳,参数为元组 + # timestamp = utime.mktime(time) + # clog.info(timestamp) + self.reply_cmd('06',"{0}@{1}".format(time,zone)) + elif cmd == "07": + clog.info("cmd ==== 07!") + # 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() + clog.info("imei:{0},sim:{1},oper:{2},signal:{3},net:{4}".format(imei,simstat,operator,signal,netstat)) + self.reply_cmd('07',"imei:{0}@sim:{1}@oper:{2}@signal:{3}@net:{4}".format(imei,simstat,operator,signal,netstat)) + elif cmd == "09": + clog.info("{},{}".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: + clog.info("reply:{},ret:{}".format(resp.decode(),ret)) + self.reply_cmd('09',"{}".format(resp.decode())) + else: + clog.info("cmd error ret:{}".format(ret)) + self.reply_cmd('09',"{}".format("at error")) + + elif cmd == "10" or cmd == "12" or cmd == "14": #获取固件版本号或者获取BT保存的SIM卡的ICCID BLE那边是否开启电信入库功能 + if 1: #CHINA_TELECOM_DM_FUN_ENABLE == 1 : + if eventMesh.publish("get_dmp_change_mode") == 1: + self.telecom_recv_cmd(cmd,parm) + else: + pass + + if 1:#CHINA_MOBILE_DM_FUN_ENABLE == 1: + if eventMesh.publish("get_dmp_change_mode") > 1: + self.china_mobile_recv_cmd(cmd,parm) + else: + pass + pass + elif cmd == "13": + on = int(parm) + clog.info("set_dmp_change_mode on:{}".format(on)) + eventMesh.publish("set_dmp_change_mode",on) + + elif cmd == "16": + if 1: #CHINA_MOBILE_DM_FUN_ENABLE == 1: + if eventMesh.publish("get_dmp_change_mode") > 1: + self.china_mobile_recv_cmd(cmd,parm) + else: + pass + elif cmd == "17": #用于CAT1恢复出厂需要清空数据的标识通用 + eventMesh.publish("set_factory_status",int(parm)) + elif cmd == "18": + eventMesh.publish("set_dmp_cm_address",str(parm)) + elif cmd == "19": #DTMF功能 + voiceCall.startDtmf(str(parm),100) #100ms 持续时间 100-1000 + elif cmd == "1A": + eventMesh.publish("set_volte_switch",int(parm)) + elif cmd == "1B": + print("fota {}".format(str(parm).split("and")[0])) + print("fota {}".format(str(parm).split("and")[-1])) + # httpota = httpota() + httpota.run( str(parm).split("and")[0], str(parm).split("and")[-1]) + # eventMesh.publish("set_volte_switch",int(parm)) + # UDP_MSG_OTA + elif cmd == "1C":# + self.read_dev_ai_id() + elif cmd == "AC":# + if self.ack_sem==1: + self.ack_sem=0 + + + + def telecom_recv_cmd(self,cmd,parm): + if cmd == "10": + self.software_version = str(parm) + eventMesh.publish("set_dev_version",self.software_version) + clog.info("software_version:{},{}".format(self.software_version,parm)) + elif cmd == "12": + pass + elif cmd == "14":# + pass + pass + + def set_volte_switch(self,event,msg): #设置VOLTE开关 + self.volte_switch = int(msg) + + + def get_volte_switch(self,event,msg): #获取VOLTE开关 + + return self.volte_switch + + + def china_mobile_recv_cmd(self,cmd,parm): #移动入库相关指令 + if cmd == "10": + self.software_version = str(parm) + eventMesh.publish("set_dev_version",self.software_version) + clog.info("software_version:{},{}".format(self.software_version,parm)) + elif cmd == "16": #获取BLE mac地址 + eventMesh.publish("set_dev_mac",str(parm)) + clog.info("parm:{}\r\n".format(parm)) + + pass + def get_factory_status(self,event,msg): + return self.factory_status + def set_factory_status(self,event,msg): + self.factory_status = int(msg) + if self.factory_status == 0: #只有为的时候才设置进去 1不再设置 + self.reply_cmd('17',"{}".format(1)) + + def send_dmp_cm_address_toBLE(self,event,msg): + buf_tmp = "address:"+str(msg) + self.reply_cmd('18',"{}".format(buf_tmp)) + + def set_dmp_change_mode(self,event,msg): + self.telecom_dmp_switch = msg + def delete_sms_single_data(self,event,msg): #删除单条信息 + sms.deleteMsg(int(msg)) + + def get_dmp_change_mode(self,event,msg): + return self.telecom_dmp_switch + def delete_sms_event(self,event,msg): + self.deletSmsTimer.start(2*1000,0,self.delete_sms_cb) + def delete_sms_cb(self,*argc): + eventMesh.publish_async("remove_all_sms_cb","",1*1024) + def remove_all_sms_cb(self, event, msg): + clog.info("remove_all_sms_cb\r\n") + msg_nums = sms.getMsgNums() #短信数量 + if msg_nums == -1: + msg_nums = 0 + sms_data = sms.getSaveLoc() + clog.info("{}\r\n".format(sms_data)) + if sms_data == -1: + return + sms_max = sms_data[0][2] #最大存储短信数量 + if sms_max >= msg_nums and sms_max > 0: + sms.deleteMsg(1,4) #删除所有的sms信息 + + def send_singal_data_toBle(self,event,msg): + msg_nums = sms.getMsgNums() #短信数量 + if msg_nums == -1: + msg_nums = 0 + sms_data = sms.getSaveLoc() + if sms_data == -1: + return + sms_max = sms_data[0][2] #最大存储短信数量 + clog.info("recv:{}".format(int(msg))) + message=self.sms_get_message_info(int(msg)) + if message == -1: #说明没有这条短信 + return + message_pdu = sms.decodePdu(message[5],20) + + if message_pdu != -1: #解码出来的内容 + + message_ref = message[0] #编码 + message_total_num = message[1] #总共条数 + message_seq = message[2] #当前第几条 + data = message[5] #内容 + data_len = len(data) #内容长度 + # ref :短信参考标识,同一个标识表明为同一条短信 + # total_num :此条长短信总条数 大于1属于长短信 + # seq :此条短信在长短信中的序号 + # print("message:{} {}\r\n".format(message,message_pdu)) + msg_total = "ref:"+str(message_ref)+"@total_num:"+str(message_total_num)+"@seq:"+str(message_seq)+"@data:"+str(message[5]) + self.reply_cmd('15',msg_total) + + eventMesh.publish("delete_sms_single_data",int(msg)) + + def sms_deal_phone_number(self,args): + data=enumerate(args) + data_str1="" + data_str2="" + data_str3="" + for index,value in data: + if index % 2 == 0: + data_str1=data_str1+value + else: + data_str2=data_str2+value + for i in range(0,len(data_str1)): + data_str3=data_str3+data_str2[i] + data_str3=data_str3+data_str1[i] + return data_str3 + def sms_get_message_info(self,index): + """ + :param index :短信索引值 + :tyoe index :整形 + + :return :元组类型 + 元组内容: + (message_ref,message_total_num,message_seq,sub_message_data,pdu_tye,sub_message_len) + + :message_ref :短信参考标识,同一个标识表明为同一条短信 + :message_total_num :此条长短信总条数 + :message_seq :此条短信在长短信中的序号 + :sub_message_data :词条短信的内容 + :pdu_tye :PDU类型,bit 6标记是否包含用户报文头,长短信需要 + :sub_message_len :此条短信内容长度 + + """ + + message0=sms.searchPduMsg(index) + #print("sms_get_message_info:message0:{}".format(message0)) + if message0 == -1: + return -1 + + sca_num = int(message0[0:2],16) - 1 + data_len = 2 + addr_type= message0[data_len:data_len+1*2] + data_len = data_len+1*2 + + sca = message0[data_len:data_len+sca_num*2] + # 电话号码高低位需要转换 + sca = self.sms_deal_phone_number(sca) + + # if sca_num % 2 == 1: + # print("Get SCA phone {}".format(sca[:-1])) + # else: + # print("Get SCA phone {}".format(sca)) + + data_len = data_len+sca_num*2 + + pdu_tye = int(message0[data_len:data_len+1*2],16) + data_len = data_len+1*2 + + oa_num = int(message0[data_len:data_len+1*2],16) + data_len = data_len+1*2 + oa_addr_type = message0[data_len:data_len+1*2] + data_len = data_len+1*2 + + if oa_num % 2 == 1: + oa_num_t = int((oa_num + 1)/2) + else: + oa_num_t = int((oa_num )/2) + + oa = message0[data_len:data_len+oa_num_t*2] + # 电话号码高低位需要转换 + oa = self.sms_deal_phone_number(oa) + + # if oa_num % 2 == 1: + # print("Get OA phone {}".format(oa[:-1])) + # else: + # print("get OA phone {}".format(oa)) + + data_len = data_len+oa_num_t*2 + pid = message0[data_len:data_len+1*2] + + data_len = data_len+1*2 + dcs = message0[data_len:data_len+1*2] + data_len = data_len+1*2 + scts = message0[data_len:data_len+7*2] + data_len = data_len+7*2 + sub_message_len = int(message0[data_len:data_len+1*2],16) + data_len = data_len+1*2 + sub_message_head = message0[data_len:data_len+6*2] + data_len = data_len+6*2 + + # 或短信用户数据 + sub_message_data = message0[data_len:data_len+sub_message_len*2] + + #长短信 + if ((pdu_tye & 0x40 ) >> 6) == 1: + #长短信,处理长短信用户报文头 + message_ref = int(sub_message_head[6:8],16) + message_total_num = int(sub_message_head[8:10],16) + message_seq = int(sub_message_head[10:12],16) + return [message_ref,message_total_num,message_seq,pdu_tye,sub_message_len,message0] + else: + # 短短信 + return [0,1,1,pdu_tye,sub_message_len,message0] + + + + def send_sms_max_to_Ble(self,event,msg): + msg_nums = sms.getMsgNums()#短信数量 + if msg_nums == -1: + msg_nums = 0 + sms_data = sms.getSaveLoc() + if sms_data != -1: + sms_max = sms_data[0][2]#最大存储短信数量 + self.reply_cmd('15',"@sms_max:"+str(sms_max)+"@current_num:"+str(msg_nums)) + pass + + def get_all_sms_data(self,event,msg): + msg_total = "" + SMS_lis={} + SMS_lis_count = 0 + sms_data = sms.getSaveLoc() + clog.info(sms_data) + if sms_data == -1: + return + sms_max = sms_data[0][2]#最大存储短信数量 + clog.info(sms_max) + self.msg_nums = sms.getMsgNums() + if self.msg_nums_old != self.msg_nums: + self.send_data = [] + self.msg_nums_old = self.msg_nums + if self.send_data == [] : + for i in range(self.msg_nums): + phonenum = "" + data ="" + time = "" + data_len = 0 + message=self.sms_get_message_info(self.msg_nums-i-1) + if message == -1: + break + data = message[5] + sms_data = [] + code = message[0]#编码 + num = message[1]#总共条数 + curren_num = message[2]#当前第几条 + data_len = message[4] + sms_data.append(code)#编码 编码相同是同一条短信的内容 + sms_data.append(num) + sms_data.append(curren_num) + sms_data.append(data) + sms_data.append(data_len) + self.send_data.append(sms_data) + count = len(self.send_data) + for i in range(count): + text = self.send_data[i] + clog.info("text:{} {} {}\r\n".format(text[0],text[1],text[2])) + + msg_total = "@code:"+str(text[0])+"@totalcodenum:"+str(text[1])+"@currcodeid:"+str(text[2])+"@data:"+str(text[3]) + self.reply_cmd('17',msg_total) + + # 来电提醒 + def notifyIncomingcall(self, incomming_numb): + self.clear_remain() + __head = '0C' + __message = str(incomming_numb) + self.__Socket_UDP(__head, __message) + # if self.__err == 1 or self.__value[2] != 'OK': + # return -1 + return 0 + + # 电话接听消息 + def notifyConnecteCall(self, phone_numb): + self.clear_remain() + __head = '0A' + __message = str(phone_numb) + self.__Socket_UDP(__head, __message) + # if self.__err == 1 or self.__value[2] != 'OK': + # return -1 + return 0 + + # 电话拒接消息 + def notifyDisconnectCall(self, phone_numb): + self.clear_remain() + __head = '0B' + __message = str(phone_numb) + self.__Socket_UDP(__head, __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: + clog.info('Network connection successful.') + self.set_network_config() + self.__net_connected = 1 + eventMesh.publish("set_network_state",self.__net_connected) + self.__waiting_netstat = 0 + return 0 + else: + clog.info('Network connection failed, stage={}, state={}'.format(stage, state)) + self.reset_network_config() + self.__net_connected = 0 + eventMesh.publish("set_network_state",self.__net_connected) + + self.__waiting_netstat = 0 + return -1 + + # 查询网卡状态 + def timesync(self,_timesync): + self.clear_remain() + message = str(_timesync) + self.__Socket_UDP('0D', message) + return 0 + + def reply_timesync(self,_timesync): + self.clear_remain() + message = str(_timesync) + self.__Socket_UDP_noreply('0D', message) + return 0 + + def reply_cmd(self,cmd,_timesync): + try : + clog.info('reply_cmd 1') + self.clear_remain() + message = str(_timesync) + clog.info('reply_cmd 2') + self.__Socket_UDP_noreply(cmd, message) + except: + clog.info('reply_cmd') + 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): + clog.info("skip reset_network_config") + return 0 + Info = dataCall.getInfo(1,0) + clog.info("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) + clog.info("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) : + clog.info("skip set_network_config") + return 0 + Info = dataCall.getInfo(1,0) + clog.info("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) + clog.info("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() + if eventMesh.publish("get_dmp_change_mode") == 0:#入库功能关闭 + return + if 1: #CHINA_TELECOM_DM_FUN_ENABLE == 1:#电信入库功能 不使用设置 0 防止两边不同步修改 + if eventMesh.publish("get_dmp_change_mode") == 1: + eventMesh.publish("set_network_state",1) + telecomDmpCb.telecom_dmp_power_on_init() + if 1: #CHINA_MOBILE_DM_FUN_ENABLE == 1: + if eventMesh.publish("get_dmp_change_mode") == 2: + eventMesh.publish("set_network_state",1) + if self.china_mobile_init == 1: + return + self.china_mobile_init = 1 + #移动入库的初始化 + chinamobileCb.china_mobile_init() + if eventMesh.publish("get_dmp_change_mode") == 3: + if self.china_mobile_ai_init == 1: + return + self.china_mobile_ai_init = 1 + eventMesh.publish("set_network_state",1) + aiRegulation.AIRegulation_init() + + def cat1_reply_iccid_to_ble(self,event,msg): + ICCID_DATA = str("ICCID:")+str(msg) + self.reply_cmd('11',"{}".format(ICCID_DATA)) + pass + def cat1_reply_timesec_to_ble(self,event,msg): + + self.reply_cmd('14',"REGIST_TIME:{}".format(msg)) + pass + # 释放slip网卡 + def stop(self): + slip.destroy() + return 0 + + def read_dev_ai_id(self): + + IFEXIST = ql_fs.path_exists("/usr/cm_ai_regulation.json") # + if IFEXIST == True: #文件存在 + fileSize = ql_fs.path_getsize('usr/cm_ai_regulation.json') + if fileSize == 0: + + print("设备信息配置文件不存在\r\n") + else: + try: + with open("/usr/cm_ai_regulation.json","r",encoding='utf-8') as fd: + try: + config_data = ujson.load(fd) #转换成json格式 + if len(config_data) != 0: + if "deviceId" in config_data:# + deviceId = str(config_data["deviceId"]) #设备ID + self.reply_cmd('1C',"{}".format(deviceId)) + except Exception as error: + print("配置文件的内容不是json格式 保存数据的时候格式不对\r\n") + except Exception as error: + print("打开配置文件失败\r\n") + + + + + # 封装tlv数据包 + def __pack_tlv_format(self, head, content): + # self.head = head + # self.content = content + if len(content) == 0 or len(content) > 9999 or len(head) != 2: + clog.error('illegal pack tlv content') + return -1 + len_str ='%04d' % len(content) + tlv_pack = CAT1_SERVICE_HEAD+head+len_str+content + return tlv_pack + # 解码tlv数据包 + def __unpack_tlv_format(self, msg): + clog.info('__unpack_tlv_format {}\r\n'.format(msg)) + self.msg = str(msg)[2:]#这是去除head FE + 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]: + clog.error('__unpack_tlv_format err') + return -1 + clog.info('__unpack_tlv_format: {} {} {}\r\n'.format(tag,length,value)) + unpack = (tag,length,value) + return unpack + # socket通信(UDP)模块 + def __Socket_UDP(self, head, content): + # 0 则 __Socket_UDP_write + self.send_data_q.put([head,content]) + def Socket_SEND_Thread(self): + while True: + try: + clog.info("send====") + data=self.send_data_q.get() + self.ack_sem=1 + # # if data[2]: + # self.__Socket_UDP_noreply_write( data[0], data[1]) + # else : + self.__Socket_UDP_write( data[0], data[1]) + + + clog.info("Socket_SEND_Thread data:{} {}".format(data[0],data[1])) + count=20 + + while count & self.ack_sem : + utime.sleep_ms(1) + count=count-1 + # if data[2]: + # self.__Socket_UDP_noreply_write( data[0], data[1]) + # else : + self.__Socket_UDP_write( data[0], data[1]) + + clog.info("Socket_SEND_Thread while data:{} {}".format(data[0],data[1])) + + if data: + clog.info("data ok!!") + else: + clog.error("data error!!") + except Exception : + clog.error("sned Socket >>>") + + def __Socket_UDP_write(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(head, content) + + # 向服务端发送消息 + server_addr = ('172.16.1.5',1000) + clog.info("__Socket_UDP send msg {}".format(msg)) + self.__err = 0 + self.__sock.sendto(msg,server_addr) + clog.info("__Socket_UDP send 2") + self.__wait_resp = 1 + # data = self.__queue.get() + self.__wait_resp = 0 + # return data + return 1 + except Exception as error: + clog.error(error) + return 0 + + def __Socket_UDP_noreply(self, head, content): + # 1 则 __Socket_UDP_noreply_write + self.send_data_q.put([head,content]) + + def __Socket_UDP_noreply_write(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(head, content) + + # 向服务端发送消息 + server_addr = ('172.16.1.5',1000) + + clog.info("__Socket_UDP_noreply send msg {}".format(msg)) + self.__err = 0 + data_size = self.__sock.sendto(msg,server_addr) + clog.info("self.__sock data_size {}".format(data_size)) + self.__wait_resp = 0 + return 0 + + # socket通信(UDP)模块 + def __Socket_Thread(self): + while True: + try: + clog.info("recv====") + data=self.__sock.recv(1024) + clog.info("data:{}".format(data)) + if data: + value = self.__unpack_tlv_format(data.decode()) + if value != -1: + clog.info('mode: {0}, recv {1} bytes, Data: {2}'.format (value[0],len(data), value[2])) + if value[1] == '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]) + clog.info("End else Thread") + else: + clog.error("data error!!") + except Exception as recverr: + clog.error("recverr:{}\r\n".format(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() + + + + clog.info("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卡状态 +# 下文进行系统配置 +clog.info("Cat1Service start") + +cat1service = Cat1Service() + +#send_data_q = Queue(100) + +#voice call callback function +def voice_callback(args): + if args[0] == 10: + if eventMesh.publish("get_volte_switch") == 0: #关闭VOLTE功能 + clog.info('voicecall auto end:') + voiceCall.callEnd() + else: + # gpioWakeBT.write(1) + cat1service.notifyIncomingcall(args[6]) + elif args[0] == 11: + if eventMesh.publish("get_volte_switch") == 1: #开启VOLTE功能 + clog.info('voicecall connected, PhoneNO: \n'.format(args[6])) + cat1service.notifyConnecteCall(args[6]) + elif args[0] == 12: + clog.info('voicecall disconnect') + if eventMesh.publish("get_volte_switch") == 1: #开启VOLTE功能 + clog.info('voicecall disconnected, PhoneNO: \n'.format(args[6])) + cat1service.notifyDisconnectCall(args[6]) + elif args[0] == 13: + clog.info('voicecall is waiting, PhoneNO: \n'.format(args[6])) + elif args[0] == 14: + clog.info('voicecall dialing, PhoneNO: \n'.format(args[6])) + elif args[0] == 15: + clog.info('voicecall alerting, PhoneNO: \n'.format(args[6])) + elif args[0] == 16: + clog.info('voicecall holding, PhoneNO: \n'.format(args[6])) + else: + clog.info('voice_callback , args[0]: \n'.format(args[6])) + +#电话消息反馈 +voiceCall.setCallback(voice_callback) + + +def checknet_cb(arg): + clog.info("start checktime!!") + # if 1: #CHINA_TELECOM_DM_FUN_ENABLE == 1:#这是手表每30s检查一次 + # if eventMesh.publish("get_dmp_change_mode") == 1: + # telecomDmpCb.telecom_dmp_power_on_count() + + _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)) +# _thread.start_new_thread(cat1service.wait_network_ready, ()) +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): +# clog.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) + + +#url = "http://zzhc.vnet.cn:9998/" + + diff --git a/code/sdk/build/config/target_config/brandy/config.py b/code/sdk/build/config/target_config/brandy/config.py index dff9169ae..0650693c6 100644 --- a/code/sdk/build/config/target_config/brandy/config.py +++ b/code/sdk/build/config/target_config/brandy/config.py @@ -463,6 +463,8 @@ target = { "zhihui_ai_old", #音频相关配置 "audio_manager", + #AI桩函数 + "ai_stub", "producttest", "ppg_hal", @@ -1229,9 +1231,6 @@ target = { 'BOARD_LEINIAO', # cat1 相关配置 'FT_SINGLE_UART', - # 'ENABLE_SLIP', - # 'SUPPORT_CAT1_SERVICE', - 'SUPPORT_TCPIP', 'CONFIG_EFUSE_READ_TO_RAM', 'CUSTOM_UTILS', @@ -1297,7 +1296,13 @@ target = { "thunderbird_toys",#雷鸟 "leiniaoMediaService", #cat1 相关配置 + #有方需要开启 PPP "ppp", + + #EG810 需要开启 cat1Service 和 cat1Test + # "cat1Service", + # "cat1Test", + #websocket 相关配置 "zhihui_websocket", #ai 相关配置 @@ -1305,6 +1310,8 @@ target = { "aiService", #ai_old相关配置 "zhihui_ai_old", + #ai_stub 专门解决ai_old和ai_service的依赖问题 + "ai_stub", #音频相关配置 "audio_manager", # "CustomUIcomponentTool", diff --git a/code/sdk/zhihui/4g/cat1Service/Service/cat1_ctl.c b/code/sdk/zhihui/4g/cat1Service/Service/cat1_ctl.c index d57dc28a8..d96883871 100644 --- a/code/sdk/zhihui/4g/cat1Service/Service/cat1_ctl.c +++ b/code/sdk/zhihui/4g/cat1Service/Service/cat1_ctl.c @@ -73,10 +73,10 @@ static ctl_pin_4g_t g_cat1_ctl_pins={ S_AGPIO_L23, // pwr_pin 1, S_AGPIO_L24,//reset_pin - 0, - PIN_NONE,//ring_pin - 0, - PIN_NONE,//wakemodem_pin + 1, //电路中 控制gpio拉高,reset才拉低 + S_MGPIO21,//ring_pin + 2, + S_MGPIO22,//wakemodem_pin 0, #else PIN_NONE, //bat_pin @@ -112,14 +112,14 @@ errcode_t cat1_register_ctl_pin(ctl_pin_4g_t ctl_pin) return ERRCODE_SUCC; } -uint32_t cat1_api_cat1_bat_on(uint32_t pwron) +uint32_t cat1_api_bat_pin(uint32_t pwron) { pin_t en_pin = g_cat1_ctl_pins.bat_pin; uint8_t en_value = g_cat1_ctl_pins.bat_pin_en_value; if (en_pin == PIN_NONE) { - printf("cat1_api_cat1_bat_on en_pin is none\r\n"); + printf("cat1_api_bat_pin en_pin is none\r\n"); return 0xff; } @@ -147,14 +147,14 @@ uint32_t cat1_api_cat1_bat_on(uint32_t pwron) } return 0; } -uint32_t cat1_api_cat1_pwrkey_on(uint32_t pwron) +uint32_t cat1_api_power_pin(uint32_t pwron) { pin_t en_pin = g_cat1_ctl_pins.pwr_pin; uint8_t en_value = g_cat1_ctl_pins.pwr_pin_en_value; if (en_pin == PIN_NONE) { - printf("cat1_api_cat1_pwrkey_on en_pin is none\r\n"); + printf("cat1_api_power_pin en_pin is none\r\n"); return 0xff; } if( pwron == 0) @@ -181,7 +181,7 @@ uint32_t cat1_api_cat1_pwrkey_on(uint32_t pwron) } return 0; } -uint32_t cat1_api_cat1_reset(uint32_t pwron) +uint32_t cat1_api_reset_pin(uint32_t pwron) { pin_t en_pin = g_cat1_ctl_pins.reset_pin; @@ -189,7 +189,7 @@ uint32_t cat1_api_cat1_reset(uint32_t pwron) if (en_pin == PIN_NONE) { - printf("cat1_api_cat1_reset en_pin is none\r\n"); + printf("cat1_api_reset_pin en_pin is none\r\n"); return 0xff; } @@ -235,10 +235,10 @@ bool cat1_api_is_cat1_enabled(void) } if ( en_value == uapi_gpio_get_output_val(en_pin)) { - printf("cat1_api_is_cat1_enabled en_value is %d\r\n",en_value); + // printf("cat1_api_is_cat1_enabled en_value is %d\r\n",en_value); return true; }else{ - printf("cat1_api_is_cat1_enabled en_value is %d\r\n",en_value); + // printf("cat1_api_is_cat1_enabled en_value is %d\r\n",en_value); return false; } } @@ -246,14 +246,20 @@ bool cat1_api_is_cat1_enabled(void) void cat1_api_power_on_cat1(void) { #if defined(BOARD_FD230) - cat1_api_cat1_pwrkey_on(1); - cat1_api_cat1_reset(0); - #elif (defined(BOARD_W9) || defined(BOARD_N9) || defined(BOARD_LEINIAO)) - cat1_api_cat1_reset(0); - cat1_api_cat1_pwrkey_on(1); - cat1_api_cat1_bat_on(1); + cat1_api_power_pin(1); + cat1_api_reset_pin(0); + #elif (defined(BOARD_W9) || defined(BOARD_N9) ) + cat1_api_reset_pin(0); + cat1_api_power_pin(1); + cat1_api_bat_pin(1); osDelay(900); - cat1_api_cat1_pwrkey_on(0); + cat1_api_power_pin(0); + #elif defined(BOARD_LEINIAO) + cat1_api_reset_pin(0); + cat1_api_power_pin(1); + cat1_api_bat_pin(1); + osDelay(900); + cat1_api_power_pin(0); #endif } @@ -261,12 +267,16 @@ void cat1_api_power_on_cat1(void) void cat1_api_power_off_cat1(void) { #if defined(BOARD_FD230) - cat1_api_cat1_reset(1); - cat1_api_cat1_pwrkey_on(0); - #elif (defined(BOARD_W9) || defined(BOARD_N9) || defined(BOARD_LEINIAO)) - cat1_api_cat1_bat_on(0); - cat1_api_cat1_reset(1); - cat1_api_cat1_pwrkey_on(1); + cat1_api_reset_pin(1); + cat1_api_power_pin(0); + #elif (defined(BOARD_W9) || defined(BOARD_N9) ) + cat1_api_bat_pin(0); + cat1_api_reset_pin(1); + cat1_api_power_pin(1); + #elif defined(BOARD_LEINIAO) + cat1_api_bat_pin(0); + cat1_api_reset_pin(1); + cat1_api_power_pin(1); #endif } diff --git a/code/sdk/zhihui/4g/cat1Service/include/cat1_ctl.h b/code/sdk/zhihui/4g/cat1Service/include/cat1_ctl.h index cb385087b..b79bbf80d 100644 --- a/code/sdk/zhihui/4g/cat1Service/include/cat1_ctl.h +++ b/code/sdk/zhihui/4g/cat1Service/include/cat1_ctl.h @@ -23,11 +23,11 @@ extern "C" { void cat1_api_uart_init(void); /**set powerpin 1/0*/ -uint32_t cat1_api_cat1_pwrkey_on(uint32_t pwron); +uint32_t cat1_api_power_pin(uint32_t pwron); /**set resetpin 0/1*/ -uint32_t cat1_api_cat1_reset(uint32_t pwron); +uint32_t cat1_api_reset_pin(uint32_t pwron); -uint32_t cat1_api_cat1_bat_on(uint32_t pwron); +uint32_t cat1_api_bat_pin(uint32_t pwron); /**set powerpin 1 ,set resetpin 0*/ void cat1_api_power_on_cat1(void); diff --git a/code/sdk/zhihui/CMakeLists.txt b/code/sdk/zhihui/CMakeLists.txt index ba5faf93b..39e2cc58c 100644 --- a/code/sdk/zhihui/CMakeLists.txt +++ b/code/sdk/zhihui/CMakeLists.txt @@ -21,6 +21,7 @@ endif() add_subdirectory_if_exist(4gTest) add_subdirectory_if_exist(ai) add_subdirectory_if_exist(ai_old) +add_subdirectory_if_exist(ai_stub) add_subdirectory_if_exist(ai/media) add_subdirectory_if_exist(websocket) add_subdirectory_if_exist(4gTestcpp) diff --git a/code/sdk/zhihui/ai_stub/CMakeLists.txt b/code/sdk/zhihui/ai_stub/CMakeLists.txt new file mode 100644 index 000000000..3cadb1dea --- /dev/null +++ b/code/sdk/zhihui/ai_stub/CMakeLists.txt @@ -0,0 +1,59 @@ +#=============================================================================== +# @brief AI Stub Functions CMakeLists +# Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. +#=============================================================================== + +# 设置模块名称 +set(COMPONENT_NAME "ai_stub") + +# 源文件列表 +set(SOURCES + src/ppp_stub_functions.c +) + +# 头文件目录 +set(PUBLIC_HEADER + ${CMAKE_CURRENT_SOURCE_DIR}/include +) + +set(PRIVATE_HEADER +) + +# 包含目录 +set(INCLUDE_DIRS + include +) + +# AI桩函数编译时配置 +set(PUBLIC_DEFINES + SUPPORT_AI_STUB +) + +set(PRIVATE_DEFINES +) + +# 编译选项 +set(COMPONENT_PUBLIC_CCFLAGS +) + +set(COMPONENT_CCFLAGS + -Wall + -Wextra + -Werror + -O2 + -ffunction-sections + -fdata-sections +) + +# 是否整体链接 +set(WHOLE_LINK + true +) + +# 是否为主组件 +set(MAIN_COMPONENT + false +) + +# 构建组件 +build_component() \ No newline at end of file diff --git a/code/sdk/zhihui/ppp/src/ppp_stub_functions.c b/code/sdk/zhihui/ai_stub/src/ppp_stub_functions.c similarity index 72% rename from code/sdk/zhihui/ppp/src/ppp_stub_functions.c rename to code/sdk/zhihui/ai_stub/src/ppp_stub_functions.c index 1f73edaac..cc4caa5be 100644 --- a/code/sdk/zhihui/ppp/src/ppp_stub_functions.c +++ b/code/sdk/zhihui/ai_stub/src/ppp_stub_functions.c @@ -9,6 +9,8 @@ #include #include +#ifndef SUPPORT_CAT1_SERVICE + /** * @brief HTTP客户端文件下载桩函数 * @param url 下载URL @@ -25,7 +27,7 @@ int httpc_get_file_dns_to_disk(const char *url, const char *file_path, int timeo // 桩函数 - 不实现实际功能 return -1; } - +#endif /** * @brief AI流式录音发送桩函数 * @param data 音频数据 @@ -47,12 +49,14 @@ int streamingRecordAndSend_AI(void *data, int len, const char *session_id) * @brief AI消息队列发送桩函数 * @param msg_data 消息数据 * @param data_len 数据长度 + * @param type 消息类型 * @return 总是返回失败(-1) */ -int send_msg_data_into_Ai_msg_queue(void *msg_data, int data_len) +int send_msg_data_into_Ai_msg_queue(void *msg_data, uint16_t data_len, uint16_t type) { (void)msg_data; (void)data_len; + (void)type; // 桩函数 - 不实现实际功能 return -1; @@ -61,29 +65,41 @@ int send_msg_data_into_Ai_msg_queue(void *msg_data, int data_len) /** * @brief 蓝牙设置AI回答字符串桩函数 * @param answer_str AI回答字符串 - * @return 总是返回失败(-1) + * @param type 消息类型 */ -int ble_set_ai_Answer_str(const char *answer_str) +void ble_set_ai_Answer_str(char *answer_str, uint8_t type) { (void)answer_str; + (void)type; // 桩函数 - 不实现实际功能 - return -1; } /** * @brief 蓝牙设置AI问题字符串桩函数 * @param question_str AI问题字符串 - * @return 总是返回失败(-1) */ -int ble_set_ai_Question_str(const char *question_str) +void ble_set_ai_Question_str(char *question_str) { (void)question_str; // 桩函数 - 不实现实际功能 - return -1; } +#ifdef SUPPORT_CAT1_SERVICE + +/** + * @brief PPP环境初始化桩函数 + * @return 总是返回成功(0) + */ +int ppp_env_init(void) +{ + // 桩函数 - 简单返回成功 + // 注意:实际的ppp_env_init实现在ppp_example.c中 + // 如果需要完整功能,请确保ppp_example.c被正确编译和链接 + return 0; +} +#endif /* * 注意:这些桩函数仅用于解决链接问题,不提供实际功能 * 如果需要使用相关功能,请实现对应的真实函数 diff --git a/code/sdk/zhihui/ppp/CMakeLists.txt b/code/sdk/zhihui/ppp/CMakeLists.txt index 4e83333a7..48f198def 100644 --- a/code/sdk/zhihui/ppp/CMakeLists.txt +++ b/code/sdk/zhihui/ppp/CMakeLists.txt @@ -23,7 +23,6 @@ set(SOURCES src/ppp_debug_manager.c src/ppp_power_ctl.c src/ppp_cat1_api.c - src/ppp_stub_functions.c ${PPP_AT_CMD_SOURCE} ) diff --git a/code/sdk/zhihui/ppp/include/ppp_performance_config.h b/code/sdk/zhihui/ppp/include/ppp_performance_config.h new file mode 100644 index 000000000..1a52d2320 --- /dev/null +++ b/code/sdk/zhihui/ppp/include/ppp_performance_config.h @@ -0,0 +1,176 @@ +/** + * @file ppp_performance_config.h + * @brief PPP性能优化配置 + * + * 本文件包含针对PPP协商性能问题的优化配置参数 + * 主要解决LCP协商缓慢、Magic Number冲突、超时参数不当等问题 + * + * 注意:当前这些宏定义主要用作参考和文档说明 + * 实际的优化参数已直接在相关源文件中定义和使用: + * - ppp_lwip.c: PPP协商超时参数和Magic Number生成 + * - ppp_serial.c: UART通信超时参数 + */ + +#ifndef PPP_PERFORMANCE_CONFIG_H +#define PPP_PERFORMANCE_CONFIG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ================================ PPP协商超时优化 ================================ */ + +/** + * @brief PPP FSM超时时间优化 (秒) + * 默认值: 6秒 -> 优化值: 3秒 + * 说明: 减少LCP/IPCP协商的单次超时时间,提高协商响应速度 + */ +#define PPP_OPTIMIZED_FSM_TIMEOUT 3 + +/** + * @brief PPP最大Configure-Request重传次数优化 + * 默认值: 10次 -> 优化值: 6次 + * 说明: 减少不必要的重传,避免过长的协商时间 + */ +#define PPP_OPTIMIZED_MAX_CONF_REQ 6 + +/** + * @brief PPP最大NAK循环次数优化 + * 默认值: 5次 -> 优化值: 3次 + * 说明: 减少NAK循环,加快协商收敛 + */ +#define PPP_OPTIMIZED_MAX_NAK_LOOPS 3 + +/** + * @brief PPP Terminate-Request重传次数 + * 默认值: 2次 -> 保持: 2次 + * 说明: 连接终止重传次数保持不变 + */ +#define PPP_OPTIMIZED_MAX_TERM_REQ 2 + +/* ================================ UART通信优化 ================================ */ + +/** + * @brief UART写操作超时优化 (毫秒) + * 默认值: 1000ms -> 优化值: 200ms + * 说明: 减少UART写操作超时,提高PPP帧传输效率 + */ +#define PPP_OPTIMIZED_UART_WRITE_TIMEOUT 200 + +/** + * @brief UART读操作超时优化 (毫秒) + * 默认值: 200ms -> 优化值: 100ms + * 说明: 减少PPP数据模式下的读取超时,提高协商响应速度 + */ +#define PPP_OPTIMIZED_UART_READ_TIMEOUT 100 + +/* ================================ Magic Number优化 ================================ */ + +/** + * @brief Magic Number基础种子值 + * 说明: 用于生成唯一Magic Number的基础种子 + */ +#define PPP_MAGIC_NUMBER_SEED 0x12345678 + +/** + * @brief Magic Number异或掩码 + * 说明: 增加Magic Number随机性的固定异或值 + */ +#define PPP_MAGIC_NUMBER_XOR_MASK 0xDEADBEEF + +/** + * @brief Magic Number备用值 + * 说明: 当生成的Magic Number为0时使用的备用值 + */ +#define PPP_MAGIC_NUMBER_FALLBACK 0xCAFEBABE + +/* ================================ 性能监控配置 ================================ */ + +/** + * @brief PPP阶段切换超时阈值 (毫秒) + * 说明: 超过此时间的阶段切换将被标记为性能问题 + */ +#define PPP_PHASE_TIMEOUT_THRESHOLD 5000 + +/** + * @brief PPP协商总超时阈值 (毫秒) + * 说明: PPP完整协商过程的最大允许时间 + */ +#define PPP_NEGOTIATION_TOTAL_TIMEOUT 30000 + +/* ================================ 调试配置 ================================ */ + +/** + * @brief 启用PPP性能监控 + * 说明: 启用后会监控PPP阶段切换时间和性能指标 + */ +#define PPP_ENABLE_PERFORMANCE_MONITORING 1 + +/** + * @brief 启用Magic Number增强随机性 + * 说明: 启用后使用多重随机源生成Magic Number + */ +#define PPP_ENABLE_ENHANCED_MAGIC_NUMBER 1 + +/* ================================ 性能优化函数声明 ================================ */ + +/** + * @brief 应用PPP性能优化配置 + * @param ppp_pcb PPP控制块指针 + * @return 0成功,非0失败 + */ +int ppp_apply_performance_config(void *ppp_pcb); + +/** + * @brief 生成优化的Magic Number + * @param base_counter 基础计数器值 + * @param pcb_addr PCB地址用于增加随机性 + * @return 生成的Magic Number + */ +uint32_t ppp_generate_optimized_magic_number(uint32_t base_counter, void *pcb_addr); + +/** + * @brief 检查PPP性能指标 + * @param phase_duration 阶段持续时间(毫秒) + * @param phase_id 阶段ID + * @return 1表示性能正常,0表示性能异常 + */ +int ppp_check_performance_metrics(uint32_t phase_duration, int phase_id); + +/* ================================ 性能优化建议 ================================ */ + +/* + * PPP协商性能优化建议: + * + * 1. Magic Number冲突解决: + * - 使用多重随机源(时间戳、PCB地址、栈地址) + * - 避免Magic Number为0 + * - 增加位旋转和异或操作 + * + * 2. 超时参数优化: + * - FSM超时从6秒减少到3秒 + * - 最大重传次数从10减少到6 + * - NAK循环从5减少到3 + * + * 3. UART通信优化: + * - 写超时从1000ms减少到200ms + * - 读超时从200ms减少到100ms + * + * 4. 性能监控: + * - 监控阶段切换时间 + * - 检测异常缓慢的协商过程 + * - 提供性能诊断信息 + * + * 5. 预期效果: + * - LCP协商时间从30秒减少到5-10秒 + * - 减少Magic Number冲突导致的重协商 + * - 提高整体PPP连接建立速度 + */ + +#ifdef __cplusplus +} +#endif + +#endif /* PPP_PERFORMANCE_CONFIG_H */ \ No newline at end of file diff --git a/code/sdk/zhihui/ppp/src/ppp_api.c b/code/sdk/zhihui/ppp/src/ppp_api.c index a4130d230..5c2335ff5 100644 --- a/code/sdk/zhihui/ppp/src/ppp_api.c +++ b/code/sdk/zhihui/ppp/src/ppp_api.c @@ -58,7 +58,8 @@ errcode_t ppp_api_power_init(void) .pwr_pin_en_value = 1, .reset_pin = S_AGPIO_L24, .reset_pin_en_value = 1, //电路中 控制gpio拉高,reset才拉低 - .ring_pin = S_MGPIO21, //CTS cat1 wakeup mcu + .ring_pin = PIN_NONE, //CTS cat1 wakeup mcu modem还没实现,暂时不使用 + // .ring_pin = S_MGPIO21, //CTS cat1 wakeup mcu .ring_pin_en_value = 2, //2 双边沿中断 , 1 上升沿中断 , 0 下降沿中断 .wakemodem_pin = S_MGPIO22, //RTS mcu wakeup cat1 .wakemodem_pin_en_value = 0 //0 唤醒cat1 , 1 休眠cat1 @@ -139,10 +140,8 @@ errcode_t zhihui_ppp_init(const ppp_config_t *config) ppp_api_power_init(); ppp_api_power_control(true); - - // 额外等待时间,让调制解调器完全稳定(特别是在硬件复位后) - PPP_DEBUG_PRINT("Waiting for modem stabilization after power control...\n"); - osal_msleep(5000); // 等待5秒让调制解调器完全稳定 +#define PPP_SERIAL_INIT 1 //外接串口调试模组时,串口要设置input防止干扰。 +#if PPP_SERIAL_INIT // 3. UART初始化 PPP_DEBUG_PRINT("Step 3: Initializing UART for AT mode\n"); @@ -157,7 +156,6 @@ errcode_t zhihui_ppp_init(const ppp_config_t *config) .rx_callback = NULL, .rx_callback_arg = NULL }; - ppp_error_t ret = ppp_serial_init(&serial_config); if (ret != PPP_ERR_OK) { PPP_DEBUG_PRINT("Failed to initialize serial for AT mode: %d\n", ret); @@ -207,15 +205,21 @@ errcode_t zhihui_ppp_init(const ppp_config_t *config) } else { PPP_DEBUG_PRINT("AT communication test succeeded\n"); } - +#else + ppp_api_leiniao_serial_pin_to_gpio_input(); +#endif + PPP_DEBUG_PRINT("Waiting for modem stabilization after power control...\n"); + // 额外等待时间,让调制解调器完全稳定(特别是在硬件复位后) + osal_msleep(5000); // 等待5秒让调制解调器完全稳定 g_ppp_state = PPP_STATE_INITIALIZED; PPP_DEBUG_PRINT("PPP module initialized successfully\n"); return ERRCODE_SUCC; - +#if PPP_SERIAL_INIT init_failed: +#endif // 初始化失败,关闭4G电源 // ppp_api_power_control(false); return ERRCODE_FAIL; diff --git a/code/sdk/zhihui/ppp/src/ppp_lwip.c b/code/sdk/zhihui/ppp/src/ppp_lwip.c index c474d2aef..6f5b61e4b 100644 --- a/code/sdk/zhihui/ppp/src/ppp_lwip.c +++ b/code/sdk/zhihui/ppp/src/ppp_lwip.c @@ -6,6 +6,7 @@ #include "ppp_power_ctl.h" // 添加电源控制头文件 #include "securec.h" #include "osal_addr.h" // 添加OSAL内存管理头文件 +#include "osal_timer.h" // 添加OSAL时间函数头文件 #include /* lwIP相关头文件 - 需要在编译时确保PPP支持已启用 */ @@ -41,6 +42,13 @@ typedef struct { static ppp_lwip_context_t g_lwip_ctx = {0}; /* 内部函数声明 */ +static uint32_t ppp_lwip_get_time_ms(void); +static uint32_t ppp_lwip_get_time_ms(void) +{ + osal_timeval tv = {0}; + osal_gettimeofday(&tv); + return (uint32_t)(tv.tv_sec * 1000 + tv.tv_usec / 1000); +} #ifdef LWIP_PPP_SUPPORT static void ppp_lwip_status_callback(ppp_pcb *pcb, int err_code, void *ctx); static void ppp_lwip_link_status_callback(ppp_pcb *pcb, int err_code, void *ctx); @@ -130,6 +138,19 @@ ppp_error_t ppp_lwip_init(const ppp_lwip_config_t *config) PPP_DEBUG_DEBUG("IPCP configuration completed with standard options"); + /* 优化PPP协商超时参数 - 运行时覆盖编译时默认值以获得更好性能 */ + g_lwip_ctx.ppp_pcb->settings.fsm_timeout_time = 3; /* 减少FSM超时从6秒到3秒 */ + g_lwip_ctx.ppp_pcb->settings.fsm_max_conf_req_transmits = 6; /* 减少最大重传次数从10到6 */ + g_lwip_ctx.ppp_pcb->settings.fsm_max_term_transmits = 2; /* 保持terminate重传为2 */ + g_lwip_ctx.ppp_pcb->settings.fsm_max_nak_loops = 3; /* 减少NAK循环从5到3 */ + + /* 优化LCP相关参数以提高连接稳定性 */ + g_lwip_ctx.ppp_pcb->settings.lcp_loopbackfail = 5; /* 减少loopback检测次数从10到5 */ + g_lwip_ctx.ppp_pcb->settings.lcp_echo_interval = 0; /* 禁用LCP echo请求以减少开销 */ + g_lwip_ctx.ppp_pcb->settings.lcp_echo_fails = 3; /* 保持echo失败容忍度为3 */ + + PPP_DEBUG_INFO("PPP parameters optimized: FSM(timeout=3s, max_conf_req=6, max_nak_loops=3), LCP(loopback_fail=5, echo_interval=0)"); + /* 设置状态回调 */ ppp_set_notify_phase_callback(g_lwip_ctx.ppp_pcb, ppp_lwip_status_callback); @@ -140,14 +161,30 @@ ppp_error_t ppp_lwip_init(const ppp_lwip_config_t *config) PPP_DEBUG_DEBUG("Using standard PPP/LCP configuration..."); /* 配置LCP Magic Number以避免loopback检测问题 */ - /* 使用简单的随机数生成唯一的Magic Number */ - static uint32_t magic_counter = 0x12345678; + /* 使用增强的随机数生成算法确保唯一性 */ + #define PPP_MAGIC_NUMBER_SEED 0x12345678 + #define PPP_MAGIC_NUMBER_XOR_MASK 0xDEADBEEF + #define PPP_MAGIC_NUMBER_FALLBACK 0xCAFEBABE + + static uint32_t magic_counter = PPP_MAGIC_NUMBER_SEED; uint32_t magic_number = magic_counter++; - magic_number ^= (uint32_t)g_lwip_ctx.ppp_pcb; /* 使用PCB地址增加随机性 */ + + /* 增加多重随机性源 */ + magic_number ^= (uint32_t)g_lwip_ctx.ppp_pcb; /* PCB地址 */ + magic_number ^= (uint32_t)ppp_lwip_get_time_ms(); /* 当前时间戳 */ + magic_number ^= (uint32_t)&magic_number; /* 栈地址 */ + magic_number = (magic_number << 16) | (magic_number >> 16); /* 位旋转 */ + magic_number ^= PPP_MAGIC_NUMBER_XOR_MASK; /* 使用配置的异或掩码 */ + + /* 确保Magic Number不为0(避免协商问题) */ + if (magic_number == 0) { + magic_number = PPP_MAGIC_NUMBER_FALLBACK; /* 使用配置的备用值 */ + } + g_lwip_ctx.ppp_pcb->lcp_wantoptions.neg_magicnumber = 1; g_lwip_ctx.ppp_pcb->lcp_wantoptions.magicnumber = magic_number; g_lwip_ctx.ppp_pcb->lcp_allowoptions.neg_magicnumber = 1; - PPP_DEBUG_DEBUG("LCP Magic Number configured: 0x%08X", magic_number); + PPP_DEBUG_INFO("LCP Magic Number configured: 0x%08X (enhanced randomness)", magic_number); /* 使用标准PPP/LCP配置 */ PPP_DEBUG_DEBUG("Using standard PPP/LCP configuration..."); @@ -399,6 +436,9 @@ static void ppp_lwip_status_callback(ppp_pcb *pcb, int err_code, void *ctx) { (void)pcb; (void)ctx; + + static int last_phase = -1; + static uint32_t phase_start_time = 0; PPP_DEBUG_DEBUG("PPP status callback: err_code=%d", err_code); @@ -420,6 +460,27 @@ static void ppp_lwip_status_callback(ppp_pcb *pcb, int err_code, void *ctx) case PPP_PHASE_DISCONNECT: phase_str = "DISCONNECT"; break; default: phase_str = "OTHER"; break; } + + /* 监控阶段切换时间以诊断性能问题 */ + uint32_t current_time = ppp_lwip_get_time_ms(); + if (last_phase != err_code) { + if (last_phase != -1) { + uint32_t phase_duration = current_time - phase_start_time; + PPP_DEBUG_INFO("PPP Phase transition: %d -> %s (%d) [duration: %ums]", + last_phase, phase_str, err_code, phase_duration); + + /* 检测异常缓慢的阶段 */ + if (phase_duration > 5000) { /* 超过5秒 */ + PPP_DEBUG_WARN("PPP Phase %d took too long: %ums (potential performance issue)", + last_phase, phase_duration); + } + } else { + PPP_DEBUG_INFO("PPP Phase: %s (%d) [initial]", phase_str, err_code); + } + last_phase = err_code; + phase_start_time = current_time; + } + PPP_DEBUG_DEBUG("PPP Phase: %s (%d)", phase_str, err_code); ppp_lwip_event_t event; diff --git a/code/sdk/zhihui/ppp/src/ppp_power_ctl.c b/code/sdk/zhihui/ppp/src/ppp_power_ctl.c index d332c6b52..b1f2538ff 100644 --- a/code/sdk/zhihui/ppp/src/ppp_power_ctl.c +++ b/code/sdk/zhihui/ppp/src/ppp_power_ctl.c @@ -117,18 +117,29 @@ void ppp_api_gpio_init(void) { case 0: uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_FALLING_EDGE, ppp_ring_isr_callback); + PPP_DEBUG_PRINT("PPP: Register ring pin %d falling edge interrupt\n", gpiopin); break; case 1: uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_RISING_EDGE, ppp_ring_isr_callback); + PPP_DEBUG_PRINT("PPP: Register ring pin %d rising edge interrupt\n", gpiopin); break; case 2: default: uapi_gpio_register_isr_func(gpiopin, GPIO_INTERRUPT_DEDGE, ppp_ring_isr_callback); + PPP_DEBUG_PRINT("PPP: Register ring pin %d both edge interrupt\n", gpiopin); break; } } } +void ppp_api_leiniao_serial_pin_to_gpio_input(void) +{ + uapi_pin_set_mode(SIO_UART_TX_PIN, (pin_mode_t)HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(SIO_UART_TX_PIN, GPIO_DIRECTION_INPUT); + uapi_pin_set_mode(SIO_UART_RX_PIN, (pin_mode_t)HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(SIO_UART_RX_PIN, GPIO_DIRECTION_INPUT); + PPP_DEBUG_PRINT("PPP: Leiniao serial pin to gpio input\n"); +} /** * @brief PPP模块设置电源引脚状态 diff --git a/code/sdk/zhihui/ppp/src/ppp_serial.c b/code/sdk/zhihui/ppp/src/ppp_serial.c index d45a76542..61123c92d 100644 --- a/code/sdk/zhihui/ppp/src/ppp_serial.c +++ b/code/sdk/zhihui/ppp/src/ppp_serial.c @@ -12,6 +12,10 @@ #include #include "arch_port.h" +/* PPP性能优化配置 */ +#define PPP_OPTIMIZED_UART_WRITE_TIMEOUT 200 /* UART写超时优化: 1000ms -> 200ms */ +#define PPP_OPTIMIZED_UART_READ_TIMEOUT 100 /* UART读超时优化: 200ms -> 100ms */ + /* 串口上下文结构 - 优化缓存机制 */ typedef struct { bool initialized; @@ -289,7 +293,7 @@ ppp_error_t ppp_serial_switch_to_ppp_mode(void) g_serial_ctx.current_mode = PPP_SERIAL_MODE_PPP_DATA; PPP_DEBUG_CRITICAL("Serial mode switched to PPP_DATA (%d)", g_serial_ctx.current_mode); - PPP_DEBUG_CRITICAL("PPP data mode active - UART will use direct read with 200ms timeout (balanced)"); + PPP_DEBUG_CRITICAL("PPP data mode active - UART will use direct read with %dms timeout (optimized for fast negotiation)", PPP_OPTIMIZED_UART_READ_TIMEOUT); PPP_DEBUG_INFO("=== PPP Data Mode Switch Complete ==="); return PPP_ERR_OK; } @@ -404,10 +408,11 @@ ppp_error_t ppp_serial_write(const uint8_t *data, uint32_t length) // } // PPP_DEBUG_PRINT("\n"); - PPP_DEBUG_INFO("Calling uapi_uart_write(bus=%u, data=%p, len=%u, timeout=1000)...", - g_serial_ctx.uart_bus, data, length); + PPP_DEBUG_DEBUG("Calling uapi_uart_write(bus=%u, data=%p, len=%u, timeout=%d)...", + g_serial_ctx.uart_bus, data, length, PPP_OPTIMIZED_UART_WRITE_TIMEOUT); - write_result = uapi_uart_write(g_serial_ctx.uart_bus, data, length, 1000); + /* 优化UART写超时:使用配置的优化值以提高PPP协商速度 */ + write_result = uapi_uart_write(g_serial_ctx.uart_bus, data, length, PPP_OPTIMIZED_UART_WRITE_TIMEOUT); PPP_DEBUG_INFO("uapi_uart_write returned: %d (expected: %u)", write_result, length); if (write_result != (int32_t)length) { @@ -473,7 +478,8 @@ ppp_error_t ppp_serial_read(uint8_t *buffer, uint32_t buffer_size, uint32_t *byt { /* 使用适中的超时时间来平衡响应性和帧完整性 */ // PPP_DEBUG_DEBUG("PPP mode: Attempting UART read (timeout: 200ms)"); - int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, 200); + /* 优化PPP数据模式读取超时:使用配置的优化值以提高协商响应速度 */ + int32_t read_result = uapi_uart_read(g_serial_ctx.uart_bus, buffer, buffer_size, PPP_OPTIMIZED_UART_READ_TIMEOUT); if (read_result > 0) { *bytes_read = (uint32_t)read_result; g_serial_ctx.rx_bytes += *bytes_read; diff --git a/code/sdk/zhihui/utils/custom_utils.c b/code/sdk/zhihui/utils/custom_utils.c index 60581755b..f19980695 100644 --- a/code/sdk/zhihui/utils/custom_utils.c +++ b/code/sdk/zhihui/utils/custom_utils.c @@ -702,10 +702,7 @@ void startup_post_init_task(void) -#ifdef BOARD_LEINIAO - extern int ppp_env_init(void); - ppp_env_init(); -#else +#ifdef SUPPORT_CAT1_SERVICE if ( cm_poweron_cat1_on_bootup_flag() ) { PRINT("PowerOn Cat1 !\r\n"); @@ -714,6 +711,13 @@ if ( cm_poweron_cat1_on_bootup_flag() ) PRINT("PowerOff Cat1 !\r\n"); uapi_set4GCapability(false); } +#else + +#ifdef BOARD_LEINIAO + extern int ppp_env_init(void); + ppp_env_init(); +#endif + #endif #ifdef A5133_DEMO_SERVER