quectel-cm: update to version 1.6.5

This commit is contained in:
coolsnowwolf 2024-03-17 14:26:15 +08:00
parent 68253688d8
commit 1dce308893
23 changed files with 360 additions and 221 deletions

View File

@ -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

View File

@ -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.
---------------------------------------------------------------------------
******************************************************************************/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.
---------------------------------------------------------------------------
******************************************************************************/

View File

@ -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

View File

@ -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; i<profile_num; i++)
{
profile_indexs[j++] = pProfileList->ProfileList[k];
if(pProfileList->ProfileList[++k] == 0)
k+=2;
else
k+=2+pProfileList->ProfileList[k];
}
}
free(pResponse);
for(int i=0; i<profile_num; i++)
{
profile->profile_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;

View File

@ -53,9 +53,9 @@
#include <stddef.h>
#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;

View File

@ -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;
}
}

View File

@ -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:

View File

@ -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

View File

@ -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.
---------------------------------------------------------------------------
******************************************************************************/

View File

@ -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_<iface idx> 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)

View File

@ -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.
---------------------------------------------------------------------------
******************************************************************************/

View File

@ -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.
---------------------------------------------------------------------------
******************************************************************************/

View File

@ -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.
---------------------------------------------------------------------------
******************************************************************************/

View File

@ -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.
---------------------------------------------------------------------------
******************************************************************************/

View File

@ -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;

View File

@ -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];

View File

@ -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);

View File

@ -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.
---------------------------------------------------------------------------
******************************************************************************/

View File

@ -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.
---------------------------------------------------------------------------
******************************************************************************/