mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00
quectel-cm: update to version 1.6.5
This commit is contained in:
parent
68253688d8
commit
1dce308893
@ -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
|
||||
|
@ -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.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
@ -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.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
@ -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.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
@ -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.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
@ -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.
|
||||
---------------------------------------------------------------------------
|
||||
******************************************************************************/
|
||||
|
Loading…
Reference in New Issue
Block a user