2552 lines
78 KiB
C
2552 lines
78 KiB
C
#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
|