From 1dce308893489696e28b109e8ae932ce72ebc87a Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Sun, 17 Mar 2024 14:26:15 +0800 Subject: [PATCH] quectel-cm: update to version 1.6.5 --- package/wwan/app/quectel_cm_5G/Makefile | 2 +- .../wwan/app/quectel_cm_5G/src/GobiNetCM.c | 2 +- package/wwan/app/quectel_cm_5G/src/Makefile | 3 +- .../quectel_cm_5G/src/{MPQCTL.h => QCQCTL.h} | 26 +- .../quectel_cm_5G/src/{MPQMI.h => QCQMI.h} | 27 +-- .../quectel_cm_5G/src/{MPQMUX.c => QCQMUX.c} | 2 +- .../quectel_cm_5G/src/{MPQMUX.h => QCQMUX.h} | 69 ++++-- .../wwan/app/quectel_cm_5G/src/QMIThread.c | 80 +++++-- .../wwan/app/quectel_cm_5G/src/QMIThread.h | 11 +- .../wwan/app/quectel_cm_5G/src/QmiWwanCM.c | 6 +- .../app/quectel_cm_5G/src/ReleaseNote.txt | 14 ++ package/wwan/app/quectel_cm_5G/src/atc.c | 3 +- package/wwan/app/quectel_cm_5G/src/device.c | 2 +- package/wwan/app/quectel_cm_5G/src/main.c | 30 ++- package/wwan/app/quectel_cm_5G/src/mbim-cm.c | 2 +- .../app/quectel_cm_5G/src/qmap_bridge_mode.c | 2 +- package/wwan/app/quectel_cm_5G/src/qrtr.c | 2 +- .../app/quectel_cm_5G/src/quectel-atc-proxy.c | 2 +- .../app/quectel_cm_5G/src/quectel-qmi-proxy.c | 226 +++++++++--------- .../quectel_cm_5G/src/quectel-qrtr-proxy.c | 8 +- package/wwan/app/quectel_cm_5G/src/udhcpc.c | 58 +++-- .../app/quectel_cm_5G/src/udhcpc_script.c | 2 +- package/wwan/app/quectel_cm_5G/src/util.c | 2 +- 23 files changed, 360 insertions(+), 221 deletions(-) rename package/wwan/app/quectel_cm_5G/src/{MPQCTL.h => QCQCTL.h} (93%) rename package/wwan/app/quectel_cm_5G/src/{MPQMI.h => QCQMI.h} (89%) rename package/wwan/app/quectel_cm_5G/src/{MPQMUX.c => QCQMUX.c} (99%) rename package/wwan/app/quectel_cm_5G/src/{MPQMUX.h => QCQMUX.h} (95%) diff --git a/package/wwan/app/quectel_cm_5G/Makefile b/package/wwan/app/quectel_cm_5G/Makefile index 5eff117ab..85507e686 100644 --- a/package/wwan/app/quectel_cm_5G/Makefile +++ b/package/wwan/app/quectel_cm_5G/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:= quectel-CM-5G -PKG_VERSION:=1.6.4 +PKG_VERSION:=1.6.5 PKG_RELEASE:=1 include $(INCLUDE_DIR)/package.mk diff --git a/package/wwan/app/quectel_cm_5G/src/GobiNetCM.c b/package/wwan/app/quectel_cm_5G/src/GobiNetCM.c index 253a4f1d1..e9c4c81bc 100644 --- a/package/wwan/app/quectel_cm_5G/src/GobiNetCM.c +++ b/package/wwan/app/quectel_cm_5G/src/GobiNetCM.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ diff --git a/package/wwan/app/quectel_cm_5G/src/Makefile b/package/wwan/app/quectel_cm_5G/src/Makefile index 9c48439bf..5219a2166 100644 --- a/package/wwan/app/quectel_cm_5G/src/Makefile +++ b/package/wwan/app/quectel_cm_5G/src/Makefile @@ -9,7 +9,7 @@ CC:=$(CROSS-COMPILE)gcc endif LD:=$(CROSS-COMPILE)ld -QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c MPQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c +QL_CM_SRC=QmiWwanCM.c GobiNetCM.c main.c QCQMUX.c QMIThread.c util.c qmap_bridge_mode.c mbim-cm.c device.c QL_CM_SRC+=atc.c atchannel.c at_tok.c #QL_CM_SRC+=qrtr.c rmnetctl.c ifeq (1,1) @@ -21,6 +21,7 @@ QL_CM_DHCP=udhcpc_netlink.c QL_CM_DHCP+=${LIBMNL} endif +CFLAGS += -Wall -Wextra -Werror -O1 #-s LDFLAGS += -lpthread -ldl -lrt release: clean qmi-proxy mbim-proxy atc-proxy #qrtr-proxy diff --git a/package/wwan/app/quectel_cm_5G/src/MPQCTL.h b/package/wwan/app/quectel_cm_5G/src/QCQCTL.h similarity index 93% rename from package/wwan/app/quectel_cm_5G/src/MPQCTL.h rename to package/wwan/app/quectel_cm_5G/src/QCQCTL.h index c2faa3c46..eaf2ad6f6 100644 --- a/package/wwan/app/quectel_cm_5G/src/MPQCTL.h +++ b/package/wwan/app/quectel_cm_5G/src/QCQCTL.h @@ -1,19 +1,23 @@ -/*=========================================================================== +/****************************************************************************** + @file QCQCTL.h - M P Q C T L. H -DESCRIPTION: + DESCRIPTION + This module contains QMI QCTL module. - This module contains QMI QCTL module. + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. -INITIALIZATION AND SEQUENCING REQUIREMENTS: + --------------------------------------------------------------------------- + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Quectel Wireless Solution Proprietary and Confidential. + --------------------------------------------------------------------------- +******************************************************************************/ -Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved. -===========================================================================*/ -#ifndef MPQCTL_H -#define MPQCTL_H +#ifndef QCQCTL_H +#define QCQCTL_H -#include "MPQMI.h" +#include "QCQMI.h" #pragma pack(push, 1) @@ -387,4 +391,4 @@ typedef struct _QMICTL_MSG } __attribute__ ((packed)) QMICTL_MSG, *PQMICTL_MSG; #pragma pack(pop) -#endif // MPQCTL_H +#endif //QCQCTL_H \ No newline at end of file diff --git a/package/wwan/app/quectel_cm_5G/src/MPQMI.h b/package/wwan/app/quectel_cm_5G/src/QCQMI.h similarity index 89% rename from package/wwan/app/quectel_cm_5G/src/MPQMI.h rename to package/wwan/app/quectel_cm_5G/src/QCQMI.h index f5af61274..2b2a26042 100644 --- a/package/wwan/app/quectel_cm_5G/src/MPQMI.h +++ b/package/wwan/app/quectel_cm_5G/src/QCQMI.h @@ -1,23 +1,18 @@ -/*=========================================================================== +/****************************************************************************** + @file QCQMI.h - M P Q M I. H -DESCRIPTION: + DESCRIPTION + This module contains QMI module. - This module contains forward references to the QMI module. + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. -INITIALIZATION AND SEQUENCING REQUIREMENTS: + --------------------------------------------------------------------------- + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Quectel Wireless Solution Proprietary and Confidential. + --------------------------------------------------------------------------- +******************************************************************************/ -Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved. -===========================================================================*/ -/*=========================================================================== - - EDIT HISTORY FOR FILE - $Header: //depot/QMI/win/qcdrivers/ndis/MPQMI.h#3 $ - -when who what, where, why --------- --- ---------------------------------------------------------- -11/20/04 hg Initial version. -===========================================================================*/ #ifndef USBQMI_H #define USBQMI_H diff --git a/package/wwan/app/quectel_cm_5G/src/MPQMUX.c b/package/wwan/app/quectel_cm_5G/src/QCQMUX.c similarity index 99% rename from package/wwan/app/quectel_cm_5G/src/MPQMUX.c rename to package/wwan/app/quectel_cm_5G/src/QCQMUX.c index 7c8dfb38e..97f2d1ae4 100644 --- a/package/wwan/app/quectel_cm_5G/src/MPQMUX.c +++ b/package/wwan/app/quectel_cm_5G/src/QCQMUX.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ diff --git a/package/wwan/app/quectel_cm_5G/src/MPQMUX.h b/package/wwan/app/quectel_cm_5G/src/QCQMUX.h similarity index 95% rename from package/wwan/app/quectel_cm_5G/src/MPQMUX.h rename to package/wwan/app/quectel_cm_5G/src/QCQMUX.h index 32dd644f5..b1feb1d3f 100644 --- a/package/wwan/app/quectel_cm_5G/src/MPQMUX.h +++ b/package/wwan/app/quectel_cm_5G/src/QCQMUX.h @@ -1,19 +1,23 @@ -/*=========================================================================== +/****************************************************************************** + @file QCQMUX.h - M P Q M U X. H -DESCRIPTION: + DESCRIPTION + This module contains QMI QMUX module. - This file provides support for QMUX. + INITIALIZATION AND SEQUENCING REQUIREMENTS + None. -INITIALIZATION AND SEQUENCING REQUIREMENTS: + --------------------------------------------------------------------------- + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Quectel Wireless Solution Proprietary and Confidential. + --------------------------------------------------------------------------- +******************************************************************************/ -Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved. -===========================================================================*/ -#ifndef MPQMUX_H -#define MPQMUX_H +#ifndef QCQMUX_H +#define QCQMUX_H -#include "MPQMI.h" +#include "QCQMI.h" #pragma pack(push, 1) @@ -31,12 +35,14 @@ Copyright (C) 2011 by Qualcomm Technologies, Incorporated. All Rights Reserved. #define QMIWDS_GET_CURRENT_CHANNEL_RATE_RESP 0x0023 #define QMIWDS_GET_PKT_STATISTICS_REQ 0x0024 #define QMIWDS_GET_PKT_STATISTICS_RESP 0x0024 -#define QMIWDS_CREATE_PROFILE_REQ 0x0027 -#define QMIWDS_CREATE_PROFILE_RESP 0x0027 +#define QMIWDS_CREATE_PROFILE_REQ 0x0027 +#define QMIWDS_CREATE_PROFILE_RESP 0x0027 #define QMIWDS_MODIFY_PROFILE_SETTINGS_REQ 0x0028 #define QMIWDS_MODIFY_PROFILE_SETTINGS_RESP 0x0028 -#define QMIWDS_GET_PROFILE_SETTINGS_REQ 0x002B -#define QMIWDS_GET_PROFILE_SETTINGS_RESP 0x002B +#define QMIWDS_GET_PROFILE_LIST_REQ 0x002A +#define QMIWDS_GET_PROFILE_LIST_RESP 0x002A +#define QMIWDS_GET_PROFILE_SETTINGS_REQ 0x002B +#define QMIWDS_GET_PROFILE_SETTINGS_RESP 0x002B #define QMIWDS_GET_DEFAULT_SETTINGS_REQ 0x002C #define QMIWDS_GET_DEFAULT_SETTINGS_RESP 0x002C #define QMIWDS_GET_RUNTIME_SETTINGS_REQ 0x002D @@ -643,6 +649,20 @@ typedef struct _QMIWDS_GPRS_QOS */ #endif +typedef struct _QMIWDS_PDPCONTEXT +{ + UCHAR TLVType; + USHORT TLVLength; + UCHAR pdp_context; +} __attribute__ ((packed)) QMIWDS_PDPCONTEXT, *PQMIWDS_PDPCONTEXT; + +typedef struct _QMIWDS_PROFILELIST +{ + UCHAR TLVType; + USHORT TLVLength; + UCHAR ProfileList[1024]; +} __attribute__ ((packed)) QMIWDS_PROFILELIST, *PQMIWDS_PROFILELIST; + typedef struct _QMIWDS_PROFILENAME { UCHAR TLVType; @@ -819,6 +839,21 @@ typedef struct _QMIWDS_CREATE_PROFILE_SETTINGS_REQ_MSG UCHAR pdp_context; } __attribute__ ((packed)) QMIWDS_CREATE_PROFILE_SETTINGS_REQ_MSG, *PQMIWDS_CREATE_PROFILE_SETTINGS_REQ_MSG; +typedef struct _QMIWDS_GET_PROFILE_LIST_REQ_MSG +{ + USHORT Type; + USHORT Length; +} __attribute__ ((packed)) QMIWDS_GET_PROFILE_LIST_REQ_MSG, *PQMIWDS_GET_PROFILE_LIST_REQ_MSG; + +typedef struct _QMIWDS_GET_PROFILE_LIST_RESP_MSG +{ + USHORT Type; + USHORT Length; + UCHAR TLVType; + USHORT TLVLength; + UCHAR ProfileList[1024]; +} __attribute__ ((packed)) QMIWDS_GET_PROFILE_LIST_RESP_MSG, *PQMIWDS_GET_PROFILE_LIST_RESP_MSG; + #if 0 typedef struct _QMIWDS_EVENT_REPORT_IND_DATA_BEARER_TLV { @@ -4091,8 +4126,10 @@ typedef struct _QMUX_MSG QMIWDS_GET_DEFAULT_SETTINGS_RESP_MSG GetDefaultSettingsResp; QMIWDS_MODIFY_PROFILE_SETTINGS_REQ_MSG ModifyProfileSettingsReq; QMIWDS_MODIFY_PROFILE_SETTINGS_RESP_MSG ModifyProfileSettingsResp; - QMIWDS_GET_PROFILE_SETTINGS_REQ_MSG GetProfileSettingsReq; + QMIWDS_GET_PROFILE_SETTINGS_REQ_MSG GetProfileSettingsReq; QMIWDS_CREATE_PROFILE_SETTINGS_REQ_MSG CreatetProfileSettingsReq; + QMIWDS_GET_PROFILE_LIST_REQ_MSG GetProfileListReq; + QMIWDS_GET_PROFILE_LIST_RESP_MSG GetProfileListResp; #if 0 QMIWDS_GET_DATA_BEARER_REQ_MSG GetDataBearerReq; QMIWDS_GET_DATA_BEARER_RESP_MSG GetDataBearerResp; @@ -4269,5 +4306,5 @@ typedef struct _QCQMIMSG { #pragma pack(pop) -#endif // MPQMUX_H +#endif // QCQMUX_H diff --git a/package/wwan/app/quectel_cm_5G/src/QMIThread.c b/package/wwan/app/quectel_cm_5G/src/QMIThread.c index 40ea8d2dc..8f7e86669 100644 --- a/package/wwan/app/quectel_cm_5G/src/QMIThread.c +++ b/package/wwan/app/quectel_cm_5G/src/QMIThread.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ @@ -255,11 +255,11 @@ static USHORT WdsStartNwInterfaceReq(PQMUX_MSG pMUXMsg, void *arg) { TLVLength += (le16_to_cpu(pIpFamily->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); //Set Profile Index - if (profile->pdp && !s_is_cdma) { //cdma only support one pdp, so no need to set profile index + if (profile->profile_index && !s_is_cdma) { //cdma only support one pdp, so no need to set profile index PQMIWDS_PROFILE_IDENTIFIER pProfileIndex = (PQMIWDS_PROFILE_IDENTIFIER)(pTLV + TLVLength); pProfileIndex->TLVLength = cpu_to_le16(0x01); pProfileIndex->TLVType = 0x31; - pProfileIndex->ProfileIndex = profile->pdp; + pProfileIndex->ProfileIndex = profile->profile_index; if (s_is_cdma && s_hdr_personality == 0x02) { pProfileIndex->TLVType = 0x32; //profile_index_3gpp2 pProfileIndex->ProfileIndex = 101; @@ -478,6 +478,13 @@ static USHORT UimReadTransparentIMSIReqSend(PQMUX_MSG pMUXMsg, void *arg) { #endif #ifdef CONFIG_APN + +static USHORT WdsGetProfileListReqSend(PQMUX_MSG pMUXMsg, void *arg) { + (void)(arg); + pMUXMsg->GetProfileListReq.Length = cpu_to_le16(sizeof(QMIWDS_GET_PROFILE_LIST_REQ_MSG) - 4); + return sizeof(QMIWDS_GET_PROFILE_LIST_REQ_MSG); +} + static USHORT WdsCreateProfileSettingsReqSend(PQMUX_MSG pMUXMsg, void *arg) { PROFILE_T *profile = (PROFILE_T *)arg; pMUXMsg->CreatetProfileSettingsReq.Length = cpu_to_le16(sizeof(QMIWDS_CREATE_PROFILE_SETTINGS_REQ_MSG) - 4); @@ -496,7 +503,7 @@ static USHORT WdsGetProfileSettingsReqSend(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->GetProfileSettingsReq.TLVType = 0x01; pMUXMsg->GetProfileSettingsReq.TLVLength = cpu_to_le16(0x02); pMUXMsg->GetProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2 - pMUXMsg->GetProfileSettingsReq.ProfileIndex = profile->pdp; + pMUXMsg->GetProfileSettingsReq.ProfileIndex = profile->profile_index; return sizeof(QMIWDS_GET_PROFILE_SETTINGS_REQ_MSG); } @@ -510,7 +517,7 @@ static USHORT WdsModifyProfileSettingsReq(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->ModifyProfileSettingsReq.TLVType = 0x01; pMUXMsg->ModifyProfileSettingsReq.TLVLength = cpu_to_le16(0x02); pMUXMsg->ModifyProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2 - pMUXMsg->ModifyProfileSettingsReq.ProfileIndex = profile->pdp; + pMUXMsg->ModifyProfileSettingsReq.ProfileIndex = profile->profile_index; pTLV = (UCHAR *)(&pMUXMsg->ModifyProfileSettingsReq + 1); @@ -1858,8 +1865,9 @@ static int requestSetupDataCall(PROFILE_T *profile, int curIpFamily) { dbg_time("call_end_reason_verbose is %d", verbose_call_end_reason); } + err = le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError); free(pResponse); - return le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError); + return err; } if (curIpFamily == IpFamilyV4) { @@ -2026,8 +2034,8 @@ static int requestSetProfile(PROFILE_T *profile) { const char *new_password = profile->password ? profile->password : ""; const char *ipStr[] = {"IPV4", "NULL", "IPV6", "IPV4V6"}; - dbg_time("%s[%d] %s/%s/%s/%d/%s", __func__, profile->pdp, profile->apn, profile->user, profile->password, profile->auth,ipStr[profile->iptype]); - if (!profile->pdp) + dbg_time("%s[pdp:%d index:%d] %s/%s/%s/%d/%s", __func__, profile->pdp, profile->profile_index, profile->apn, profile->user, profile->password, profile->auth,ipStr[profile->iptype]); + if (!profile->profile_index) return -1; if ( !strcmp(profile->old_apn, new_apn) && !strcmp(profile->old_user, new_user) @@ -2057,6 +2065,9 @@ static int requestGetProfile(PROFILE_T *profile) { PQMIWDS_PASSWD pPassWd; PQMIWDS_AUTH_PREFERENCE pAuthPref; PQMIWDS_IPTYPE pIpType; + PQMIWDS_PDPCONTEXT pPdpContext; + PQMIWDS_PROFILELIST pProfileList; + const char *ipStr[] = {"IPV4", "NULL", "IPV6", "IPV4V6"}; profile->old_apn[0] = profile->old_user[0] = profile->old_password[0] = '\0'; @@ -2073,19 +2084,52 @@ static int requestGetProfile(PROFILE_T *profile) { return 0; _re_check: - pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_GET_PROFILE_SETTINGS_REQ, WdsGetProfileSettingsReqSend, profile); - err = QmiThreadSendQMI(pRequest, &pResponse); - if (err == 0 && pResponse && le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.QMUXResult) - && le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.QMUXError) == QMI_ERR_EXTENDED_INTERNAL) + pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_GET_PROFILE_LIST_REQ, WdsGetProfileListReqSend, profile); + err = QmiThreadSendQMI(pRequest, &pResponse);s_pResponse = malloc(le16_to_cpu(pResponse->QMIHdr.Length) + 1); + qmi_rsp_check_and_return(); + + pProfileList = (PQMIWDS_PROFILELIST)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01); + uint8 profile_indexs[42] = {0}; + uint8 profile_num = pProfileList->ProfileList[0]; + if(profile_num >= 1) { - free(pResponse); - pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_CREATE_PROFILE_REQ, WdsCreateProfileSettingsReqSend, profile); + uint8 j = 0; + uint8 k = 2; + for(int i=0; iProfileList[k]; + if(pProfileList->ProfileList[++k] == 0) + k+=2; + else + k+=2+pProfileList->ProfileList[k]; + } + } + free(pResponse); + + for(int i=0; iprofile_index = profile_indexs[i]; + + pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_GET_PROFILE_SETTINGS_REQ, WdsGetProfileSettingsReqSend, profile); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); - free(pResponse); - goto _re_check; + + pPdpContext = (PQMIWDS_PDPCONTEXT)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x25); + if(pPdpContext->pdp_context == profile->pdp) + break; + else + free(pResponse); + + if(i == profile_num-1) + { + pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_CREATE_PROFILE_REQ, WdsCreateProfileSettingsReqSend, profile); + err = QmiThreadSendQMI(pRequest, &pResponse); + qmi_rsp_check_and_return(); + free(pResponse); + goto _re_check; + } } - qmi_rsp_check_and_return(); + pApnName = (PQMIWDS_APNNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x14); pUserName = (PQMIWDS_USERNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1B); @@ -2106,7 +2150,7 @@ _re_check: profile->old_iptype = pIpType->IPType; } - dbg_time("%s[%d] %s/%s/%s/%d/%s", __func__, profile->pdp, profile->old_apn, profile->old_user, profile->old_password, profile->old_auth, ipStr[profile->old_iptype]); + dbg_time("%s[pdp:%d index:%d] %s/%s/%s/%d/%s", __func__, profile->pdp, profile->profile_index, profile->old_apn, profile->old_user, profile->old_password, profile->old_auth, ipStr[profile->old_iptype]); free(pResponse); return 0; diff --git a/package/wwan/app/quectel_cm_5G/src/QMIThread.h b/package/wwan/app/quectel_cm_5G/src/QMIThread.h index 01f84b76b..bbf2d4b29 100644 --- a/package/wwan/app/quectel_cm_5G/src/QMIThread.h +++ b/package/wwan/app/quectel_cm_5G/src/QMIThread.h @@ -53,9 +53,9 @@ #include #include "qendian.h" -#include "MPQMI.h" -#include "MPQCTL.h" -#include "MPQMUX.h" +#include "QCQMI.h" +#include "QCQCTL.h" +#include "QCQMUX.h" #include "util.h" #define DEVICE_CLASS_UNKNOWN 0 @@ -196,10 +196,12 @@ typedef struct __PROFILE { int iptype; const char *pincode; char proxy[32]; - int pdp; + int pdp;//pdp_context + int profile_index;//profile_index int enable_bridge; bool enable_ipv4; bool enable_ipv6; + bool no_dhcp; const char *logfile; const char *usblogfile; char expect_adapter[32]; @@ -221,6 +223,7 @@ typedef struct __PROFILE { UINT qos_id; #endif int wda_client; + uint32_t udhcpc_ip; IPV4_T ipv4; IPV6_T ipv6; UINT PCSCFIpv4Addr1; diff --git a/package/wwan/app/quectel_cm_5G/src/QmiWwanCM.c b/package/wwan/app/quectel_cm_5G/src/QmiWwanCM.c index 99f96b679..bea11c664 100644 --- a/package/wwan/app/quectel_cm_5G/src/QmiWwanCM.c +++ b/package/wwan/app/quectel_cm_5G/src/QmiWwanCM.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ @@ -264,8 +264,8 @@ static int QmiWwanDeInit(void) { { if (qmiclientId[i] != 0) { - QmiWwanReleaseClientID(i, qmiclientId[i]); - qmiclientId[i] = 0; + QmiWwanReleaseClientID((QMUX_TYPE_WDS_IPV6 == i ? QMUX_TYPE_WDS : i), qmiclientId[i]); + qmiclientId[i] = 0; } } diff --git a/package/wwan/app/quectel_cm_5G/src/ReleaseNote.txt b/package/wwan/app/quectel_cm_5G/src/ReleaseNote.txt index 5da5cb766..a5eb77dff 100644 --- a/package/wwan/app/quectel_cm_5G/src/ReleaseNote.txt +++ b/package/wwan/app/quectel_cm_5G/src/ReleaseNote.txt @@ -1,5 +1,19 @@ Release Notes +[V1.6.5] +Date: 7/3/2023 +enhancement: + 1. Fix the issue of qmi client id leakage caused by kill 9 killing the client of quectel-qmi-proxy + 2. Fix wds_ipv6 client ID can't be released issue + 3. Fix wds_ipv6 client ID can't be released issue + 4. Resolve PDP_ Context&Profile_ The issue of index mixing + 5. Add parameter - d to obtain IP and DNS information through qmi + 6. Fix mbim dialing. When the user does not specify apn through - s, prompt the user and exit the dialing program + 7. Prioritize the use of IP commands for optimization, and use ifconfig if not available + 8. Optimize and add/remove copyright +fix: + + [V1.6.4] Date: 9/7/2022 enhancement: diff --git a/package/wwan/app/quectel_cm_5G/src/atc.c b/package/wwan/app/quectel_cm_5G/src/atc.c index 3f61c359c..ef78ec697 100644 --- a/package/wwan/app/quectel_cm_5G/src/atc.c +++ b/package/wwan/app/quectel_cm_5G/src/atc.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ @@ -503,6 +503,7 @@ AT< OK safe_at_response_free(p_response); switch (cops_act) { case 2: //UTRAN + case 3: //GSM W/EGPRS case 4: //UTRAN W/HSDPA case 5: //UTRAN W/HSUPA case 6: //UTRAN W/HSDPA and HSUPA diff --git a/package/wwan/app/quectel_cm_5G/src/device.c b/package/wwan/app/quectel_cm_5G/src/device.c index 9371f70b2..fba46c61e 100644 --- a/package/wwan/app/quectel_cm_5G/src/device.c +++ b/package/wwan/app/quectel_cm_5G/src/device.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ diff --git a/package/wwan/app/quectel_cm_5G/src/main.c b/package/wwan/app/quectel_cm_5G/src/main.c index e39a5f31f..579b4f1d8 100644 --- a/package/wwan/app/quectel_cm_5G/src/main.c +++ b/package/wwan/app/quectel_cm_5G/src/main.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 -2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 -2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ @@ -58,8 +58,10 @@ static int check_ipv4_address(PROFILE_T *profile) { if (profile->request_ops == &mbim_request_ops) return 1; //we will get a new ipv6 address per requestGetIPAddress() - if (profile->request_ops == &atc_request_ops) - return 1; //TODO + if (profile->request_ops == &atc_request_ops) { + if (!profile->udhcpc_ip) return 1; + oldAddress = profile->udhcpc_ip; + } if (profile->request_ops->requestGetIPAddress(profile, IpFamilyV4) == 0) { if (profile->ipv4.Address != oldAddress || debug_qmi) { @@ -248,6 +250,7 @@ static int usage(const char *progname) { dbg_time("-m iface-idx Bind QMI data call to wwan0_ when QMAP used. E.g '-n 7 -m 1' bind pdn-7 data call to wwan0_1"); dbg_time("-b Enable network interface bridge function (default 0)"); dbg_time("-v Verbose log mode, for debug purpose."); + dbg_time("-d Obtain the IP address and dns through qmi"); dbg_time("[Examples]"); dbg_time("Example 1: %s ", progname); dbg_time("Example 2: %s -s 3gnet ", progname); @@ -367,6 +370,15 @@ static int qmi_main(PROFILE_T *profile) request_ops->requestRegisterQos(profile); #endif +#if 1 //USB disconnnect and re-connect, but not reboot modem, will get this bug + if (profile->enable_ipv4 + && profile->request_ops == &atc_request_ops + && !request_ops->requestQueryDataCall(&IPv4ConnectionStatus, IpFamilyV4) + && IPv4ConnectionStatus == QWDS_PKT_DATA_CONNECTED) { + request_ops->requestDeactivateDefaultPDP(profile, IpFamilyV4); + } +#endif + send_signo_to_main(SIG_EVENT_CHECK); while (1) @@ -716,6 +728,11 @@ static int quectel_CM(PROFILE_T *profile) dbg_time("Modem works in MBIM mode"); profile->request_ops = &mbim_request_ops; profile->qmi_ops = &mbim_dev_ops; + if (!profile->apn || !profile->apn[0]) { + //see FAE-51804 FAE-59811 + dbg_time("When MBIM mode, must specify APN with '-s', or setup data call may fail!"); + exit(-404); //if no such issue on your side, please comment this + } ret = qmi_main(profile); } else if (profile->software_interface == SOFTWARE_QMI) { @@ -757,6 +774,7 @@ static int parse_user_input(int argc, char **argv, PROFILE_T *profile) { int opt = 1; profile->pdp = CONFIG_DEFAULT_PDP; + profile->profile_index = CONFIG_DEFAULT_PDP; if (!strcmp(argv[argc-1], "&")) argc--; @@ -865,6 +883,10 @@ static int parse_user_input(int argc, char **argv, PROFILE_T *profile) { profile->enable_ipv6 = 1; break; + case 'd': + profile->no_dhcp = 1; + break; + case 'u': if (has_more_argv()) { profile->usblogfile = argv[opt++]; @@ -899,7 +921,7 @@ int main(int argc, char *argv[]) int ret; PROFILE_T *ctx = &s_profile; - dbg_time("QConnectManager_Linux_V1.6.4"); + dbg_time("QConnectManager_Linux_V1.6.5"); ret = parse_user_input(argc, argv, ctx); if (!ret) diff --git a/package/wwan/app/quectel_cm_5G/src/mbim-cm.c b/package/wwan/app/quectel_cm_5G/src/mbim-cm.c index 836025ab7..15ae7721d 100644 --- a/package/wwan/app/quectel_cm_5G/src/mbim-cm.c +++ b/package/wwan/app/quectel_cm_5G/src/mbim-cm.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ diff --git a/package/wwan/app/quectel_cm_5G/src/qmap_bridge_mode.c b/package/wwan/app/quectel_cm_5G/src/qmap_bridge_mode.c index f6c81cb93..18e825dee 100644 --- a/package/wwan/app/quectel_cm_5G/src/qmap_bridge_mode.c +++ b/package/wwan/app/quectel_cm_5G/src/qmap_bridge_mode.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ diff --git a/package/wwan/app/quectel_cm_5G/src/qrtr.c b/package/wwan/app/quectel_cm_5G/src/qrtr.c index 111a6b2ce..450c6bd8d 100644 --- a/package/wwan/app/quectel_cm_5G/src/qrtr.c +++ b/package/wwan/app/quectel_cm_5G/src/qrtr.c @@ -10,7 +10,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ diff --git a/package/wwan/app/quectel_cm_5G/src/quectel-atc-proxy.c b/package/wwan/app/quectel_cm_5G/src/quectel-atc-proxy.c index dc929ade6..9f7b32978 100644 --- a/package/wwan/app/quectel_cm_5G/src/quectel-atc-proxy.c +++ b/package/wwan/app/quectel_cm_5G/src/quectel-atc-proxy.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ diff --git a/package/wwan/app/quectel_cm_5G/src/quectel-qmi-proxy.c b/package/wwan/app/quectel_cm_5G/src/quectel-qmi-proxy.c index e1d28bcaf..828f1b939 100644 --- a/package/wwan/app/quectel_cm_5G/src/quectel-qmi-proxy.c +++ b/package/wwan/app/quectel_cm_5G/src/quectel-qmi-proxy.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ @@ -34,9 +34,9 @@ #include "qendian.h" #include "qlist.h" -#include "MPQMI.h" -#include "MPQCTL.h" -#include "MPQMUX.h" +#include "QCQMI.h" +#include "QCQCTL.h" +#include "QCQMUX.h" #ifndef MIN #define MIN(a, b) ((a) < (b)? (a): (b)) @@ -117,6 +117,8 @@ static int modem_reset_flag = 0; static int qmi_sync_done = 0; static uint8_t qmi_buf[4096]; +static int send_qmi_to_cdc_wdm(PQCQMIMSG pQMI); + #ifdef QUECTEL_QMI_MERGE static int merge_qmi_rsp_packet(void *buf, ssize_t *src_size) { static QMI_MSG_PACKET s_QMIPacket; @@ -168,8 +170,8 @@ static int create_local_server(const char *name) { alen = strlen(name) + offsetof(struct sockaddr_un, sun_path) + 1; SYSCHECK(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,sizeof(reuse_addr))); if(bind(sockfd, (struct sockaddr *)&sockaddr, alen) < 0) { - close(sockfd); dprintf("bind %s errno: %d (%s)\n", name, errno, strerror(errno)); + close(sockfd); return -1; } @@ -201,7 +203,7 @@ static void accept_qmi_connection(int serverfd) { cfmakenoblock(clientfd); } -static void cleanup_qmi_connection(int clientfd) { +static void cleanup_qmi_connection(int clientfd, int clientDisconnect) { struct qlistnode *con_node, *qmi_node; qlist_for_each(con_node, &qmi_proxy_connection) { @@ -211,8 +213,33 @@ static void cleanup_qmi_connection(int clientfd) { while (!qlist_empty(&qmi_con->client_qnode)) { QMI_PROXY_CLINET *qmi_client = qnode_to_item(qlist_head(&qmi_con->client_qnode), QMI_PROXY_CLINET, qnode); - dprintf("xxx ClientFd=%d QMIType=%d ClientId=%d\n", qmi_con->ClientFd, qmi_client->QMIType, qmi_client->ClientId); + if (clientDisconnect) { + int size = 17; + QMI_PROXY_MSG *qmi_msg = malloc(sizeof(QMI_PROXY_MSG) + size); + PQCQMIMSG pQMI = &qmi_msg->qmi[0]; + dprintf("xxx ClientFd=%d QMIType=%d ClientId=%d\n", qmi_con->ClientFd, qmi_client->QMIType, qmi_client->ClientId); + qlist_init(&qmi_msg->qnode); + qmi_msg->ClientFd = qmi_proxy_server_fd; + pQMI->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI; + pQMI->QMIHdr.Length = htole16(16); + pQMI->QMIHdr.CtlFlags = 0x00; + pQMI->QMIHdr.QMIType = QMUX_TYPE_CTL; + pQMI->QMIHdr.ClientId= 0x00; + pQMI->CTLMsg.ReleaseClientIdReq.CtlFlags = QMICTL_FLAG_REQUEST; + pQMI->CTLMsg.ReleaseClientIdReq.TransactionId = 255; + pQMI->CTLMsg.ReleaseClientIdReq.QMICTLType = htole16(QMICTL_RELEASE_CLIENT_ID_REQ); + pQMI->CTLMsg.ReleaseClientIdReq.Length = htole16(5); + pQMI->CTLMsg.ReleaseClientIdReq.TLVType = QCTLV_TYPE_REQUIRED_PARAMETER; + pQMI->CTLMsg.ReleaseClientIdReq.TLVLength = htole16(2); + pQMI->CTLMsg.ReleaseClientIdReq.QMIType = qmi_client->QMIType; + pQMI->CTLMsg.ReleaseClientIdReq.ClientId = qmi_client->ClientId; + + if (qlist_empty(&qmi_proxy_ctl_msg)) + send_qmi_to_cdc_wdm(pQMI); + qlist_add_tail(&qmi_proxy_ctl_msg, &qmi_msg->qnode); + } + qlist_remove(&qmi_client->qnode); free(qmi_client); } @@ -273,12 +300,13 @@ static void dump_qmi(PQCQMIMSG pQMI, int fd, const char flag) { unsigned i; unsigned size = le16toh(pQMI->QMIHdr.Length) + 1; - printf("%c %d %u: ", flag, fd, size); - if (size > 16) - size = 16; - for (i = 0; i < size; i++) - printf("%02x ", ((uint8_t *)pQMI)[i]); - printf("\n"); + char buf[128]; + int cnt = 0; + + cnt += snprintf(buf + cnt, sizeof(buf) - cnt, "%c %d %u: ", flag, fd, size); + for (i = 0; i < size && i < 24; i++) + cnt += snprintf(buf + cnt, sizeof(buf) - cnt, "%02x ", ((uint8_t *)pQMI)[i]); + dprintf("%s\n", buf) } } @@ -327,40 +355,51 @@ static void recv_qmi_from_dev(PQCQMIMSG pQMI) { if (!qlist_empty(&qmi_proxy_ctl_msg)) { QMI_PROXY_MSG *qmi_msg = qnode_to_item(qlist_head(&qmi_proxy_ctl_msg), QMI_PROXY_MSG, qnode); - qlist_for_each(con_node, &qmi_proxy_connection) { - QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(con_node, QMI_PROXY_CONNECTION, qnode); + if (qmi_msg->qmi[0].CTLMsg.QMICTLMsgHdrRsp.TransactionId != pQMI->CTLMsg.QMICTLMsgHdrRsp.TransactionId + || qmi_msg->qmi[0].CTLMsg.QMICTLMsgHdrRsp.QMICTLType != pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) { + dprintf("ERROR: ctl rsp tid:%d, type:%d - ctl req %d, %d\n", + pQMI->CTLMsg.QMICTLMsgHdrRsp.TransactionId, pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType, + qmi_msg->qmi[0].CTLMsg.QMICTLMsgHdrRsp.TransactionId, qmi_msg->qmi[0].CTLMsg.QMICTLMsgHdrRsp.QMICTLType); + } + else if (qmi_msg->ClientFd == qmi_proxy_server_fd) { + if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_RELEASE_CLIENT_ID_RESP) { + dprintf("--- ClientFd=%d QMIType=%d ClientId=%d\n", qmi_proxy_server_fd, + pQMI->CTLMsg.ReleaseClientIdRsp.QMIType, pQMI->CTLMsg.ReleaseClientIdRsp.ClientId); + } + } + else { + qlist_for_each(con_node, &qmi_proxy_connection) { + QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(con_node, QMI_PROXY_CONNECTION, qnode); - if (qmi_con->ClientFd == qmi_msg->ClientFd) { - send_qmi_to_client(pQMI, qmi_msg->ClientFd); + if (qmi_con->ClientFd == qmi_msg->ClientFd) { + send_qmi_to_client(pQMI, qmi_msg->ClientFd); - if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_GET_CLIENT_ID_RESP) - get_client_id(qmi_con, &pQMI->CTLMsg.GetClientIdRsp); - else if ((le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_RELEASE_CLIENT_ID_RESP) || - (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_REVOKE_CLIENT_ID_IND)) { - release_client_id(qmi_con, &pQMI->CTLMsg.ReleaseClientIdRsp); - if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_REVOKE_CLIENT_ID_IND) - modem_reset_flag = 1; - } - else { + if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_GET_CLIENT_ID_RESP) { + get_client_id(qmi_con, &pQMI->CTLMsg.GetClientIdRsp); + } + else if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_RELEASE_CLIENT_ID_RESP) { + release_client_id(qmi_con, &pQMI->CTLMsg.ReleaseClientIdRsp); + } + else { + } } } } qlist_remove(&qmi_msg->qnode); free(qmi_msg); - } - } - if (!qlist_empty(&qmi_proxy_ctl_msg)) { - QMI_PROXY_MSG *qmi_msg = qnode_to_item(qlist_head(&qmi_proxy_ctl_msg), QMI_PROXY_MSG, qnode); + if (!qlist_empty(&qmi_proxy_ctl_msg)) { + QMI_PROXY_MSG *qmi_msg = qnode_to_item(qlist_head(&qmi_proxy_ctl_msg), QMI_PROXY_MSG, qnode); - qlist_for_each(con_node, &qmi_proxy_connection) { - QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(con_node, QMI_PROXY_CONNECTION, qnode); - - if (qmi_con->ClientFd == qmi_msg->ClientFd) { send_qmi_to_cdc_wdm(qmi_msg->qmi); } } + } + else if (pQMI->QMIHdr.QMIType == QMICTL_CTL_FLAG_IND) { + if (le16toh(pQMI->CTLMsg.QMICTLMsgHdrRsp.QMICTLType) == QMICTL_REVOKE_CLIENT_ID_IND) { + modem_reset_flag = 1; + } } } else { @@ -380,10 +419,10 @@ static void recv_qmi_from_dev(PQCQMIMSG pQMI) { } static int recv_qmi_from_client(PQCQMIMSG pQMI, unsigned size, int clientfd) { - if (qmi_proxy_server_fd <= 0) { - send_qmi_to_cdc_wdm(pQMI); - } - else if (pQMI->QMIHdr.QMIType == QMUX_TYPE_CTL) { + if (qmi_proxy_server_fd == -1) + return -1; + + if (pQMI->QMIHdr.QMIType == QMUX_TYPE_CTL) { QMI_PROXY_MSG *qmi_msg; if (pQMI->CTLMsg.QMICTLMsgHdr.QMICTLType == QMICTL_SYNC_REQ) { @@ -391,13 +430,13 @@ static int recv_qmi_from_client(PQCQMIMSG pQMI, unsigned size, int clientfd) { return 0; } - if (qlist_empty(&qmi_proxy_ctl_msg)) - send_qmi_to_cdc_wdm(pQMI); - qmi_msg = malloc(sizeof(QMI_PROXY_MSG) + size); qlist_init(&qmi_msg->qnode); qmi_msg->ClientFd = clientfd; memcpy(qmi_msg->qmi, pQMI, size); + + if (qlist_empty(&qmi_proxy_ctl_msg)) + send_qmi_to_cdc_wdm(pQMI); qlist_add_tail(&qmi_proxy_ctl_msg, &qmi_msg->qnode); } else { @@ -407,7 +446,7 @@ static int recv_qmi_from_client(PQCQMIMSG pQMI, unsigned size, int clientfd) { return 0; } -static int qmi_proxy_init(void) { +static int qmi_proxy_init(unsigned retry) { unsigned i; QCQMIMSG _QMI; PQCQMIMSG pQMI = &_QMI; @@ -422,10 +461,10 @@ static int qmi_proxy_init(void) { pQMI->CTLMsg.QMICTLMsgHdr.CtlFlags = QMICTL_FLAG_REQUEST; qmi_sync_done = 0; - for (i = 0; i < 10; i++) { + for (i = 0; i < retry; i++) { pQMI->CTLMsg.SyncReq.TransactionId = i+1; - pQMI->CTLMsg.SyncReq.QMICTLType = QMICTL_SYNC_REQ; - pQMI->CTLMsg.SyncReq.Length = 0; + pQMI->CTLMsg.SyncReq.QMICTLType = htole16(QMICTL_SYNC_REQ); + pQMI->CTLMsg.SyncReq.Length = htole16(0); pQMI->QMIHdr.Length = htole16(le16toh(pQMI->CTLMsg.QMICTLMsgHdr.Length) + sizeof(QCQMI_HDR) + sizeof(QCQMICTL_MSG_HDR) - 1); @@ -442,22 +481,6 @@ static int qmi_proxy_init(void) { return qmi_sync_done ? 0 : -1; } -static void qmi_start_server(const char* servername) { - qmi_proxy_server_fd = create_local_server(servername); - dprintf("qmi_proxy_server_fd = %d\n", qmi_proxy_server_fd); - if (qmi_proxy_server_fd == -1) { - dprintf("Failed to create %s, errno: %d (%s)\n", servername, errno, strerror(errno)); - } -} - -static void qmi_close_server(const char* servername) { - if (qmi_proxy_server_fd != -1) { - dprintf("%s %s close server\n", __func__, servername); - close(qmi_proxy_server_fd); - qmi_proxy_server_fd = -1; - } -} - static void *qmi_proxy_loop(void *param) { PQCQMIMSG pQMI = (PQCQMIMSG)qmi_buf; @@ -510,7 +533,7 @@ static void *qmi_proxy_loop(void *param) do { //ret = poll(pollfds, nevents, -1); ret = poll(pollfds, nevents, (qmi_proxy_server_fd > 0) ? -1 : 200); - } while (ret == -1 && errno == EINTR && qmi_proxy_quit == 0); + } while (ret == -1 && errno == EINTR && qmi_proxy_quit == 0); if (ret < 0) { dprintf("%s poll=%d, errno: %d (%s)\n", __func__, ret, errno, strerror(errno)); @@ -528,7 +551,7 @@ static void *qmi_proxy_loop(void *param) } else if(fd == qmi_proxy_server_fd) { } else { - cleanup_qmi_connection(fd); + cleanup_qmi_connection(fd, 1); } continue; @@ -566,7 +589,7 @@ static void *qmi_proxy_loop(void *param) if (nreads <= 0) { dprintf("%s read=%d errno: %d (%s)", __func__, (int)nreads, errno, strerror(errno)); - cleanup_qmi_connection(fd); + cleanup_qmi_connection(fd, 1); break; } @@ -585,7 +608,7 @@ qmi_proxy_loop_exit: while (!qlist_empty(&qmi_proxy_connection)) { QMI_PROXY_CONNECTION *qmi_con = qnode_to_item(qlist_head(&qmi_proxy_connection), QMI_PROXY_CONNECTION, qnode); - cleanup_qmi_connection(qmi_con->ClientFd); + cleanup_qmi_connection(qmi_con->ClientFd, 0); } dprintf("%s exit, thread_id %p\n", __func__, (void *)pthread_self()); @@ -601,8 +624,7 @@ static void usage(void) { } static void sig_action(int sig) { - if (qmi_proxy_quit == 0) { - qmi_proxy_quit = 1; + if (qmi_proxy_quit++ == 0) { if (thread_id) pthread_kill(thread_id, sig); } @@ -611,7 +633,6 @@ static void sig_action(int sig) { int main(int argc, char *argv[]) { int opt; char cdc_wdm[32+1] = "/dev/cdc-wdm0"; - int retry_times = 0; char servername[64] = {0}; optind = 1; @@ -632,62 +653,47 @@ int main(int argc, char *argv[]) { } } - if (access(cdc_wdm, R_OK | W_OK)) { - dprintf("Fail to access %s, errno: %d (%s). break\n", cdc_wdm, errno, strerror(errno)); - return -1; - } - sprintf(servername, "quectel-qmi-proxy%c", cdc_wdm[strlen(cdc_wdm)-1]); dprintf("Will use cdc-wdm='%s', proxy='%s'\n", cdc_wdm, servername); while (qmi_proxy_quit == 0) { - if (access(cdc_wdm, R_OK | W_OK)) { - dprintf("Fail to access %s, errno: %d (%s). continue\n", cdc_wdm, errno, strerror(errno)); - // wait device - sleep(3); - continue; - } - cdc_wdm_fd = open(cdc_wdm, O_RDWR | O_NONBLOCK | O_NOCTTY); if (cdc_wdm_fd == -1) { - dprintf("Failed to open %s, errno: %d (%s). break\n", cdc_wdm, errno, strerror(errno)); - return -1; + dprintf("Failed to open %s, errno: %d (%s)\n", cdc_wdm, errno, strerror(errno)); + sleep(3); + continue; } cfmakenoblock(cdc_wdm_fd); /* no qmi_proxy_loop lives, create one */ pthread_create(&thread_id, NULL, qmi_proxy_loop, NULL); - /* try to redo init if failed, init function must be successfully */ - while (qmi_proxy_init() != 0) { - if (retry_times < 5) { - dprintf("fail to init proxy, try again in 2 seconds.\n"); - sleep(2); - retry_times++; - } else { - dprintf("has failed too much times, restart the modem and have a try...\n"); - break; - } - /* break loop if modem is detached */ - if (access(cdc_wdm, F_OK|R_OK|W_OK)) - break; - } - retry_times = 0; - qmi_start_server(servername); - if (qmi_proxy_server_fd == -1) - pthread_cancel(thread_id); - pthread_join(thread_id, NULL); - /* close local server at last */ - qmi_close_server(servername); - close(cdc_wdm_fd); - /* DO RESTART IN 20s IF MODEM RESET ITSELF */ - if (modem_reset_flag) { - unsigned int time_to_wait = 20; - while (time_to_wait) { - time_to_wait = sleep(time_to_wait); + if (qmi_proxy_init(60) == 0) { + qmi_proxy_server_fd = create_local_server(servername); + dprintf("qmi_proxy_server_fd = %d\n", qmi_proxy_server_fd); + if (qmi_proxy_server_fd == -1) { + dprintf("Failed to create %s, errno: %d (%s)\n", servername, errno, strerror(errno)); + pthread_cancel(thread_id); } - modem_reset_flag = 0; } + else { + pthread_cancel(thread_id); + } + + pthread_join(thread_id, NULL); + thread_id = 0; + + if (qmi_proxy_server_fd != -1) { + dprintf("close server %s\n", servername); + close(qmi_proxy_server_fd); + qmi_proxy_server_fd = -1; + } + close(cdc_wdm_fd); + cdc_wdm_fd = -1; + + if (qmi_proxy_quit == 0) + sleep(modem_reset_flag ? 30 : 3); + modem_reset_flag = 0; } return 0; diff --git a/package/wwan/app/quectel_cm_5G/src/quectel-qrtr-proxy.c b/package/wwan/app/quectel_cm_5G/src/quectel-qrtr-proxy.c index 9404e963a..67ddc16d5 100644 --- a/package/wwan/app/quectel_cm_5G/src/quectel-qrtr-proxy.c +++ b/package/wwan/app/quectel_cm_5G/src/quectel-qrtr-proxy.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ @@ -36,9 +36,9 @@ #include "qendian.h" #include "qlist.h" -#include "MPQMI.h" -#include "MPQCTL.h" -#include "MPQMUX.h" +#include "QCQMI.h" +#include "QCQCTL.h" +#include "QCQMUX.h" static const char * get_time(void) { static char time_buf[128]; diff --git a/package/wwan/app/quectel_cm_5G/src/udhcpc.c b/package/wwan/app/quectel_cm_5G/src/udhcpc.c index c439229e9..8ab381e79 100644 --- a/package/wwan/app/quectel_cm_5G/src/udhcpc.c +++ b/package/wwan/app/quectel_cm_5G/src/udhcpc.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ @@ -105,6 +105,17 @@ static short ifc_get_flags(const char *ifname) return ret; } +static void ifc_set_state(const char *ifname, int state) { + char shell_cmd[128]; + + if (!access("/sbin/ip", X_OK)) { + snprintf(shell_cmd, sizeof(shell_cmd), "ip link set dev %s %s", ifname, state ? "up" : "down"); + } else { + snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s %s", ifname, state ? "up" : "down"); + } + ql_system(shell_cmd); +} + static int ql_netcard_ipv4_address_check(const char *ifname, in_addr_t ip) { in_addr_t addr = 0; @@ -115,7 +126,6 @@ static int ql_netcard_ipv4_address_check(const char *ifname, in_addr_t ip) { static int ql_raw_ip_mode_check(const char *ifname, uint32_t ip) { int fd; char raw_ip[128]; - char shell_cmd[128]; char mode[2] = "X"; int mode_change = 0; @@ -135,14 +145,12 @@ static int ql_raw_ip_mode_check(const char *ifname, uint32_t ip) { if (read(fd, mode, 2) == -1) {}; if (mode[0] == '0' || mode[0] == 'N') { dbg_time("File:%s Line:%d udhcpc fail to get ip address, try next:", __func__, __LINE__); - snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s down", ifname); - ql_system(shell_cmd); + ifc_set_state(ifname, 0); dbg_time("echo Y > /sys/class/net/%s/qmi/raw_ip", ifname); mode[0] = 'Y'; if (write(fd, mode, 2) == -1) {}; mode_change = 1; - snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s up", ifname); - ql_system(shell_cmd); + ifc_set_state(ifname, 1); } close(fd); @@ -211,8 +219,7 @@ void ql_set_driver_link_state(PROFILE_T *profile, int link_state) { lseek(fd, 0, SEEK_SET); rc = read(fd, link_file, sizeof(link_file)); if (rc > 1 && (!strncasecmp(link_file, "0\n", 2) || !strncasecmp(link_file, "0x0\n", 4))) { - snprintf(link_file, sizeof(link_file), "ifconfig %s down", profile->usbnet_adapter); - ql_system(link_file); + ifc_set_state(profile->usbnet_adapter, 0); } } @@ -470,7 +477,6 @@ static void ql_openwrt_setup_wan6(const char *ifname, const IPV6_T *ipv6) { void udhcpc_start(PROFILE_T *profile) { char *ifname = profile->usbnet_adapter; - char shell_cmd[128]; ql_set_driver_link_state(profile, 1); @@ -483,17 +489,13 @@ void udhcpc_start(PROFILE_T *profile) { } if (strcmp(ifname, profile->usbnet_adapter)) { - snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s up", profile->usbnet_adapter); - ql_system(shell_cmd); + ifc_set_state(profile->usbnet_adapter, 1); if (ifc_get_flags(ifname)&IFF_UP) { - snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s down", ifname); - ql_system(shell_cmd); + ifc_set_state(ifname, 0); } } - snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s up", ifname); - ql_system(shell_cmd); - + ifc_set_state(ifname, 1); if (profile->ipv4.Address) { if (profile->PCSCFIpv4Addr1) dbg_time("pcscf1: %s", ipv4Str(profile->PCSCFIpv4Addr1)); @@ -528,7 +530,7 @@ void udhcpc_start(PROFILE_T *profile) { if (profile->ipv4.Address == 0) goto set_ipv6; - if (profile->request_ops == &mbim_request_ops) { //lots of mbim modem do not support DHCP + if (profile->no_dhcp || profile->request_ops == &mbim_request_ops) { //lots of mbim modem do not support DHCP update_ip_address_by_qmi(ifname, &profile->ipv4, NULL); } else @@ -579,9 +581,16 @@ void udhcpc_start(PROFILE_T *profile) { pthread_create(&udhcpc_thread_id, NULL, udhcpc_thread_function, (void*)strdup(udhcpc_cmd)); pthread_join(udhcpc_thread_id, NULL); - if (profile->request_ops == &atc_request_ops - && !ql_netcard_ipv4_address_check(ifname, qmi2addr(profile->ipv4.Address))) { - ql_get_netcard_carrier_state(ifname); + if (profile->request_ops == &atc_request_ops) { + profile->udhcpc_ip = 0; + ifc_get_addr(ifname, &profile->udhcpc_ip); + if (profile->udhcpc_ip != profile->ipv4.Address) { + unsigned char *l = (unsigned char *)&profile->udhcpc_ip; + unsigned char *r = (unsigned char *)&profile->ipv4.Address; + dbg_time("ERROR: IP from udhcpc (%d.%d.%d.%d) is different to IP from ATC (%d.%d.%d.%d)!", + l[0], l[1], l[2], l[3], r[0], r[1], r[2], r[3]); + ql_get_netcard_carrier_state(ifname); //miss udhcpc default.script or modem not report usb-net-cdc-linkup + } } if (profile->request_ops != &qmi_request_ops) { //only QMI modem support next fixup! @@ -720,11 +729,14 @@ void udhcpc_stop(PROFILE_T *profile) { dibbler_client_alive = 0; } + profile->udhcpc_ip = 0; //it seems when call netif_carrier_on(), and netcard 's IP is "0.0.0.0", will cause netif_queue_stopped() - snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s 0.0.0.0", ifname); - ql_system(shell_cmd); - snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s down", ifname); + if (!access("/sbin/ip", X_OK)) + snprintf(shell_cmd, sizeof(shell_cmd), "ip addr flush dev %s", ifname); + else + snprintf(shell_cmd, sizeof(shell_cmd), "ifconfig %s 0.0.0.0", ifname); ql_system(shell_cmd); + ifc_set_state(ifname, 0); #ifdef QL_OPENWER_NETWORK_SETUP ql_openwrt_setup_wan(ifname, NULL); diff --git a/package/wwan/app/quectel_cm_5G/src/udhcpc_script.c b/package/wwan/app/quectel_cm_5G/src/udhcpc_script.c index 032f8cfa8..3e164a43e 100644 --- a/package/wwan/app/quectel_cm_5G/src/udhcpc_script.c +++ b/package/wwan/app/quectel_cm_5G/src/udhcpc_script.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/ diff --git a/package/wwan/app/quectel_cm_5G/src/util.c b/package/wwan/app/quectel_cm_5G/src/util.c index 53b60f415..c84b07627 100644 --- a/package/wwan/app/quectel_cm_5G/src/util.c +++ b/package/wwan/app/quectel_cm_5G/src/util.c @@ -9,7 +9,7 @@ None. --------------------------------------------------------------------------- - Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. + Copyright (c) 2016 - 2023 Quectel Wireless Solution, Co., Ltd. All Rights Reserved. Quectel Wireless Solution Proprietary and Confidential. --------------------------------------------------------------------------- ******************************************************************************/