#include "QMIThread.h" #include "query_pcie_mode.h" extern char *strndup(const char *__string, size_t __n); //2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817 //extern int *speed_arr; //extern int *name_arr; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; //2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817 #define qmi_rsp_check_and_return()\ do { \ if (err < 0 || pResponse == NULL) { \ dbg_time("%s err = %d", __func__, err); \ return err; \ } \ pMUXMsg = &pResponse->MUXMsg; \ if (le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult) || \ le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError)) { \ USHORT QMUXError = le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError); \ dbg_time("%s QMUXResult = 0x%x, QMUXError = 0x%x", __func__, \ le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult), \ QMUXError); \ free(pResponse); \ return QMUXError; \ } \ } while (0) #define qmi_rsp_check() \ do { \ if (err < 0 || pResponse == NULL) { \ dbg_time("%s err = %d", __func__, err); \ return err; \ } \ pMUXMsg = &pResponse->MUXMsg; \ if (le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult) || \ le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError)) { \ USHORT QMUXError = le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError); \ dbg_time("%s QMUXResult = 0x%x, QMUXError = 0x%x", __func__, \ le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult), \ QMUXError); \ } \ } while (0) int qmiclientId[QMUX_TYPE_WDS_ADMIN + 1]; // GobiNet use fd to indicate client ID, so type of // qmiclientId must be int static uint32_t WdsConnectionIPv4Handle = 0; static uint32_t WdsConnectionIPv6Handle = 0; static int s_is_cdma = 0; static int s_hdr_personality = 0; // 0x01-HRPD, 0x02-eHRPD static char *qstrcpy(char *to, const char *from) { // no __strcpy_chk char *save = to; for (; (*to = *from) != '\0'; ++from, ++to) ; return (save); } typedef USHORT (*CUSTOMQMUX)(PQMUX_MSG pMUXMsg, void *arg); // To retrieve the ith (Index) TLV PQMI_TLV_HDR GetTLV(PQCQMUX_MSG_HDR pQMUXMsgHdr, int TLVType) { int TLVFind = 0; USHORT Length = le16_to_cpu(pQMUXMsgHdr->Length); PQMI_TLV_HDR pTLVHdr = (PQMI_TLV_HDR)(pQMUXMsgHdr + 1); while (Length >= sizeof(QMI_TLV_HDR)) { TLVFind++; if (TLVType > 0x1000) { if ((TLVFind + 0x1000) == TLVType) return pTLVHdr; } else if (pTLVHdr->TLVType == TLVType) { return pTLVHdr; } Length -= (le16_to_cpu((pTLVHdr->TLVLength)) + sizeof(QMI_TLV_HDR)); pTLVHdr = (PQMI_TLV_HDR)(((UCHAR *)pTLVHdr) + le16_to_cpu(pTLVHdr->TLVLength) + sizeof(QMI_TLV_HDR)); } return NULL; } static USHORT GetQMUXTransactionId(void) { static int TransactionId = 0; if (++TransactionId > 0xFFFF) TransactionId = 1; return TransactionId; } static PQCQMIMSG ComposeQMUXMsg(UCHAR QMIType, USHORT Type, CUSTOMQMUX customQmuxMsgFunction, void *arg) { UCHAR QMIBuf[WDM_DEFAULT_BUFSIZE]; PQCQMIMSG pRequest = (PQCQMIMSG)QMIBuf; int Length; memset(QMIBuf, 0x00, sizeof(QMIBuf)); pRequest->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI; pRequest->QMIHdr.CtlFlags = 0x00; pRequest->QMIHdr.QMIType = QMIType; pRequest->QMIHdr.ClientId = qmiclientId[QMIType] & 0xFF; if (qmiclientId[QMIType] == 0) { dbg_time("QMIType %d has no clientID", QMIType); return NULL; } pRequest->MUXMsg.QMUXHdr.CtlFlags = QMUX_CTL_FLAG_SINGLE_MSG | QMUX_CTL_FLAG_TYPE_CMD; pRequest->MUXMsg.QMUXHdr.TransactionId = cpu_to_le16(GetQMUXTransactionId()); pRequest->MUXMsg.QMUXMsgHdr.Type = cpu_to_le16(Type); if (customQmuxMsgFunction) pRequest->MUXMsg.QMUXMsgHdr.Length = cpu_to_le16(customQmuxMsgFunction(&pRequest->MUXMsg, arg) - sizeof(QCQMUX_MSG_HDR)); else pRequest->MUXMsg.QMUXMsgHdr.Length = cpu_to_le16(0x0000); pRequest->QMIHdr.Length = cpu_to_le16( le16_to_cpu(pRequest->MUXMsg.QMUXMsgHdr.Length) + sizeof(QCQMUX_MSG_HDR) + sizeof(QCQMUX_HDR) + sizeof(QCQMI_HDR) - 1); Length = le16_to_cpu(pRequest->QMIHdr.Length) + 1; pRequest = (PQCQMIMSG)malloc(Length); if (pRequest == NULL) { dbg_time("%s fail to malloc", __func__); } else { memcpy(pRequest, QMIBuf, Length); } return pRequest; } static USHORT WdsStartNwInterfaceReq(PQMUX_MSG pMUXMsg, void *arg) { PQMIWDS_TECHNOLOGY_PREFERECE pTechPref; PQMIWDS_AUTH_PREFERENCE pAuthPref; PQMIWDS_USERNAME pUserName; PQMIWDS_PASSWD pPasswd; PQMIWDS_APNNAME pApnName; PQMIWDS_IP_FAMILY_TLV pIpFamily; USHORT TLVLength = 0; UCHAR *pTLV; PROFILE_T *profile = (PROFILE_T *)arg; const char *profile_user = profile->user; const char *profile_password = profile->password; int profile_auth = profile->auth; if (s_is_cdma && (profile_user == NULL || profile_user[0] == '\0') && (profile_password == NULL || profile_password[0] == '\0')) { profile_user = "ctnet@mycdma.cn"; profile_password = "vnet.mobi"; profile_auth = 2; // chap } pTLV = (UCHAR *)(&pMUXMsg->StartNwInterfaceReq + 1); pMUXMsg->StartNwInterfaceReq.Length = 0; // Set technology Preferece pTechPref = (PQMIWDS_TECHNOLOGY_PREFERECE)(pTLV + TLVLength); pTechPref->TLVType = 0x30; pTechPref->TLVLength = cpu_to_le16(0x01); if (s_is_cdma == 0) pTechPref->TechPreference = 0x01; else pTechPref->TechPreference = 0x02; TLVLength += (le16_to_cpu(pTechPref->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); // Set APN Name if (profile->apn && !s_is_cdma) { // cdma no apn pApnName = (PQMIWDS_APNNAME)(pTLV + TLVLength); pApnName->TLVType = 0x14; pApnName->TLVLength = cpu_to_le16(strlen(profile->apn)); qstrcpy((char *)&pApnName->ApnName, profile->apn); TLVLength += (le16_to_cpu(pApnName->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Set User Name if (profile_user) { pUserName = (PQMIWDS_USERNAME)(pTLV + TLVLength); pUserName->TLVType = 0x17; pUserName->TLVLength = cpu_to_le16(strlen(profile_user)); qstrcpy((char *)&pUserName->UserName, profile_user); TLVLength += (le16_to_cpu(pUserName->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Set Password if (profile_password) { pPasswd = (PQMIWDS_PASSWD)(pTLV + TLVLength); pPasswd->TLVType = 0x18; pPasswd->TLVLength = cpu_to_le16(strlen(profile_password)); qstrcpy((char *)&pPasswd->Passwd, profile_password); TLVLength += (le16_to_cpu(pPasswd->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Set Auth Protocol if (profile_user && profile_password) { pAuthPref = (PQMIWDS_AUTH_PREFERENCE)(pTLV + TLVLength); pAuthPref->TLVType = 0x16; pAuthPref->TLVLength = cpu_to_le16(0x01); pAuthPref->AuthPreference = profile_auth; // 0 ~ None, 1 ~ Pap, 2 ~ Chap, 3 ~ MsChapV2 TLVLength += (le16_to_cpu(pAuthPref->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Add IP Family Preference pIpFamily = (PQMIWDS_IP_FAMILY_TLV)(pTLV + TLVLength); pIpFamily->TLVType = 0x19; pIpFamily->TLVLength = cpu_to_le16(0x01); pIpFamily->IpFamily = profile->curIpFamily; 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 PQMIWDS_PROFILE_IDENTIFIER pProfileIndex = (PQMIWDS_PROFILE_IDENTIFIER)(pTLV + TLVLength); pProfileIndex->TLVLength = cpu_to_le16(0x01); pProfileIndex->TLVType = 0x31; pProfileIndex->ProfileIndex = profile->pdpindex; if (s_is_cdma && s_hdr_personality == 0x02) { pProfileIndex->TLVType = 0x32; // profile_index_3gpp2 pProfileIndex->ProfileIndex = 101; } TLVLength += (le16_to_cpu(pProfileIndex->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } return sizeof(QMIWDS_START_NETWORK_INTERFACE_REQ_MSG) + TLVLength; } static USHORT WdsStopNwInterfaceReq(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->StopNwInterfaceReq.TLVType = 0x01; pMUXMsg->StopNwInterfaceReq.TLVLength = cpu_to_le16(0x04); if (*((int *)arg) == IpFamilyV4) pMUXMsg->StopNwInterfaceReq.Handle = cpu_to_le32(WdsConnectionIPv4Handle); else pMUXMsg->StopNwInterfaceReq.Handle = cpu_to_le32(WdsConnectionIPv6Handle); return sizeof(QMIWDS_STOP_NETWORK_INTERFACE_REQ_MSG); } static USHORT WdsSetClientIPFamilyPref(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->SetClientIpFamilyPrefReq.TLVType = 0x01; pMUXMsg->SetClientIpFamilyPrefReq.TLVLength = cpu_to_le16(0x01); pMUXMsg->SetClientIpFamilyPrefReq.IpPreference = *((UCHAR *)arg); return sizeof(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ_MSG); } static USHORT WdsSetAutoConnect(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->SetAutoConnectReq.TLVType = 0x01; pMUXMsg->SetAutoConnectReq.TLVLength = cpu_to_le16(0x01); pMUXMsg->SetAutoConnectReq.autoconnect_setting = *((UCHAR *)arg); return sizeof(QMIWDS_SET_AUTO_CONNECT_REQ_MSG); } enum peripheral_ep_type { DATA_EP_TYPE_RESERVED = 0x0, DATA_EP_TYPE_HSIC = 0x1, DATA_EP_TYPE_HSUSB = 0x2, DATA_EP_TYPE_PCIE = 0x3, DATA_EP_TYPE_EMBEDDED = 0x4, DATA_EP_TYPE_BAM_DMUX = 0x5, }; typedef struct { UINT rx_urb_size; enum peripheral_ep_type ep_type; UINT iface_id; UCHAR MuxId; } QMAP_SETTING; static USHORT WdsSetQMUXBindMuxDataPort(PQMUX_MSG pMUXMsg, void *arg) { QMAP_SETTING *qmap_settings = (QMAP_SETTING *)arg; pMUXMsg->BindMuxDataPortReq.TLVType = 0x10; pMUXMsg->BindMuxDataPortReq.TLVLength = cpu_to_le16(0x08); pMUXMsg->BindMuxDataPortReq.ep_type = cpu_to_le32(qmap_settings->ep_type); pMUXMsg->BindMuxDataPortReq.iface_id = cpu_to_le32(qmap_settings->iface_id); pMUXMsg->BindMuxDataPortReq.TLV2Type = 0x11; pMUXMsg->BindMuxDataPortReq.TLV2Length = cpu_to_le16(0x01); pMUXMsg->BindMuxDataPortReq.MuxId = qmap_settings->MuxId; pMUXMsg->BindMuxDataPortReq.TLV3Type = 0x13; pMUXMsg->BindMuxDataPortReq.TLV3Length = cpu_to_le16(0x04); pMUXMsg->BindMuxDataPortReq.client_type = cpu_to_le32(1); // WDS_CLIENT_TYPE_TETHERED return sizeof(QMIWDS_BIND_MUX_DATA_PORT_REQ_MSG); } static USHORT WdaSetDataFormat(PQMUX_MSG pMUXMsg, void *arg) { QMAP_SETTING *qmap_settings = (QMAP_SETTING *)arg; if (qmap_settings->rx_urb_size == 0) { PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV_QOS pWdsAdminQosTlv; PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV linkProto; PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV dlTlp; pWdsAdminQosTlv = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV_QOS)(&pMUXMsg->QMUXMsgHdr + 1); pWdsAdminQosTlv->TLVType = 0x10; pWdsAdminQosTlv->TLVLength = cpu_to_le16(0x0001); pWdsAdminQosTlv->QOSSetting = 0; /* no-QOS header */ linkProto = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)(pWdsAdminQosTlv + 1); linkProto->TLVType = 0x11; linkProto->TLVLength = cpu_to_le16(4); linkProto->Value = cpu_to_le32(0x01); /* Set Ethernet mode */ dlTlp = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)(linkProto + 1); ; dlTlp->TLVType = 0x13; dlTlp->TLVLength = cpu_to_le16(4); dlTlp->Value = cpu_to_le32(0x00); if (sizeof(*linkProto) != 7) dbg_time("%s sizeof(*linkProto) = %d, is not 7!", __func__, sizeof(*linkProto)); return sizeof(QCQMUX_MSG_HDR) + sizeof(*pWdsAdminQosTlv) + sizeof(*linkProto) + sizeof(*dlTlp); } else { // Indicates whether the Quality of Service(QOS) data format is used by // the client. pMUXMsg->SetDataFormatReq.QosDataFormatTlv.TLVType = 0x10; pMUXMsg->SetDataFormatReq.QosDataFormatTlv.TLVLength = cpu_to_le16(0x0001); pMUXMsg->SetDataFormatReq.QosDataFormatTlv.QOSSetting = 0; /* no-QOS header */ // Underlying Link Layer Protocol pMUXMsg->SetDataFormatReq.UnderlyingLinkLayerProtocolTlv.TLVType = 0x11; pMUXMsg->SetDataFormatReq.UnderlyingLinkLayerProtocolTlv.TLVLength = cpu_to_le16(4); pMUXMsg->SetDataFormatReq.UnderlyingLinkLayerProtocolTlv.Value = cpu_to_le32(0x02); /* Set IP mode */ // Uplink (UL) data aggregation protocol to be used for uplink data // transfer. pMUXMsg->SetDataFormatReq.UplinkDataAggregationProtocolTlv.TLVType = 0x12; pMUXMsg->SetDataFormatReq.UplinkDataAggregationProtocolTlv.TLVLength = cpu_to_le16(4); pMUXMsg->SetDataFormatReq.UplinkDataAggregationProtocolTlv.Value = cpu_to_le32(0x05); // UL QMAP is enabled // Downlink (DL) data aggregation protocol to be used for downlink data // transfer pMUXMsg->SetDataFormatReq.DownlinkDataAggregationProtocolTlv.TLVType = 0x13; pMUXMsg->SetDataFormatReq.DownlinkDataAggregationProtocolTlv.TLVLength = cpu_to_le16(4); pMUXMsg->SetDataFormatReq.DownlinkDataAggregationProtocolTlv.Value = cpu_to_le32(0x05); // UL QMAP is enabled // Maximum number of datagrams in a single aggregated packet on downlink pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxDatagramsTlv .TLVType = 0x15; pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxDatagramsTlv .TLVLength = cpu_to_le16(4); pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxDatagramsTlv.Value = cpu_to_le32(qmap_settings->rx_urb_size / 512); // Maximum size in bytes of a single aggregated packet allowed on // downlink pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxSizeTlv.TLVType = 0x16; pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxSizeTlv.TLVLength = cpu_to_le16(4); pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxSizeTlv.Value = cpu_to_le32(qmap_settings->rx_urb_size); // Peripheral End Point ID pMUXMsg->SetDataFormatReq.epTlv.TLVType = 0x17; pMUXMsg->SetDataFormatReq.epTlv.TLVLength = cpu_to_le16(8); pMUXMsg->SetDataFormatReq.epTlv.ep_type = cpu_to_le32(qmap_settings->ep_type); pMUXMsg->SetDataFormatReq.epTlv.iface_id = cpu_to_le32(qmap_settings->iface_id); return sizeof(QMIWDS_ADMIN_SET_DATA_FORMAT_REQ_MSG); } } #ifdef CONFIG_SIM static USHORT UimVerifyPinReqSend(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->UIMUIMVerifyPinReq.TLVType = 0x01; pMUXMsg->UIMUIMVerifyPinReq.TLVLength = cpu_to_le16(0x02); pMUXMsg->UIMUIMVerifyPinReq.Session_Type = 0x00; pMUXMsg->UIMUIMVerifyPinReq.Aid_Len = 0x00; pMUXMsg->UIMUIMVerifyPinReq.TLV2Type = 0x02; pMUXMsg->UIMUIMVerifyPinReq.TLV2Length = cpu_to_le16(2 + strlen((const char *)arg)); pMUXMsg->UIMUIMVerifyPinReq.PINID = 0x01; // Pin1, not Puk pMUXMsg->UIMUIMVerifyPinReq.PINLen = strlen((const char *)arg); qstrcpy((PCHAR)&pMUXMsg->UIMUIMVerifyPinReq.PINValue, ((const char *)arg)); return sizeof(QMIUIM_VERIFY_PIN_REQ_MSG) + (strlen((const char *)arg) - 1); } //2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817 static USHORT UimBindPinReqSend_NAS_WMS(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->UIMUIMBindPinReq.TLVType = 0x01; pMUXMsg->UIMUIMBindPinReq.TLVLength = cpu_to_le16(0x01); pMUXMsg->UIMUIMBindPinReq.Value = 0x01; return sizeof(QMIUIM_BIND_PIN_REQ_MSG); } static USHORT UimBindPinReqSend_WDS_DMS_QOS(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->UIMUIMBindPinReq_4.TLVType = 0x01; pMUXMsg->UIMUIMBindPinReq_4.TLVLength = cpu_to_le16(0x04); pMUXMsg->UIMUIMBindPinReq_4.Value = 0x0002; return sizeof(QMIUIM_BIND_PIN_REQ_MSG_4); } //2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817 #ifdef CONFIG_IMSI_ICCID static USHORT UimReadTransparentIMSIReqSend(PQMUX_MSG pMUXMsg, void *arg) { PREAD_TRANSPARENT_TLV pReadTransparent; pMUXMsg->UIMUIMReadTransparentReq.TLVType = 0x01; pMUXMsg->UIMUIMReadTransparentReq.TLVLength = cpu_to_le16(0x02); if (!strcmp((char *)arg, "EF_ICCID")) { pMUXMsg->UIMUIMReadTransparentReq.Session_Type = 0x06; pMUXMsg->UIMUIMReadTransparentReq.Aid_Len = 0x00; pMUXMsg->UIMUIMReadTransparentReq.TLV2Type = 0x02; pMUXMsg->UIMUIMReadTransparentReq.file_id = cpu_to_le16(0x2FE2); pMUXMsg->UIMUIMReadTransparentReq.path_len = 0x02; pMUXMsg->UIMUIMReadTransparentReq.path[0] = 0x00; pMUXMsg->UIMUIMReadTransparentReq.path[1] = 0x3F; } else if (!strcmp((char *)arg, "EF_IMSI")) { pMUXMsg->UIMUIMReadTransparentReq.Session_Type = 0x00; pMUXMsg->UIMUIMReadTransparentReq.Aid_Len = 0x00; pMUXMsg->UIMUIMReadTransparentReq.TLV2Type = 0x02; pMUXMsg->UIMUIMReadTransparentReq.file_id = cpu_to_le16(0x6F07); pMUXMsg->UIMUIMReadTransparentReq.path_len = 0x04; pMUXMsg->UIMUIMReadTransparentReq.path[0] = 0x00; pMUXMsg->UIMUIMReadTransparentReq.path[1] = 0x3F; pMUXMsg->UIMUIMReadTransparentReq.path[2] = 0xFF; pMUXMsg->UIMUIMReadTransparentReq.path[3] = 0x7F; } pMUXMsg->UIMUIMReadTransparentReq.TLV2Length = cpu_to_le16(3 + pMUXMsg->UIMUIMReadTransparentReq.path_len); pReadTransparent = (PREAD_TRANSPARENT_TLV)( &pMUXMsg->UIMUIMReadTransparentReq .path[pMUXMsg->UIMUIMReadTransparentReq.path_len]); pReadTransparent->TLVType = 0x03; pReadTransparent->TLVLength = cpu_to_le16(0x04); pReadTransparent->Offset = cpu_to_le16(0x00); pReadTransparent->Length = cpu_to_le16(0x00); return (sizeof(QMIUIM_READ_TRANSPARENT_REQ_MSG) + pMUXMsg->UIMUIMReadTransparentReq.path_len + sizeof(READ_TRANSPARENT_TLV)); } #endif #endif #ifdef CONFIG_APN static USHORT WdsGetProfileSettingsReqSend(PQMUX_MSG pMUXMsg, void *arg) { PROFILE_T *profile = (PROFILE_T *)arg; pMUXMsg->GetProfileSettingsReq.Length = cpu_to_le16(sizeof(QMIWDS_GET_PROFILE_SETTINGS_REQ_MSG) - 4); pMUXMsg->GetProfileSettingsReq.TLVType = 0x01; pMUXMsg->GetProfileSettingsReq.TLVLength = cpu_to_le16(0x02); pMUXMsg->GetProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2 pMUXMsg->GetProfileSettingsReq.ProfileIndex = profile->pdpindex; return sizeof(QMIWDS_GET_PROFILE_SETTINGS_REQ_MSG); } //begin modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610 static USHORT WdsCreateProfileSettingsReq(PQMUX_MSG pMUXMsg, void *arg) { USHORT TLVLength = 0; UCHAR *pTLV; PROFILE_T *profile = (PROFILE_T *)arg; PQMIWDS_PDPTYPE pPdpType; pMUXMsg->CreateProfileSettingsReq.Length = cpu_to_le16(sizeof(QMIWDS_CREATE_PROFILE_SETTINGS_REQ_MSG) - 4); pMUXMsg->CreateProfileSettingsReq.TLVType = 0x01; pMUXMsg->CreateProfileSettingsReq.TLVLength = cpu_to_le16(0x01); pMUXMsg->CreateProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2 pTLV = (UCHAR *)(&pMUXMsg->CreateProfileSettingsReq + 1); pPdpType = (PQMIWDS_PDPTYPE)(pTLV + TLVLength); pPdpType->TLVType = 0x11; pPdpType->TLVLength = cpu_to_le16(0x01); // 0 ?C PDP-IP (IPv4) // 1 ?C PDP-PPP // 2 ?C PDP-IPv6 // 3 ?C PDP-IPv4v6 if (profile->ipv4_flag && profile->ipv6_flag) pPdpType->PdpType = 3; else if (profile->ipv6_flag) pPdpType->PdpType = 2; else pPdpType->PdpType = 0; TLVLength += (le16_to_cpu(pPdpType->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); // Set APN Name if (profile->apn) { PQMIWDS_APNNAME pApnName = (PQMIWDS_APNNAME)(pTLV + TLVLength); pApnName->TLVType = 0x14; pApnName->TLVLength = cpu_to_le16(strlen(profile->apn)); qstrcpy((char *)&pApnName->ApnName, profile->apn); TLVLength += (le16_to_cpu(pApnName->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Set User Name if (profile->user) { PQMIWDS_USERNAME pUserName = (PQMIWDS_USERNAME)(pTLV + TLVLength); pUserName->TLVType = 0x1B; pUserName->TLVLength = cpu_to_le16(strlen(profile->user)); qstrcpy((char *)&pUserName->UserName, profile->user); TLVLength += (le16_to_cpu(pUserName->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Set Password if (profile->password) { PQMIWDS_PASSWD pPasswd = (PQMIWDS_PASSWD)(pTLV + TLVLength); pPasswd->TLVType = 0x1C; pPasswd->TLVLength = cpu_to_le16(strlen(profile->password)); qstrcpy((char *)&pPasswd->Passwd, profile->password); TLVLength += (le16_to_cpu(pPasswd->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Set Auth Protocol if (profile->user && profile->password) { PQMIWDS_AUTH_PREFERENCE pAuthPref = (PQMIWDS_AUTH_PREFERENCE)(pTLV + TLVLength); pAuthPref->TLVType = 0x1D; pAuthPref->TLVLength = cpu_to_le16(0x01); pAuthPref->AuthPreference = profile->auth; // 0 ~ None, 1 ~ Pap, 2 ~ Chap, 3 ~ MsChapV2 TLVLength += (le16_to_cpu(pAuthPref->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } return sizeof(QMIWDS_CREATE_PROFILE_SETTINGS_REQ_MSG) + TLVLength; } //end modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610 static USHORT WdsModifyProfileSettingsReq(PQMUX_MSG pMUXMsg, void *arg) { USHORT TLVLength = 0; UCHAR *pTLV; PROFILE_T *profile = (PROFILE_T *)arg; PQMIWDS_PDPTYPE pPdpType; pMUXMsg->ModifyProfileSettingsReq.Length = cpu_to_le16(sizeof(QMIWDS_MODIFY_PROFILE_SETTINGS_REQ_MSG) - 4); pMUXMsg->ModifyProfileSettingsReq.TLVType = 0x01; pMUXMsg->ModifyProfileSettingsReq.TLVLength = cpu_to_le16(0x02); pMUXMsg->ModifyProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2 pMUXMsg->ModifyProfileSettingsReq.ProfileIndex = profile->pdpindex; pTLV = (UCHAR *)(&pMUXMsg->ModifyProfileSettingsReq + 1); pPdpType = (PQMIWDS_PDPTYPE)(pTLV + TLVLength); pPdpType->TLVType = 0x11; pPdpType->TLVLength = cpu_to_le16(0x01); // 0 ?C PDP-IP (IPv4) // 1 ?C PDP-PPP // 2 ?C PDP-IPv6 // 3 ?C PDP-IPv4v6 if (profile->ipv6_flag && profile->ipv4_flag) pPdpType->PdpType = 3; else if (profile->ipv6_flag) pPdpType->PdpType = 2; else pPdpType->PdpType = 0; TLVLength += (le16_to_cpu(pPdpType->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); // Set APN Name if (profile->apn) { PQMIWDS_APNNAME pApnName = (PQMIWDS_APNNAME)(pTLV + TLVLength); pApnName->TLVType = 0x14; pApnName->TLVLength = cpu_to_le16(strlen(profile->apn)); qstrcpy((char *)&pApnName->ApnName, profile->apn); TLVLength += (le16_to_cpu(pApnName->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Set User Name if (profile->user) { PQMIWDS_USERNAME pUserName = (PQMIWDS_USERNAME)(pTLV + TLVLength); pUserName->TLVType = 0x1B; pUserName->TLVLength = cpu_to_le16(strlen(profile->user)); qstrcpy((char *)&pUserName->UserName, profile->user); TLVLength += (le16_to_cpu(pUserName->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Set Password if (profile->password) { PQMIWDS_PASSWD pPasswd = (PQMIWDS_PASSWD)(pTLV + TLVLength); pPasswd->TLVType = 0x1C; pPasswd->TLVLength = cpu_to_le16(strlen(profile->password)); qstrcpy((char *)&pPasswd->Passwd, profile->password); TLVLength += (le16_to_cpu(pPasswd->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } // Set Auth Protocol if (profile->user && profile->password) { PQMIWDS_AUTH_PREFERENCE pAuthPref = (PQMIWDS_AUTH_PREFERENCE)(pTLV + TLVLength); pAuthPref->TLVType = 0x1D; pAuthPref->TLVLength = cpu_to_le16(0x01); pAuthPref->AuthPreference = profile->auth; // 0 ~ None, 1 ~ Pap, 2 ~ Chap, 3 ~ MsChapV2 TLVLength += (le16_to_cpu(pAuthPref->TLVLength) + sizeof(QCQMICTL_TLV_HDR)); } return sizeof(QMIWDS_MODIFY_PROFILE_SETTINGS_REQ_MSG) + TLVLength; } #endif static USHORT WdsGetRuntimeSettingReq(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->GetRuntimeSettingsReq.TLVType = 0x10; pMUXMsg->GetRuntimeSettingsReq.TLVLength = cpu_to_le16(0x04); // the following mask also applies to IPV6 pMUXMsg->GetRuntimeSettingsReq.Mask = cpu_to_le32(QMIWDS_GET_RUNTIME_SETTINGS_MASK_IPV4DNS_ADDR | QMIWDS_GET_RUNTIME_SETTINGS_MASK_IPV4_ADDR | QMIWDS_GET_RUNTIME_SETTINGS_MASK_MTU | QMIWDS_GET_RUNTIME_SETTINGS_MASK_IPV4GATEWAY_ADDR); // | // QMIWDS_GET_RUNTIME_SETTINGS_MASK_PCSCF_SV_ADDR | // QMIWDS_GET_RUNTIME_SETTINGS_MASK_PCSCF_DOM_NAME; return sizeof(QMIWDS_GET_RUNTIME_SETTINGS_REQ_MSG); } static PQCQMIMSG s_pRequest; static PQCQMIMSG s_pResponse; static pthread_mutex_t s_commandmutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t s_commandcond = PTHREAD_COND_INITIALIZER; static int is_response(const PQCQMIMSG pRequest, const PQCQMIMSG pResponse) { if ((pRequest->QMIHdr.QMIType == pResponse->QMIHdr.QMIType) && (pRequest->QMIHdr.ClientId == pResponse->QMIHdr.ClientId)) { USHORT requestTID, responseTID; if (pRequest->QMIHdr.QMIType == QMUX_TYPE_CTL) { requestTID = pRequest->CTLMsg.QMICTLMsgHdr.TransactionId; responseTID = pResponse->CTLMsg.QMICTLMsgHdr.TransactionId; } else { requestTID = le16_to_cpu(pRequest->MUXMsg.QMUXHdr.TransactionId); responseTID = le16_to_cpu(pResponse->MUXMsg.QMUXHdr.TransactionId); } return (requestTID == responseTID); } return 0; } int (*qmidev_send)(PQCQMIMSG pRequest); int QmiThreadSendQMITimeout(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse, unsigned msecs) { int ret; if (!pRequest) { return -EINVAL; } pthread_mutex_lock(&s_commandmutex); if (ppResponse) *ppResponse = NULL; dump_qmi(pRequest, le16_to_cpu(pRequest->QMIHdr.Length) + 1); s_pRequest = pRequest; s_pResponse = NULL; ret = qmidev_send(pRequest); if (ret == 0) { ret = pthread_cond_timeout_np(&s_commandcond, &s_commandmutex, msecs); if (!ret) { if (s_pResponse && ppResponse) { *ppResponse = s_pResponse; } else { if (s_pResponse) { free(s_pResponse); s_pResponse = NULL; } } } else { dbg_time("%s pthread_cond_timeout_np=%d, errno: %d (%s)", __func__, ret, errno, strerror(errno)); } } pthread_mutex_unlock(&s_commandmutex); return ret; } int QmiThreadSendQMI(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse) { return QmiThreadSendQMITimeout(pRequest, ppResponse, 30 * 1000); } void QmiThreadRecvQMI(PQCQMIMSG pResponse) { pthread_mutex_lock(&s_commandmutex); if (pResponse == NULL) { if (s_pRequest) { free(s_pRequest); s_pRequest = NULL; s_pResponse = NULL; pthread_cond_signal(&s_commandcond); } pthread_mutex_unlock(&s_commandmutex); return; } dump_qmi(pResponse, le16_to_cpu(pResponse->QMIHdr.Length) + 1); if (s_pRequest && is_response(s_pRequest, pResponse)) { free(s_pRequest); s_pRequest = NULL; s_pResponse = malloc(le16_to_cpu(pResponse->QMIHdr.Length) + 1); if (s_pResponse != NULL) { memcpy(s_pResponse, pResponse, le16_to_cpu(pResponse->QMIHdr.Length) + 1); } pthread_cond_signal(&s_commandcond); } else if ((pResponse->QMIHdr.QMIType == QMUX_TYPE_NAS) && (le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.Type) == QMINAS_SERVING_SYSTEM_IND)) { qmidevice_send_event_to_main( RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED); } else if ((pResponse->QMIHdr.QMIType == QMUX_TYPE_WDS) && (le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.Type) == QMIWDS_GET_PKT_SRVC_STATUS_IND)) { qmidevice_send_event_to_main(RIL_UNSOL_DATA_CALL_LIST_CHANGED); } else if ((pResponse->QMIHdr.QMIType == QMUX_TYPE_WDS_IPV6) && (le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.Type) == QMIWDS_GET_PKT_SRVC_STATUS_IND)) { qmidevice_send_event_to_main(RIL_UNSOL_DATA_CALL_LIST_CHANGED); } else if ((pResponse->QMIHdr.QMIType == QMUX_TYPE_NAS) && (le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.Type) == QMINAS_SYS_INFO_IND)) { qmidevice_send_event_to_main( RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED); } else { if (debug_qmi) dbg_time("nobody care this qmi msg!!"); } pthread_mutex_unlock(&s_commandmutex); } int requestSetEthMode(PROFILE_T *profile) { PQCQMIMSG pRequest; PQCQMIMSG pResponse = NULL; PQMUX_MSG pMUXMsg; int err; PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV linkProto; UCHAR IpPreference; UCHAR autoconnect_setting = 0; QMAP_SETTING qmap_settings = {0, 0, 0, 0}; if (profile->qmap_mode) { profile->rawIP = 1; qmap_settings.MuxId = profile->muxid; if (qmidev_is_pciemhi(profile->qmichannel)) { // SDX20_PCIE qmap_settings.rx_urb_size = 32*1024; //SDX24&SDX55 support 32KB qmap_settings.ep_type = DATA_EP_TYPE_PCIE; qmap_settings.iface_id = 0x04; } else { // for MDM9x07&MDM9x40&SDX20 USB qmap_settings.rx_urb_size = profile->qmap_size; //profile->qmap_size; // SDX24&SDX55 support 32KB qmap_settings.ep_type = DATA_EP_TYPE_HSUSB; //2021-02-08 zhangkaibo@fibocom.com changed begin for mantis 0070613 qmap_settings.iface_id = profile->interfacenum; //2021-02-08 zhangkaibo@fibocom.com changed end for mantis 0070613 } if (qmidev_is_gobinet( profile->qmichannel)) { // GobiNet set data format // in GobiNet driver goto skip_WdaSetDataFormat; } else if (profile->qmap_mode > 1) { // QMAP MUX enabled, set data format in fibo-qmi-proxy //2021-06-03 willa.liu@fibocom.com changed begin for support mantis 0079541 //2021-01-27 willa.liu@fibocom.com changed begin for support mantis 0068849 //goto skip_WdaSetDataFormat; goto skip_WdaSetDataFormat; //2021-01-27 willa.liu@fibocom.com changed end for support mantis 0068849 //2021-06-03 willa.liu@fibocom.com changed end for support mantis 0079541 } } pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS_ADMIN, QMIWDS_ADMIN_SET_DATA_FORMAT_REQ, WdaSetDataFormat, (void *)&qmap_settings); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); linkProto = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, 0x11); if (linkProto != NULL) { profile->rawIP = (le32_to_cpu(linkProto->Value) == 2); } linkProto = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, 0x16); if (linkProto != NULL && profile->qmap_mode) { qmap_settings.rx_urb_size = le32_to_cpu(linkProto->Value); dbg_time( "qmap_settings.rx_urb_size = %d", qmap_settings.rx_urb_size); // must same as rx_urb_size defined // in GobiNet&qmi_wwan driver } free(pResponse); skip_WdaSetDataFormat: //bind v4 client // set ipv4 if(profile->ipv4_flag) { /* IpPreference = IpFamilyV4; pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ, WdsSetClientIPFamilyPref, (void *)&IpPreference); err = QmiThreadSendQMI(pRequest, &pResponse); if (pResponse) free(pResponse); */ if (profile->qmapnet_adapter) { // bind wds mux data port pRequest = ComposeQMUXMsg( QMUX_TYPE_WDS, QMIWDS_BIND_MUX_DATA_PORT_REQ, WdsSetQMUXBindMuxDataPort, (void *)&qmap_settings); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); if (pResponse) free(pResponse); } // set auto connect pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_SET_AUTO_CONNECT_REQ, WdsSetAutoConnect, (void *)&autoconnect_setting); QmiThreadSendQMI(pRequest, &pResponse); if (pResponse) free(pResponse); } //bind v6 client if(profile->ipv6_flag) { IpPreference = IpFamilyV6; pRequest = ComposeQMUXMsg( QMUX_TYPE_WDS_IPV6, QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ, WdsSetClientIPFamilyPref, (void *)&IpPreference); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); if (pResponse) free(pResponse); if (profile->qmapnet_adapter) { // bind wds mux data port pRequest = ComposeQMUXMsg( QMUX_TYPE_WDS_IPV6, QMIWDS_BIND_MUX_DATA_PORT_REQ, WdsSetQMUXBindMuxDataPort, (void *)&qmap_settings); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); if (pResponse) free(pResponse); } IpPreference = IpFamilyV6; pRequest = ComposeQMUXMsg( QMUX_TYPE_WDS_IPV6, QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ, WdsSetClientIPFamilyPref, (void *)&IpPreference); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); if (pResponse) free(pResponse); // set auto connect pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS_IPV6, QMIWDS_SET_AUTO_CONNECT_REQ, WdsSetAutoConnect, (void *)&autoconnect_setting); QmiThreadSendQMI(pRequest, &pResponse); if (pResponse) free(pResponse); } return 0; } #ifdef CONFIG_SIM int requestGetPINStatus(SIM_Status *pSIMStatus) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; PQMIDMS_UIM_PIN_STATUS pPin1Status = NULL; // PQMIDMS_UIM_PIN_STATUS pPin2Status = NULL; pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_GET_CARD_STATUS_REQ, NULL, NULL); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); pPin1Status = (PQMIDMS_UIM_PIN_STATUS)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11); // pPin2Status = // (PQMIDMS_UIM_PIN_STATUS)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x12); if (pPin1Status != NULL) { if (pPin1Status->PINStatus == QMI_PIN_STATUS_NOT_VERIF) { *pSIMStatus = SIM_PIN; } else if (pPin1Status->PINStatus == QMI_PIN_STATUS_BLOCKED) { *pSIMStatus = SIM_PUK; } else if (pPin1Status->PINStatus == QMI_PIN_STATUS_PERM_BLOCKED) { *pSIMStatus = SIM_BAD; } } free(pResponse); return 0; } static int requestGetSIMMode(PROFILE_T *profile) { int i; int fd; int ret; int len; char buffer[1024] = {0}; char *sendbuffer = "AT+GTDUALSIMEN?"; int totallen = 0; fd_set readfds; struct timeval timeout; struct termios tiosfd, tio; int timeoutVal = 5; char *dev = NULL; if(qmidev_is_gobinet(profile->qmichannel)) { dev = "/dev/ttyUSB1"; //The port under Linux is operated by opening the device file } else { dev = "/dev/mhi_DUN"; //The port under Linux is operated by opening the device file } fd = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK); if(fd < 0) goto ERR; fcntl(fd, F_SETFL, O_RDWR); xget1(fd, &tio, &tiosfd); if(xset1(fd, &tio, dev)) goto ERR; tcflush(fd, TCIOFLUSH); FD_ZERO(&readfds); FD_SET(fd, &readfds); sprintf(buffer, "%s\r", sendbuffer); ret = write (fd, buffer, strlen(buffer)); if(ret < 0) { dbg_time("write failed\n"); goto ERR; } dbg_time("dev: %s\nsendbuffer:%s\n", dev, sendbuffer); sleep(3); while(1) { timeout.tv_sec = timeoutVal; timeout.tv_usec = 0; ret = select(fd+1, &readfds, (fd_set *)0, (fd_set *)0, &timeout); if(ret > 0) { ret = read(fd, buffer+totallen, sizeof(buffer)-totallen-1); if(ret < 0) { dbg_time("read failed\n"); goto ERR; } if(ret == 0) { goto ERR; } totallen += ret; buffer[totallen] = '\0'; dbg_time("read %d %s", ret, &buffer[totallen-ret]); //current buffer is return value if(strstr(buffer, "+GTDUALSIMEN: 1")) { close(fd); dbg_time("read 1\n"); return 1; } else { close(fd); dbg_time("read 0/2/3\n"); return 0; } } else { dbg_time("select timeout\n"); goto ERR; } } close(fd); ERR: if(fd > 0) close(fd); return -1; } //2021-03-24 willa.liu@fibocom.com changed begin for support mantis 0071817 int requestGetSIMCardNumber(PROFILE_T *profile) { int i; int fd; int ret; int len; char buffer[1024] = {0}; int rate; char *sendbuffer; int totallen = 0; fd_set readfds; struct timeval timeout; struct termios tiosfd, tio; int timeoutVal = 5; char *dev = NULL; if(qmidev_is_gobinet(profile->qmichannel)) { dev = "/dev/ttyUSB1"; //The port under Linux is operated by opening the device file } else { dev = "/dev/mhi_DUN"; //The port under Linux is operated by opening the device file } rate = 115200; sendbuffer = "AT+GTDUALSIM?"; if(requestGetSIMMode(profile) != 1) { return 0; } fd = open(dev, O_RDWR | O_NOCTTY | O_NONBLOCK); if(fd < 0) goto ERR; fcntl(fd, F_SETFL, O_RDWR); xget1(fd, &tio, &tiosfd); if(xset1(fd, &tio, dev)) goto ERR; tcflush(fd, TCIOFLUSH); FD_ZERO(&readfds); FD_SET(fd, &readfds); sprintf(buffer, "%s\r", sendbuffer); ret = write (fd, buffer, strlen(buffer)); if(ret < 0) { dbg_time("write failed\n"); goto ERR; } dbg_time("dev: %s\nrate:%d\nsendbuffer:%s\n", dev, rate, sendbuffer); sleep(3); goto read_result; while(1) { timeout.tv_sec = timeoutVal; timeout.tv_usec = 0; //ret = select(fd+1, &readfds, (fd_set *)0, (fd_set *)0, &timeout); //if(ret > 0) { read_result: ret = read(fd, buffer+totallen, sizeof(buffer)-totallen-1); if(ret < 0) { dbg_time("read failed\n"); goto ERR; } if(ret == 0) { goto ERR; } totallen += ret; buffer[totallen] = '\0'; dbg_time("read %d %s", ret, &buffer[totallen-ret]); //current buffer is return value if(strstr(buffer, "+GTDUALSIM: 0")) { close(fd); dbg_time("read 0\n"); return 0; } else if(strstr(buffer, "+GTDUALSIM: 1")) { close(fd); dbg_time("read 1\n"); return 1; } else continue; } //else { //dbg_time("select timeout\n"); //goto ERR; } } close(fd); ERR: if(fd > 0) close(fd); return -1; } int requestSimBindSubscription_NAS_WMS() { PQCQMIMSG pRequest_nas; PQCQMIMSG pResponse_nas; int err; pRequest_nas = ComposeQMUXMsg(QMUX_TYPE_NAS, QMI_NAS_BIND_SUBSCRIPTION_REQ_V01, UimBindPinReqSend_NAS_WMS, NULL); err = QmiThreadSendQMI(pRequest_nas, &pResponse_nas); free(pResponse_nas); return 0; } int requestSimBindSubscription_WDS_DMS_QOS() { PQCQMIMSG pRequest_wds; PQCQMIMSG pRequest_dms; PQCQMIMSG pResponse_wds; PQCQMIMSG pResponse_dms; int err; pRequest_wds = ComposeQMUXMsg(QMUX_TYPE_WDS, QMI_WDS_BIND_SUBSCRIPTION_REQ_V01, UimBindPinReqSend_WDS_DMS_QOS, NULL); err = QmiThreadSendQMI(pRequest_wds, &pResponse_wds); pRequest_dms = ComposeQMUXMsg(QMUX_TYPE_DMS, QMI_DMS_BIND_SUBSCRIPTION_REQ_V01, UimBindPinReqSend_WDS_DMS_QOS, NULL); err = QmiThreadSendQMI(pRequest_dms, &pResponse_dms); free(pResponse_wds); free(pResponse_dms); return 0; } //int requestGetSIMStatus(SIM_Status *pSIMStatus) int requestGetSIMStatus(SIM_Status *pSIMStatus, const int sim_select) { // RIL_REQUEST_GET_SIM_STATUS int i; dbg_time("sim_select = %d\n", sim_select); PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; const char *SIM_Status_String[] = { "SIM_ABSENT", "SIM_NOT_READY", "SIM_READY", /* SIM_READY means the radio state is RADIO_STATE_SIM_READY */ "SIM_PIN", "SIM_PUK", "SIM_NETWORK_PERSONALIZATION"}; pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_GET_CARD_STATUS_REQ, NULL, NULL); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); *pSIMStatus = SIM_ABSENT; PQMIUIM_CARD_STATUS pCardStatus = NULL; PQMIUIM_PIN_STATE pPINState = NULL; UCHAR CardState = 0x01; UCHAR PIN1State = QMI_PIN_STATUS_NOT_VERIF; // UCHAR PIN1Retries; // UCHAR PUK1Retries; // UCHAR PIN2State; // UCHAR PIN2Retries; // UCHAR PUK2Retries; void *temp = NULL; QMIUIM_APP_STATUS * curr_app = NULL; Instance * curr_ints = NULL; pCardStatus = (PQMIUIM_CARD_STATUS)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x10); if(sim_select == 0) { temp =(void*)pCardStatus + sizeof(QMIUIM_CARD_STATUS); curr_ints = temp; dbg_time("curr_ints_sim1 %s", curr_ints); temp = temp + sizeof(Instance); curr_app = temp; } else { temp = (void*)pCardStatus + sizeof(QMIUIM_CARD_STATUS); temp = temp + sizeof(Instance) + (sizeof(QMIUIM_APP_STATUS)*(((Instance *)temp)->NumApp)); curr_ints = temp; dbg_time("curr_ints_sim2 %s", curr_ints); curr_app = temp + sizeof(Instance); } /* if (pCardStatus != NULL) { for (i = 0; i < pCardStatus->NumApp; i++) { if (pCardStatus->AppStatus[i].AppType == 2) { pPINState = &(pCardStatus->AppStatus[i].PinState); break; } } if (i == pCardStatus->NumApp) { dbg_time("no USIM Card info"); return -1; } CardState = pCardStatus->CardState; if (pPINState->UnivPIN == 1) { PIN1State = pCardStatus->UPINState; */ if (curr_ints != NULL) { dbg_time("curr_ints->CardState is %d", curr_ints->CardState); dbg_time("curr_ints->NumApp is %d", curr_ints->NumApp); for (i = 0; i < curr_ints->NumApp; i++) { dbg_time("AppType = %d\n", curr_app[i].AppType); if (curr_app[i].AppType == 2) { pPINState = &(curr_app[i].PinState); break; } } if (i == curr_ints->NumApp) { dbg_time("no USIM Card info"); return -1; } //CardState = pCardStatus->CardState; CardState = curr_ints->CardState; if (pPINState->UnivPIN == 1) { PIN1State = curr_ints->UPINState; // PIN1Retries = pCardStatus->UPINRetries; // PUK1Retries = pCardStatus->UPUKRetries; } else { PIN1State = pPINState->PIN1State; // PIN1Retries = pPINState->PIN1Retries; // PUK1Retries = pPINState->PUK1Retries; } // PIN2State = pPINState->PIN2State; // PIN2Retries = pPINState->PIN2Retries; // PUK2Retries = pPINState->PUK2Retries; } //2021-03-24 willa.liu@fibocom.com changed end for support mantis 0071817 *pSIMStatus = SIM_ABSENT; if ((CardState == 0x01) && ((PIN1State == QMI_PIN_STATUS_VERIFIED) || (PIN1State == QMI_PIN_STATUS_DISABLED))) { *pSIMStatus = SIM_READY; } else if (CardState == 0x01) { if (PIN1State == QMI_PIN_STATUS_NOT_VERIF) { *pSIMStatus = SIM_PIN; } if (PIN1State == QMI_PIN_STATUS_BLOCKED) { *pSIMStatus = SIM_PUK; } else if (PIN1State == QMI_PIN_STATUS_PERM_BLOCKED) { *pSIMStatus = SIM_BAD; } else if (PIN1State == QMI_PIN_STATUS_NOT_INIT || PIN1State == QMI_PIN_STATUS_VERIFIED || PIN1State == QMI_PIN_STATUS_DISABLED) { *pSIMStatus = SIM_READY; } } else if (CardState == 0x00 || CardState == 0x02) { } else { } dbg_time("%s SIMStatus: %s", __func__, SIM_Status_String[*pSIMStatus]); free(pResponse); return 0; } int requestEnterSimPin(const CHAR *pPinCode) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_VERIFY_PIN_REQ, UimVerifyPinReqSend, (void *)pPinCode); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); free(pResponse); return 0; } #ifdef CONFIG_IMSI_ICCID int requestGetICCID(void) { // RIL_REQUEST_GET_IMSI PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; PQMIUIM_CONTENT pUimContent; int err; pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_READ_TRANSPARENT_REQ, UimReadTransparentIMSIReqSend, (void *)"EF_ICCID"); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); pUimContent = (PQMIUIM_CONTENT)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11); if (pUimContent != NULL) { static char DeviceICCID[32] = {'\0'}; int i = 0, j = 0; for (i = 0, j = 0; i < le16_to_cpu(pUimContent->content_len); ++i) { char charmaps[] = "0123456789ABCDEF"; DeviceICCID[j++] = charmaps[(pUimContent->content[i] & 0x0F)]; DeviceICCID[j++] = charmaps[((pUimContent->content[i] & 0xF0) >> 0x04)]; } DeviceICCID[j] = '\0'; dbg_time("%s DeviceICCID: %s", __func__, DeviceICCID); } free(pResponse); return 0; } int requestGetIMSI(void) { // RIL_REQUEST_GET_IMSI PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; PQMIUIM_CONTENT pUimContent; int err; pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_READ_TRANSPARENT_REQ, UimReadTransparentIMSIReqSend, (void *)"EF_IMSI"); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); pUimContent = (PQMIUIM_CONTENT)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11); if (pUimContent != NULL) { static char DeviceIMSI[32] = {'\0'}; int i = 0, j = 0; for (i = 0, j = 0; i < le16_to_cpu(pUimContent->content[0]); ++i) { if (i != 0) DeviceIMSI[j++] = (pUimContent->content[i + 1] & 0x0F) + '0'; DeviceIMSI[j++] = ((pUimContent->content[i + 1] & 0xF0) >> 0x04) + '0'; } DeviceIMSI[j] = '\0'; dbg_time("%s DeviceIMSI: %s", __func__, DeviceIMSI); } free(pResponse); return 0; } #endif #endif static void fibo_convert_cdma_mcc_2_ascii_mcc(USHORT *p_mcc, USHORT mcc) { unsigned int d1, d2, d3, buf = mcc + 111; if (mcc == 0x3FF) // wildcard { *p_mcc = 3; } else { d3 = buf % 10; buf = (d3 == 0) ? (buf - 10) / 10 : buf / 10; d2 = buf % 10; buf = (d2 == 0) ? (buf - 10) / 10 : buf / 10; d1 = (buf == 10) ? 0 : buf; // dbg_time("d1:%d, d2:%d,d3:%d",d1,d2,d3); if (d1 < 10 && d2 < 10 && d3 < 10) { *p_mcc = d1 * 100 + d2 * 10 + d3; } else { // dbg_time( "invalid digits %d %d %d", d1, d2, d3 ); *p_mcc = 0; } } } static void fibo_convert_cdma_mnc_2_ascii_mnc(USHORT *p_mnc, USHORT imsi_11_12) { unsigned int d1, d2, buf = imsi_11_12 + 11; if (imsi_11_12 == 0x7F) // wildcard { *p_mnc = 7; } else { d2 = buf % 10; buf = (d2 == 0) ? (buf - 10) / 10 : buf / 10; d1 = (buf == 10) ? 0 : buf; if (d1 < 10 && d2 < 10) { *p_mnc = d1 * 10 + d2; } else { // dbg_time( "invalid digits %d %d", d1, d2, 0 ); *p_mnc = 0; } } } int requestGetHomeNetwork(USHORT *p_mcc, USHORT *p_mnc, USHORT *p_sid, USHORT *p_nid) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; PHOME_NETWORK pHomeNetwork; PHOME_NETWORK_SYSTEMID pHomeNetworkSystemID; pRequest = ComposeQMUXMsg(QMUX_TYPE_NAS, QMINAS_GET_HOME_NETWORK_REQ, NULL, NULL); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); pHomeNetwork = (PHOME_NETWORK)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01); if (pHomeNetwork && p_mcc && p_mnc) { *p_mcc = le16_to_cpu(pHomeNetwork->MobileCountryCode); *p_mnc = le16_to_cpu(pHomeNetwork->MobileNetworkCode); // dbg_time("%s MobileCountryCode: %d, MobileNetworkCode: %d", __func__, // *pMobileCountryCode, *pMobileNetworkCode); } pHomeNetworkSystemID = (PHOME_NETWORK_SYSTEMID)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x10); if (pHomeNetworkSystemID && p_sid && p_nid) { *p_sid = le16_to_cpu( pHomeNetworkSystemID->SystemID); // china-hefei: sid 14451 *p_nid = le16_to_cpu(pHomeNetworkSystemID->NetworkID); // dbg_time("%s SystemID: %d, NetworkID: %d", __func__, *pSystemID, // *pNetworkID); } free(pResponse); return 0; } struct wwan_data_class_str class2str[] = { {WWAN_DATA_CLASS_NONE, "UNKNOWN"}, {WWAN_DATA_CLASS_GPRS, "GPRS"}, {WWAN_DATA_CLASS_EDGE, "EDGE"}, {WWAN_DATA_CLASS_UMTS, "UMTS"}, {WWAN_DATA_CLASS_HSDPA, "HSDPA"}, {WWAN_DATA_CLASS_HSUPA, "HSUPA"}, {WWAN_DATA_CLASS_LTE, "LTE"}, {WWAN_DATA_CLASS_1XRTT, "1XRTT"}, {WWAN_DATA_CLASS_1XEVDO, "1XEVDO"}, {WWAN_DATA_CLASS_1XEVDO_REVA, "1XEVDO_REVA"}, {WWAN_DATA_CLASS_1XEVDV, "1XEVDV"}, {WWAN_DATA_CLASS_3XRTT, "3XRTT"}, {WWAN_DATA_CLASS_1XEVDO_REVB, "1XEVDO_REVB"}, {WWAN_DATA_CLASS_UMB, "UMB"}, {WWAN_DATA_CLASS_CUSTOM, "CUSTOM"}, //begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 {WWAN_DATA_CLASS_5G, "NR5G"}, //end modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 }; CHAR *wwan_data_class2str(ULONG class) { unsigned int i = 0; for (i = 0; i < sizeof(class2str) / sizeof(class2str[0]); i++) { if (class2str[i].class == class) { return class2str[i].str; } } return "UNKNOWN"; } int requestRegistrationState2(UCHAR *pPSAttachedState) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; USHORT MobileCountryCode = 0; USHORT MobileNetworkCode = 0; const char *pDataCapStr = "UNKNOW"; LONG remainingLen; PSERVICE_STATUS_INFO pServiceStatusInfo; int is_lte = 0; PCDMA_SYSTEM_INFO pCdmaSystemInfo; PHDR_SYSTEM_INFO pHdrSystemInfo; PGSM_SYSTEM_INFO pGsmSystemInfo; PWCDMA_SYSTEM_INFO pWcdmaSystemInfo; PLTE_SYSTEM_INFO pLteSystemInfo; //begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 PNR5G_SYSTEM_INFO pNr5gSystemInfo; //end modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 PTDSCDMA_SYSTEM_INFO pTdscdmaSystemInfo; UCHAR DeviceClass = 0; ULONG DataCapList = 0; *pPSAttachedState = 0; pRequest = ComposeQMUXMsg(QMUX_TYPE_NAS, QMINAS_GET_SYS_INFO_REQ, NULL, NULL); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); pServiceStatusInfo = (PSERVICE_STATUS_INFO)( ((PCHAR)&pMUXMsg->GetSysInfoResp) + QCQMUX_MSG_HDR_SIZE); remainingLen = le16_to_cpu(pMUXMsg->GetSysInfoResp.Length); s_is_cdma = 0; s_hdr_personality = 0; while (remainingLen > 0) { switch (pServiceStatusInfo->TLVType) { case 0x10: // CDMA if (pServiceStatusInfo->SrvStatus == 0x02) { DataCapList = WWAN_DATA_CLASS_1XRTT | WWAN_DATA_CLASS_1XEVDO | WWAN_DATA_CLASS_1XEVDO_REVA | WWAN_DATA_CLASS_1XEVDV | WWAN_DATA_CLASS_1XEVDO_REVB; DeviceClass = DEVICE_CLASS_CDMA; s_is_cdma = (0 == is_lte); } break; case 0x11: // HDR if (pServiceStatusInfo->SrvStatus == 0x02) { DataCapList = WWAN_DATA_CLASS_3XRTT | WWAN_DATA_CLASS_UMB; DeviceClass = DEVICE_CLASS_CDMA; s_is_cdma = (0 == is_lte); } break; case 0x12: // GSM if (pServiceStatusInfo->SrvStatus == 0x02) { DataCapList = WWAN_DATA_CLASS_GPRS | WWAN_DATA_CLASS_EDGE; DeviceClass = DEVICE_CLASS_GSM; } break; case 0x13: // WCDMA if (pServiceStatusInfo->SrvStatus == 0x02) { DataCapList = WWAN_DATA_CLASS_UMTS; DeviceClass = DEVICE_CLASS_GSM; } break; //begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 case 0x4A: // NR5G if (pServiceStatusInfo->SrvStatus == 0x02) { DataCapList = WWAN_DATA_CLASS_5G; DeviceClass = DEVICE_CLASS_GSM; is_lte = 1; s_is_cdma = 0; } break; //end modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 case 0x14: // LTE if (pServiceStatusInfo->SrvStatus == 0x02) { DataCapList = WWAN_DATA_CLASS_LTE; DeviceClass = DEVICE_CLASS_GSM; is_lte = 1; s_is_cdma = 0; } break; case 0x24: // TDSCDMA if (pServiceStatusInfo->SrvStatus == 0x02) { pDataCapStr = "TD-SCDMA"; } break; case 0x15: // CDMA // CDMA_SYSTEM_INFO pCdmaSystemInfo = (PCDMA_SYSTEM_INFO)pServiceStatusInfo; if (pCdmaSystemInfo->SrvDomainValid == 0x01) { *pPSAttachedState = 0; if (pCdmaSystemInfo->SrvDomain & 0x02) { *pPSAttachedState = 1; s_is_cdma = (0 == is_lte); } } #if 0 if (pCdmaSystemInfo->SrvCapabilityValid == 0x01) { *pPSAttachedState = 0; if (pCdmaSystemInfo->SrvCapability & 0x02) { *pPSAttachedState = 1; s_is_cdma = (0 == is_lte); } } #endif if (pCdmaSystemInfo->NetworkIdValid == 0x01) { int i; CHAR temp[10]; strncpy(temp, (CHAR *)pCdmaSystemInfo->MCC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileCountryCode = (USHORT)atoi(temp); strncpy(temp, (CHAR *)pCdmaSystemInfo->MNC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileNetworkCode = (USHORT)atoi(temp); } break; case 0x16: // HDR // HDR_SYSTEM_INFO pHdrSystemInfo = (PHDR_SYSTEM_INFO)pServiceStatusInfo; if (pHdrSystemInfo->SrvDomainValid == 0x01) { *pPSAttachedState = 0; if (pHdrSystemInfo->SrvDomain & 0x02) { *pPSAttachedState = 1; s_is_cdma = (0 == is_lte); } } #if 0 if (pHdrSystemInfo->SrvCapabilityValid == 0x01) { *pPSAttachedState = 0; if (pHdrSystemInfo->SrvCapability & 0x02) { *pPSAttachedState = 1; s_is_cdma = (0 == is_lte); } } #endif if (*pPSAttachedState && pHdrSystemInfo->HdrPersonalityValid == 0x01) { if (pHdrSystemInfo->HdrPersonality == 0x03) s_hdr_personality = 0x02; // else if (pHdrSystemInfo->HdrPersonality == 0x02) // s_hdr_personality = 0x01; } USHORT cmda_mcc = 0, cdma_mnc = 0; if (!requestGetHomeNetwork(&cmda_mcc, &cdma_mnc, NULL, NULL) && cmda_mcc) { fibo_convert_cdma_mcc_2_ascii_mcc(&MobileCountryCode, cmda_mcc); fibo_convert_cdma_mnc_2_ascii_mnc(&MobileNetworkCode, cdma_mnc); } break; case 0x17: // GSM // GSM_SYSTEM_INFO pGsmSystemInfo = (PGSM_SYSTEM_INFO)pServiceStatusInfo; if (pGsmSystemInfo->SrvDomainValid == 0x01) { *pPSAttachedState = 0; if (pGsmSystemInfo->SrvDomain & 0x02) { *pPSAttachedState = 1; } } #if 0 if (pGsmSystemInfo->SrvCapabilityValid == 0x01) { *pPSAttachedState = 0; if (pGsmSystemInfo->SrvCapability & 0x02) { *pPSAttachedState = 1; } } #endif if (pGsmSystemInfo->NetworkIdValid == 0x01) { int i; CHAR temp[10]; strncpy(temp, (CHAR *)pGsmSystemInfo->MCC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileCountryCode = (USHORT)atoi(temp); strncpy(temp, (CHAR *)pGsmSystemInfo->MNC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileNetworkCode = (USHORT)atoi(temp); } break; case 0x18: // WCDMA // WCDMA_SYSTEM_INFO pWcdmaSystemInfo = (PWCDMA_SYSTEM_INFO)pServiceStatusInfo; if (pWcdmaSystemInfo->SrvDomainValid == 0x01) { *pPSAttachedState = 0; if (pWcdmaSystemInfo->SrvDomain & 0x02) { *pPSAttachedState = 1; } } #if 0 if (pWcdmaSystemInfo->SrvCapabilityValid == 0x01) { *pPSAttachedState = 0; if (pWcdmaSystemInfo->SrvCapability & 0x02) { *pPSAttachedState = 1; } } #endif if (pWcdmaSystemInfo->NetworkIdValid == 0x01) { int i; CHAR temp[10]; strncpy(temp, (CHAR *)pWcdmaSystemInfo->MCC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileCountryCode = (USHORT)atoi(temp); strncpy(temp, (CHAR *)pWcdmaSystemInfo->MNC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileNetworkCode = (USHORT)atoi(temp); } break; case 0x19: // LTE_SYSTEM_INFO // LTE_SYSTEM_INFO pLteSystemInfo = (PLTE_SYSTEM_INFO)pServiceStatusInfo; if (pLteSystemInfo->SrvDomainValid == 0x01) { *pPSAttachedState = 0; if (pLteSystemInfo->SrvDomain & 0x02) { *pPSAttachedState = 1; is_lte = 1; s_is_cdma = 0; } } #if 0 if (pLteSystemInfo->SrvCapabilityValid == 0x01) { *pPSAttachedState = 0; if (pLteSystemInfo->SrvCapability & 0x02) { *pPSAttachedState = 1; is_lte = 1; s_is_cdma = 0; } } #endif if (pLteSystemInfo->NetworkIdValid == 0x01) { int i; CHAR temp[10]; strncpy(temp, (CHAR *)pLteSystemInfo->MCC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileCountryCode = (USHORT)atoi(temp); strncpy(temp, (CHAR *)pLteSystemInfo->MNC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileNetworkCode = (USHORT)atoi(temp); } break; //begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 case 0x4b: // NR5G_SYSTEM_INFO // NR5G_SYSTEM_INFO pNr5gSystemInfo = (PNR5G_SYSTEM_INFO)pServiceStatusInfo; if (pNr5gSystemInfo->SrvDomainValid == 0x01) { *pPSAttachedState = 0; if (pNr5gSystemInfo->SrvDomain & 0x02) { *pPSAttachedState = 1; is_lte = 1; s_is_cdma = 0; } } if (pNr5gSystemInfo->NetworkIdValid == 0x01) { int i; CHAR temp[10]; strncpy(temp, (CHAR *)pNr5gSystemInfo->MCC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileCountryCode = (USHORT)atoi(temp); strncpy(temp, (CHAR *)pNr5gSystemInfo->MNC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileNetworkCode = (USHORT)atoi(temp); } break; //end modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 case 0x25: // TDSCDMA // TDSCDMA_SYSTEM_INFO pTdscdmaSystemInfo = (PTDSCDMA_SYSTEM_INFO)pServiceStatusInfo; if (pTdscdmaSystemInfo->SrvDomainValid == 0x01) { *pPSAttachedState = 0; if (pTdscdmaSystemInfo->SrvDomain & 0x02) { *pPSAttachedState = 1; } } #if 0 if (pTdscdmaSystemInfo->SrvCapabilityValid == 0x01) { *pPSAttachedState = 0; if (pTdscdmaSystemInfo->SrvCapability & 0x02) { *pPSAttachedState = 1; } } #endif if (pTdscdmaSystemInfo->NetworkIdValid == 0x01) { int i; CHAR temp[10]; strncpy(temp, (CHAR *)pTdscdmaSystemInfo->MCC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileCountryCode = (USHORT)atoi(temp); strncpy(temp, (CHAR *)pTdscdmaSystemInfo->MNC, 3); temp[3] = '\0'; for (i = 0; i < 4; i++) { if ((UCHAR)temp[i] == 0xFF) { temp[i] = '\0'; } } MobileNetworkCode = (USHORT)atoi(temp); } break; default: break; } /* switch (pServiceStatusInfo->TLYType) */ remainingLen -= (le16_to_cpu(pServiceStatusInfo->TLVLength) + 3); pServiceStatusInfo = (PSERVICE_STATUS_INFO)( (PCHAR)&pServiceStatusInfo->TLVLength + le16_to_cpu(pServiceStatusInfo->TLVLength) + sizeof(USHORT)); } /* while (remainingLen > 0) */ if (DeviceClass == DEVICE_CLASS_CDMA) { if (s_hdr_personality == 2) { pDataCapStr = s_hdr_personality == 2 ? "eHRPD" : "HRPD"; } else if (DataCapList & WWAN_DATA_CLASS_1XEVDO_REVB) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_1XEVDO_REVB); } else if (DataCapList & WWAN_DATA_CLASS_1XEVDO_REVA) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_1XEVDO_REVA); } else if (DataCapList & WWAN_DATA_CLASS_1XEVDO) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_1XEVDO); } else if (DataCapList & WWAN_DATA_CLASS_1XRTT) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_1XRTT); } else if (DataCapList & WWAN_DATA_CLASS_3XRTT) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_3XRTT); } else if (DataCapList & WWAN_DATA_CLASS_UMB) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_UMB); } } else { if (DataCapList & WWAN_DATA_CLASS_LTE) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_LTE); } else if ((DataCapList & WWAN_DATA_CLASS_HSDPA) && (DataCapList & WWAN_DATA_CLASS_HSUPA)) { pDataCapStr = "HSDPA_HSUPA"; } else if (DataCapList & WWAN_DATA_CLASS_HSDPA) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_HSDPA); } else if (DataCapList & WWAN_DATA_CLASS_HSUPA) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_HSUPA); } else if (DataCapList & WWAN_DATA_CLASS_UMTS) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_UMTS); } else if (DataCapList & WWAN_DATA_CLASS_EDGE) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_EDGE); } else if (DataCapList & WWAN_DATA_CLASS_GPRS) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_GPRS); //begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 } else if (DataCapList & WWAN_DATA_CLASS_5G) { pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_5G); //end modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 } } g_MobileCountryCode = MobileCountryCode; g_MobileNetworkCode = MobileNetworkCode; dbg_time("%s MCC: %d, MNC: %d, PS: %s, DataCap: %s", __func__, MobileCountryCode, MobileNetworkCode, (*pPSAttachedState == 1) ? "Attached" : "Detached", pDataCapStr); free(pResponse); return 0; } int requestRegistrationState(UCHAR *pPSAttachedState) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; PQMINAS_CURRENT_PLMN_MSG pCurrentPlmn; PSERVING_SYSTEM pServingSystem; PQMINAS_DATA_CAP pDataCap; USHORT MobileCountryCode = 0; USHORT MobileNetworkCode = 0; const char *pDataCapStr = "UNKNOW"; //begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 /* for 9x07 later, QMINAS_GET_SERVING_SYSTEM_REQ has been declara as Deprecated so sdx55 NR5G register info can not get by QMINAS_GET_SERVING_SYSTEM_REQ. coninue use QMINAS_GET_SERVING_SYSTEM_REQ, fibocom-dial will show network as UNKNOWN */ //begin modified by zhaofei delete incorrect registration interface on x55/x24 platform. 20200603 // #if 0 // if (s_9x07) { //eturn requestRegistrationState2(pPSAttachedState); // } // #endif //end modified by zhaofei delete incorrect registration interface on x55/x24 platform.20200603 //begin modified by zhangkaibo add 5G network detect feature on x55 platform. 20200605 pRequest = ComposeQMUXMsg(QMUX_TYPE_NAS, QMINAS_GET_SERVING_SYSTEM_REQ, NULL, NULL); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); pCurrentPlmn = (PQMINAS_CURRENT_PLMN_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x12); if (pCurrentPlmn) { MobileCountryCode = le16_to_cpu(pCurrentPlmn->MobileCountryCode); MobileNetworkCode = le16_to_cpu(pCurrentPlmn->MobileNetworkCode); } *pPSAttachedState = 0; pServingSystem = (PSERVING_SYSTEM)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01); if (pServingSystem) { // Packet-switched domain attach state of the mobile. // 0x00 PS_UNKNOWN ?Unknown or not applicable // 0x01 PS_ATTACHED ?Attached // 0x02 PS_DETACHED ?Detached *pPSAttachedState = pServingSystem->RegistrationState; if (pServingSystem->RegistrationState == 0x01) // 0x01 ?C REGISTERED ?C Registered with a network *pPSAttachedState = pServingSystem->PSAttachedState; else { // MobileCountryCode = MobileNetworkCode = 0; *pPSAttachedState = 0x02; } } pDataCap = (PQMINAS_DATA_CAP)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11); if (pDataCap && pDataCap->DataCapListLen) { UCHAR *DataCap = &pDataCap->DataCap; if (pDataCap->DataCapListLen == 2) { if ((DataCap[0] == 0x06) && ((DataCap[1] == 0x08) || (DataCap[1] == 0x0A))) DataCap[0] = DataCap[1]; } switch (DataCap[0]) { case 0x01: pDataCapStr = "GPRS"; break; case 0x02: pDataCapStr = "EDGE"; break; case 0x03: pDataCapStr = "HSDPA"; break; case 0x04: pDataCapStr = "HSUPA"; break; case 0x05: pDataCapStr = "UMTS"; break; case 0x06: pDataCapStr = "1XRTT"; break; case 0x07: pDataCapStr = "1XEVDO"; break; case 0x08: pDataCapStr = "1XEVDO_REVA"; break; case 0x09: pDataCapStr = "GPRS"; break; case 0x0A: pDataCapStr = "1XEVDO_REVB"; break; case 0x0B: pDataCapStr = "LTE"; break; case 0x0C: pDataCapStr = "HSDPA"; break; case 0x0D: pDataCapStr = "HSDPA"; break; default: pDataCapStr = "UNKNOW"; break; } } if (pServingSystem && pServingSystem->RegistrationState == 0x01 && pServingSystem->InUseRadioIF && pServingSystem->RadioIF == 0x09) { pDataCapStr = "TD-SCDMA"; } s_is_cdma = 0; if (pServingSystem && pServingSystem->RegistrationState == 0x01 && pServingSystem->InUseRadioIF && (pServingSystem->RadioIF == 0x01 || pServingSystem->RadioIF == 0x02)) { USHORT cmda_mcc = 0, cdma_mnc = 0; s_is_cdma = 1; if (!requestGetHomeNetwork(&cmda_mcc, &cdma_mnc, NULL, NULL) && cmda_mcc) { fibo_convert_cdma_mcc_2_ascii_mcc(&MobileCountryCode, cmda_mcc); fibo_convert_cdma_mnc_2_ascii_mnc(&MobileNetworkCode, cdma_mnc); } if (1) { PQCQMUX_TLV pTLV = (PQCQMUX_TLV)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x23); if (pTLV) s_hdr_personality = pTLV->Value; else s_hdr_personality = 0; if (s_hdr_personality == 2) pDataCapStr = "eHRPD"; } } dbg_time("%s MCC: %d, MNC: %d, PS: %s, DataCap: %s", __func__, MobileCountryCode, MobileNetworkCode, (*pPSAttachedState == 1) ? "Attached" : "Detached", pDataCapStr); free(pResponse); return 0; } int requestQueryDataCall(UCHAR *pConnectionStatus, int curIpFamily) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; PQMIWDS_PKT_SRVC_TLV pPktSrvc; UCHAR oldConnectionStatus = *pConnectionStatus; UCHAR QMIType = (curIpFamily == IpFamilyV4) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6; pRequest = ComposeQMUXMsg(QMIType, QMIWDS_GET_PKT_SRVC_STATUS_REQ, NULL, NULL); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); *pConnectionStatus = QWDS_PKT_DATA_DISCONNECTED; pPktSrvc = (PQMIWDS_PKT_SRVC_TLV)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01); if (pPktSrvc) { *pConnectionStatus = pPktSrvc->ConnectionStatus; if ((le16_to_cpu(pPktSrvc->TLVLength) == 2) && (pPktSrvc->ReconfigReqd == 0x01)) *pConnectionStatus = QWDS_PKT_DATA_DISCONNECTED; } if (*pConnectionStatus == QWDS_PKT_DATA_DISCONNECTED) { if (curIpFamily == IpFamilyV4) WdsConnectionIPv4Handle = 0; else WdsConnectionIPv6Handle = 0; } if (oldConnectionStatus != *pConnectionStatus || debug_qmi) { dbg_time("%s %sConnectionStatus: %s", __func__, (curIpFamily == IpFamilyV4) ? "IPv4" : "IPv6", (*pConnectionStatus == QWDS_PKT_DATA_CONNECTED) ? "CONNECTED" : "DISCONNECTED"); } free(pResponse); return 0; } int requestSetupDataCall(PROFILE_T *profile, int curIpFamily) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err = 0; UCHAR QMIType = (curIpFamily == IpFamilyV4) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6; // DualIPSupported means can get ipv4 & ipv6 address at the same time, one // wds for ipv4, the other wds for ipv6 profile->curIpFamily = curIpFamily; pRequest = ComposeQMUXMsg(QMIType, QMIWDS_START_NETWORK_INTERFACE_REQ, WdsStartNwInterfaceReq, profile); err = QmiThreadSendQMITimeout(pRequest, &pResponse, 120 * 1000); qmi_rsp_check(); if (le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult) || le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError)) { PQMI_TLV_HDR pTLVHdr; pTLVHdr = GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x10); if (pTLVHdr) { uint16_t *data16 = (uint16_t *)(pTLVHdr + 1); uint16_t call_end_reason = le16_to_cpu(data16[0]); dbg_time("call_end_reason is %d", call_end_reason); } pTLVHdr = GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11); if (pTLVHdr) { uint16_t *data16 = (uint16_t *)(pTLVHdr + 1); uint16_t call_end_reason_type = le16_to_cpu(data16[0]); uint16_t verbose_call_end_reason = le16_to_cpu(data16[1]); dbg_time("call_end_reason_type is %d", call_end_reason_type); dbg_time("call_end_reason_verbose is %d", verbose_call_end_reason); } free(pResponse); return le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError); } if (curIpFamily == IpFamilyV4) { WdsConnectionIPv4Handle = le32_to_cpu(pResponse->MUXMsg.StartNwInterfaceResp.Handle); dbg_time("%s WdsConnectionIPv4Handle: 0x%08x", __func__, WdsConnectionIPv4Handle); } else { WdsConnectionIPv6Handle = le32_to_cpu(pResponse->MUXMsg.StartNwInterfaceResp.Handle); dbg_time("%s WdsConnectionIPv6Handle: 0x%08x", __func__, WdsConnectionIPv6Handle); } free(pResponse); return 0; } int requestDeactivateDefaultPDP(PROFILE_T *profile, int curIpFamily) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; UCHAR QMIType = (curIpFamily == 0x04) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6; if (curIpFamily == IpFamilyV4 && WdsConnectionIPv4Handle == 0) return 0; if (curIpFamily == IpFamilyV6 && WdsConnectionIPv6Handle == 0) return 0; pRequest = ComposeQMUXMsg(QMIType, QMIWDS_STOP_NETWORK_INTERFACE_REQ, WdsStopNwInterfaceReq, &curIpFamily); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); if (curIpFamily == IpFamilyV4) WdsConnectionIPv4Handle = 0; else WdsConnectionIPv6Handle = 0; free(pResponse); return 0; } int requestGetIPAddress(PROFILE_T *profile, int curIpFamily) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR pIpv4Addr; PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_ADDR pIpv6Addr = NULL; PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_DNS_ADDR pIpv6DNSAddr = NULL; PQMIWDS_GET_RUNTIME_SETTINGS_TLV_MTU pMtu; IPV4_T *pIpv4 = &profile->ipv4; IPV6_T *pIpv6 = &profile->ipv6; UCHAR QMIType = (curIpFamily == 0x04) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6; if (curIpFamily == IpFamilyV4) { memset(pIpv4, 0x00, sizeof(IPV4_T)); if (WdsConnectionIPv4Handle == 0) return 0; } else if (curIpFamily == IpFamilyV6) { memset(pIpv6, 0x00, sizeof(IPV6_T)); if (WdsConnectionIPv6Handle == 0) return 0; } pRequest = ComposeQMUXMsg(QMIType, QMIWDS_GET_RUNTIME_SETTINGS_REQ, WdsGetRuntimeSettingReq, NULL); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4PRIMARYDNS); if (pIpv4Addr) { pIpv4->DnsPrimary = pIpv4Addr->IPV4Address; } pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4SECONDARYDNS); if (pIpv4Addr) { pIpv4->DnsSecondary = pIpv4Addr->IPV4Address; } pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4GATEWAY); if (pIpv4Addr) { pIpv4->Gateway = pIpv4Addr->IPV4Address; } pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4SUBNET); if (pIpv4Addr) { pIpv4->SubnetMask = pIpv4Addr->IPV4Address; } pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4); if (pIpv4Addr) { pIpv4->Address = pIpv4Addr->IPV4Address; } pIpv6DNSAddr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_DNS_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV6PRIMARYDNS); if (pIpv6DNSAddr) { memcpy(pIpv6->DnsPrimary, pIpv6DNSAddr->IPV6Address, 16); } pIpv6DNSAddr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_DNS_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV6SECONDARYDNS); if (pIpv6DNSAddr) { memcpy(pIpv6->DnsSecondary, pIpv6DNSAddr->IPV6Address, 16); } //2021-02-25 willa.liu@fibocom.com changed begin for support eipd SN-20210129001 /* pIpv6Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV6GATEWAY); if(pIpv6Addr) { memcpy(pIpv6->Gateway, pIpv6Addr->IPV6Address, 16); pIpv6->PrefixLengthGateway = pIpv6Addr->PrefixLength; } */ if(profile->ipv6_prigateway_flag == 1) { char localip6gateway[1024] = {0}; get_private_gateway(localip6gateway); int length = sizeof(localip6gateway)/sizeof(localip6gateway[0]); if (pIpv6Addr) { int i = 0; char *token = strtok(localip6gateway, "."); while(token != NULL) { pIpv6->Gateway[i++] = atoi(token); //printf("token:%s, pIpv6->Gateway[%d]:%d\n", token, i-1, pIpv6->Gateway[i-1]); token = strtok(NULL, "."); } pIpv6->PrefixLengthGateway = 16; } } else { pIpv6Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV6GATEWAY); if(pIpv6Addr) { memcpy(pIpv6->Gateway, pIpv6Addr->IPV6Address, 16); pIpv6->PrefixLengthGateway = pIpv6Addr->PrefixLength; } } //2021-02-25 willa.liu@fibocom.com changed end for support eipd SN-20210129001 pIpv6Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_ADDR)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV6); if (pIpv6Addr) { memcpy(pIpv6->Address, pIpv6Addr->IPV6Address, 16); pIpv6->PrefixLengthIPAddr = pIpv6Addr->PrefixLength; } pMtu = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_MTU)GetTLV( &pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_MTU); if (pMtu) { pIpv4->Mtu = pIpv6->Mtu = le32_to_cpu(pMtu->Mtu); } free(pResponse); return 0; } #ifdef CONFIG_APN int requestSetProfile(PROFILE_T *profile) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; if (!profile->pdp) return 0; dbg_time("%s[%d] %s/%s/%s/%d", __func__, profile->pdpindex, profile->apn, profile->user, profile->password, profile->auth); UCHAR QMIType = (profile->ipv4_flag) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6; pRequest = ComposeQMUXMsg(QMIType, QMIWDS_MODIFY_PROFILE_SETTINGS_REQ, WdsModifyProfileSettingsReq, profile); err = QmiThreadSendQMI(pRequest, &pResponse); //begin modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610 //modify profile no check return value, try create qmi_rsp_check(); if(le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError)) { pRequest = ComposeQMUXMsg(QMIType, QMIWDS_CREATE_PROFILE_SETTINGS_REQ, WdsCreateProfileSettingsReq, profile); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check(); if(le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError)){ free(pResponse); return -1; } dbg_time("WdsCreateProfileSettingsReq[%d] %s/%s/%s/%d", profile->pdpindex, profile->apn, profile->user, profile->password, profile->auth); } //end modified by zhangkaibo add create profile qmi. mantis 0049137,0048741 20200610 free(pResponse); return 0; } int requestGetProfile(PROFILE_T *profile) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; char *apn = NULL; char *user = NULL; char *password = NULL; int auth = 0; PQMIWDS_APNNAME pApnName; PQMIWDS_USERNAME pUserName; PQMIWDS_PASSWD pPassWd; PQMIWDS_AUTH_PREFERENCE pAuthPref; if (!profile->pdp) return 0; UCHAR QMIType = (profile->ipv4_flag) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6; pRequest = ComposeQMUXMsg(QMIType, QMIWDS_GET_PROFILE_SETTINGS_REQ, WdsGetProfileSettingsReqSend, profile); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); pApnName = (PQMIWDS_APNNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x14); pUserName = (PQMIWDS_USERNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1B); pPassWd = (PQMIWDS_PASSWD)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1C); pAuthPref = (PQMIWDS_AUTH_PREFERENCE)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1D); if (pApnName /* && le16_to_cpu(pApnName->TLVLength)*/) apn = strndup((const char *)(&pApnName->ApnName), le16_to_cpu(pApnName->TLVLength)); if (pUserName /* && pUserName->UserName*/) user = strndup((const char *)(&pUserName->UserName), le16_to_cpu(pUserName->TLVLength)); if (pPassWd /* && le16_to_cpu(pPassWd->TLVLength)*/) password = strndup((const char *)(&pPassWd->Passwd), le16_to_cpu(pPassWd->TLVLength)); if (pAuthPref /* && le16_to_cpu(pAuthPref->TLVLength)*/) { auth = pAuthPref->AuthPreference; } #if 0 if (profile) { profile->apn = apn; profile->user = user; profile->password = password; profile->auth = auth; } #endif dbg_time("%s[%d] %s/%s/%s/%d", __func__, profile->pdpindex, apn, user, password, auth); free(pResponse); return 0; } #endif #ifdef CONFIG_VERSION int requestBaseBandVersion(const char **pp_reversion) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; PDEVICE_REV_ID revId; int err; if (pp_reversion) *pp_reversion = NULL; pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_GET_DEVICE_REV_ID_REQ, NULL, NULL); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); revId = (PDEVICE_REV_ID)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01); if (revId && le16_to_cpu(revId->TLVLength)) { char *DeviceRevisionID = strndup((const char *)(&revId->RevisionID), le16_to_cpu(revId->TLVLength)); dbg_time("%s %s", __func__, DeviceRevisionID); if (pp_reversion) *pp_reversion = DeviceRevisionID; } free(pResponse); return 0; } #endif #ifdef CONFIG_RESET_RADIO static USHORT DmsSetOperatingModeReq(PQMUX_MSG pMUXMsg, void *arg) { pMUXMsg->SetOperatingModeReq.TLVType = 0x01; pMUXMsg->SetOperatingModeReq.TLVLength = cpu_to_le16(1); pMUXMsg->SetOperatingModeReq.OperatingMode = *((UCHAR *)arg); return sizeof(QMIDMS_SET_OPERATING_MODE_REQ_MSG); } int requestSetOperatingMode(UCHAR OperatingMode) { PQCQMIMSG pRequest; PQCQMIMSG pResponse; PQMUX_MSG pMUXMsg; int err; dbg_time("%s(%d)", __func__, OperatingMode); pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_SET_OPERATING_MODE_REQ, DmsSetOperatingModeReq, &OperatingMode); err = QmiThreadSendQMI(pRequest, &pResponse); qmi_rsp_check_and_return(); free(pResponse); return 0; } #endif