Add Foxconn FCC Unlock mechanism to quectel-5G-M (#51)
This commit is contained in:
parent
6fe59c1d2b
commit
393dd33334
@ -314,6 +314,11 @@ typedef struct _QMI_TLV
|
||||
#define QMUX_CTL_FLAG_TYPE_IND 0x04
|
||||
#define QMUX_CTL_FLAG_MASK_COMPOUND 0x01
|
||||
#define QMUX_CTL_FLAG_MASK_TYPE 0x06 // 00-cmd, 01-rsp, 10-ind
|
||||
// Add these definitions to the DMS message types section
|
||||
#define QMIDMS_FOXCONN_SET_FCC_AUTH_REQ 0x555C
|
||||
#define QMIDMS_FOXCONN_SET_FCC_AUTH_RESP 0x555C
|
||||
#define QMIDMS_FOXCONN_SET_FCC_AUTH_V2_REQ 0x555D
|
||||
#define QMIDMS_FOXCONN_SET_FCC_AUTH_V2_RESP 0x555D
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
@ -399,25 +399,25 @@ typedef struct _QCTLV_PKT_STATISTICS
|
||||
//#ifdef QC_IP_MODE
|
||||
|
||||
/*
|
||||
�Bit 0 �Profile identifier
|
||||
�Bit 1 �Profile name
|
||||
�Bit 2 �PDP type
|
||||
�Bit 3 �APN name
|
||||
�Bit 4 �DNS address
|
||||
�Bit 5 �UMTS/GPRS granted QoS
|
||||
�Bit 6 �Username
|
||||
�Bit 7 �Authentication Protocol
|
||||
�Bit 8 �IP address
|
||||
�Bit 9 �Gateway information (address and subnet mask)
|
||||
�Bit 10 �PCSCF address using a PCO flag
|
||||
�Bit 11 �PCSCF server address list
|
||||
�Bit 12 �PCSCF domain name list
|
||||
�Bit 13 �MTU
|
||||
�Bit 14 �Domain name list
|
||||
�Bit 15 �IP family
|
||||
�Bit 16 �IM_CM flag
|
||||
�Bit 17 �Technology name
|
||||
�Bit 18 �Operator reserved PCO
|
||||
<EFBFBD>?Bit 0 <EFBFBD>?Profile identifier
|
||||
<EFBFBD>?Bit 1 <EFBFBD>?Profile name
|
||||
<EFBFBD>?Bit 2 <EFBFBD>?PDP type
|
||||
<EFBFBD>?Bit 3 <EFBFBD>?APN name
|
||||
<EFBFBD>?Bit 4 <EFBFBD>?DNS address
|
||||
<EFBFBD>?Bit 5 <EFBFBD>?UMTS/GPRS granted QoS
|
||||
<EFBFBD>?Bit 6 <EFBFBD>?Username
|
||||
<EFBFBD>?Bit 7 <EFBFBD>?Authentication Protocol
|
||||
<EFBFBD>?Bit 8 <EFBFBD>?IP address
|
||||
<EFBFBD>?Bit 9 <EFBFBD>?Gateway information (address and subnet mask)
|
||||
<EFBFBD>?Bit 10 <EFBFBD>?PCSCF address using a PCO flag
|
||||
<EFBFBD>?Bit 11 <EFBFBD>?PCSCF server address list
|
||||
<EFBFBD>?Bit 12 <EFBFBD>?PCSCF domain name list
|
||||
<EFBFBD>?Bit 13 <EFBFBD>?MTU
|
||||
<EFBFBD>?Bit 14 <EFBFBD>?Domain name list
|
||||
<EFBFBD>?Bit 15 <EFBFBD>?IP family
|
||||
<EFBFBD>?Bit 16 <EFBFBD>?IM_CM flag
|
||||
<EFBFBD>?Bit 17 <EFBFBD>?Technology name
|
||||
<EFBFBD>?Bit 18 <EFBFBD>?Operator reserved PCO
|
||||
*/
|
||||
#define QMIWDS_GET_RUNTIME_SETTINGS_MASK_IPV4DNS_ADDR (1 << 4)
|
||||
#define QMIWDS_GET_RUNTIME_SETTINGS_MASK_IPV4_ADDR (1 << 8)
|
||||
@ -4067,6 +4067,25 @@ typedef struct _QMIUIM_SET_CARD_SLOT_REQ_MSG
|
||||
#define QMI_COEX_GET_WWAN_STATE_REQ 0x22
|
||||
#define QMI_COEX_GET_WWAN_STATE_RESP 0x22
|
||||
|
||||
// Add these structure definitions after existing message structures
|
||||
|
||||
#ifdef CONFIG_FOXCONN_FCC_AUTH
|
||||
typedef struct _QMIDMS_FOXCONN_SET_FCC_AUTH_REQ_MSG
|
||||
{
|
||||
USHORT Type;
|
||||
USHORT Length;
|
||||
UCHAR TLVType;
|
||||
USHORT TLVLength;
|
||||
UCHAR magic_value;
|
||||
} __attribute__ ((packed)) QMIDMS_FOXCONN_SET_FCC_AUTH_REQ_MSG, *PQMIDMS_FOXCONN_SET_FCC_AUTH_REQ_MSG;
|
||||
|
||||
typedef struct _QMIDMS_FOXCONN_SET_FCC_AUTH_V2_REQ_MSG
|
||||
{
|
||||
USHORT Type;
|
||||
USHORT Length;
|
||||
} __attribute__ ((packed)) QMIDMS_FOXCONN_SET_FCC_AUTH_V2_REQ_MSG, *PQMIDMS_FOXCONN_SET_FCC_AUTH_V2_REQ_MSG;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
|
||||
uint32_t freq;
|
||||
@ -4293,6 +4312,10 @@ typedef struct _QMUX_MSG
|
||||
QMIWDS_ADMIN_SET_DATA_FORMAT_REQ_MSG SetDataFormatReq;
|
||||
QMI_WDA_SET_LOOPBACK_CONFIG_REQ_MSG SetLoopBackReq;
|
||||
QMI_WDA_SET_LOOPBACK_CONFIG_IND_MSG SetLoopBackInd;
|
||||
#ifdef CONFIG_FOXCONN_FCC_AUTH
|
||||
QMIDMS_FOXCONN_SET_FCC_AUTH_REQ_MSG FoxconnSetFccAuthReq;
|
||||
QMIDMS_FOXCONN_SET_FCC_AUTH_V2_REQ_MSG FoxconnSetFccAuthV2Req;
|
||||
#endif
|
||||
};
|
||||
} __attribute__ ((packed)) QMUX_MSG, *PQMUX_MSG;
|
||||
|
||||
|
@ -1832,6 +1832,88 @@ static int requestQueryDataCall(UCHAR *pConnectionStatus, int curIpFamily) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Add these implementations after existing function implementations
|
||||
|
||||
#ifdef CONFIG_FOXCONN_FCC_AUTH
|
||||
// Make sure these functions are static to avoid symbol conflicts
|
||||
static USHORT DmsFoxconnSetFccAuthenticationReq(PQMUX_MSG pMUXMsg, void *arg) {
|
||||
UCHAR magic_value = *((UCHAR *)arg);
|
||||
|
||||
pMUXMsg->FoxconnSetFccAuthReq.TLVType = 0x01;
|
||||
pMUXMsg->FoxconnSetFccAuthReq.TLVLength = cpu_to_le16(1);
|
||||
pMUXMsg->FoxconnSetFccAuthReq.magic_value = magic_value;
|
||||
|
||||
return sizeof(QMIDMS_FOXCONN_SET_FCC_AUTH_REQ_MSG);
|
||||
}
|
||||
|
||||
static USHORT DmsFoxconnSetFccAuthenticationV2Req(PQMUX_MSG pMUXMsg, void *arg) {
|
||||
FOXCONN_FCC_AUTH_V2_T *fcc_auth = (FOXCONN_FCC_AUTH_V2_T *)arg;
|
||||
USHORT TLVLength = 0;
|
||||
UCHAR *pTLV;
|
||||
|
||||
pTLV = (UCHAR *)(&pMUXMsg->FoxconnSetFccAuthV2Req + 1);
|
||||
|
||||
// Magic string TLV (0x01)
|
||||
*pTLV++ = 0x01; // TLV Type
|
||||
*(USHORT *)pTLV = cpu_to_le16(strlen(fcc_auth->magic_string));
|
||||
pTLV += 2;
|
||||
memcpy(pTLV, fcc_auth->magic_string, strlen(fcc_auth->magic_string));
|
||||
pTLV += strlen(fcc_auth->magic_string);
|
||||
TLVLength += 3 + strlen(fcc_auth->magic_string);
|
||||
|
||||
// Magic number TLV (0x02)
|
||||
*pTLV++ = 0x02; // TLV Type
|
||||
*(USHORT *)pTLV = cpu_to_le16(1);
|
||||
pTLV += 2;
|
||||
*pTLV++ = fcc_auth->magic_number;
|
||||
TLVLength += 4;
|
||||
|
||||
return sizeof(QMIDMS_FOXCONN_SET_FCC_AUTH_V2_REQ_MSG) + TLVLength;
|
||||
}
|
||||
|
||||
// These functions should NOT be static since they're used externally
|
||||
int requestFoxconnSetFccAuthentication(UCHAR magic_value) {
|
||||
PQCQMIMSG pRequest;
|
||||
PQCQMIMSG pResponse;
|
||||
PQMUX_MSG pMUXMsg;
|
||||
int err;
|
||||
|
||||
dbg_time("%s(magic_value=0x%02x)", __func__, magic_value);
|
||||
|
||||
pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_FOXCONN_SET_FCC_AUTH_REQ, DmsFoxconnSetFccAuthenticationReq, &magic_value);
|
||||
err = QmiThreadSendQMI(pRequest, &pResponse);
|
||||
qmi_rsp_check_and_return();
|
||||
|
||||
free(pResponse);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int requestFoxconnSetFccAuthenticationV2(const char *magic_string, UCHAR magic_number) {
|
||||
PQCQMIMSG pRequest;
|
||||
PQCQMIMSG pResponse;
|
||||
PQMUX_MSG pMUXMsg;
|
||||
int err;
|
||||
FOXCONN_FCC_AUTH_V2_T fcc_auth;
|
||||
|
||||
dbg_time("%s(magic_string='%s', magic_number=0x%02x)", __func__, magic_string, magic_number);
|
||||
|
||||
if (!magic_string || strlen(magic_string) >= sizeof(fcc_auth.magic_string)) {
|
||||
dbg_time("%s: Invalid magic_string", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy(fcc_auth.magic_string, magic_string);
|
||||
fcc_auth.magic_number = magic_number;
|
||||
|
||||
pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_FOXCONN_SET_FCC_AUTH_V2_REQ, DmsFoxconnSetFccAuthenticationV2Req, &fcc_auth);
|
||||
err = QmiThreadSendQMI(pRequest, &pResponse);
|
||||
qmi_rsp_check_and_return();
|
||||
|
||||
free(pResponse);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int requestSetupDataCall(PROFILE_T *profile, int curIpFamily) {
|
||||
PQCQMIMSG pRequest;
|
||||
PQCQMIMSG pResponse;
|
||||
@ -2271,6 +2353,17 @@ static int requestBaseBandVersion(PROFILE_T *profile) {
|
||||
{
|
||||
uchar2char(profile->BaseBandVersion, sizeof(profile->BaseBandVersion), &revId->RevisionID, le16_to_cpu(revId->TLVLength));
|
||||
dbg_time("%s %s", __func__, profile->BaseBandVersion);
|
||||
|
||||
#ifdef CONFIG_FOXCONN_FCC_AUTH
|
||||
// Check if this modem model needs FCC authentication
|
||||
if (strstr(profile->BaseBandVersion, "T99W175")) {
|
||||
profile->needs_fcc_auth = 1;
|
||||
dbg_time("Modem model %s requires FCC authentication", profile->BaseBandVersion);
|
||||
} else {
|
||||
profile->needs_fcc_auth = 0;
|
||||
dbg_time("Modem model %s does not require FCC authentication", profile->BaseBandVersion);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
free(pResponse);
|
||||
@ -2555,6 +2648,10 @@ const struct request_ops qmi_request_ops = {
|
||||
#ifdef CONFIG_COEX_WWAN_STATE
|
||||
.requestGetCoexWWANState = requestGetCoexWWANState,
|
||||
#endif
|
||||
#ifdef CONFIG_FOXCONN_FCC_AUTH
|
||||
.requestFoxconnSetFccAuthentication = requestFoxconnSetFccAuthentication,
|
||||
.requestFoxconnSetFccAuthenticationV2 = requestFoxconnSetFccAuthenticationV2,
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CELLINFO
|
||||
|
@ -20,6 +20,7 @@
|
||||
//#define CONFIG_REG_QOS_IND
|
||||
//#define CONFIG_GET_QOS_INFO
|
||||
//#define CONFIG_GET_QOS_DATA_RATE
|
||||
#define CONFIG_FOXCONN_FCC_AUTH
|
||||
|
||||
#if (defined(CONFIG_REG_QOS_IND) || defined(CONFIG_GET_QOS_INFO) || defined(CONFIG_GET_QOS_DATA_RATE))
|
||||
#ifndef CONFIG_REG_QOS_IND
|
||||
@ -344,7 +345,20 @@ struct request_ops {
|
||||
int (*requestRegisterQos)(PROFILE_T *profile);
|
||||
int (*requestGetQosInfo)(PROFILE_T *profile);
|
||||
int (*requestGetCoexWWANState)(void);
|
||||
#ifdef CONFIG_FOXCONN_FCC_AUTH
|
||||
int (*requestFoxconnSetFccAuthentication)(UCHAR magic_value);
|
||||
int (*requestFoxconnSetFccAuthenticationV2)(const char *magic_string, UCHAR magic_number);
|
||||
#endif
|
||||
};
|
||||
|
||||
// Add structure for V2 parameters
|
||||
#ifdef CONFIG_FOXCONN_FCC_AUTH
|
||||
typedef struct {
|
||||
char magic_string[256];
|
||||
UCHAR magic_number;
|
||||
} FOXCONN_FCC_AUTH_V2_T;
|
||||
#endif
|
||||
|
||||
extern const struct request_ops qmi_request_ops;
|
||||
extern const struct request_ops mbim_request_ops;
|
||||
extern const struct request_ops atc_request_ops;
|
||||
|
@ -325,6 +325,37 @@ static int qmi_main(PROFILE_T *profile)
|
||||
if (request_ops->requestSetEthMode)
|
||||
request_ops->requestSetEthMode(profile);
|
||||
|
||||
#ifdef CONFIG_FOXCONN_FCC_AUTH
|
||||
// Only execute FCC authentication if the modem model requires it
|
||||
if (profile->needs_fcc_auth) {
|
||||
dbg_time("Executing FCC authentication for modem model: %s", profile->BaseBandVersion);
|
||||
|
||||
if (request_ops->requestFoxconnSetFccAuthentication) {
|
||||
// Use magic value 0x01 as seen in libqmi
|
||||
qmierr = request_ops->requestFoxconnSetFccAuthentication(0x01);
|
||||
if (qmierr) {
|
||||
dbg_time("Foxconn FCC Authentication failed with error: %d", qmierr);
|
||||
} else {
|
||||
dbg_time("Foxconn FCC Authentication successful");
|
||||
}
|
||||
}
|
||||
|
||||
if (request_ops->requestFoxconnSetFccAuthenticationV2) {
|
||||
// Based on libqmi, use "FOXCONN" as magic string for Foxconn modems
|
||||
const char *magic_string = "FOXCONN"; // Correct magic string for Foxconn
|
||||
UCHAR magic_number = 0x01; // Standard magic number from libqmi
|
||||
|
||||
qmierr = request_ops->requestFoxconnSetFccAuthenticationV2(magic_string, magic_number);
|
||||
if (qmierr) {
|
||||
dbg_time("Foxconn FCC Authentication V2 failed with error: %d", qmierr);
|
||||
} else {
|
||||
dbg_time("Foxconn FCC Authentication V2 successful");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dbg_time("Skipping FCC authentication - not required for this modem model");
|
||||
}
|
||||
#endif
|
||||
if (request_ops->requestSetLoopBackState && profile->loopback_state) {
|
||||
qmierr = request_ops->requestSetLoopBackState(profile->loopback_state, profile->replication_factor);
|
||||
if (qmierr != QMI_ERR_INVALID_QMI_CMD) //X20 return this error
|
||||
|
Loading…
x
Reference in New Issue
Block a user