quectel_CM_5G_M: Add MBIM Support for FCC unlock.

Add MBIM Support for FCC unlock.
This commit is contained in:
sfwtw 2025-06-02 20:44:31 +08:00 committed by GitHub
commit 26f3636a37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 72 additions and 17 deletions

View File

@ -250,7 +250,9 @@ typedef struct __PROFILE {
char old_password[64]; char old_password[64];
int old_auth; int old_auth;
int old_iptype; int old_iptype;
#ifdef CONFIG_FOXCONN_FCC_AUTH
int needs_fcc_auth; // Add this field for FCC authentication flag
#endif
const struct qmi_device_ops *qmi_ops; const struct qmi_device_ops *qmi_ops;
const struct request_ops *request_ops; const struct request_ops *request_ops;
RMNET_INFO rmnet_info; RMNET_INFO rmnet_info;

View File

@ -329,27 +329,28 @@ static int qmi_main(PROFILE_T *profile)
// Only execute FCC authentication if the modem model requires it // Only execute FCC authentication if the modem model requires it
if (profile->needs_fcc_auth) { if (profile->needs_fcc_auth) {
dbg_time("Executing FCC authentication for modem model: %s", profile->BaseBandVersion); dbg_time("Executing FCC authentication for modem model: %s", profile->BaseBandVersion);
// Check if the fcc auth was successful
char fcc_auth_success = 0;
if (request_ops->requestFoxconnSetFccAuthentication) { if (request_ops->requestFoxconnSetFccAuthentication) {
// Use magic value 0x01 as seen in libqmi // Use magic value 0x01 as seen in libqmi
qmierr = request_ops->requestFoxconnSetFccAuthentication(0x01); qmierr = request_ops->requestFoxconnSetFccAuthentication(0x01);
if (qmierr) { if (!qmierr) {
dbg_time("Foxconn FCC Authentication failed with error: %d", qmierr);
} else {
dbg_time("Foxconn FCC Authentication successful"); dbg_time("Foxconn FCC Authentication successful");
fcc_auth_success = 1;
} }
} }
if(fcc_auth_success != 1) {
if (request_ops->requestFoxconnSetFccAuthenticationV2) { if (request_ops->requestFoxconnSetFccAuthenticationV2) {
// Based on libqmi, use "FOXCONN" as magic string for Foxconn modems // Based on libqmi, use "FOXCONN" as magic string for Foxconn modems
const char *magic_string = "FOXCONN"; // Correct magic string for Foxconn const char *magic_string = "FOXCONN"; // Correct magic string for Foxconn
UCHAR magic_number = 0x01; // Standard magic number from libqmi UCHAR magic_number = 0x01; // Standard magic number from libqmi
qmierr = request_ops->requestFoxconnSetFccAuthenticationV2(magic_string, magic_number); qmierr = request_ops->requestFoxconnSetFccAuthenticationV2(magic_string, magic_number);
if (qmierr) { if (!qmierr) {
dbg_time("Foxconn FCC Authentication V2 failed with error: %d", qmierr); dbg_time("Foxconn FCC Authentication V2 successful");
} else { }
dbg_time("Foxconn FCC Authentication V2 successful");
} }
} }
} else { } else {

View File

@ -841,6 +841,8 @@ static pthread_mutex_t mbim_command_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t mbim_command_cond = PTHREAD_COND_INITIALIZER; static pthread_cond_t mbim_command_cond = PTHREAD_COND_INITIALIZER;
static int mbim_ms_version = 1; static int mbim_ms_version = 1;
static uint8_t qmi_over_mbim_nas = 0; static uint8_t qmi_over_mbim_nas = 0;
static uint8_t qmi_over_mbim_dms = 0; // Add DMS client ID
int qmi_over_mbim_qmidev_send(PQCQMIMSG pQMI); int qmi_over_mbim_qmidev_send(PQCQMIMSG pQMI);
static const UUID_T * str2uuid(const char *str) { static const UUID_T * str2uuid(const char *str) {
@ -1801,6 +1803,16 @@ static int mbim_device_caps_query(PROFILE_T *profile) {
wchar2char((const char *)pInfo + le32toh(pInfo->FirmwareInfoOffset), le32toh(pInfo->FirmwareInfoSize), tmp, sizeof(tmp)); wchar2char((const char *)pInfo + le32toh(pInfo->FirmwareInfoOffset), le32toh(pInfo->FirmwareInfoSize), tmp, sizeof(tmp));
strncpy(profile->BaseBandVersion, tmp, sizeof(profile->BaseBandVersion)); strncpy(profile->BaseBandVersion, tmp, sizeof(profile->BaseBandVersion));
mbim_debug("FirmwareInfo: %s", tmp); mbim_debug("FirmwareInfo: %s", tmp);
#ifdef CONFIG_FOXCONN_FCC_AUTH
// Check if this modem model needs FCC authentication
if (strstr(profile->BaseBandVersion, "T99W175")) {
profile->needs_fcc_auth = 1;
mbim_debug("Modem model %s requires FCC authentication", profile->BaseBandVersion);
} else {
profile->needs_fcc_auth = 0;
mbim_debug("Modem model %s does not require FCC authentication", profile->BaseBandVersion);
}
#endif
} }
if (le32toh(pInfo->HardwareInfoOffset) && le32toh(pInfo->HardwareInfoSize)) { if (le32toh(pInfo->HardwareInfoOffset) && le32toh(pInfo->HardwareInfoSize)) {
wchar2char((const char *)pInfo + le32toh(pInfo->HardwareInfoOffset), le32toh(pInfo->HardwareInfoSize), tmp, sizeof(tmp)); wchar2char((const char *)pInfo + le32toh(pInfo->HardwareInfoOffset), le32toh(pInfo->HardwareInfoSize), tmp, sizeof(tmp));
@ -2186,6 +2198,11 @@ static int mbim_init(PROFILE_T *profile) {
qmidev_send = qmi_over_mbim_qmidev_send; qmidev_send = qmi_over_mbim_qmidev_send;
#ifdef CONFIG_CELLINFO //by now, only this function need QMI OVER MBIM #ifdef CONFIG_CELLINFO //by now, only this function need QMI OVER MBIM
qmi_over_mbim_nas = qmi_over_mbim_get_client_id(QMUX_TYPE_NAS); qmi_over_mbim_nas = qmi_over_mbim_get_client_id(QMUX_TYPE_NAS);
#endif
#ifdef CONFIG_FOXCONN_FCC_AUTH
// Get DMS client ID for FCC authentication
qmi_over_mbim_dms = qmi_over_mbim_get_client_id(QMUX_TYPE_DMS);
mbim_debug("Got DMS client ID: %d for FCC authentication", qmi_over_mbim_dms);
#endif #endif
} }
} }
@ -2201,7 +2218,12 @@ static int mbim_deinit(void) {
qmi_over_mbim_release_client_id(QMUX_TYPE_NAS, qmi_over_mbim_nas); qmi_over_mbim_release_client_id(QMUX_TYPE_NAS, qmi_over_mbim_nas);
qmi_over_mbim_nas = 0; qmi_over_mbim_nas = 0;
} }
#ifdef CONFIG_FOXCONN_FCC_AUTH
if (qmi_over_mbim_dms) {
qmi_over_mbim_release_client_id(QMUX_TYPE_DMS, qmi_over_mbim_dms);
qmi_over_mbim_dms = 0;
}
#endif
mbim_close_device(); mbim_close_device();
if (qmi_over_mbim_sk[0] != -1) { if (qmi_over_mbim_sk[0] != -1) {
@ -2380,6 +2402,29 @@ static int requestGetCellInfoList(void) {
} }
#endif #endif
#ifdef CONFIG_FOXCONN_FCC_AUTH
// Use QMI over MBIM for Foxconn FCC authentication
static int requestFoxconnSetFccAuthentication(UCHAR magic_value) {
if (qmi_over_mbim_support && qmi_request_ops.requestFoxconnSetFccAuthentication) {
mbim_debug("%s(magic_value=0x%02x) via QMI over MBIM", __func__, magic_value);
return qmi_request_ops.requestFoxconnSetFccAuthentication(magic_value);
}
mbim_debug("%s: QMI over MBIM not available for FCC auth", __func__);
return -ENOTSUP;
}
static int requestFoxconnSetFccAuthenticationV2(const char *magic_string, UCHAR magic_number) {
if (qmi_over_mbim_support && qmi_request_ops.requestFoxconnSetFccAuthenticationV2) {
mbim_debug("%s(magic_string='%s', magic_number=0x%02x) via QMI over MBIM", __func__, magic_string, magic_number);
return qmi_request_ops.requestFoxconnSetFccAuthenticationV2(magic_string, magic_number);
}
mbim_debug("%s: QMI over MBIM not available for FCC auth", __func__);
return -ENOTSUP;
}
#endif
const struct request_ops mbim_request_ops = { const struct request_ops mbim_request_ops = {
.requestBaseBandVersion = requestBaseBandVersion, .requestBaseBandVersion = requestBaseBandVersion,
.requestGetSIMStatus = requestGetSIMStatus, .requestGetSIMStatus = requestGetSIMStatus,
@ -2391,6 +2436,10 @@ const struct request_ops mbim_request_ops = {
#ifdef CONFIG_CELLINFO #ifdef CONFIG_CELLINFO
.requestGetCellInfoList = requestGetCellInfoList, .requestGetCellInfoList = requestGetCellInfoList,
#endif #endif
#ifdef CONFIG_FOXCONN_FCC_AUTH
.requestFoxconnSetFccAuthentication = requestFoxconnSetFccAuthentication,
.requestFoxconnSetFccAuthenticationV2 = requestFoxconnSetFccAuthenticationV2,
#endif
}; };
int qmi_over_mbim_qmidev_send(PQCQMIMSG pQMI) { int qmi_over_mbim_qmidev_send(PQCQMIMSG pQMI) {
@ -2402,6 +2451,9 @@ int qmi_over_mbim_qmidev_send(PQCQMIMSG pQMI) {
if (pQMI->QMIHdr.QMIType != QMUX_TYPE_CTL) { if (pQMI->QMIHdr.QMIType != QMUX_TYPE_CTL) {
if (pQMI->QMIHdr.QMIType == QMUX_TYPE_NAS) if (pQMI->QMIHdr.QMIType == QMUX_TYPE_NAS)
pQMI->QMIHdr.ClientId = qmi_over_mbim_nas; pQMI->QMIHdr.ClientId = qmi_over_mbim_nas;
else if (pQMI->QMIHdr.QMIType == QMUX_TYPE_DMS)
pQMI->QMIHdr.ClientId = qmi_over_mbim_dms;
if (pQMI->QMIHdr.ClientId == 0) { if (pQMI->QMIHdr.ClientId == 0) {
dbg_time("QMIType %d has no clientID", pQMI->QMIHdr.QMIType); dbg_time("QMIType %d has no clientID", pQMI->QMIHdr.QMIType);