xref: /OK3568_Linux_fs/app/forlinx/quectelCM/QMIThread.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2   @file    QMIThread.c
3   @brief   QMI WWAN connectivity manager.
4 
5   DESCRIPTION
6   Connectivity Management Tool for USB network adapter of Quectel wireless cellular modules.
7 
8   INITIALIZATION AND SEQUENCING REQUIREMENTS
9   None.
10 
11   ---------------------------------------------------------------------------
12   Copyright (c) 2016 - 2020 Quectel Wireless Solution, Co., Ltd.  All Rights Reserved.
13   Quectel Wireless Solution Proprietary and Confidential.
14   ---------------------------------------------------------------------------
15 ******************************************************************************/
16 #include "QMIThread.h"
17 #ifndef MIN
18 #define MIN(a, b)	((a) < (b)? (a): (b))
19 #endif
20 
21 extern char *strndup (const char *__string, size_t __n);
22 
23 #define qmi_rsp_check_and_return() do { \
24         if (err < 0 || pResponse == NULL) { \
25             dbg_time("%s err = %d", __func__, err); \
26             return err; \
27         } \
28         pMUXMsg = &pResponse->MUXMsg; \
29         if (le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult) || le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError)) { \
30             USHORT QMUXError = le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError); \
31             dbg_time("%s QMUXResult = 0x%x, QMUXError = 0x%x", __func__, \
32                 le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult), QMUXError); \
33             free(pResponse); \
34             return QMUXError; \
35         } \
36 } while(0)
37 
38 #define qmi_rsp_check() do { \
39         if (err < 0 || pResponse == NULL) { \
40             dbg_time("%s err = %d", __func__, err); \
41             return err; \
42         } \
43         pMUXMsg = &pResponse->MUXMsg; \
44         if (le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult) || le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError)) { \
45             USHORT QMUXError = le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError); \
46             dbg_time("%s QMUXResult = 0x%x, QMUXError = 0x%x", __func__, \
47                 le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult), QMUXError); \
48         } \
49 } while(0)
50 
51 static uint32_t WdsConnectionIPv4Handle = 0;
52 static uint32_t WdsConnectionIPv6Handle = 0;
53 static int s_is_cdma = 0;
54 static int s_5g_type = WWAN_DATA_CLASS_NONE;
55 static int s_hdr_personality = 0; // 0x01-HRPD, 0x02-eHRPD
qstrcpy(char * to,const char * from)56 static char *qstrcpy(char *to, const char *from) { //no __strcpy_chk
57 	char *save = to;
58 	for (; (*to = *from) != '\0'; ++from, ++to);
59 	return(save);
60 }
61 
62 static int s_9x07 = 1;
63 
64 typedef USHORT (*CUSTOMQMUX)(PQMUX_MSG pMUXMsg, void *arg);
65 
66 // To retrieve the ith (Index) TLV
GetTLV(PQCQMUX_MSG_HDR pQMUXMsgHdr,int TLVType)67 PQMI_TLV_HDR GetTLV (PQCQMUX_MSG_HDR pQMUXMsgHdr, int TLVType) {
68     int TLVFind = 0;
69     USHORT Length = le16_to_cpu(pQMUXMsgHdr->Length);
70     PQMI_TLV_HDR pTLVHdr = (PQMI_TLV_HDR)(pQMUXMsgHdr + 1);
71 
72     while (Length >= sizeof(QMI_TLV_HDR)) {
73         TLVFind++;
74         if (TLVType > 0x1000) {
75             if ((TLVFind + 0x1000) == TLVType)
76                 return pTLVHdr;
77         } else  if (pTLVHdr->TLVType == TLVType) {
78             return pTLVHdr;
79         }
80 
81         Length -= (le16_to_cpu((pTLVHdr->TLVLength)) + sizeof(QMI_TLV_HDR));
82         pTLVHdr = (PQMI_TLV_HDR)(((UCHAR *)pTLVHdr) + le16_to_cpu(pTLVHdr->TLVLength) + sizeof(QMI_TLV_HDR));
83     }
84 
85    return NULL;
86 }
87 
GetQMUXTransactionId(void)88 static USHORT GetQMUXTransactionId(void) {
89     static int TransactionId = 0;
90     if (++TransactionId > 0xFFFF)
91         TransactionId = 1;
92     return TransactionId;
93 }
94 
ComposeQMUXMsg(UCHAR QMIType,USHORT Type,CUSTOMQMUX customQmuxMsgFunction,void * arg)95 static PQCQMIMSG ComposeQMUXMsg(UCHAR QMIType, USHORT Type, CUSTOMQMUX customQmuxMsgFunction, void *arg) {
96     UCHAR QMIBuf[WDM_DEFAULT_BUFSIZE];
97     PQCQMIMSG pRequest = (PQCQMIMSG)QMIBuf;
98     int Length;
99 
100     memset(QMIBuf, 0x00, sizeof(QMIBuf));
101     pRequest->QMIHdr.IFType = USB_CTL_MSG_TYPE_QMI;
102     pRequest->QMIHdr.CtlFlags = 0x00;
103     pRequest->QMIHdr.QMIType = QMIType;
104 
105     pRequest->MUXMsg.QMUXHdr.CtlFlags = QMUX_CTL_FLAG_SINGLE_MSG | QMUX_CTL_FLAG_TYPE_CMD;
106     pRequest->MUXMsg.QMUXHdr.TransactionId = cpu_to_le16(GetQMUXTransactionId());
107     pRequest->MUXMsg.QMUXMsgHdr.Type = cpu_to_le16(Type);
108     if (customQmuxMsgFunction)
109         pRequest->MUXMsg.QMUXMsgHdr.Length = cpu_to_le16(customQmuxMsgFunction(&pRequest->MUXMsg, arg) - sizeof(QCQMUX_MSG_HDR));
110     else
111         pRequest->MUXMsg.QMUXMsgHdr.Length = cpu_to_le16(0x0000);
112 
113     pRequest->QMIHdr.Length = cpu_to_le16(le16_to_cpu(pRequest->MUXMsg.QMUXMsgHdr.Length) + sizeof(QCQMUX_MSG_HDR) + sizeof(QCQMUX_HDR)
114         + sizeof(QCQMI_HDR) - 1);
115     Length = le16_to_cpu(pRequest->QMIHdr.Length) + 1;
116 
117     pRequest = (PQCQMIMSG)malloc(Length);
118     if (pRequest == NULL) {
119         dbg_time("%s fail to malloc", __func__);
120     } else {
121         memcpy(pRequest, QMIBuf, Length);
122     }
123 
124     return pRequest;
125 }
126 
127 #if 0
128 static USHORT NasSetEventReportReq(PQMUX_MSG pMUXMsg, void *arg) {
129     pMUXMsg->SetEventReportReq.TLVType = 0x10;
130     pMUXMsg->SetEventReportReq.TLVLength = 0x04;
131     pMUXMsg->SetEventReportReq.ReportSigStrength = 0x00;
132     pMUXMsg->SetEventReportReq.NumTresholds = 2;
133     pMUXMsg->SetEventReportReq.TresholdList[0] = -113;
134     pMUXMsg->SetEventReportReq.TresholdList[1] = -50;
135     return sizeof(QMINAS_SET_EVENT_REPORT_REQ_MSG);
136 }
137 
138 static USHORT WdsSetEventReportReq(PQMUX_MSG pMUXMsg, void *arg) {
139     pMUXMsg->EventReportReq.TLVType = 0x10;          // 0x10 -- current channel rate indicator
140     pMUXMsg->EventReportReq.TLVLength = 0x0001;        // 1
141     pMUXMsg->EventReportReq.Mode = 0x00;             // 0-do not report; 1-report when rate changes
142 
143     pMUXMsg->EventReportReq.TLV2Type = 0x11;         // 0x11
144     pMUXMsg->EventReportReq.TLV2Length = 0x0005;       // 5
145     pMUXMsg->EventReportReq.StatsPeriod = 0x00;      // seconds between reports; 0-do not report
146     pMUXMsg->EventReportReq.StatsMask = 0x000000ff;        //
147 
148     pMUXMsg->EventReportReq.TLV3Type = 0x12;          // 0x12 -- current data bearer indicator
149     pMUXMsg->EventReportReq.TLV3Length = 0x0001;        // 1
150     pMUXMsg->EventReportReq.Mode3 = 0x01;             // 0-do not report; 1-report when changes
151 
152     pMUXMsg->EventReportReq.TLV4Type = 0x13;          // 0x13 -- dormancy status indicator
153     pMUXMsg->EventReportReq.TLV4Length = 0x0001;        // 1
154     pMUXMsg->EventReportReq.DormancyStatus = 0x00;    // 0-do not report; 1-report when changes
155     return sizeof(QMIWDS_SET_EVENT_REPORT_REQ_MSG);
156 }
157 
158 static USHORT DmsSetEventReportReq(PQMUX_MSG pMUXMsg) {
159     PPIN_STATUS pPinState = (PPIN_STATUS)(&pMUXMsg->DmsSetEventReportReq + 1);
160     PUIM_STATE pUimState = (PUIM_STATE)(pPinState + 1);
161     // Pin State
162     pPinState->TLVType = 0x12;
163     pPinState->TLVLength = 0x01;
164     pPinState->ReportPinState = 0x01;
165     // UIM State
166     pUimState->TLVType = 0x15;
167     pUimState->TLVLength = 0x01;
168     pUimState->UIMState = 0x01;
169     return sizeof(QMIDMS_SET_EVENT_REPORT_REQ_MSG) + sizeof(PIN_STATUS) + sizeof(UIM_STATE);
170 }
171 #endif
172 
WdsStartNwInterfaceReq(PQMUX_MSG pMUXMsg,void * arg)173 static USHORT WdsStartNwInterfaceReq(PQMUX_MSG pMUXMsg, void *arg) {
174     PQMIWDS_TECHNOLOGY_PREFERECE pTechPref;
175     PQMIWDS_AUTH_PREFERENCE pAuthPref;
176     PQMIWDS_USERNAME pUserName;
177     PQMIWDS_PASSWD pPasswd;
178     PQMIWDS_APNNAME pApnName;
179     PQMIWDS_IP_FAMILY_TLV pIpFamily;
180     USHORT TLVLength = 0;
181     UCHAR *pTLV;
182     PROFILE_T *profile = (PROFILE_T *)arg;
183     const char *profile_user = profile->user;
184     const char *profile_password = profile->password;
185     int profile_auth = profile->auth;
186 
187     if (s_is_cdma && (profile_user == NULL || profile_user[0] == '\0') && (profile_password == NULL || profile_password[0] == '\0')) {
188         profile_user = "ctnet@mycdma.cn";
189         profile_password = "vnet.mobi";
190         profile_auth = 2; //chap
191     }
192 
193     pTLV = (UCHAR *)(&pMUXMsg->StartNwInterfaceReq + 1);
194     pMUXMsg->StartNwInterfaceReq.Length = 0;
195 
196     // Set technology Preferece
197     pTechPref = (PQMIWDS_TECHNOLOGY_PREFERECE)(pTLV + TLVLength);
198     pTechPref->TLVType = 0x30;
199     pTechPref->TLVLength = cpu_to_le16(0x01);
200     if (s_is_cdma == 0)
201         pTechPref->TechPreference = 0x01;
202     else
203         pTechPref->TechPreference = 0x02;
204     TLVLength +=(le16_to_cpu(pTechPref->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
205 
206     // Set APN Name
207     if (profile->apn && !s_is_cdma) { //cdma no apn
208         pApnName = (PQMIWDS_APNNAME)(pTLV + TLVLength);
209         pApnName->TLVType = 0x14;
210         pApnName->TLVLength = cpu_to_le16(strlen(profile->apn));
211         qstrcpy((char *)&pApnName->ApnName, profile->apn);
212         TLVLength +=(le16_to_cpu(pApnName->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
213     }
214 
215     // Set User Name
216     if (profile_user) {
217         pUserName = (PQMIWDS_USERNAME)(pTLV + TLVLength);
218         pUserName->TLVType = 0x17;
219         pUserName->TLVLength = cpu_to_le16(strlen(profile_user));
220         qstrcpy((char *)&pUserName->UserName, profile_user);
221         TLVLength += (le16_to_cpu(pUserName->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
222     }
223 
224     // Set Password
225     if (profile_password) {
226         pPasswd = (PQMIWDS_PASSWD)(pTLV + TLVLength);
227         pPasswd->TLVType = 0x18;
228         pPasswd->TLVLength = cpu_to_le16(strlen(profile_password));
229         qstrcpy((char *)&pPasswd->Passwd, profile_password);
230 	TLVLength += (le16_to_cpu(pPasswd->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
231     }
232 
233     // Set Auth Protocol
234     if (profile_user && profile_password) {
235         pAuthPref = (PQMIWDS_AUTH_PREFERENCE)(pTLV + TLVLength);
236         pAuthPref->TLVType = 0x16;
237         pAuthPref->TLVLength = cpu_to_le16(0x01);
238         pAuthPref->AuthPreference = profile_auth; // 0 ~ None, 1 ~ Pap, 2 ~ Chap, 3 ~ MsChapV2
239         TLVLength += (le16_to_cpu(pAuthPref->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
240     }
241 
242     // Add IP Family Preference
243     pIpFamily = (PQMIWDS_IP_FAMILY_TLV)(pTLV + TLVLength);
244     pIpFamily->TLVType = 0x19;
245     pIpFamily->TLVLength = cpu_to_le16(0x01);
246     pIpFamily->IpFamily = profile->curIpFamily;
247     TLVLength += (le16_to_cpu(pIpFamily->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
248 
249     //Set Profile Index
250     if (profile->pdp && !s_is_cdma) { //cdma only support one pdp, so no need to set profile index
251         PQMIWDS_PROFILE_IDENTIFIER pProfileIndex = (PQMIWDS_PROFILE_IDENTIFIER)(pTLV + TLVLength);
252         pProfileIndex->TLVLength = cpu_to_le16(0x01);
253         pProfileIndex->TLVType = 0x31;
254         pProfileIndex->ProfileIndex = profile->pdp;
255         if (s_is_cdma && s_hdr_personality == 0x02) {
256             pProfileIndex->TLVType = 0x32; //profile_index_3gpp2
257             pProfileIndex->ProfileIndex = 101;
258         }
259         TLVLength += (le16_to_cpu(pProfileIndex->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
260     }
261 
262     return sizeof(QMIWDS_START_NETWORK_INTERFACE_REQ_MSG) + TLVLength;
263 }
264 
WdsStopNwInterfaceReq(PQMUX_MSG pMUXMsg,void * arg)265 static USHORT WdsStopNwInterfaceReq(PQMUX_MSG pMUXMsg, void *arg) {
266     pMUXMsg->StopNwInterfaceReq.TLVType = 0x01;
267     pMUXMsg->StopNwInterfaceReq.TLVLength = cpu_to_le16(0x04);
268     if (*((int *)arg) == IpFamilyV4)
269         pMUXMsg->StopNwInterfaceReq.Handle =  cpu_to_le32(WdsConnectionIPv4Handle);
270     else
271         pMUXMsg->StopNwInterfaceReq.Handle =  cpu_to_le32(WdsConnectionIPv6Handle);
272     return sizeof(QMIWDS_STOP_NETWORK_INTERFACE_REQ_MSG);
273 }
274 
WdsSetClientIPFamilyPref(PQMUX_MSG pMUXMsg,void * arg)275 static USHORT WdsSetClientIPFamilyPref(PQMUX_MSG pMUXMsg, void *arg) {
276     pMUXMsg->SetClientIpFamilyPrefReq.TLVType = 0x01;
277     pMUXMsg->SetClientIpFamilyPrefReq.TLVLength = cpu_to_le16(0x01);
278     pMUXMsg->SetClientIpFamilyPrefReq.IpPreference = *((UCHAR *)arg);
279     return sizeof(QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ_MSG);
280 }
281 
WdsSetAutoConnect(PQMUX_MSG pMUXMsg,void * arg)282 static USHORT WdsSetAutoConnect(PQMUX_MSG pMUXMsg, void *arg) {
283     pMUXMsg->SetAutoConnectReq.TLVType = 0x01;
284     pMUXMsg->SetAutoConnectReq.TLVLength = cpu_to_le16(0x01);
285     pMUXMsg->SetAutoConnectReq.autoconnect_setting = *((UCHAR *)arg);
286     return sizeof(QMIWDS_SET_AUTO_CONNECT_REQ_MSG);
287 }
288 
289 enum peripheral_ep_type {
290 	DATA_EP_TYPE_RESERVED	= 0x0,
291 	DATA_EP_TYPE_HSIC	= 0x1,
292 	DATA_EP_TYPE_HSUSB	= 0x2,
293 	DATA_EP_TYPE_PCIE	= 0x3,
294 	DATA_EP_TYPE_EMBEDDED	= 0x4,
295 	DATA_EP_TYPE_BAM_DMUX	= 0x5,
296 };
297 
WdsSetQMUXBindMuxDataPort(PQMUX_MSG pMUXMsg,void * arg)298 static USHORT WdsSetQMUXBindMuxDataPort(PQMUX_MSG pMUXMsg, void *arg) {
299     QMAP_SETTING *qmap_settings = (QMAP_SETTING *)arg;
300 
301     pMUXMsg->BindMuxDataPortReq.TLVType = 0x10;
302     pMUXMsg->BindMuxDataPortReq.TLVLength = cpu_to_le16(0x08);
303     pMUXMsg->BindMuxDataPortReq.ep_type = cpu_to_le32(qmap_settings->ep_type);
304     pMUXMsg->BindMuxDataPortReq.iface_id = cpu_to_le32(qmap_settings->iface_id);
305     pMUXMsg->BindMuxDataPortReq.TLV2Type = 0x11;
306     pMUXMsg->BindMuxDataPortReq.TLV2Length = cpu_to_le16(0x01);
307     pMUXMsg->BindMuxDataPortReq.MuxId = qmap_settings->MuxId;
308     pMUXMsg->BindMuxDataPortReq.TLV3Type = 0x13;
309     pMUXMsg->BindMuxDataPortReq.TLV3Length = cpu_to_le16(0x04);
310     pMUXMsg->BindMuxDataPortReq.client_type = cpu_to_le32(1); //WDS_CLIENT_TYPE_TETHERED
311 
312     return sizeof(QMIWDS_BIND_MUX_DATA_PORT_REQ_MSG);
313 }
314 
315 static int qmap_version = 0x05;
WdaSetDataFormat(PQMUX_MSG pMUXMsg,void * arg)316 static USHORT WdaSetDataFormat(PQMUX_MSG pMUXMsg, void *arg) {
317     QMAP_SETTING *qmap_settings = (QMAP_SETTING *)arg;
318 
319     if (qmap_settings->rx_urb_size == 0) {
320         PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV_QOS pWdsAdminQosTlv;
321         PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV linkProto;
322         PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV dlTlp;
323 
324         pWdsAdminQosTlv = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV_QOS)(&pMUXMsg->QMUXMsgHdr + 1);
325         pWdsAdminQosTlv->TLVType = 0x10;
326         pWdsAdminQosTlv->TLVLength = cpu_to_le16(0x0001);
327         pWdsAdminQosTlv->QOSSetting = 0; /* no-QOS header */
328 
329         linkProto = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)(pWdsAdminQosTlv + 1);
330         linkProto->TLVType = 0x11;
331         linkProto->TLVLength = cpu_to_le16(4);
332         linkProto->Value = cpu_to_le32(0x01);     /* Set Ethernet  mode */
333 
334         dlTlp = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)(linkProto + 1);;
335         dlTlp->TLVType = 0x13;
336         dlTlp->TLVLength = cpu_to_le16(4);
337         dlTlp->Value = cpu_to_le32(0x00);
338 
339         if (sizeof(*linkProto) != 7 )
340             dbg_time("%s sizeof(*linkProto) = %zu, is not 7!", __func__, sizeof(*linkProto) );
341 
342         return sizeof(QCQMUX_MSG_HDR) + sizeof(*pWdsAdminQosTlv) + sizeof(*linkProto) + sizeof(*dlTlp);
343     }
344     else {
345     //Indicates whether the Quality of Service(QOS) data format is used by the client.
346         pMUXMsg->SetDataFormatReq.QosDataFormatTlv.TLVType = 0x10;
347         pMUXMsg->SetDataFormatReq.QosDataFormatTlv.TLVLength = cpu_to_le16(0x0001);
348         pMUXMsg->SetDataFormatReq.QosDataFormatTlv.QOSSetting = 0; /* no-QOS header */
349 
350     //Underlying Link Layer Protocol
351         pMUXMsg->SetDataFormatReq.UnderlyingLinkLayerProtocolTlv.TLVType = 0x11;
352         pMUXMsg->SetDataFormatReq.UnderlyingLinkLayerProtocolTlv.TLVLength = cpu_to_le16(4);
353         pMUXMsg->SetDataFormatReq.UnderlyingLinkLayerProtocolTlv.Value = cpu_to_le32(0x02);     /* Set IP  mode */
354 
355     //Uplink (UL) data aggregation protocol to be used for uplink data transfer.
356         pMUXMsg->SetDataFormatReq.UplinkDataAggregationProtocolTlv.TLVType = 0x12;
357         pMUXMsg->SetDataFormatReq.UplinkDataAggregationProtocolTlv.TLVLength = cpu_to_le16(4);
358         pMUXMsg->SetDataFormatReq.UplinkDataAggregationProtocolTlv.Value = cpu_to_le32(qmap_version); //UL QMAP is enabled
359 
360     //Downlink (DL) data aggregation protocol to be used for downlink data transfer
361         pMUXMsg->SetDataFormatReq.DownlinkDataAggregationProtocolTlv.TLVType = 0x13;
362         pMUXMsg->SetDataFormatReq.DownlinkDataAggregationProtocolTlv.TLVLength = cpu_to_le16(4);
363         pMUXMsg->SetDataFormatReq.DownlinkDataAggregationProtocolTlv.Value = cpu_to_le32(qmap_version); //DL QMAP is enabled
364 
365     //Maximum number of datagrams in a single aggregated packet on downlink
366         pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxDatagramsTlv.TLVType = 0x15;
367         pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxDatagramsTlv.TLVLength = cpu_to_le16(4);
368         pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxDatagramsTlv.Value = cpu_to_le32(qmap_settings->rx_urb_size/512);
369 
370     //Maximum size in bytes of a single aggregated packet allowed on downlink
371         pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxSizeTlv.TLVType = 0x16;
372         pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxSizeTlv.TLVLength = cpu_to_le16(4);
373         pMUXMsg->SetDataFormatReq.DownlinkDataAggregationMaxSizeTlv.Value = cpu_to_le32(qmap_settings->rx_urb_size);
374 
375     //Peripheral End Point ID
376         pMUXMsg->SetDataFormatReq.epTlv.TLVType = 0x17;
377         pMUXMsg->SetDataFormatReq.epTlv.TLVLength = cpu_to_le16(8);
378         pMUXMsg->SetDataFormatReq.epTlv.ep_type = cpu_to_le32(qmap_settings->ep_type);
379         pMUXMsg->SetDataFormatReq.epTlv.iface_id = cpu_to_le32(qmap_settings->iface_id);
380 
381 #ifdef QUECTEL_UL_DATA_AGG
382         if (!qmap_settings->ul_data_aggregation_max_datagrams) {
383             return ((size_t)&((QMIWDS_ADMIN_SET_DATA_FORMAT_REQ_MSG *)0)->DlMinimumPassingTlv);
384         }
385 
386      //Maximum number of datagrams in a single aggregated packet on uplink
387         pMUXMsg->SetDataFormatReq.DlMinimumPassingTlv.TLVType = 0x19;
388         pMUXMsg->SetDataFormatReq.DlMinimumPassingTlv.TLVLength = cpu_to_le16(4);
389         pMUXMsg->SetDataFormatReq.DlMinimumPassingTlv.Value = cpu_to_le32(qmap_settings->dl_minimum_padding);
390 
391      //Maximum number of datagrams in a single aggregated packet on uplink
392         pMUXMsg->SetDataFormatReq.UplinkDataAggregationMaxDatagramsTlv.TLVType = 0x1B;
393         pMUXMsg->SetDataFormatReq.UplinkDataAggregationMaxDatagramsTlv.TLVLength = cpu_to_le16(4);
394         pMUXMsg->SetDataFormatReq.UplinkDataAggregationMaxDatagramsTlv.Value = cpu_to_le32(qmap_settings->ul_data_aggregation_max_datagrams);
395 
396     //Maximum size in bytes of a single aggregated packet allowed on downlink
397         pMUXMsg->SetDataFormatReq.UplinkDataAggregationMaxSizeTlv.TLVType = 0x1C;
398         pMUXMsg->SetDataFormatReq.UplinkDataAggregationMaxSizeTlv.TLVLength = cpu_to_le16(4);
399         pMUXMsg->SetDataFormatReq.UplinkDataAggregationMaxSizeTlv.Value = cpu_to_le32(qmap_settings->ul_data_aggregation_max_size);
400 #endif
401 
402         return sizeof(QMIWDS_ADMIN_SET_DATA_FORMAT_REQ_MSG);
403     }
404 }
405 
406 #ifdef CONFIG_SIM
DmsUIMVerifyPinReqSend(PQMUX_MSG pMUXMsg,void * arg)407 static USHORT DmsUIMVerifyPinReqSend(PQMUX_MSG pMUXMsg, void *arg) {
408     pMUXMsg->UIMVerifyPinReq.TLVType = 0x01;
409     pMUXMsg->UIMVerifyPinReq.PINID = 0x01; //Pin1, not Puk
410     pMUXMsg->UIMVerifyPinReq.PINLen = strlen((const char *)arg);
411     qstrcpy((PCHAR)&pMUXMsg->UIMVerifyPinReq.PINValue, ((const char *)arg));
412     pMUXMsg->UIMVerifyPinReq.TLVLength = cpu_to_le16(2 + strlen((const char *)arg));
413     return sizeof(QMIDMS_UIM_VERIFY_PIN_REQ_MSG) + (strlen((const char *)arg) - 1);
414 }
415 
UimVerifyPinReqSend(PQMUX_MSG pMUXMsg,void * arg)416 static USHORT UimVerifyPinReqSend(PQMUX_MSG pMUXMsg, void *arg)
417 {
418     pMUXMsg->UIMUIMVerifyPinReq.TLVType = 0x01;
419     pMUXMsg->UIMUIMVerifyPinReq.TLVLength = cpu_to_le16(0x02);
420     pMUXMsg->UIMUIMVerifyPinReq.Session_Type = 0x00;
421     pMUXMsg->UIMUIMVerifyPinReq.Aid_Len = 0x00;
422     pMUXMsg->UIMUIMVerifyPinReq.TLV2Type = 0x02;
423     pMUXMsg->UIMUIMVerifyPinReq.TLV2Length = cpu_to_le16(2 + strlen((const char *)arg));
424     pMUXMsg->UIMUIMVerifyPinReq.PINID = 0x01;  //Pin1, not Puk
425     pMUXMsg->UIMUIMVerifyPinReq.PINLen= strlen((const char *)arg);
426     qstrcpy((PCHAR)&pMUXMsg->UIMUIMVerifyPinReq.PINValue, ((const char *)arg));
427     return sizeof(QMIUIM_VERIFY_PIN_REQ_MSG) + (strlen((const char *)arg) - 1);
428 }
429 
430 #ifdef CONFIG_IMSI_ICCID
UimReadTransparentIMSIReqSend(PQMUX_MSG pMUXMsg,void * arg)431 static USHORT UimReadTransparentIMSIReqSend(PQMUX_MSG pMUXMsg, void *arg) {
432     PREAD_TRANSPARENT_TLV pReadTransparent;
433 
434     pMUXMsg->UIMUIMReadTransparentReq.TLVType =  0x01;
435     pMUXMsg->UIMUIMReadTransparentReq.TLVLength = cpu_to_le16(0x02);
436     if (!strcmp((char *)arg, "EF_ICCID")) {
437         pMUXMsg->UIMUIMReadTransparentReq.Session_Type = 0x06;
438         pMUXMsg->UIMUIMReadTransparentReq.Aid_Len = 0x00;
439 
440         pMUXMsg->UIMUIMReadTransparentReq.TLV2Type = 0x02;
441         pMUXMsg->UIMUIMReadTransparentReq.file_id = cpu_to_le16(0x2FE2);
442         pMUXMsg->UIMUIMReadTransparentReq.path_len = 0x02;
443         pMUXMsg->UIMUIMReadTransparentReq.path[0] = 0x00;
444         pMUXMsg->UIMUIMReadTransparentReq.path[1] = 0x3F;
445     }
446     else if(!strcmp((char *)arg, "EF_IMSI")) {
447         pMUXMsg->UIMUIMReadTransparentReq.Session_Type = 0x00;
448         pMUXMsg->UIMUIMReadTransparentReq.Aid_Len = 0x00;
449 
450         pMUXMsg->UIMUIMReadTransparentReq.TLV2Type = 0x02;
451         pMUXMsg->UIMUIMReadTransparentReq.file_id = cpu_to_le16(0x6F07);
452         pMUXMsg->UIMUIMReadTransparentReq.path_len = 0x04;
453         pMUXMsg->UIMUIMReadTransparentReq.path[0] = 0x00;
454         pMUXMsg->UIMUIMReadTransparentReq.path[1] = 0x3F;
455         pMUXMsg->UIMUIMReadTransparentReq.path[2] = 0xFF;
456         pMUXMsg->UIMUIMReadTransparentReq.path[3] = 0x7F;
457     }
458 
459     pMUXMsg->UIMUIMReadTransparentReq.TLV2Length = cpu_to_le16(3 +  pMUXMsg->UIMUIMReadTransparentReq.path_len);
460 
461     pReadTransparent = (PREAD_TRANSPARENT_TLV)(&pMUXMsg->UIMUIMReadTransparentReq.path[pMUXMsg->UIMUIMReadTransparentReq.path_len]);
462     pReadTransparent->TLVType = 0x03;
463     pReadTransparent->TLVLength = cpu_to_le16(0x04);
464     pReadTransparent->Offset = cpu_to_le16(0x00);
465     pReadTransparent->Length = cpu_to_le16(0x00);
466 
467     return (sizeof(QMIUIM_READ_TRANSPARENT_REQ_MSG) + pMUXMsg->UIMUIMReadTransparentReq.path_len + sizeof(READ_TRANSPARENT_TLV));
468 }
469 #endif
470 #endif
471 
472 #ifdef CONFIG_APN
WdsGetProfileSettingsReqSend(PQMUX_MSG pMUXMsg,void * arg)473 static USHORT WdsGetProfileSettingsReqSend(PQMUX_MSG pMUXMsg, void *arg) {
474     PROFILE_T *profile = (PROFILE_T *)arg;
475     pMUXMsg->GetProfileSettingsReq.Length = cpu_to_le16(sizeof(QMIWDS_GET_PROFILE_SETTINGS_REQ_MSG) - 4);
476     pMUXMsg->GetProfileSettingsReq.TLVType = 0x01;
477     pMUXMsg->GetProfileSettingsReq.TLVLength = cpu_to_le16(0x02);
478     pMUXMsg->GetProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2
479     pMUXMsg->GetProfileSettingsReq.ProfileIndex = profile->pdp;
480     return sizeof(QMIWDS_GET_PROFILE_SETTINGS_REQ_MSG);
481 }
482 
WdsModifyProfileSettingsReq(PQMUX_MSG pMUXMsg,void * arg)483 static USHORT WdsModifyProfileSettingsReq(PQMUX_MSG pMUXMsg, void *arg) {
484     USHORT TLVLength = 0;
485     UCHAR *pTLV;
486     PROFILE_T *profile = (PROFILE_T *)arg;
487     PQMIWDS_PDPTYPE pPdpType;
488 
489     pMUXMsg->ModifyProfileSettingsReq.Length = cpu_to_le16(sizeof(QMIWDS_MODIFY_PROFILE_SETTINGS_REQ_MSG) - 4);
490     pMUXMsg->ModifyProfileSettingsReq.TLVType = 0x01;
491     pMUXMsg->ModifyProfileSettingsReq.TLVLength = cpu_to_le16(0x02);
492     pMUXMsg->ModifyProfileSettingsReq.ProfileType = 0x00; // 0 ~ 3GPP, 1 ~ 3GPP2
493     pMUXMsg->ModifyProfileSettingsReq.ProfileIndex = profile->pdp;
494 
495     pTLV = (UCHAR *)(&pMUXMsg->ModifyProfileSettingsReq + 1);
496 
497     pPdpType = (PQMIWDS_PDPTYPE)(pTLV + TLVLength);
498     pPdpType->TLVType = 0x11;
499     pPdpType->TLVLength = cpu_to_le16(0x01);
500 // 0 ?C PDP-IP (IPv4)
501 // 1 ?C PDP-PPP
502 // 2 ?C PDP-IPv6
503 // 3 ?C PDP-IPv4v6
504     if (profile->enable_ipv4 && profile->enable_ipv6)
505         pPdpType->PdpType = 3;
506     else if (profile->enable_ipv6)
507     	pPdpType->PdpType = 2;
508 	else
509         pPdpType->PdpType = 0;
510     TLVLength +=(le16_to_cpu(pPdpType->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
511 
512     // Set APN Name
513     if (profile->apn) {
514         PQMIWDS_APNNAME pApnName = (PQMIWDS_APNNAME)(pTLV + TLVLength);
515         pApnName->TLVType = 0x14;
516         pApnName->TLVLength = cpu_to_le16(strlen(profile->apn));
517         qstrcpy((char *)&pApnName->ApnName, profile->apn);
518         TLVLength +=(le16_to_cpu(pApnName->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
519     }
520 
521     // Set User Name
522     if (profile->user) {
523         PQMIWDS_USERNAME pUserName = (PQMIWDS_USERNAME)(pTLV + TLVLength);
524         pUserName->TLVType = 0x1B;
525         pUserName->TLVLength = cpu_to_le16(strlen(profile->user));
526         qstrcpy((char *)&pUserName->UserName, profile->user);
527         TLVLength += (le16_to_cpu(pUserName->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
528     }
529 
530     // Set Password
531     if (profile->password) {
532         PQMIWDS_PASSWD pPasswd = (PQMIWDS_PASSWD)(pTLV + TLVLength);
533         pPasswd->TLVType = 0x1C;
534         pPasswd->TLVLength = cpu_to_le16(strlen(profile->password));
535         qstrcpy((char *)&pPasswd->Passwd, profile->password);
536         TLVLength +=(le16_to_cpu(pPasswd->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
537     }
538 
539     // Set Auth Protocol
540     if (profile->user && profile->password) {
541         PQMIWDS_AUTH_PREFERENCE pAuthPref = (PQMIWDS_AUTH_PREFERENCE)(pTLV + TLVLength);
542         pAuthPref->TLVType = 0x1D;
543         pAuthPref->TLVLength = cpu_to_le16(0x01);
544         pAuthPref->AuthPreference = profile->auth; // 0 ~ None, 1 ~ Pap, 2 ~ Chap, 3 ~ MsChapV2
545         TLVLength += (le16_to_cpu(pAuthPref->TLVLength) + sizeof(QCQMICTL_TLV_HDR));
546     }
547 
548     return sizeof(QMIWDS_MODIFY_PROFILE_SETTINGS_REQ_MSG) + TLVLength;
549 }
550 #endif
551 
WdsGetRuntimeSettingReq(PQMUX_MSG pMUXMsg,void * arg)552 static USHORT WdsGetRuntimeSettingReq(PQMUX_MSG pMUXMsg, void *arg)
553 {
554     (void)arg;
555     pMUXMsg->GetRuntimeSettingsReq.TLVType = 0x10;
556     pMUXMsg->GetRuntimeSettingsReq.TLVLength = cpu_to_le16(0x04);
557     // the following mask also applies to IPV6
558     pMUXMsg->GetRuntimeSettingsReq.Mask = cpu_to_le32(QMIWDS_GET_RUNTIME_SETTINGS_MASK_IPV4DNS_ADDR |
559                                                       QMIWDS_GET_RUNTIME_SETTINGS_MASK_IPV4_ADDR |
560                                                       QMIWDS_GET_RUNTIME_SETTINGS_MASK_MTU |
561                                                       QMIWDS_GET_RUNTIME_SETTINGS_MASK_IPV4GATEWAY_ADDR) |
562                                           QMIWDS_GET_RUNTIME_SETTINGS_MASK_PCSCF_SV_ADDR |
563                                           QMIWDS_GET_RUNTIME_SETTINGS_MASK_PCSCF_DOM_NAME;
564 
565     return sizeof(QMIWDS_GET_RUNTIME_SETTINGS_REQ_MSG);
566 }
567 
568 static PQCQMIMSG s_pRequest;
569 static PQCQMIMSG s_pResponse;
570 
is_response(const PQCQMIMSG pRequest,const PQCQMIMSG pResponse)571 static int is_response(const PQCQMIMSG pRequest, const PQCQMIMSG pResponse) {
572     if ((pRequest->QMIHdr.QMIType == pResponse->QMIHdr.QMIType)
573         && (pRequest->QMIHdr.ClientId == pResponse->QMIHdr.ClientId)) {
574             USHORT requestTID, responseTID;
575         if (pRequest->QMIHdr.QMIType == QMUX_TYPE_CTL) {
576             requestTID = pRequest->CTLMsg.QMICTLMsgHdr.TransactionId;
577             responseTID = pResponse->CTLMsg.QMICTLMsgHdr.TransactionId;
578         } else {
579             requestTID = le16_to_cpu(pRequest->MUXMsg.QMUXHdr.TransactionId);
580             responseTID = le16_to_cpu(pResponse->MUXMsg.QMUXHdr.TransactionId);
581         }
582         return (requestTID == responseTID);
583     }
584     return 0;
585 }
586 
587 int (*qmidev_send)(PQCQMIMSG pRequest);
588 
QmiThreadSendQMITimeout(PQCQMIMSG pRequest,PQCQMIMSG * ppResponse,unsigned msecs,const char * funcname)589 int QmiThreadSendQMITimeout(PQCQMIMSG pRequest, PQCQMIMSG *ppResponse, unsigned msecs, const char *funcname) {
590     int ret;
591 
592     if (!pRequest)
593         return -EINVAL;
594 
595     pthread_mutex_lock(&cm_command_mutex);
596 
597     if (ppResponse)
598         *ppResponse = NULL;
599 
600     dump_qmi(pRequest, le16_to_cpu(pRequest->QMIHdr.Length) + 1);
601 
602     s_pRequest = pRequest;
603     s_pResponse = NULL;
604 
605     ret = qmidev_send(pRequest);
606 
607     if (ret == 0) {
608         ret = pthread_cond_timeout_np(&cm_command_cond, &cm_command_mutex, msecs);
609         if (!ret) {
610             if (s_pResponse && ppResponse) {
611                 *ppResponse = s_pResponse;
612             } else {
613                 if (s_pResponse) {
614                     free(s_pResponse);
615                     s_pResponse = NULL;
616                 }
617             }
618         } else {
619             dbg_time("%s message timeout", funcname);
620         }
621     }
622 
623     pthread_mutex_unlock(&cm_command_mutex);
624 
625     return ret;
626 }
627 
QmiThreadRecvQMI(PQCQMIMSG pResponse)628 void QmiThreadRecvQMI(PQCQMIMSG pResponse) {
629     pthread_mutex_lock(&cm_command_mutex);
630     if (pResponse == NULL) {
631         if (s_pRequest) {
632             free(s_pRequest);
633             s_pRequest = NULL;
634             s_pResponse = NULL;
635             pthread_cond_signal(&cm_command_cond);
636         }
637         pthread_mutex_unlock(&cm_command_mutex);
638         return;
639     }
640     dump_qmi(pResponse, le16_to_cpu(pResponse->QMIHdr.Length) + 1);
641     if (s_pRequest && is_response(s_pRequest, pResponse)) {
642         free(s_pRequest);
643         s_pRequest = NULL;
644         s_pResponse = malloc(le16_to_cpu(pResponse->QMIHdr.Length) + 1);
645         if (s_pResponse != NULL) {
646             memcpy(s_pResponse, pResponse, le16_to_cpu(pResponse->QMIHdr.Length) + 1);
647         }
648         pthread_cond_signal(&cm_command_cond);
649     } else if ((pResponse->QMIHdr.QMIType == QMUX_TYPE_CTL)
650                     && (le16_to_cpu(pResponse->CTLMsg.QMICTLMsgHdrRsp.QMICTLType == QMICTL_REVOKE_CLIENT_ID_IND))) {
651         qmidevice_send_event_to_main(MODEM_REPORT_RESET_EVENT);
652     } else if ((pResponse->QMIHdr.QMIType == QMUX_TYPE_NAS)
653                     && (le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.Type) == QMINAS_SERVING_SYSTEM_IND)) {
654         qmidevice_send_event_to_main(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED);
655     } else if ((pResponse->QMIHdr.QMIType == QMUX_TYPE_WDS)
656                     && (le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.Type) == QMIWDS_GET_PKT_SRVC_STATUS_IND)) {
657         qmidevice_send_event_to_main(RIL_UNSOL_DATA_CALL_LIST_CHANGED);
658     } else if ((pResponse->QMIHdr.QMIType == QMUX_TYPE_NAS)
659                     && (le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.Type) == QMINAS_SYS_INFO_IND)) {
660         qmidevice_send_event_to_main(RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED);
661     } else if ((pResponse->QMIHdr.QMIType == QMUX_TYPE_WDS_ADMIN)
662                     && (le16_to_cpu(pResponse->MUXMsg.QMUXMsgHdrResp.Type) == QMI_WDA_SET_LOOPBACK_CONFIG_IND)) {
663     	qmidevice_send_event_to_main_ext(RIL_UNSOL_LOOPBACK_CONFIG_IND,
664             &pResponse->MUXMsg.SetLoopBackInd, sizeof(pResponse->MUXMsg.SetLoopBackInd));
665     } else {
666         if (debug_qmi)
667             dbg_time("nobody care this qmi msg!!");
668     }
669     pthread_mutex_unlock(&cm_command_mutex);
670 }
671 
requestSetEthMode(PROFILE_T * profile)672 static int requestSetEthMode(PROFILE_T *profile) {
673     PQCQMIMSG pRequest;
674     PQCQMIMSG pResponse = NULL;
675     PQMUX_MSG pMUXMsg;
676     int err;
677     PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV linkProto;
678     UCHAR IpPreference;
679     UCHAR autoconnect_setting = 0;
680     QMAP_SETTING qmap_settings = {0};
681 
682     qmap_settings.size = sizeof(qmap_settings);
683 
684     if (profile->qmap_mode) {
685         profile->rawIP = 1;
686         s_9x07 = profile->rawIP;
687 
688         qmap_settings.MuxId = profile->muxid;
689 
690         if (qmidev_is_pciemhi(profile->qmichannel)) { //SDX20_PCIE
691             qmap_settings.rx_urb_size = profile->qmap_size; //SDX24&SDX55 support 32KB
692             qmap_settings.ep_type = DATA_EP_TYPE_PCIE;
693             qmap_settings.iface_id = 0x04;
694         }
695         else { // for MDM9x07&MDM9x40&SDX20 USB
696             qmap_settings.rx_urb_size = profile->qmap_size; //SDX24&SDX55 support 32KB
697             qmap_settings.ep_type = DATA_EP_TYPE_HSUSB;
698             qmap_settings.iface_id = 0x04;
699         }
700 
701         qmap_settings.ul_data_aggregation_max_datagrams = 11; //by test result, 11 can get best TPUT
702         qmap_settings.ul_data_aggregation_max_size = 8*1024;
703         qmap_settings.dl_minimum_padding = 0; //no effect when register to real netowrk
704         if(profile->qmap_version != 0x09)
705             profile->qmap_version = 0x05;
706 
707         qmap_version = profile->qmap_version;
708         if (profile->rmnet_info.size) {
709             qmap_settings.rx_urb_size = profile->rmnet_info.rx_urb_size;
710             qmap_settings.ep_type = profile->rmnet_info.ep_type;
711             qmap_settings.iface_id = profile->rmnet_info.iface_id;
712             qmap_settings.dl_minimum_padding = profile->rmnet_info.dl_minimum_padding;
713             qmap_version = profile->rmnet_info.qmap_version;
714         }
715 
716         if (!profile->wda_client) {
717             if (qmidev_is_gobinet(profile->qmichannel)) {
718                 //when QMAP enabled, set data format in GobiNet driver
719             }
720             else if (profile->proxy[0]) {
721                 /* the first running 'quectel-cm' had alloc wda client and set data format,
722                    so we can ingore to set data format here. */
723             }
724             goto skip_WdaSetDataFormat;
725         }
726     }
727 
728     pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS_ADMIN, QMIWDS_ADMIN_SET_DATA_FORMAT_REQ, WdaSetDataFormat, (void *)&qmap_settings);
729     err = QmiThreadSendQMI(pRequest, &pResponse);
730     qmi_rsp_check_and_return();
731 
732     linkProto = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11);
733     if (linkProto != NULL) {
734         profile->rawIP = (le32_to_cpu(linkProto->Value) == 2);
735         s_9x07 = profile->rawIP; //MDM90x7 only support RAW IP, do not support Eth
736     }
737 
738     linkProto = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x16);
739     if (linkProto != NULL && profile->qmap_mode) {
740         qmap_settings.rx_urb_size = le32_to_cpu(linkProto->Value);
741         dbg_time("qmap_settings.rx_urb_size = %u", qmap_settings.rx_urb_size); //must same as rx_urb_size defined in GobiNet&qmi_wwan driver
742     }
743 
744 #ifdef QUECTEL_UL_DATA_AGG
745     if (qmap_settings.ul_data_aggregation_max_datagrams)
746     {
747         linkProto = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x17);
748         if (linkProto != NULL) {
749             qmap_settings.ul_data_aggregation_max_datagrams = MIN(qmap_settings.ul_data_aggregation_max_datagrams, le32_to_cpu(linkProto->Value));
750             dbg_time("qmap_settings.ul_data_aggregation_max_datagrams  = %u", qmap_settings.ul_data_aggregation_max_datagrams);
751         }
752 
753         linkProto = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x18);
754         if (linkProto != NULL) {
755             qmap_settings.ul_data_aggregation_max_size = MIN(qmap_settings.ul_data_aggregation_max_size, le32_to_cpu(linkProto->Value));
756             dbg_time("qmap_settings.ul_data_aggregation_max_size       = %u", qmap_settings.ul_data_aggregation_max_size);
757         }
758 
759         linkProto = (PQMIWDS_ADMIN_SET_DATA_FORMAT_TLV)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1A);
760         if (linkProto != NULL) {
761             qmap_settings.dl_minimum_padding = le32_to_cpu(linkProto->Value);
762             dbg_time("qmap_settings.dl_minimum_padding                 = %u", qmap_settings.dl_minimum_padding);
763         }
764 
765 	if (qmap_settings.ul_data_aggregation_max_datagrams > 1) {
766 		ql_set_driver_qmap_setting(profile, &qmap_settings);
767 	}
768     }
769 #endif
770 
771     free(pResponse);
772 
773 skip_WdaSetDataFormat:
774     if (profile->enable_ipv4) {
775     	if (profile->qmapnet_adapter[0]) {
776             // bind wds mux data port
777         	pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_BIND_MUX_DATA_PORT_REQ , WdsSetQMUXBindMuxDataPort, (void *)&qmap_settings);
778         	err = QmiThreadSendQMI(pRequest, &pResponse);
779         	qmi_rsp_check_and_return();
780         	if (pResponse) free(pResponse);
781         }
782 
783         // set ipv4
784     	IpPreference = IpFamilyV4;
785     	pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ, WdsSetClientIPFamilyPref, (void *)&IpPreference);
786     	err = QmiThreadSendQMI(pRequest, &pResponse);
787     	if (pResponse) free(pResponse);
788     }
789 
790     if (profile->enable_ipv6) {
791         if (profile->qmapnet_adapter[0]) {
792             // bind wds ipv6 mux data port
793             pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS_IPV6, QMIWDS_BIND_MUX_DATA_PORT_REQ , WdsSetQMUXBindMuxDataPort, (void *)&qmap_settings);
794             err = QmiThreadSendQMI(pRequest, &pResponse);
795             qmi_rsp_check_and_return();
796             if (pResponse) free(pResponse);
797         }
798 
799         // set ipv6
800         IpPreference = IpFamilyV6;
801         pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS_IPV6, QMIWDS_SET_CLIENT_IP_FAMILY_PREF_REQ, WdsSetClientIPFamilyPref, (void *)&IpPreference);
802         err = QmiThreadSendQMI(pRequest, &pResponse);
803         qmi_rsp_check_and_return();
804         if (pResponse) free(pResponse);
805     }
806 
807     pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_SET_AUTO_CONNECT_REQ , WdsSetAutoConnect, (void *)&autoconnect_setting);
808     QmiThreadSendQMI(pRequest, &pResponse);
809     if (pResponse) free(pResponse);
810 
811     return 0;
812 }
813 
814 #ifdef CONFIG_SIM
requestGetPINStatus(SIM_Status * pSIMStatus)815 static int requestGetPINStatus(SIM_Status *pSIMStatus) {
816     PQCQMIMSG pRequest;
817     PQCQMIMSG pResponse;
818     PQMUX_MSG pMUXMsg;
819     int err;
820     PQMIDMS_UIM_PIN_STATUS pPin1Status = NULL;
821     //PQMIDMS_UIM_PIN_STATUS pPin2Status = NULL;
822 
823     if (s_9x07)
824         pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_GET_CARD_STATUS_REQ, NULL, NULL);
825     else
826         pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_UIM_GET_PIN_STATUS_REQ, NULL, NULL);
827     err = QmiThreadSendQMI(pRequest, &pResponse);
828     qmi_rsp_check_and_return();
829 
830     pPin1Status = (PQMIDMS_UIM_PIN_STATUS)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11);
831     //pPin2Status = (PQMIDMS_UIM_PIN_STATUS)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x12);
832 
833     if (pPin1Status != NULL) {
834         if (pPin1Status->PINStatus == QMI_PIN_STATUS_NOT_VERIF) {
835             *pSIMStatus = SIM_PIN;
836         } else if (pPin1Status->PINStatus == QMI_PIN_STATUS_BLOCKED) {
837             *pSIMStatus = SIM_PUK;
838         } else if (pPin1Status->PINStatus == QMI_PIN_STATUS_PERM_BLOCKED) {
839             *pSIMStatus = SIM_BAD;
840         }
841     }
842 
843     free(pResponse);
844     return 0;
845 }
846 
requestGetSIMStatus(SIM_Status * pSIMStatus)847 static int requestGetSIMStatus(SIM_Status *pSIMStatus) { //RIL_REQUEST_GET_SIM_STATUS
848     PQCQMIMSG pRequest;
849     PQCQMIMSG pResponse;
850     PQMUX_MSG pMUXMsg;
851     int err;
852     const char * SIM_Status_String[] = {
853         "SIM_ABSENT",
854         "SIM_NOT_READY",
855         "SIM_READY", /* SIM_READY means the radio state is RADIO_STATE_SIM_READY */
856         "SIM_PIN",
857         "SIM_PUK",
858         "SIM_NETWORK_PERSONALIZATION"
859     };
860 
861     if (s_9x07)
862         pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_GET_CARD_STATUS_REQ, NULL, NULL);
863     else
864         pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_UIM_GET_STATE_REQ, NULL, NULL);
865 
866     err = QmiThreadSendQMI(pRequest, &pResponse);
867     qmi_rsp_check_and_return();
868 
869     *pSIMStatus = SIM_ABSENT;
870     if (s_9x07)
871     {
872         PQMIUIM_CARD_STATUS pCardStatus = NULL;
873         PQMIUIM_PIN_STATE pPINState = NULL;
874         UCHAR CardState = 0x01;
875         UCHAR PIN1State = QMI_PIN_STATUS_NOT_VERIF;
876         //UCHAR PIN1Retries;
877         //UCHAR PUK1Retries;
878         //UCHAR PIN2State;
879         //UCHAR PIN2Retries;
880         //UCHAR PUK2Retries;
881 
882         pCardStatus = (PQMIUIM_CARD_STATUS)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x10);
883         if (pCardStatus != NULL)
884         {
885             pPINState = (PQMIUIM_PIN_STATE)((PUCHAR)pCardStatus + sizeof(QMIUIM_CARD_STATUS) + pCardStatus->AIDLength);
886             CardState  = pCardStatus->CardState;
887             if (CardState == UIM_CARD_STATE_PRESENT) {
888                 if (pPINState->UnivPIN == 1)
889                 {
890                    PIN1State = pCardStatus->UPINState;
891                    //PIN1Retries = pCardStatus->UPINRetries;
892                    //PUK1Retries = pCardStatus->UPUKRetries;
893                 }
894                 else
895                 {
896                    PIN1State = pPINState->PIN1State;
897                    //PIN1Retries = pPINState->PIN1Retries;
898                    //PUK1Retries = pPINState->PUK1Retries;
899                 }
900                 //PIN2State = pPINState->PIN2State;
901                 //PIN2Retries = pPINState->PIN2Retries;
902                 //PUK2Retries = pPINState->PUK2Retries;
903             }
904         }
905 
906         *pSIMStatus = SIM_ABSENT;
907         if ((CardState == 0x01) &&  ((PIN1State == QMI_PIN_STATUS_VERIFIED)|| (PIN1State == QMI_PIN_STATUS_DISABLED)))
908         {
909             *pSIMStatus = SIM_READY;
910         }
911         else if (CardState == 0x01)
912         {
913             if (PIN1State == QMI_PIN_STATUS_NOT_VERIF)
914             {
915                 *pSIMStatus = SIM_PIN;
916             }
917             if ( PIN1State == QMI_PIN_STATUS_BLOCKED)
918             {
919                 *pSIMStatus = SIM_PUK;
920             }
921             else if (PIN1State == QMI_PIN_STATUS_PERM_BLOCKED)
922             {
923                 *pSIMStatus = SIM_BAD;
924             }
925             else if (PIN1State == QMI_PIN_STATUS_NOT_INIT || PIN1State == QMI_PIN_STATUS_VERIFIED || PIN1State == QMI_PIN_STATUS_DISABLED)
926             {
927                 *pSIMStatus = SIM_READY;
928             }
929         }
930         else if (CardState == 0x00 || CardState == 0x02)
931         {
932         }
933         else
934         {
935         }
936     }
937     else
938     {
939     //UIM state. Values:
940     // 0x00  UIM initialization completed
941     // 0x01  UIM is locked or the UIM failed
942     // 0x02  UIM is not present
943     // 0x03  Reserved
944     // 0xFF  UIM state is currently
945     //unavailable
946         if (pResponse->MUXMsg.UIMGetStateResp.UIMState == 0x00) {
947             *pSIMStatus = SIM_READY;
948         } else if (pResponse->MUXMsg.UIMGetStateResp.UIMState == 0x01) {
949             *pSIMStatus = SIM_ABSENT;
950             err = requestGetPINStatus(pSIMStatus);
951         } else if ((pResponse->MUXMsg.UIMGetStateResp.UIMState == 0x02) || (pResponse->MUXMsg.UIMGetStateResp.UIMState == 0xFF)) {
952             *pSIMStatus = SIM_ABSENT;
953         } else {
954             *pSIMStatus = SIM_ABSENT;
955         }
956     }
957     dbg_time("%s SIMStatus: %s", __func__, SIM_Status_String[*pSIMStatus]);
958 
959     free(pResponse);
960 
961     return 0;
962 }
963 
requestEnterSimPin(const CHAR * pPinCode)964 static int requestEnterSimPin(const CHAR *pPinCode) {
965     PQCQMIMSG pRequest;
966     PQCQMIMSG pResponse;
967     PQMUX_MSG pMUXMsg;
968     int err;
969 
970     if (s_9x07)
971         pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_VERIFY_PIN_REQ, UimVerifyPinReqSend, (void *)pPinCode);
972     else
973         pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_UIM_VERIFY_PIN_REQ, DmsUIMVerifyPinReqSend, (void *)pPinCode);
974     err = QmiThreadSendQMI(pRequest, &pResponse);
975     qmi_rsp_check_and_return();
976 
977     free(pResponse);
978     return 0;
979 }
980 #endif
981 
982 #ifdef CONFIG_IMSI_ICCID
requestGetICCID(void)983 static int requestGetICCID(void) { //RIL_REQUEST_GET_IMSI
984     PQCQMIMSG pRequest;
985     PQCQMIMSG pResponse;
986     PQMUX_MSG pMUXMsg;
987     PQMIUIM_CONTENT pUimContent;
988     int err;
989 
990     if (s_9x07) {
991         pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_READ_TRANSPARENT_REQ, UimReadTransparentIMSIReqSend, (void *)"EF_ICCID");
992         err = QmiThreadSendQMI(pRequest, &pResponse);
993     } else {
994         return 0;
995     }
996     qmi_rsp_check_and_return();
997 
998     pUimContent = (PQMIUIM_CONTENT)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11);
999     if (pUimContent != NULL) {
1000         static char DeviceICCID[32] = {'\0'};
1001         int i = 0, j = 0;
1002 
1003         for (i = 0, j = 0; i < le16_to_cpu(pUimContent->content_len); ++i) {
1004             char charmaps[] = "0123456789ABCDEF";
1005 
1006             DeviceICCID[j++] = charmaps[(pUimContent->content[i] & 0x0F)];
1007             DeviceICCID[j++] = charmaps[((pUimContent->content[i] & 0xF0) >> 0x04)];
1008         }
1009         DeviceICCID[j] = '\0';
1010 
1011         dbg_time("%s DeviceICCID: %s", __func__, DeviceICCID);
1012     }
1013 
1014     free(pResponse);
1015     return 0;
1016 }
1017 
requestGetIMSI(void)1018 static int requestGetIMSI(void) { //RIL_REQUEST_GET_IMSI
1019     PQCQMIMSG pRequest;
1020     PQCQMIMSG pResponse;
1021     PQMUX_MSG pMUXMsg;
1022     PQMIUIM_CONTENT pUimContent;
1023     int err;
1024 
1025     if (s_9x07) {
1026         pRequest = ComposeQMUXMsg(QMUX_TYPE_UIM, QMIUIM_READ_TRANSPARENT_REQ, UimReadTransparentIMSIReqSend, (void *)"EF_IMSI");
1027         err = QmiThreadSendQMI(pRequest, &pResponse);
1028     } else {
1029         return 0;
1030     }
1031     qmi_rsp_check_and_return();
1032 
1033     pUimContent = (PQMIUIM_CONTENT)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11);
1034     if (pUimContent != NULL) {
1035         static char DeviceIMSI[32] = {'\0'};
1036         int i = 0, j = 0;
1037 
1038         for (i = 0, j = 0; i < le16_to_cpu(pUimContent->content[0]); ++i) {
1039             if (i != 0)
1040                 DeviceIMSI[j++] = (pUimContent->content[i+1] & 0x0F) + '0';
1041             DeviceIMSI[j++] = ((pUimContent->content[i+1] & 0xF0) >> 0x04) + '0';
1042         }
1043         DeviceIMSI[j] = '\0';
1044 
1045         dbg_time("%s DeviceIMSI: %s", __func__, DeviceIMSI);
1046     }
1047 
1048     free(pResponse);
1049     return 0;
1050 }
1051 #endif
1052 
1053 #if 1
quectel_convert_cdma_mcc_2_ascii_mcc(USHORT * p_mcc,USHORT mcc)1054 static void quectel_convert_cdma_mcc_2_ascii_mcc( USHORT *p_mcc, USHORT mcc )
1055 {
1056   unsigned int d1, d2, d3, buf = mcc + 111;
1057 
1058   if ( mcc == 0x3FF ) // wildcard
1059   {
1060     *p_mcc = 3;
1061   }
1062   else
1063   {
1064     d3 = buf % 10;
1065     buf = ( d3 == 0 ) ? (buf-10)/10 : buf/10;
1066 
1067     d2 = buf % 10;
1068     buf = ( d2 == 0 ) ? (buf-10)/10 : buf/10;
1069 
1070     d1 = ( buf == 10 ) ? 0 : buf;
1071 
1072 //dbg_time("d1:%d, d2:%d,d3:%d",d1,d2,d3);
1073     if ( d1<10 && d2<10 && d3<10 )
1074     {
1075     *p_mcc = d1*100+d2*10+d3;
1076 #if 0
1077       *(p_mcc+0) = '0' + d1;
1078       *(p_mcc+1) = '0' + d2;
1079       *(p_mcc+2) = '0' + d3;
1080 #endif
1081     }
1082     else
1083     {
1084       //dbg_time( "invalid digits %d %d %d", d1, d2, d3 );
1085       *p_mcc = 0;
1086     }
1087   }
1088 }
1089 
quectel_convert_cdma_mnc_2_ascii_mnc(USHORT * p_mnc,USHORT imsi_11_12)1090 static void quectel_convert_cdma_mnc_2_ascii_mnc( USHORT *p_mnc, USHORT imsi_11_12)
1091 {
1092   unsigned int d1, d2, buf = imsi_11_12 + 11;
1093 
1094   if ( imsi_11_12 == 0x7F ) // wildcard
1095   {
1096     *p_mnc = 7;
1097   }
1098   else
1099   {
1100     d2 = buf % 10;
1101     buf = ( d2 == 0 ) ? (buf-10)/10 : buf/10;
1102 
1103     d1 = ( buf == 10 ) ? 0 : buf;
1104 
1105     if ( d1<10 && d2<10 )
1106     {
1107      *p_mnc = d1*10 + d2;
1108     }
1109     else
1110     {
1111       //dbg_time( "invalid digits %d %d", d1, d2, 0 );
1112       *p_mnc = 0;
1113     }
1114   }
1115 }
1116 
requestGetHomeNetwork(USHORT * p_mcc,USHORT * p_mnc,USHORT * p_sid,USHORT * p_nid)1117 static int requestGetHomeNetwork(USHORT *p_mcc, USHORT *p_mnc, USHORT *p_sid, USHORT *p_nid) {
1118     PQCQMIMSG pRequest;
1119     PQCQMIMSG pResponse;
1120     PQMUX_MSG pMUXMsg;
1121     int err;
1122     PHOME_NETWORK pHomeNetwork;
1123     PHOME_NETWORK_SYSTEMID pHomeNetworkSystemID;
1124 
1125     pRequest = ComposeQMUXMsg(QMUX_TYPE_NAS, QMINAS_GET_HOME_NETWORK_REQ, NULL, NULL);
1126     err = QmiThreadSendQMI(pRequest, &pResponse);
1127     qmi_rsp_check_and_return();
1128 
1129     pHomeNetwork = (PHOME_NETWORK)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01);
1130     if (pHomeNetwork && p_mcc && p_mnc ) {
1131         *p_mcc = le16_to_cpu(pHomeNetwork->MobileCountryCode);
1132         *p_mnc = le16_to_cpu(pHomeNetwork->MobileNetworkCode);
1133         //dbg_time("%s MobileCountryCode: %d, MobileNetworkCode: %d", __func__, *pMobileCountryCode, *pMobileNetworkCode);
1134     }
1135 
1136     pHomeNetworkSystemID = (PHOME_NETWORK_SYSTEMID)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x10);
1137     if (pHomeNetworkSystemID && p_sid && p_nid) {
1138         *p_sid = le16_to_cpu(pHomeNetworkSystemID->SystemID); //china-hefei: sid 14451
1139         *p_nid = le16_to_cpu(pHomeNetworkSystemID->NetworkID);
1140         //dbg_time("%s SystemID: %d, NetworkID: %d", __func__, *pSystemID, *pNetworkID);
1141     }
1142 
1143     free(pResponse);
1144 
1145     return 0;
1146 }
1147 #endif
1148 
1149 #if 0
1150 // Lookup table for carriers known to produce SIMs which incorrectly indicate MNC length.
1151 static const char * MCCMNC_CODES_HAVING_3DIGITS_MNC[] = {
1152     "302370", "302720", "310260",
1153     "405025", "405026", "405027", "405028", "405029", "405030", "405031", "405032",
1154     "405033", "405034", "405035", "405036", "405037", "405038", "405039", "405040",
1155     "405041", "405042", "405043", "405044", "405045", "405046", "405047", "405750",
1156     "405751", "405752", "405753", "405754", "405755", "405756", "405799", "405800",
1157     "405801", "405802", "405803", "405804", "405805", "405806", "405807", "405808",
1158     "405809", "405810", "405811", "405812", "405813", "405814", "405815", "405816",
1159     "405817", "405818", "405819", "405820", "405821", "405822", "405823", "405824",
1160     "405825", "405826", "405827", "405828", "405829", "405830", "405831", "405832",
1161     "405833", "405834", "405835", "405836", "405837", "405838", "405839", "405840",
1162     "405841", "405842", "405843", "405844", "405845", "405846", "405847", "405848",
1163     "405849", "405850", "405851", "405852", "405853", "405875", "405876", "405877",
1164     "405878", "405879", "405880", "405881", "405882", "405883", "405884", "405885",
1165     "405886", "405908", "405909", "405910", "405911", "405912", "405913", "405914",
1166     "405915", "405916", "405917", "405918", "405919", "405920", "405921", "405922",
1167     "405923", "405924", "405925", "405926", "405927", "405928", "405929", "405930",
1168     "405931", "405932", "502142", "502143", "502145", "502146", "502147", "502148"
1169 };
1170 
1171 static const char * MCC_CODES_HAVING_3DIGITS_MNC[] = {
1172     "302",    //Canada
1173     "310",    //United States of America
1174     "311",    //United States of America
1175     "312",    //United States of America
1176     "313",    //United States of America
1177     "314",    //United States of America
1178     "315",    //United States of America
1179     "316",    //United States of America
1180     "334",    //Mexico
1181     "338",    //Jamaica
1182     "342", //Barbados
1183     "344",    //Antigua and Barbuda
1184     "346",    //Cayman Islands
1185     "348",    //British Virgin Islands
1186     "365",    //Anguilla
1187     "708",    //Honduras (Republic of)
1188     "722",    //Argentine Republic
1189     "732"    //Colombia (Republic of)
1190 };
1191 
1192 int requestGetIMSI(const char **pp_imsi, USHORT *pMobileCountryCode, USHORT *pMobileNetworkCode) {
1193     PQCQMIMSG pRequest;
1194     PQCQMIMSG pResponse;
1195     PQMUX_MSG pMUXMsg;
1196     int err;
1197 
1198     if (pp_imsi) *pp_imsi = NULL;
1199     if (pMobileCountryCode) *pMobileCountryCode = 0;
1200     if (pMobileNetworkCode) *pMobileNetworkCode = 0;
1201 
1202     pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_UIM_GET_IMSI_REQ, NULL, NULL);
1203     err = QmiThreadSendQMI(pRequest, &pResponse);
1204     qmi_rsp_check_and_return();
1205 
1206     if (pMUXMsg->UIMGetIMSIResp.TLV2Type == 0x01 &&  le16_to_cpu(pMUXMsg->UIMGetIMSIResp.TLV2Length) >= 5) {
1207         int mnc_len = 2;
1208         unsigned i;
1209         char tmp[4];
1210 
1211         if (pp_imsi) *pp_imsi = strndup((const char *)(&pMUXMsg->UIMGetIMSIResp.IMSI), le16_to_cpu(pMUXMsg->UIMGetIMSIResp.TLV2Length));
1212 
1213         for (i = 0; i < sizeof(MCCMNC_CODES_HAVING_3DIGITS_MNC)/sizeof(MCCMNC_CODES_HAVING_3DIGITS_MNC[0]); i++) {
1214             if (!strncmp((const char *)(&pMUXMsg->UIMGetIMSIResp.IMSI), MCCMNC_CODES_HAVING_3DIGITS_MNC[i], 6)) {
1215                 mnc_len = 3;
1216                 break;
1217             }
1218         }
1219         if (mnc_len == 2) {
1220             for (i = 0; i < sizeof(MCC_CODES_HAVING_3DIGITS_MNC)/sizeof(MCC_CODES_HAVING_3DIGITS_MNC[0]); i++) {
1221                 if (!strncmp((const char *)(&pMUXMsg->UIMGetIMSIResp.IMSI), MCC_CODES_HAVING_3DIGITS_MNC[i], 3)) {
1222                     mnc_len = 3;
1223                     break;
1224                 }
1225             }
1226         }
1227 
1228         tmp[0] = (&pMUXMsg->UIMGetIMSIResp.IMSI)[0];
1229         tmp[1] = (&pMUXMsg->UIMGetIMSIResp.IMSI)[1];
1230         tmp[2] = (&pMUXMsg->UIMGetIMSIResp.IMSI)[2];
1231         tmp[3] = 0;
1232         if (pMobileCountryCode) *pMobileCountryCode = atoi(tmp);
1233         tmp[0] = (&pMUXMsg->UIMGetIMSIResp.IMSI)[3];
1234         tmp[1] = (&pMUXMsg->UIMGetIMSIResp.IMSI)[4];
1235         tmp[2] = 0;
1236         if (mnc_len == 3) {
1237             tmp[2] = (&pMUXMsg->UIMGetIMSIResp.IMSI)[6];
1238         }
1239         if (pMobileNetworkCode) *pMobileNetworkCode = atoi(tmp);
1240     }
1241 
1242     free(pResponse);
1243 
1244     return 0;
1245 }
1246 #endif
1247 
1248 static struct wwan_data_class_str class2str[] = {
1249     {WWAN_DATA_CLASS_NONE, "UNKNOWN"},
1250     {WWAN_DATA_CLASS_GPRS, "GPRS"},
1251     {WWAN_DATA_CLASS_EDGE, "EDGE"},
1252     {WWAN_DATA_CLASS_UMTS, "UMTS"},
1253     {WWAN_DATA_CLASS_HSDPA, "HSDPA"},
1254     {WWAN_DATA_CLASS_HSUPA, "HSUPA"},
1255     {WWAN_DATA_CLASS_LTE, "LTE"},
1256     {WWAN_DATA_CLASS_5G_NSA, "5G_NSA"},
1257     {WWAN_DATA_CLASS_5G_SA, "5G_SA"},
1258     {WWAN_DATA_CLASS_1XRTT, "1XRTT"},
1259     {WWAN_DATA_CLASS_1XEVDO, "1XEVDO"},
1260     {WWAN_DATA_CLASS_1XEVDO_REVA, "1XEVDO_REVA"},
1261     {WWAN_DATA_CLASS_1XEVDV, "1XEVDV"},
1262     {WWAN_DATA_CLASS_3XRTT, "3XRTT"},
1263     {WWAN_DATA_CLASS_1XEVDO_REVB, "1XEVDO_REVB"},
1264     {WWAN_DATA_CLASS_UMB, "UMB"},
1265     {WWAN_DATA_CLASS_CUSTOM, "CUSTOM"},
1266 };
1267 
wwan_data_class2str(ULONG class)1268 static CHAR *wwan_data_class2str(ULONG class)
1269 {
1270     unsigned int i = 0;
1271     for (i = 0; i < sizeof(class2str)/sizeof(class2str[0]); i++) {
1272         if (class2str[i].class == class) {
1273             return class2str[i].str;
1274         }
1275     }
1276     return "UNKNOWN";
1277 }
1278 
char2ushort(UCHAR str[3])1279 static USHORT char2ushort(UCHAR str[3]) {
1280     int i;
1281     char temp[4];
1282     USHORT ret= 0;
1283 
1284     memcpy(temp, str, 3);
1285     temp[3] = '\0';
1286 
1287     for (i = 0; i < 4; i++) {
1288         if ((UCHAR)temp[i] == 0xFF) {
1289             temp[i] = '\0';
1290         }
1291     }
1292     ret = (USHORT)atoi(temp);
1293 
1294     return ret;
1295 }
1296 
requestRegistrationState2(UCHAR * pPSAttachedState)1297 static int requestRegistrationState2(UCHAR *pPSAttachedState) {
1298     PQCQMIMSG pRequest;
1299     PQCQMIMSG pResponse;
1300     PQMUX_MSG pMUXMsg;
1301     int err;
1302     USHORT MobileCountryCode = 0;
1303     USHORT MobileNetworkCode = 0;
1304     const char *pDataCapStr = "UNKNOW";
1305     LONG remainingLen;
1306     PSERVICE_STATUS_INFO pServiceStatusInfo;
1307     int is_lte = 0;
1308     PCDMA_SYSTEM_INFO pCdmaSystemInfo;
1309     PHDR_SYSTEM_INFO pHdrSystemInfo;
1310     PGSM_SYSTEM_INFO pGsmSystemInfo;
1311     PWCDMA_SYSTEM_INFO pWcdmaSystemInfo;
1312     PLTE_SYSTEM_INFO pLteSystemInfo;
1313     PTDSCDMA_SYSTEM_INFO pTdscdmaSystemInfo;
1314     PNR5G_SYSTEM_INFO pNr5gSystemInfo;
1315     UCHAR DeviceClass = 0;
1316     ULONG DataCapList = 0;
1317 
1318     /*  Additional LTE System Info - Availability of Dual connectivity of E-UTRA with NR5G */
1319     uint8_t endc_available_valid = 0;  /**< Must be set to true if endc_available is being passed */
1320     uint8_t endc_available = 0x00;
1321     /**<
1322        Upper layer indication in LTE SIB2. Values: \n
1323        - 0x00 -- 5G Not available \n
1324        - 0x01 -- 5G Available
1325 
1326     */
1327     /*  Additional LTE System Info - DCNR restriction Info */
1328     uint8_t restrict_dcnr_valid = 0;  /**< Must be set to true if restrict_dcnr is being passed */
1329     uint8_t restrict_dcnr = 0x01;
1330     /**<
1331        DCNR restriction in NAS attach/TAU accept. Values: \n
1332        - 0x00 -- Not restricted \n
1333        - 0x01 -- Restricted
1334     */
1335 
1336     *pPSAttachedState = 0;
1337     pRequest = ComposeQMUXMsg(QMUX_TYPE_NAS, QMINAS_GET_SYS_INFO_REQ, NULL, NULL);
1338     err = QmiThreadSendQMI(pRequest, &pResponse);
1339     qmi_rsp_check_and_return();
1340 
1341     pServiceStatusInfo = (PSERVICE_STATUS_INFO)(((PCHAR)&pMUXMsg->GetSysInfoResp) + QCQMUX_MSG_HDR_SIZE);
1342     remainingLen = le16_to_cpu(pMUXMsg->GetSysInfoResp.Length);
1343 
1344     s_is_cdma = 0;
1345     s_5g_type = WWAN_DATA_CLASS_NONE;
1346     s_hdr_personality = 0;
1347     while (remainingLen > 0) {
1348         switch (pServiceStatusInfo->TLVType) {
1349         case 0x10: // CDMA
1350             if (pServiceStatusInfo->SrvStatus == 0x02) {
1351                 DataCapList = WWAN_DATA_CLASS_1XRTT|
1352                               WWAN_DATA_CLASS_1XEVDO|
1353                               WWAN_DATA_CLASS_1XEVDO_REVA|
1354                               WWAN_DATA_CLASS_1XEVDV|
1355                               WWAN_DATA_CLASS_1XEVDO_REVB;
1356                 DeviceClass = DEVICE_CLASS_CDMA;
1357                 s_is_cdma = (0 == is_lte);
1358             }
1359             break;
1360         case 0x11: // HDR
1361             if (pServiceStatusInfo->SrvStatus == 0x02) {
1362                 DataCapList = WWAN_DATA_CLASS_3XRTT|
1363                               WWAN_DATA_CLASS_UMB;
1364                 DeviceClass = DEVICE_CLASS_CDMA;
1365                 s_is_cdma = (0 == is_lte);
1366             }
1367             break;
1368         case 0x12: // GSM
1369             if (pServiceStatusInfo->SrvStatus == 0x02) {
1370                 DataCapList = WWAN_DATA_CLASS_GPRS|
1371                               WWAN_DATA_CLASS_EDGE;
1372                 DeviceClass = DEVICE_CLASS_GSM;
1373             }
1374             break;
1375         case 0x13: // WCDMA
1376             if (pServiceStatusInfo->SrvStatus == 0x02) {
1377                 DataCapList = WWAN_DATA_CLASS_UMTS;
1378                 DeviceClass = DEVICE_CLASS_GSM;
1379             }
1380             break;
1381         case 0x14: // LTE
1382             if (pServiceStatusInfo->SrvStatus == 0x02) {
1383                 DataCapList = WWAN_DATA_CLASS_LTE;
1384                 DeviceClass = DEVICE_CLASS_GSM;
1385                 is_lte = 1;
1386                 s_is_cdma = 0;
1387             }
1388             break;
1389         case 0x4A: // NR5G Service Status Info
1390             if (pServiceStatusInfo->SrvStatus == NAS_SYS_SRV_STATUS_SRV_V01) {
1391                 DataCapList |= WWAN_DATA_CLASS_5G_SA;
1392                 DeviceClass = DEVICE_CLASS_GSM;
1393                 is_lte = 1;
1394                 s_is_cdma = 0;
1395             }
1396             break;
1397         case 0x4B: // NR5G System Info
1398             pNr5gSystemInfo = (PNR5G_SYSTEM_INFO)pServiceStatusInfo;
1399             if (pNr5gSystemInfo->srv_domain_valid == 0x01) {
1400                 if (pNr5gSystemInfo->srv_domain & SYS_SRV_DOMAIN_PS_ONLY_V01) {
1401                     *pPSAttachedState = 1;
1402                 }
1403             }
1404 
1405             if (pNr5gSystemInfo->network_id_valid == 0x01) {
1406                 MobileCountryCode = (USHORT)char2ushort(pNr5gSystemInfo->MCC);
1407                 MobileNetworkCode = (USHORT)char2ushort(pNr5gSystemInfo->MNC);
1408             }
1409             break;
1410         case 0x4E: //Additional LTE System Info - Availability of Dual Connectivity of E-UTRA with NR5G
1411             endc_available_valid = 1;
1412             endc_available = pServiceStatusInfo->SrvStatus;
1413             break;
1414 
1415         case 0x4F: //Additional LTE System Info - DCNR restriction Info
1416             restrict_dcnr_valid = 1;
1417             restrict_dcnr = pServiceStatusInfo->SrvStatus;
1418             break;
1419 
1420         case 0x24: // TDSCDMA
1421             if (pServiceStatusInfo->SrvStatus == 0x02) {
1422                 pDataCapStr = "TD-SCDMA";
1423             }
1424             break;
1425         case 0x15: // CDMA
1426             // CDMA_SYSTEM_INFO
1427             pCdmaSystemInfo = (PCDMA_SYSTEM_INFO)pServiceStatusInfo;
1428             if (pCdmaSystemInfo->SrvDomainValid == 0x01) {
1429                 if (pCdmaSystemInfo->SrvDomain & 0x02) {
1430                     *pPSAttachedState = 1;
1431                     s_is_cdma = (0 == is_lte);
1432                 }
1433             }
1434 #if 0
1435             if (pCdmaSystemInfo->SrvCapabilityValid == 0x01) {
1436                 *pPSAttachedState = 0;
1437                 if (pCdmaSystemInfo->SrvCapability & 0x02) {
1438                     *pPSAttachedState = 1;
1439                     s_is_cdma = (0 == is_lte);
1440                 }
1441             }
1442 #endif
1443             if (pCdmaSystemInfo->NetworkIdValid == 0x01) {
1444                 MobileCountryCode = (USHORT)char2ushort(pCdmaSystemInfo->MCC);
1445                 MobileNetworkCode = (USHORT)char2ushort(pCdmaSystemInfo->MNC);
1446             }
1447             break;
1448         case 0x16: // HDR
1449             // HDR_SYSTEM_INFO
1450             pHdrSystemInfo = (PHDR_SYSTEM_INFO)pServiceStatusInfo;
1451             if (pHdrSystemInfo->SrvDomainValid == 0x01) {
1452                 if (pHdrSystemInfo->SrvDomain & 0x02) {
1453                     *pPSAttachedState = 1;
1454                     s_is_cdma = (0 == is_lte);
1455                 }
1456             }
1457 #if 0
1458             if (pHdrSystemInfo->SrvCapabilityValid == 0x01) {
1459                 *pPSAttachedState = 0;
1460                 if (pHdrSystemInfo->SrvCapability & 0x02) {
1461                     *pPSAttachedState = 1;
1462                     s_is_cdma = (0 == is_lte);
1463                 }
1464             }
1465 #endif
1466             if (*pPSAttachedState && pHdrSystemInfo->HdrPersonalityValid == 0x01) {
1467                 if (pHdrSystemInfo->HdrPersonality == 0x03)
1468                     s_hdr_personality = 0x02;
1469                 //else if (pHdrSystemInfo->HdrPersonality == 0x02)
1470                 //    s_hdr_personality = 0x01;
1471             }
1472             USHORT cmda_mcc = 0, cdma_mnc = 0;
1473             if(!requestGetHomeNetwork(&cmda_mcc, &cdma_mnc,NULL, NULL) && cmda_mcc) {
1474                 quectel_convert_cdma_mcc_2_ascii_mcc(&MobileCountryCode, cmda_mcc);
1475                 quectel_convert_cdma_mnc_2_ascii_mnc(&MobileNetworkCode, cdma_mnc);
1476             }
1477             break;
1478         case 0x17: // GSM
1479             // GSM_SYSTEM_INFO
1480             pGsmSystemInfo = (PGSM_SYSTEM_INFO)pServiceStatusInfo;
1481             if (pGsmSystemInfo->SrvDomainValid == 0x01) {
1482                 if (pGsmSystemInfo->SrvDomain & 0x02) {
1483                     *pPSAttachedState = 1;
1484                 }
1485             }
1486 #if 0
1487             if (pGsmSystemInfo->SrvCapabilityValid == 0x01) {
1488                 *pPSAttachedState = 0;
1489                 if (pGsmSystemInfo->SrvCapability & 0x02) {
1490                     *pPSAttachedState = 1;
1491                 }
1492             }
1493 #endif
1494             if (pGsmSystemInfo->NetworkIdValid == 0x01) {
1495                 MobileCountryCode = (USHORT)char2ushort(pGsmSystemInfo->MCC);
1496                 MobileNetworkCode = (USHORT)char2ushort(pGsmSystemInfo->MNC);
1497             }
1498             break;
1499         case 0x18: // WCDMA
1500             // WCDMA_SYSTEM_INFO
1501             pWcdmaSystemInfo = (PWCDMA_SYSTEM_INFO)pServiceStatusInfo;
1502             if (pWcdmaSystemInfo->SrvDomainValid == 0x01) {
1503                 if (pWcdmaSystemInfo->SrvDomain & 0x02) {
1504                     *pPSAttachedState = 1;
1505                 }
1506             }
1507 #if 0
1508             if (pWcdmaSystemInfo->SrvCapabilityValid == 0x01) {
1509                 *pPSAttachedState = 0;
1510                 if (pWcdmaSystemInfo->SrvCapability & 0x02) {
1511                     *pPSAttachedState = 1;
1512                 }
1513             }
1514 #endif
1515             if (pWcdmaSystemInfo->NetworkIdValid == 0x01) {
1516                 MobileCountryCode = (USHORT)char2ushort(pWcdmaSystemInfo->MCC);
1517                 MobileNetworkCode = (USHORT)char2ushort(pWcdmaSystemInfo->MNC);
1518             }
1519             break;
1520         case 0x19: // LTE_SYSTEM_INFO
1521             // LTE_SYSTEM_INFO
1522             pLteSystemInfo = (PLTE_SYSTEM_INFO)pServiceStatusInfo;
1523             if (pLteSystemInfo->SrvDomainValid == 0x01) {
1524                 if (pLteSystemInfo->SrvDomain & 0x02) {
1525                     *pPSAttachedState = 1;
1526                     is_lte = 1;
1527                     s_is_cdma = 0;
1528                 }
1529             }
1530 #if 0
1531             if (pLteSystemInfo->SrvCapabilityValid == 0x01) {
1532                 *pPSAttachedState = 0;
1533                 if (pLteSystemInfo->SrvCapability & 0x02) {
1534                     *pPSAttachedState = 1;
1535                     is_lte = 1;
1536                     s_is_cdma = 0;
1537                 }
1538             }
1539 #endif
1540             if (pLteSystemInfo->NetworkIdValid == 0x01) {
1541                 MobileCountryCode = (USHORT)char2ushort(pLteSystemInfo->MCC);
1542                 MobileNetworkCode = (USHORT)char2ushort(pLteSystemInfo->MNC);
1543             }
1544             break;
1545         case 0x25: // TDSCDMA
1546             // TDSCDMA_SYSTEM_INFO
1547             pTdscdmaSystemInfo = (PTDSCDMA_SYSTEM_INFO)pServiceStatusInfo;
1548             if (pTdscdmaSystemInfo->SrvDomainValid == 0x01) {
1549                 if (pTdscdmaSystemInfo->SrvDomain & 0x02) {
1550                     *pPSAttachedState = 1;
1551                 }
1552             }
1553 #if 0
1554             if (pTdscdmaSystemInfo->SrvCapabilityValid == 0x01) {
1555                 *pPSAttachedState = 0;
1556                 if (pTdscdmaSystemInfo->SrvCapability & 0x02) {
1557                     *pPSAttachedState = 1;
1558                 }
1559             }
1560 #endif
1561             if (pTdscdmaSystemInfo->NetworkIdValid == 0x01) {
1562                 MobileCountryCode = (USHORT)char2ushort(pTdscdmaSystemInfo->MCC);
1563                 MobileNetworkCode = (USHORT)char2ushort(pTdscdmaSystemInfo->MNC);
1564             }
1565             break;
1566         default:
1567             break;
1568         } /* switch (pServiceStatusInfo->TLYType) */
1569 
1570         remainingLen -= (le16_to_cpu(pServiceStatusInfo->TLVLength) + 3);
1571         pServiceStatusInfo = (PSERVICE_STATUS_INFO)((PCHAR)&pServiceStatusInfo->TLVLength + le16_to_cpu(pServiceStatusInfo->TLVLength) + sizeof(USHORT));
1572     } /* while (remainingLen > 0) */
1573 
1574     if (DataCapList & WWAN_DATA_CLASS_LTE) {
1575         if (endc_available_valid && restrict_dcnr_valid) {
1576             if (endc_available && !restrict_dcnr) {
1577                 DataCapList |= WWAN_DATA_CLASS_5G_NSA;
1578             }
1579         }
1580     }
1581 
1582     if (DeviceClass == DEVICE_CLASS_CDMA) {
1583         if (s_hdr_personality == 2) {
1584             pDataCapStr = s_hdr_personality == 2 ? "eHRPD" : "HRPD";
1585         } else if (DataCapList & WWAN_DATA_CLASS_1XEVDO_REVB) {
1586             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_1XEVDO_REVB);
1587         } else if (DataCapList & WWAN_DATA_CLASS_1XEVDO_REVA) {
1588             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_1XEVDO_REVA);
1589         } else if (DataCapList & WWAN_DATA_CLASS_1XEVDO) {
1590             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_1XEVDO);
1591         } else if (DataCapList & WWAN_DATA_CLASS_1XRTT) {
1592             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_1XRTT);
1593         } else if (DataCapList & WWAN_DATA_CLASS_3XRTT) {
1594             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_3XRTT);
1595         } else if (DataCapList & WWAN_DATA_CLASS_UMB) {
1596             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_UMB);
1597         }
1598     } else {
1599         if (DataCapList & WWAN_DATA_CLASS_5G_SA) {
1600             s_5g_type = WWAN_DATA_CLASS_5G_SA;
1601             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_5G_SA);
1602         } else if (DataCapList & WWAN_DATA_CLASS_5G_NSA) {
1603             s_5g_type = WWAN_DATA_CLASS_5G_NSA;
1604             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_5G_NSA);
1605         } else if (DataCapList & WWAN_DATA_CLASS_LTE) {
1606             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_LTE);
1607         } else if ((DataCapList & WWAN_DATA_CLASS_HSDPA) && (DataCapList & WWAN_DATA_CLASS_HSUPA)) {
1608             pDataCapStr = "HSDPA_HSUPA";
1609         } else if (DataCapList & WWAN_DATA_CLASS_HSDPA) {
1610             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_HSDPA);
1611         } else if (DataCapList & WWAN_DATA_CLASS_HSUPA) {
1612             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_HSUPA);
1613         } else if (DataCapList & WWAN_DATA_CLASS_UMTS) {
1614             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_UMTS);
1615         } else if (DataCapList & WWAN_DATA_CLASS_EDGE) {
1616             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_EDGE);
1617         } else if (DataCapList & WWAN_DATA_CLASS_GPRS) {
1618             pDataCapStr = wwan_data_class2str(WWAN_DATA_CLASS_GPRS);
1619         }
1620     }
1621 
1622     dbg_time("%s MCC: %d, MNC: %d, PS: %s, DataCap: %s", __func__,
1623         MobileCountryCode, MobileNetworkCode, (*pPSAttachedState == 1) ? "Attached" : "Detached" , pDataCapStr);
1624 
1625     free(pResponse);
1626 
1627     return 0;
1628 }
1629 
requestRegistrationState(UCHAR * pPSAttachedState)1630 static int requestRegistrationState(UCHAR *pPSAttachedState) {
1631     PQCQMIMSG pRequest;
1632     PQCQMIMSG pResponse;
1633     PQMUX_MSG pMUXMsg;
1634     int err;
1635     PQMINAS_CURRENT_PLMN_MSG pCurrentPlmn;
1636     PSERVING_SYSTEM pServingSystem;
1637     PQMINAS_DATA_CAP pDataCap;
1638     USHORT MobileCountryCode = 0;
1639     USHORT MobileNetworkCode = 0;
1640     const char *pDataCapStr = "UNKNOW";
1641 
1642     if (s_9x07) {
1643         return requestRegistrationState2(pPSAttachedState);
1644     }
1645 
1646     pRequest = ComposeQMUXMsg(QMUX_TYPE_NAS, QMINAS_GET_SERVING_SYSTEM_REQ, NULL, NULL);
1647     err = QmiThreadSendQMI(pRequest, &pResponse);
1648     qmi_rsp_check_and_return();
1649 
1650     pCurrentPlmn = (PQMINAS_CURRENT_PLMN_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x12);
1651     if (pCurrentPlmn) {
1652         MobileCountryCode = le16_to_cpu(pCurrentPlmn->MobileCountryCode);
1653         MobileNetworkCode = le16_to_cpu(pCurrentPlmn->MobileNetworkCode);
1654     }
1655 
1656     *pPSAttachedState = 0;
1657     pServingSystem = (PSERVING_SYSTEM)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01);
1658     if (pServingSystem) {
1659     //Packet-switched domain attach state of the mobile.
1660     //0x00    PS_UNKNOWN ?Unknown or not applicable
1661     //0x01    PS_ATTACHED ?Attached
1662     //0x02    PS_DETACHED ?Detached
1663         *pPSAttachedState = pServingSystem->RegistrationState;
1664         if (pServingSystem->RegistrationState == 0x01) //0x01 ?C REGISTERED ?C Registered with a network
1665             *pPSAttachedState  = pServingSystem->PSAttachedState;
1666         else {
1667             //MobileCountryCode = MobileNetworkCode = 0;
1668             *pPSAttachedState  = 0x02;
1669         }
1670     }
1671 
1672     pDataCap = (PQMINAS_DATA_CAP)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11);
1673     if (pDataCap && pDataCap->DataCapListLen) {
1674         UCHAR *DataCap = &pDataCap->DataCap;
1675         if (pDataCap->DataCapListLen == 2) {
1676             if ((DataCap[0] == 0x06) && ((DataCap[1] == 0x08) || (DataCap[1] == 0x0A)))
1677                 DataCap[0] = DataCap[1];
1678         }
1679         switch (DataCap[0]) {
1680              case 0x01: pDataCapStr = "GPRS"; break;
1681              case 0x02: pDataCapStr = "EDGE"; break;
1682              case 0x03: pDataCapStr = "HSDPA"; break;
1683              case 0x04: pDataCapStr = "HSUPA"; break;
1684              case 0x05: pDataCapStr = "UMTS"; break;
1685              case 0x06: pDataCapStr = "1XRTT"; break;
1686              case 0x07: pDataCapStr = "1XEVDO"; break;
1687              case 0x08: pDataCapStr = "1XEVDO_REVA"; break;
1688              case 0x09: pDataCapStr = "GPRS"; break;
1689              case 0x0A: pDataCapStr = "1XEVDO_REVB"; break;
1690              case 0x0B: pDataCapStr = "LTE"; break;
1691              case 0x0C: pDataCapStr = "HSDPA"; break;
1692              case 0x0D: pDataCapStr = "HSDPA"; break;
1693              default: pDataCapStr = "UNKNOW"; break;
1694         }
1695     }
1696 
1697     if (pServingSystem && pServingSystem->RegistrationState == 0x01 && pServingSystem->InUseRadioIF && pServingSystem->RadioIF == 0x09) {
1698         pDataCapStr = "TD-SCDMA";
1699     }
1700 
1701     s_is_cdma = 0;
1702     if (pServingSystem && pServingSystem->RegistrationState == 0x01 && pServingSystem->InUseRadioIF && (pServingSystem->RadioIF == 0x01 || pServingSystem->RadioIF == 0x02)) {
1703         USHORT cmda_mcc = 0, cdma_mnc = 0;
1704         s_is_cdma = 1;
1705         if(!requestGetHomeNetwork(&cmda_mcc, &cdma_mnc,NULL, NULL) && cmda_mcc) {
1706             quectel_convert_cdma_mcc_2_ascii_mcc(&MobileCountryCode, cmda_mcc);
1707             quectel_convert_cdma_mnc_2_ascii_mnc(&MobileNetworkCode, cdma_mnc);
1708         }
1709         if (1) {
1710             PQCQMUX_TLV pTLV = (PQCQMUX_TLV)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x23);
1711             if (pTLV)
1712                 s_hdr_personality = pTLV->Value;
1713             else
1714                 s_hdr_personality = 0;
1715             if (s_hdr_personality == 2)
1716                 pDataCapStr = "eHRPD";
1717         }
1718     }
1719 
1720     dbg_time("%s MCC: %d, MNC: %d, PS: %s, DataCap: %s", __func__,
1721         MobileCountryCode, MobileNetworkCode, (*pPSAttachedState == 1) ? "Attached" : "Detached" , pDataCapStr);
1722 
1723     free(pResponse);
1724 
1725     return 0;
1726 }
1727 
requestQueryDataCall(UCHAR * pConnectionStatus,int curIpFamily)1728 static int requestQueryDataCall(UCHAR  *pConnectionStatus, int curIpFamily) {
1729     PQCQMIMSG pRequest;
1730     PQCQMIMSG pResponse;
1731     PQMUX_MSG pMUXMsg;
1732     int err;
1733     PQMIWDS_PKT_SRVC_TLV pPktSrvc;
1734     UCHAR oldConnectionStatus = *pConnectionStatus;
1735     UCHAR QMIType = (curIpFamily == IpFamilyV4) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6;
1736 
1737     pRequest = ComposeQMUXMsg(QMIType, QMIWDS_GET_PKT_SRVC_STATUS_REQ, NULL, NULL);
1738     err = QmiThreadSendQMI(pRequest, &pResponse);
1739     qmi_rsp_check_and_return();
1740 
1741     *pConnectionStatus = QWDS_PKT_DATA_DISCONNECTED;
1742     pPktSrvc = (PQMIWDS_PKT_SRVC_TLV)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01);
1743     if (pPktSrvc) {
1744         *pConnectionStatus = pPktSrvc->ConnectionStatus;
1745         if ((le16_to_cpu(pPktSrvc->TLVLength) == 2) && (pPktSrvc->ReconfigReqd == 0x01))
1746             *pConnectionStatus = QWDS_PKT_DATA_DISCONNECTED;
1747     }
1748 
1749     if (*pConnectionStatus == QWDS_PKT_DATA_DISCONNECTED) {
1750         if (curIpFamily == IpFamilyV4)
1751             WdsConnectionIPv4Handle = 0;
1752         else
1753             WdsConnectionIPv6Handle = 0;
1754     }
1755 
1756     if (oldConnectionStatus != *pConnectionStatus || debug_qmi) {
1757         dbg_time("%s %sConnectionStatus: %s", __func__, (curIpFamily == IpFamilyV4) ? "IPv4" : "IPv6",
1758             (*pConnectionStatus == QWDS_PKT_DATA_CONNECTED) ? "CONNECTED" : "DISCONNECTED");
1759     }
1760 
1761     free(pResponse);
1762     return 0;
1763 }
1764 
requestSetupDataCall(PROFILE_T * profile,int curIpFamily)1765 static int requestSetupDataCall(PROFILE_T *profile, int curIpFamily) {
1766     PQCQMIMSG pRequest;
1767     PQCQMIMSG pResponse;
1768     PQMUX_MSG pMUXMsg;
1769     int err = 0;
1770     UCHAR QMIType = (curIpFamily == IpFamilyV4) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6;
1771 
1772 //DualIPSupported means can get ipv4 & ipv6 address at the same time, one wds for ipv4, the other wds for ipv6
1773     profile->curIpFamily = curIpFamily;
1774     pRequest = ComposeQMUXMsg(QMIType, QMIWDS_START_NETWORK_INTERFACE_REQ, WdsStartNwInterfaceReq, profile);
1775     err = QmiThreadSendQMITimeout(pRequest, &pResponse, 120 * 1000, __func__);
1776     qmi_rsp_check();
1777 
1778     if (le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXResult) || le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError)) {
1779         PQMI_TLV_HDR pTLVHdr;
1780 
1781         pTLVHdr = GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x10);
1782         if (pTLVHdr) {
1783             uint16_t *data16 = (uint16_t *)(pTLVHdr+1);
1784             uint16_t call_end_reason = le16_to_cpu(data16[0]);
1785             dbg_time("call_end_reason is %d", call_end_reason);
1786         }
1787 
1788         pTLVHdr = GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11);
1789         if (pTLVHdr) {
1790             uint16_t *data16 = (uint16_t *)(pTLVHdr+1);
1791             uint16_t call_end_reason_type = le16_to_cpu(data16[0]);
1792             uint16_t verbose_call_end_reason  = le16_to_cpu(data16[1]);
1793 
1794             dbg_time("call_end_reason_type is %d", call_end_reason_type);
1795             dbg_time("call_end_reason_verbose is %d", verbose_call_end_reason);
1796         }
1797 
1798         free(pResponse);
1799         return le16_to_cpu(pMUXMsg->QMUXMsgHdrResp.QMUXError);
1800     }
1801 
1802     if (curIpFamily == IpFamilyV4) {
1803         WdsConnectionIPv4Handle = le32_to_cpu(pResponse->MUXMsg.StartNwInterfaceResp.Handle);
1804         dbg_time("%s WdsConnectionIPv4Handle: 0x%08x", __func__, WdsConnectionIPv4Handle);
1805     } else {
1806         WdsConnectionIPv6Handle = le32_to_cpu(pResponse->MUXMsg.StartNwInterfaceResp.Handle);
1807         dbg_time("%s WdsConnectionIPv6Handle: 0x%08x", __func__, WdsConnectionIPv6Handle);
1808     }
1809 
1810     free(pResponse);
1811 
1812     return 0;
1813 }
1814 
requestDeactivateDefaultPDP(PROFILE_T * profile,int curIpFamily)1815 static int requestDeactivateDefaultPDP(PROFILE_T *profile, int curIpFamily) {
1816     PQCQMIMSG pRequest;
1817     PQCQMIMSG pResponse;
1818     PQMUX_MSG pMUXMsg;
1819     int err;
1820     UCHAR QMIType = (curIpFamily == 0x04) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6;
1821 
1822     (void)profile;
1823     if (curIpFamily == IpFamilyV4 && WdsConnectionIPv4Handle == 0)
1824         return 0;
1825     if (curIpFamily == IpFamilyV6 && WdsConnectionIPv6Handle == 0)
1826         return 0;
1827 
1828     dbg_time("%s WdsConnectionIPv%dHandle", __func__, curIpFamily == IpFamilyV4 ? 4 : 6);
1829 
1830     pRequest = ComposeQMUXMsg(QMIType, QMIWDS_STOP_NETWORK_INTERFACE_REQ , WdsStopNwInterfaceReq, &curIpFamily);
1831     err = QmiThreadSendQMI(pRequest, &pResponse);
1832     qmi_rsp_check_and_return();
1833 
1834     if (curIpFamily == IpFamilyV4)
1835         WdsConnectionIPv4Handle = 0;
1836     else
1837          WdsConnectionIPv6Handle = 0;
1838     free(pResponse);
1839     return 0;
1840 }
1841 
requestGetIPAddress(PROFILE_T * profile,int curIpFamily)1842 static int requestGetIPAddress(PROFILE_T *profile, int curIpFamily) {
1843     PQCQMIMSG pRequest;
1844     PQCQMIMSG pResponse;
1845     PQMUX_MSG pMUXMsg;
1846     int err;
1847     PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR pIpv4Addr;
1848     PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_ADDR pIpv6Addr = NULL;
1849     PQMIWDS_GET_RUNTIME_SETTINGS_TLV_MTU pMtu;
1850     IPV4_T *pIpv4 = &profile->ipv4;
1851     IPV6_T *pIpv6 = &profile->ipv6;
1852     UCHAR QMIType = (curIpFamily == 0x04) ? QMUX_TYPE_WDS : QMUX_TYPE_WDS_IPV6;
1853     PQMIWDS_GET_RUNNING_SETTINGS_PCSCF_IPV6_ADDR pPCSCFIpv6Addr;
1854 	PQMIWDS_GET_RUNNING_SETTINGS_PCSCF_IPV4_ADDR pPCSCFIpv4Addr;
1855 
1856     if (curIpFamily == IpFamilyV4) {
1857         memset(pIpv4, 0x00, sizeof(IPV4_T));
1858         if (WdsConnectionIPv4Handle == 0)
1859             return 0;
1860     } else if (curIpFamily == IpFamilyV6) {
1861         memset(pIpv6, 0x00, sizeof(IPV6_T));
1862         if (WdsConnectionIPv6Handle == 0)
1863             return 0;
1864     }
1865 
1866     pRequest = ComposeQMUXMsg(QMIType, QMIWDS_GET_RUNTIME_SETTINGS_REQ, WdsGetRuntimeSettingReq, NULL);
1867     err = QmiThreadSendQMI(pRequest, &pResponse);
1868     qmi_rsp_check_and_return();
1869 
1870 	pPCSCFIpv6Addr = (PQMIWDS_GET_RUNNING_SETTINGS_PCSCF_IPV6_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x2e);    // 0x2e - pcscf ipv6 address
1871 	if (pPCSCFIpv6Addr) {
1872     	if (pPCSCFIpv6Addr->PCSCFNumber == 1) {
1873         	UCHAR *PCSCFIpv6Addr1 = (UCHAR *)(pPCSCFIpv6Addr + 1);
1874         	memcpy(profile->PCSCFIpv6Addr1, PCSCFIpv6Addr1, 16);
1875         }else if (pPCSCFIpv6Addr->PCSCFNumber == 2) {
1876         	UCHAR *PCSCFIpv6Addr1 = (UCHAR *)(pPCSCFIpv6Addr + 1);
1877         	UCHAR *PCSCFIpv6Addr2 = PCSCFIpv6Addr1 + 16;
1878         	memcpy(profile->PCSCFIpv6Addr1, PCSCFIpv6Addr1, 16);
1879         	memcpy(profile->PCSCFIpv6Addr2, PCSCFIpv6Addr2, 16);
1880         }
1881     }
1882 
1883 	pPCSCFIpv4Addr = (PQMIWDS_GET_RUNNING_SETTINGS_PCSCF_IPV4_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x23);    // 0x23 - pcscf ipv4 address
1884 	if (pPCSCFIpv4Addr) {
1885     	if (pPCSCFIpv4Addr->PCSCFNumber == 1) {
1886         	UCHAR *PCSCFIpv4Addr1 = (UCHAR *)(pPCSCFIpv4Addr + 1);
1887         	memcpy(&profile->PCSCFIpv4Addr1, PCSCFIpv4Addr1, 4);
1888         }else if (pPCSCFIpv4Addr->PCSCFNumber == 2) {
1889         	UCHAR *PCSCFIpv4Addr1 = (UCHAR *)(pPCSCFIpv4Addr + 1);
1890         	UCHAR *PCSCFIpv4Addr2 = PCSCFIpv4Addr1 + 4;
1891         	memcpy(&profile->PCSCFIpv4Addr1, PCSCFIpv4Addr1, 4);
1892         	memcpy(&profile->PCSCFIpv4Addr2, PCSCFIpv4Addr2, 4);
1893         }
1894     }
1895 
1896     pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4PRIMARYDNS);
1897     if (pIpv4Addr) {
1898         pIpv4->DnsPrimary = pIpv4Addr->IPV4Address;
1899     }
1900 
1901     pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4SECONDARYDNS);
1902     if (pIpv4Addr) {
1903         pIpv4->DnsSecondary = pIpv4Addr->IPV4Address;
1904     }
1905 
1906     pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4GATEWAY);
1907     if (pIpv4Addr) {
1908         pIpv4->Gateway = pIpv4Addr->IPV4Address;
1909     }
1910 
1911     pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4SUBNET);
1912     if (pIpv4Addr) {
1913         pIpv4->SubnetMask = pIpv4Addr->IPV4Address;
1914     }
1915 
1916     pIpv4Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV4_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV4);
1917     if (pIpv4Addr) {
1918         pIpv4->Address = pIpv4Addr->IPV4Address;
1919     }
1920 
1921     pIpv6Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV6PRIMARYDNS);
1922     if (pIpv6Addr) {
1923         memcpy(pIpv6->DnsPrimary, pIpv6Addr->IPV6Address, 16);
1924     }
1925 
1926     pIpv6Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV6SECONDARYDNS);
1927     if (pIpv6Addr) {
1928         memcpy(pIpv6->DnsSecondary, pIpv6Addr->IPV6Address, 16);
1929     }
1930 
1931     pIpv6Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV6GATEWAY);
1932     if (pIpv6Addr) {
1933         memcpy(pIpv6->Gateway, pIpv6Addr->IPV6Address, 16);
1934         pIpv6->PrefixLengthGateway = pIpv6Addr->PrefixLength;
1935     }
1936 
1937     pIpv6Addr = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_IPV6_ADDR)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_IPV6);
1938     if (pIpv6Addr) {
1939         memcpy(pIpv6->Address, pIpv6Addr->IPV6Address, 16);
1940         pIpv6->PrefixLengthIPAddr = pIpv6Addr->PrefixLength;
1941     }
1942 
1943     pMtu = (PQMIWDS_GET_RUNTIME_SETTINGS_TLV_MTU)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, QMIWDS_GET_RUNTIME_SETTINGS_TLV_TYPE_MTU);
1944     if (pMtu) {
1945         if (curIpFamily == IpFamilyV4)
1946             pIpv4->Mtu =  le32_to_cpu(pMtu->Mtu);
1947         else
1948             pIpv6->Mtu =  le32_to_cpu(pMtu->Mtu);
1949     }
1950 
1951     free(pResponse);
1952     return 0;
1953 }
1954 
1955 #ifdef CONFIG_APN
requestSetProfile(PROFILE_T * profile)1956 static int requestSetProfile(PROFILE_T *profile) {
1957     PQCQMIMSG pRequest;
1958     PQCQMIMSG pResponse;
1959     PQMUX_MSG pMUXMsg;
1960     int err;
1961 
1962     if (!profile->pdp)
1963         return 0;
1964 
1965     dbg_time("%s[%d] %s/%s/%s/%d", __func__, profile->pdp, profile->apn, profile->user, profile->password, profile->auth);
1966     pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_MODIFY_PROFILE_SETTINGS_REQ, WdsModifyProfileSettingsReq, profile);
1967     err = QmiThreadSendQMI(pRequest, &pResponse);
1968     qmi_rsp_check_and_return();
1969 
1970     free(pResponse);
1971     return 0;
1972 }
1973 
requestGetProfile(PROFILE_T * profile)1974 static int requestGetProfile(PROFILE_T *profile) {
1975     PQCQMIMSG pRequest;
1976     PQCQMIMSG pResponse;
1977     PQMUX_MSG pMUXMsg;
1978     int err;
1979     char *apn = NULL;
1980     char *user = NULL;
1981     char *password = NULL;
1982     int auth = 0;
1983     PQMIWDS_APNNAME pApnName;
1984     PQMIWDS_USERNAME pUserName;
1985     PQMIWDS_PASSWD pPassWd;
1986     PQMIWDS_AUTH_PREFERENCE pAuthPref;
1987 
1988     if (!profile->pdp)
1989         return 0;
1990 
1991     pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS, QMIWDS_GET_PROFILE_SETTINGS_REQ, WdsGetProfileSettingsReqSend, profile);
1992     err = QmiThreadSendQMI(pRequest, &pResponse);
1993     qmi_rsp_check_and_return();
1994 
1995     pApnName = (PQMIWDS_APNNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x14);
1996     pUserName = (PQMIWDS_USERNAME)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1B);
1997     pPassWd = (PQMIWDS_PASSWD)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1C);
1998     pAuthPref = (PQMIWDS_AUTH_PREFERENCE)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x1D);
1999 
2000     if (pApnName/* && le16_to_cpu(pApnName->TLVLength)*/)
2001         apn = strndup((const char *)(&pApnName->ApnName), le16_to_cpu(pApnName->TLVLength));
2002     if (pUserName/*  && pUserName->UserName*/)
2003         user = strndup((const char *)(&pUserName->UserName), le16_to_cpu(pUserName->TLVLength));
2004     if (pPassWd/*  && le16_to_cpu(pPassWd->TLVLength)*/)
2005         password = strndup((const char *)(&pPassWd->Passwd), le16_to_cpu(pPassWd->TLVLength));
2006     if (pAuthPref/*  && le16_to_cpu(pAuthPref->TLVLength)*/) {
2007         auth = pAuthPref->AuthPreference;
2008     }
2009 
2010 #if 0
2011     if (profile) {
2012         profile->apn = apn;
2013         profile->user = user;
2014         profile->password = password;
2015         profile->auth = auth;
2016     }
2017 #endif
2018 
2019     dbg_time("%s[%d] %s/%s/%s/%d", __func__, profile->pdp, apn, user, password, auth);
2020 
2021     free(pResponse);
2022     return 0;
2023 }
2024 #endif
2025 
2026 #ifdef CONFIG_SIGNALINFO
requestGetSignalInfo(void)2027 static int requestGetSignalInfo(void)
2028 {
2029     PQCQMIMSG pRequest;
2030     PQCQMIMSG pResponse;
2031     PQMUX_MSG pMUXMsg;
2032     int err;
2033 
2034     pRequest = ComposeQMUXMsg(QMUX_TYPE_NAS, QMINAS_GET_SIG_INFO_REQ, NULL, NULL);
2035     err = QmiThreadSendQMI(pRequest, &pResponse);
2036     qmi_rsp_check_and_return();
2037 
2038 
2039     // CDMA
2040     {
2041         PQMINAS_SIG_INFO_CDMA_TLV_MSG ptlv = (PQMINAS_SIG_INFO_CDMA_TLV_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x10);
2042         if (ptlv && ptlv->TLVLength)
2043         {
2044             dbg_time("%s CDMA: RSSI %d dBm, ECIO %.1lf dBm", __func__,
2045                 ptlv->rssi, (-0.5) * (double)ptlv->ecio);
2046         }
2047     }
2048 
2049     // HDR
2050     {
2051         PQMINAS_SIG_INFO_HDR_TLV_MSG ptlv = (PQMINAS_SIG_INFO_HDR_TLV_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x11);
2052         if (ptlv && ptlv->TLVLength)
2053         {
2054             dbg_time("%s HDR: RSSI %d dBm, ECIO %.1lf dBm, IO %d dBm", __func__,
2055                 ptlv->rssi, (-0.5) * (double)ptlv->ecio, ptlv->io);
2056         }
2057     }
2058 
2059     // GSM
2060     {
2061         PQMINAS_SIG_INFO_GSM_TLV_MSG ptlv = (PQMINAS_SIG_INFO_GSM_TLV_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x12);
2062         if (ptlv && ptlv->TLVLength)
2063         {
2064             dbg_time("%s GSM: RSSI %d dBm", __func__, ptlv->rssi);
2065         }
2066     }
2067 
2068     // WCDMA
2069     {
2070         PQMINAS_SIG_INFO_WCDMA_TLV_MSG ptlv = (PQMINAS_SIG_INFO_WCDMA_TLV_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x13);
2071         if (ptlv && ptlv->TLVLength)
2072         {
2073             dbg_time("%s WCDMA: RSSI %d dBm, ECIO %.1lf dBm", __func__,
2074                 ptlv->rssi, (-0.5) * (double)ptlv->ecio);
2075         }
2076     }
2077 
2078     // LTE
2079     {
2080         PQMINAS_SIG_INFO_LTE_TLV_MSG ptlv = (PQMINAS_SIG_INFO_LTE_TLV_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x14);
2081         if (ptlv && ptlv->TLVLength)
2082         {
2083             dbg_time("%s LTE: RSSI %d dBm, RSRQ %d dB, RSRP %d dBm, SNR %.1lf dB", __func__,
2084                 ptlv->rssi, ptlv->rsrq, ptlv->rsrp, (0.1) * (double)ptlv->snr);
2085         }
2086     }
2087 
2088     // TDSCDMA
2089     {
2090         PQMINAS_SIG_INFO_TDSCDMA_TLV_MSG ptlv = (PQMINAS_SIG_INFO_TDSCDMA_TLV_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x15);
2091         if (ptlv && ptlv->TLVLength)
2092         {
2093             dbg_time("%s LTE: RSCP %d dBm", __func__, ptlv->rscp);
2094         }
2095     }
2096 
2097     // 5G_NSA
2098     if (s_5g_type == WWAN_DATA_CLASS_5G_NSA)
2099     {
2100         PQMINAS_SIG_INFO_5G_NSA_TLV_MSG ptlv = (PQMINAS_SIG_INFO_5G_NSA_TLV_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x17);
2101         if (ptlv && ptlv->TLVLength)
2102         {
2103             dbg_time("%s 5G_NSA: RSRP %d dBm, SNR %.1lf dB", __func__, ptlv->rsrp, (0.1) * (double)ptlv->snr);
2104         }
2105     }
2106 
2107     // 5G_SA
2108     if (s_5g_type == WWAN_DATA_CLASS_5G_SA)
2109     {
2110         PQMINAS_SIG_INFO_5G_SA_TLV_MSG ptlv = (PQMINAS_SIG_INFO_5G_SA_TLV_MSG)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x18);
2111         if (ptlv && ptlv->TLVLength)
2112         {
2113             dbg_time("%s 5G_SA: NR5G_RSRQ %d dB", __func__, ptlv->nr5g_rsrq);
2114         }
2115     }
2116 
2117     free(pResponse);
2118     return 0;
2119 }
2120 #endif
2121 
2122 #ifdef CONFIG_VERSION
requestBaseBandVersion(PROFILE_T * profile)2123 static int requestBaseBandVersion(PROFILE_T *profile) {
2124     PQCQMIMSG pRequest;
2125     PQCQMIMSG pResponse;
2126     PQMUX_MSG pMUXMsg;
2127     PDEVICE_REV_ID revId;
2128     int err;
2129 
2130     pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_GET_DEVICE_REV_ID_REQ, NULL, NULL);
2131     err = QmiThreadSendQMI(pRequest, &pResponse);
2132     qmi_rsp_check_and_return();
2133 
2134     revId = (PDEVICE_REV_ID)GetTLV(&pResponse->MUXMsg.QMUXMsgHdr, 0x01);
2135 
2136     if (revId && le16_to_cpu(revId->TLVLength))
2137     {
2138         char *DeviceRevisionID = strndup((const char *)(&revId->RevisionID), le16_to_cpu(revId->TLVLength));
2139         dbg_time("%s %s", __func__, DeviceRevisionID);
2140         strncpy(profile->BaseBandVersion, DeviceRevisionID, sizeof(profile->BaseBandVersion));
2141         free(DeviceRevisionID);
2142     }
2143 
2144     free(pResponse);
2145     return 0;
2146 }
2147 #endif
2148 
2149 #ifdef CONFIG_RESET_RADIO
DmsSetOperatingModeReq(PQMUX_MSG pMUXMsg,void * arg)2150 static USHORT DmsSetOperatingModeReq(PQMUX_MSG pMUXMsg, void *arg) {
2151     pMUXMsg->SetOperatingModeReq.TLVType = 0x01;
2152     pMUXMsg->SetOperatingModeReq.TLVLength = cpu_to_le16(1);
2153     pMUXMsg->SetOperatingModeReq.OperatingMode = *((UCHAR *)arg);
2154 
2155     return sizeof(QMIDMS_SET_OPERATING_MODE_REQ_MSG);
2156 }
2157 
requestSetOperatingMode(UCHAR OperatingMode)2158 static int requestSetOperatingMode(UCHAR OperatingMode) {
2159     PQCQMIMSG pRequest;
2160     PQCQMIMSG pResponse;
2161     PQMUX_MSG pMUXMsg;
2162     int err;
2163 
2164     dbg_time("%s(%d)", __func__, OperatingMode);
2165 
2166     pRequest = ComposeQMUXMsg(QMUX_TYPE_DMS, QMIDMS_SET_OPERATING_MODE_REQ, DmsSetOperatingModeReq, &OperatingMode);
2167     err = QmiThreadSendQMI(pRequest, &pResponse);
2168     qmi_rsp_check_and_return();
2169 
2170     free(pResponse);
2171     return 0;
2172 }
2173 #endif
2174 
WdaSetLoopBackReq(PQMUX_MSG pMUXMsg,void * arg)2175 static USHORT WdaSetLoopBackReq(PQMUX_MSG pMUXMsg, void *arg) {
2176     (void)arg;
2177 	pMUXMsg->SetLoopBackReq.loopback_state.TLVType  = 0x01;
2178 	pMUXMsg->SetLoopBackReq.loopback_state.TLVLength = cpu_to_le16(1);
2179 
2180 	pMUXMsg->SetLoopBackReq.replication_factor.TLVType	= 0x10;
2181 	pMUXMsg->SetLoopBackReq.replication_factor.TLVLength = cpu_to_le16(4);
2182 
2183 	return sizeof(QMI_WDA_SET_LOOPBACK_CONFIG_REQ_MSG);
2184 }
2185 
requestSetLoopBackState(UCHAR loopback_state,ULONG replication_factor)2186 static int requestSetLoopBackState(UCHAR loopback_state, ULONG replication_factor) {
2187     PQCQMIMSG pRequest;
2188     PQCQMIMSG pResponse;
2189     PQMUX_MSG pMUXMsg;
2190     int err;
2191 
2192     dbg_time("%s(loopback_state=%d, replication_factor=%u)", __func__, loopback_state, replication_factor);
2193 
2194     pRequest = ComposeQMUXMsg(QMUX_TYPE_WDS_ADMIN, QMI_WDA_SET_LOOPBACK_CONFIG_REQ, WdaSetLoopBackReq, NULL);
2195     pRequest->MUXMsg.SetLoopBackReq.loopback_state.TLVVaule = loopback_state;
2196     pRequest->MUXMsg.SetLoopBackReq.replication_factor.TLVVaule = cpu_to_le16(replication_factor);
2197 
2198     err = QmiThreadSendQMI(pRequest, &pResponse);
2199     qmi_rsp_check_and_return();
2200 
2201     free(pResponse);
2202     return 0;
2203 }
2204 
2205 const struct request_ops qmi_request_ops = {
2206 #ifdef CONFIG_VERSION
2207     .requestBaseBandVersion = requestBaseBandVersion,
2208 #endif
2209     .requestSetEthMode = requestSetEthMode,
2210 #ifdef CONFIG_SIM
2211     .requestGetSIMStatus = requestGetSIMStatus,
2212     .requestEnterSimPin = requestEnterSimPin,
2213 #endif
2214 #ifdef CONFIG_IMSI_ICCID
2215     .requestGetICCID = requestGetICCID,
2216     .requestGetIMSI = requestGetIMSI,
2217 #endif
2218 #ifdef CONFIG_APN
2219     .requestSetProfile = requestSetProfile,
2220     .requestGetProfile = requestGetProfile,
2221 #endif
2222     .requestRegistrationState = requestRegistrationState,
2223     .requestSetupDataCall = requestSetupDataCall,
2224     .requestQueryDataCall = requestQueryDataCall,
2225     .requestDeactivateDefaultPDP = requestDeactivateDefaultPDP,
2226     .requestGetIPAddress = requestGetIPAddress,
2227 #ifdef CONFIG_SIGNALINFO
2228     .requestGetSignalInfo = requestGetSignalInfo,
2229 #endif
2230     .requestSetLoopBackState = requestSetLoopBackState,
2231 };
2232