• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "at_data.h"
17 
18 #include <stdlib.h>
19 
20 #include "at_support.h"
21 #include "hril_notification.h"
22 #include "securec.h"
23 #include "vendor_report.h"
24 
ConvertPdpFailReason(int32_t errorCode)25 static int32_t ConvertPdpFailReason(int32_t errorCode)
26 {
27     int32_t modemErrorCode = errorCode;
28     int32_t errNo;
29     switch (modemErrorCode) {
30         case PDP_CME_ERR_USER_VERIFICATION:
31         case PDP_CME_ERR_INCORRECT_PASSWORD:
32             errNo = HRIL_PDP_ERR_USER_VERIFICATION;
33             break;
34         case PDP_CME_ERR_INCORRECT_PARAMETERS:
35         case PDP_CME_ERR_OPERATOR_DETERMINED_BARRING:
36             errNo = HRIL_PDP_ERR_OPERATOR_DETERMINED_BARRING;
37             break;
38         case PDP_CME_ERR_SHORTAGE_RESOURCES:
39             errNo = HRIL_PDP_ERR_SHORTAGE_RESOURCES;
40             break;
41         case PDP_CME_ERR_MISSING_OR_UNKNOWN_APN:
42             errNo = HRIL_PDP_ERR_MISSING_OR_UNKNOWN_APN;
43             break;
44         case PDP_CME_ERR_UNKNOWN_PDP_ADDR_OR_TYPE:
45             errNo = HRIL_PDP_ERR_UNKNOWN_PDP_ADDR_OR_TYPE;
46             break;
47         case PDP_CME_ERR_ACTIVATION_REJECTED_GGSN:
48             errNo = HRIL_PDP_ERR_ACTIVATION_REJECTED_GGSN;
49             break;
50         case PDP_CME_ERR_SERVICE_ACTIVATION_REJECTED_UNSPECIFIED:
51             errNo = HRIL_PDP_ERR_ACTIVATION_REJECTED_UNSPECIFIED;
52             break;
53         case PDP_CME_ERR_SERVICE_OPTION_NOT_SUPPORTED:
54             errNo = HRIL_PDP_ERR_SERVICE_OPTION_NOT_SUPPORTED;
55             break;
56         case PDP_CME_ERR_SERVICE_OPTION_NOT_SUBSCRIBED:
57             errNo = HRIL_PDP_ERR_REQUESTED_SERVICE_OPTION_NOT_SUBSCRIBED;
58             break;
59         case PDP_CME_ERR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER:
60             errNo = HRIL_PDP_ERR_SERVICE_OPTION_TEMPORARILY_OUT_OF_ORDER;
61             break;
62         case PDP_CME_ERR_NSAPI_ALREADY_USED:
63             errNo = HRIL_PDP_ERR_NSAPI_ALREADY_USED;
64             break;
65         case PDP_CME_ERR_PROTOCOL_ERRORS:
66             errNo = HRIL_PDP_ERR_PROTOCOL_ERRORS;
67             break;
68         default:
69             errNo = HRIL_PDP_ERR_UNKNOWN;
70             break;
71     }
72     return errNo;
73 }
74 
OnDataReportErrorMessages(const ReqDataInfo * requestInfo,int32_t err,ResponseInfo * pResponse)75 static int32_t OnDataReportErrorMessages(const ReqDataInfo *requestInfo, int32_t err, ResponseInfo *pResponse)
76 {
77     int32_t errorNo = HRIL_ERR_SUCCESS;
78 
79     int32_t slotId = GetSlotId(requestInfo);
80     ModemReportErrorInfo errInfo = GetReportErrorInfo(pResponse);
81     if (err != HRIL_ERR_SUCCESS) {
82         if (err == AT_ERR_CHANNEL_CLOSED) {
83             err = HRIL_ERR_MODEM_DEVICE_CLOSE;
84         } else {
85             err = HRIL_ERR_CMD_SEND_FAILURE;
86         }
87     }
88     errorNo = (err != HRIL_ERR_SUCCESS) ? err : errInfo.errorNo;
89     FreeResponseInfo(pResponse);
90     if (requestInfo != NULL) {
91         struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errorNo, HRIL_RESPONSE, 0);
92         reportInfo.modemErrInfo = errInfo;
93         OnDataReport(slotId, reportInfo, NULL, 0);
94     } else {
95         struct ReportInfo reportInfo =
96             CreateReportInfo(requestInfo, errorNo, HRIL_NOTIFICATION, HNOTI_DATA_PDP_CONTEXT_LIST_UPDATED);
97         reportInfo.modemErrInfo = errInfo;
98         OnDataReport(GetSlotId(NULL), reportInfo, NULL, 0);
99     }
100     return errorNo;
101 }
102 
OnDataReportPdpErrorMessages(const ReqDataInfo * requestInfo,int32_t err,ResponseInfo * pResponse)103 static int32_t OnDataReportPdpErrorMessages(const ReqDataInfo *requestInfo, int32_t err, ResponseInfo *pResponse)
104 {
105     HRilDataCallResponse pDataCall = {};
106     ModemReportErrorInfo errInfo = GetReportErrorInfo(pResponse);
107     FreeResponseInfo(pResponse);
108     if (err != HRIL_ERR_SUCCESS) {
109         if (err == AT_ERR_CHANNEL_CLOSED) {
110             err = HRIL_ERR_MODEM_DEVICE_CLOSE;
111         } else {
112             err = HRIL_ERR_CMD_SEND_FAILURE;
113         }
114     }
115     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
116     reportInfo.modemErrInfo = errInfo;
117     pDataCall.reason = ConvertPdpFailReason(errInfo.errorNo);
118     pDataCall.retryTime = INT_DEFAULT_VALUE;
119     pDataCall.cid = INT_DEFAULT_VALUE;
120     OnDataReport(GetSlotId(requestInfo), reportInfo, (const uint8_t *)&pDataCall, sizeof(HRilDataCallResponse));
121     return (err != HRIL_ERR_SUCCESS) ? err : errInfo.errorNo;
122 }
123 
ParsePdpCmd(char * str,HRilDataCallResponse * outData)124 int32_t ParsePdpCmd(char *str, HRilDataCallResponse *outData)
125 {
126     char *pStr = NULL;
127 
128     if (str == NULL || outData == NULL) {
129         TELEPHONY_LOGE("param error");
130         return HRIL_ERR_NULL_POINT;
131     }
132     pStr = str;
133     if (ReportStrWith(str, "+CGACT:")) {
134         if (SkipATPrefix(&pStr) < 0) {
135             return HRIL_ERR_NULL_POINT;
136         }
137         if (NextInt(&pStr, &outData->cid) < 0) {
138             return HRIL_ERR_NULL_POINT;
139         }
140         if (NextInt(&pStr, &outData->active) < 0) {
141             return HRIL_ERR_NULL_POINT;
142         }
143         outData->reason = HRIL_PDP_ERR_RETRY;
144     } else if (ReportStrWith(str, "+CGDCONT:")) {
145         if (SkipATPrefix(&pStr) < 0) {
146             return HRIL_ERR_NULL_POINT;
147         }
148         if (NextInt(&pStr, &outData->cid) < 0) {
149             return HRIL_ERR_NULL_POINT;
150         }
151         if (NextStr(&pStr, &outData->type) < 0) {
152             return HRIL_ERR_NULL_POINT;
153         }
154     } else {
155         return HRIL_ERR_NULL_POINT;
156     }
157     return HRIL_ERR_SUCCESS;
158 }
159 
CreatDataCallResponseAndInit(int32_t count)160 static HRilDataCallResponse *CreatDataCallResponseAndInit(int32_t count)
161 {
162     int32_t size;
163     HRilDataCallResponse *newDcr = NULL;
164 
165     size = count * sizeof(HRilDataCallResponse);
166     if (size <= 0) {
167         TELEPHONY_LOGE("param is error, size=%{public}d", size);
168         return newDcr;
169     }
170     newDcr = (HRilDataCallResponse *)malloc(size);
171     if (newDcr == NULL) {
172         return NULL;
173     }
174     (void)memset_s(newDcr, size, 0, size);
175     return newDcr;
176 }
177 
SendInquireCGACT(int32_t * outDataNum,HRilDataCallResponse ** ppDcr)178 static ModemReportErrorInfo SendInquireCGACT(int32_t *outDataNum, HRilDataCallResponse **ppDcr)
179 {
180     int32_t ret;
181     int32_t dataCallNum = 0;
182     Line *pLine = NULL;
183     ResponseInfo *pResponse = NULL;
184     ModemReportErrorInfo errInfo = {};
185 
186     ret = SendCommandLock("AT+CGACT?", "+CGACT:", 0, &pResponse);
187     if (ret != 0 || pResponse == NULL || !pResponse->success || outDataNum == NULL || ppDcr == NULL) {
188         errInfo = GetReportErrorInfo(pResponse);
189         errInfo.errorNo = (ret != HRIL_ERR_SUCCESS) ? ret : errInfo.errorNo;
190         TELEPHONY_LOGE("send AT CMD failed! ret:%{public}d", errInfo.errorNo);
191         FreeResponseInfo(pResponse);
192         return errInfo;
193     }
194 
195     for (pLine = pResponse->head; pLine != NULL; pLine = pLine->next) {
196         dataCallNum++;
197     }
198 
199     *ppDcr = CreatDataCallResponseAndInit(dataCallNum);
200     if (*ppDcr == NULL) {
201         pResponse->success = 0;
202         errInfo = GetReportErrorInfo(pResponse);
203         FreeResponseInfo(pResponse);
204         TELEPHONY_LOGE("ppDcr is NULL! ret:%{public}d", errInfo.errorNo);
205         return errInfo;
206     }
207     HRilDataCallResponse *pDataCall = *ppDcr;
208     for (pLine = pResponse->head; pLine != NULL; pLine = pLine->next) {
209         ret = ParsePdpCmd(pLine->data, pDataCall);
210         if (ret != 0) {
211             continue;
212         }
213         pDataCall++;
214     }
215     *outDataNum = dataCallNum;
216     FreeResponseInfo(pResponse);
217     return errInfo;
218 }
219 
BuildDataInfoList(int32_t * validCount,int32_t dataNum,ResponseInfo * response,HRilDataCallResponse ** ppDcr)220 static void BuildDataInfoList(
221     int32_t *validCount, int32_t dataNum, ResponseInfo *response, HRilDataCallResponse **ppDcr)
222 {
223     if (validCount == NULL || response == NULL || ppDcr == NULL || *ppDcr == NULL) {
224         return;
225     }
226     int32_t ret;
227     int32_t i = 0;
228     int32_t count = 0;
229     int32_t dataCallNum = 0;
230     Line *pLine = NULL;
231     ResponseInfo *pResponse = response;
232     HRilDataCallResponse *pDataCall = *ppDcr;
233     HRilDataCallResponse dataCGDCONT;
234 
235     dataCallNum = dataNum;
236     for (pLine = pResponse->head; pLine != NULL; pLine = pLine->next) {
237         ret = memset_s(&dataCGDCONT, sizeof(HRilDataCallResponse), 0, sizeof(HRilDataCallResponse));
238         if (ret != EOK) {
239             TELEPHONY_LOGE("memset_s is failed!");
240         }
241         ret = ParsePdpCmd(pLine->data, &dataCGDCONT);
242         if (ret != 0) {
243             TELEPHONY_LOGE("parser pdp command failed: [%{public}s],ret=%{public}d", pLine->data, ret);
244             continue;
245         }
246         for (i = 0; i < dataCallNum; i++) {
247             if ((*ppDcr)[i].cid == dataCGDCONT.cid) {
248                 break;
249             }
250         }
251         if (i >= dataCallNum) {
252             continue;
253         }
254         if (dataCGDCONT.type != NULL) {
255             pDataCall->type = strdup(dataCGDCONT.type);
256         }
257         pDataCall->netPortName = strdup(NET_NODE);
258         pDataCall++;
259         count++;
260     }
261     *validCount = count;
262 }
263 
AddressFormat(uint64_t addr,char * outBuf,size_t bufLen)264 static int32_t AddressFormat(uint64_t addr, char *outBuf, size_t bufLen)
265 {
266     int32_t data[IPV4_INDEX_MAX] = { 0 };
267     const int32_t index1st = 0;
268     const int32_t index2nd = 1;
269     const int32_t index3rd = 2;
270     const int32_t index4th = 3;
271 
272     if ((outBuf == NULL) || !bufLen) {
273         TELEPHONY_LOGE("outBuf is Null or bufLen is zero!");
274         return -HRIL_ERR_GENERIC_FAILURE;
275     }
276     int32_t ret = memset_s(outBuf, bufLen, 0, bufLen);
277     if (ret != EOK) {
278         TELEPHONY_LOGE("memset_s outBuf is failed!");
279         return -HRIL_ERR_GENERIC_FAILURE;
280     }
281     data[index1st] = (int32_t)((addr >> ADDR_OFFSET_0BIT) & ADDR_MASK);
282     data[index2nd] = (int32_t)((addr >> ADDR_OFFSET_8BIT) & ADDR_MASK);
283     data[index3rd] = (int32_t)((addr >> ADDR_OFFSET_16BIT) & ADDR_MASK);
284     data[index4th] = (int32_t)((addr >> ADDR_OFFSET_24BIT) & ADDR_MASK);
285     GenerateCommand(
286         outBuf, MAX_CMD_LENGTH, "%d.%d.%d.%d", data[index1st], data[index2nd], data[index3rd], data[index4th]);
287     return HRIL_ERR_SUCCESS;
288 }
289 
NetMaskFormat(uint64_t addr,char * outBuf,size_t bufLen)290 static int32_t NetMaskFormat(uint64_t addr, char *outBuf, size_t bufLen)
291 {
292     if (addr < IPV4_MASK_MIN || addr > IPV4_MASK_MAX) {
293         return HRIL_ERR_NULL_POINT;
294     }
295     if ((outBuf == NULL) || !bufLen) {
296         TELEPHONY_LOGE("outBuf is Null or bufLen is zero!");
297         return HRIL_ERR_NULL_POINT;
298     }
299     int32_t ret = memset_s(outBuf, bufLen, 0, bufLen);
300     if (ret != EOK) {
301         TELEPHONY_LOGE("memset_s outBuf is failed!");
302         return HRIL_ERR_NULL_POINT;
303     }
304     int32_t prefixLen = IPV4_MASK_LEN_MIN;
305     for (int32_t i = ADDR_OFFSET_8BIT; i <= ADDR_OFFSET_24BIT; i += ADDR_OFFSET_8BIT) {
306         uint32_t maskValue = (addr >> i) & ADDR_MASK;
307         while ((maskValue & IPV4_BIT_MASK) != 0) {
308             prefixLen++;
309             maskValue = (maskValue << 1);
310         }
311     }
312     GenerateCommand(outBuf, MAX_CMD_LENGTH, "/%d", prefixLen);
313     return HRIL_ERR_SUCCESS;
314 }
315 
GetLinkInformation(int32_t activeIndex,HRilDataCallResponse ** ppDcr)316 static ModemReportErrorInfo GetLinkInformation(int32_t activeIndex, HRilDataCallResponse **ppDcr)
317 {
318     int32_t ret;
319     char readBuf[MAX_CMD_LENGTH] = {0};
320     char *lineStr = NULL;
321     Line *pLine = NULL;
322     ResponseInfo *pResponse = NULL;
323     ModemReportErrorInfo errInfo = {};
324 
325     ret = SendCommandLock("AT^DHCP?", "^DHCP:", 0, &pResponse);
326     if (ret != 0 || pResponse == NULL || pResponse->head == NULL || !pResponse->success) {
327         errInfo = GetReportErrorInfo(pResponse);
328         errInfo.errorNo = (ret != HRIL_ERR_SUCCESS) ? ret : errInfo.errorNo;
329         TELEPHONY_LOGE("send AT CMD failed! ret:%{public}d", errInfo.errorNo);
330         FreeResponseInfo(pResponse);
331         return errInfo;
332     }
333     if (ppDcr == NULL || *ppDcr == NULL) {
334         pResponse->success = 0;
335         errInfo = GetReportErrorInfo(pResponse);
336         FreeResponseInfo(pResponse);
337         TELEPHONY_LOGE("ppDcr is NULL! ret:%{public}d", errInfo.errorNo);
338         return errInfo;
339     }
340     pLine = pResponse->head;
341     lineStr = pLine->data;
342     uint64_t addr = 0;
343     SkipATPrefix(&lineStr);
344     NextULongFromHex(&lineStr, &addr); // ip
345     AddressFormat(addr, readBuf, MAX_CMD_LENGTH);
346     NextULongFromHex(&lineStr, &addr); // subnet mask
347     ret = strlen(readBuf);
348     NetMaskFormat(addr, &readBuf[ret], MAX_CMD_LENGTH - ret);
349     (*ppDcr)[activeIndex].address = strdup(readBuf);
350     NextULongFromHex(&lineStr, &addr); // default gateway
351     AddressFormat(addr, readBuf, MAX_CMD_LENGTH);
352     (*ppDcr)[activeIndex].gateway = strdup(readBuf);
353     NextULongFromHex(&lineStr, &addr); // DHCP server
354     NextULongFromHex(&lineStr, &addr); // primary DNS server
355     AddressFormat(addr, readBuf, MAX_CMD_LENGTH);
356     (*ppDcr)[activeIndex].dns = strdup(readBuf);
357     NextULongFromHex(&lineStr, &addr); // secondary DNS server
358     FreeResponseInfo(pResponse);
359     (*ppDcr)[activeIndex].reason = HRIL_PDP_ERR_NONE;
360     return errInfo;
361 }
362 
SendInquireCGDCONT(int32_t * validCount,int32_t dataNum,HRilDataCallResponse ** ppDcr)363 static ModemReportErrorInfo SendInquireCGDCONT(int32_t *validCount, int32_t dataNum, HRilDataCallResponse **ppDcr)
364 {
365     int32_t ret;
366     ResponseInfo *pResponse = NULL;
367     ModemReportErrorInfo errInfo = {};
368 
369     ret = SendCommandLock("AT+CGDCONT?", "+CGDCONT:", 0, &pResponse);
370     if (ret != 0 || pResponse == NULL || !pResponse->success) {
371         errInfo = GetReportErrorInfo(pResponse);
372         errInfo.errorNo = (ret != HRIL_ERR_SUCCESS) ? ret : errInfo.errorNo;
373         TELEPHONY_LOGE("send AT CMD failed! ret:%{public}d", errInfo.errorNo);
374         FreeResponseInfo(pResponse);
375         return errInfo;
376     }
377 
378     if (ppDcr == NULL || *ppDcr == NULL) {
379         pResponse->success = 0;
380         errInfo = GetReportErrorInfo(pResponse);
381         FreeResponseInfo(pResponse);
382         TELEPHONY_LOGE("ppDcr is NULL! ret:%{public}d", errInfo.errorNo);
383         return errInfo;
384     }
385     BuildDataInfoList(validCount, dataNum, pResponse, ppDcr);
386     FreeResponseInfo(pResponse);
387     return errInfo;
388 }
389 
QueryAllSupportPDNInfos(PDNInfo * pdnInfo)390 static int32_t QueryAllSupportPDNInfos(PDNInfo *pdnInfo)
391 {
392     if (pdnInfo == NULL) {
393         return -1;
394     }
395     char *pStr = NULL;
396     int32_t ret = -1;
397     Line *pLine = NULL;
398     PDNInfo *pdns = pdnInfo;
399     ResponseInfo *pResponse = NULL;
400 
401     ret = SendCommandLock("AT+CGDCONT?", "+CGDCONT:", 0, &pResponse);
402     if (ret != 0 || pResponse == NULL || !pResponse->success) {
403         ModemReportErrorInfo errInfo = GetReportErrorInfo(pResponse);
404         errInfo.errorNo = (ret != HRIL_ERR_SUCCESS) ? ret : errInfo.errorNo;
405         TELEPHONY_LOGE("send AT CMD failed! ret:%{public}d", ret);
406         FreeResponseInfo(pResponse);
407         return errInfo.errorNo;
408     }
409     for (pLine = pResponse->head; pLine != NULL; pLine = pLine->next) {
410         pStr = pLine->data;
411         ret = SkipATPrefix(&pStr);
412         if (ret < 0) {
413             pdns->cid = INT_DEFAULT_VALUE;
414         }
415         ret = NextInt(&pStr, &pdns->cid);
416         if (ret < 0) {
417             pdns->cid = INT_DEFAULT_VALUE;
418         }
419         ret = NextStr(&pStr, &pdns->ipType);
420         if (ret < 0) {
421             pdns->cid = INT_DEFAULT_VALUE;
422         }
423         ret = NextStr(&pStr, &pdns->apn);
424         if (ret < 0) {
425             pdns->cid = INT_DEFAULT_VALUE;
426         }
427         pdns++;
428     }
429     FreeResponseInfo(pResponse);
430     return ret;
431 }
432 
IsStrEmpty(const char * str)433 static int32_t IsStrEmpty(const char *str)
434 {
435     if (str == NULL || strcmp(str, "") == 0) {
436         return TRUE;
437     }
438     return FALSE;
439 }
440 
IsStrEqual(const char * src1,const char * src2)441 static int32_t IsStrEqual(const char *src1, const char *src2)
442 {
443     int32_t ret = FALSE;
444     if (IsStrEmpty(src1) && IsStrEmpty(src2)) {
445         ret = TRUE;
446     } else if (!IsStrEmpty(src1) && !IsStrEmpty(src2)) {
447         if (strcasecmp(src1, src2) == 0) {
448             ret = TRUE;
449         } else {
450             TELEPHONY_LOGE("IsStrEqual src1=%{public}s, src2=%{public}s", src1, src2);
451         }
452     } else {
453         TELEPHONY_LOGE("IsStrEqual src1 or src2 is empty!");
454     }
455     return ret;
456 }
457 
QuerySupportCID(const PDNInfo * pdnInfos,int32_t pdnSize,const char * apn,const char * ipType)458 static int32_t QuerySupportCID(const PDNInfo *pdnInfos, int32_t pdnSize, const char *apn, const char *ipType)
459 {
460     int32_t i;
461     int32_t j;
462     int32_t isUsedCid = 0;
463     int32_t cid = INT_DEFAULT_VALUE;
464     if (pdnInfos == NULL) {
465         return cid;
466     }
467 
468     for (j = 0; j < pdnSize; j++) {
469         if (IsStrEqual(apn, pdnInfos[j].apn)) {
470             cid = pdnInfos[j].cid;
471             break;
472         }
473     }
474     if (cid > 0) {
475         return cid;
476     }
477     for (i = MIN_CID; i <= MAX_CID; i++) {
478         isUsedCid = 0;
479         for (j = 0; j < pdnSize; j++) {
480             if (pdnInfos[j].cid == i) {
481                 isUsedCid = 1;
482                 break;
483             }
484         }
485         if (isUsedCid == 1) {
486             cid = i;
487             break;
488         }
489     }
490     return cid;
491 }
492 
GetNeedActivateCid(const char * apn,const char * ipType)493 static int32_t GetNeedActivateCid(const char *apn, const char *ipType)
494 {
495     int32_t cid = DEFAULT_CID;
496     PDNInfo pdnInfos[MAX_PDP_NUM] = {{DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""},
497         {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""},
498         {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}};
499 
500     if (!QueryAllSupportPDNInfos(pdnInfos)) {
501         cid = QuerySupportCID(pdnInfos, MAX_PDP_NUM, apn, ipType);
502     }
503     return cid;
504 }
505 
FreeDataCallResponse(HRilDataCallResponse * pDcrs,int32_t size)506 static void FreeDataCallResponse(HRilDataCallResponse *pDcrs, int32_t size)
507 {
508     int32_t i = 0;
509 
510     if (pDcrs == NULL) {
511         return;
512     }
513     for (i = 0; i < size; i++) {
514         if (pDcrs[i].address != NULL) {
515             free(pDcrs[i].address);
516         }
517         if (pDcrs[i].netPortName != NULL) {
518             free(pDcrs[i].netPortName);
519         }
520         if (pDcrs[i].type != NULL) {
521             free(pDcrs[i].type);
522         }
523         if (pDcrs[i].dns != NULL) {
524             free(pDcrs[i].dns);
525         }
526         if (pDcrs[i].gateway != NULL) {
527             free(pDcrs[i].gateway);
528         }
529     }
530     free(pDcrs);
531 }
532 
DataReportMessage(int32_t cid,const ReqDataInfo * requestInfo,ModemReportErrorInfo errInfo,HRilDataCallResponse * pDataCalls,int32_t validNum)533 static void DataReportMessage(int32_t cid, const ReqDataInfo *requestInfo, ModemReportErrorInfo errInfo,
534     HRilDataCallResponse *pDataCalls, int32_t validNum)
535 {
536     struct ReportInfo reportInfo = {};
537     int32_t slotId = GetSlotId(requestInfo);
538     if (requestInfo != NULL) {
539         /* Report results */
540         int32_t index;
541         reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
542         reportInfo.modemErrInfo = errInfo;
543         if ((cid == DEFAULT_CID) || (pDataCalls == NULL)) {
544             OnDataReport(slotId, reportInfo, (const uint8_t *)pDataCalls, validNum * sizeof(HRilDataCallResponse));
545             FreeDataCallResponse(pDataCalls, validNum);
546             return;
547         }
548         for (index = 0; index < validNum; index++) {
549             if (pDataCalls[index].cid == cid) {
550                 break;
551             }
552         }
553         OnDataReport(slotId, reportInfo, (const uint8_t *)&pDataCalls[index], sizeof(HRilDataCallResponse));
554     } else {
555         /* Change notice */
556         reportInfo.requestInfo = NULL;
557         reportInfo.error = errInfo.errorNo;
558         reportInfo.modemErrInfo = errInfo;
559         reportInfo.notifyId = HNOTI_DATA_PDP_CONTEXT_LIST_UPDATED;
560         reportInfo.type = HRIL_NOTIFICATION;
561         OnDataReport(GetSlotId(NULL), reportInfo, (const uint8_t *)pDataCalls, validNum * sizeof(HRilDataCallResponse));
562     }
563     FreeDataCallResponse(pDataCalls, validNum);
564 }
565 
InquirePdpContextList(int32_t cid,const ReqDataInfo * requestInfo)566 static void InquirePdpContextList(int32_t cid, const ReqDataInfo *requestInfo)
567 {
568     int32_t validNum = 0;
569     int32_t queryCount = 0;
570     int32_t dataCallNum = 0;
571     HRilDataCallResponse *pDataCalls = NULL;
572 
573     do {
574         ModemReportErrorInfo errInfo = SendInquireCGACT(&dataCallNum, &pDataCalls);
575         if (errInfo.errorNo != HRIL_ERR_SUCCESS) {
576             TELEPHONY_LOGE("SendInquireCGACT send failed");
577             OnDataReportErrorMessages(requestInfo, errInfo.errorNo, NULL);
578             FreeDataCallResponse(pDataCalls, validNum);
579             return;
580         }
581         for (int32_t i = 0; i < dataCallNum; i++) {
582             if ((pDataCalls[i].cid == cid) && (DEACTIVATE == pDataCalls[i].active)) {
583                 errInfo.errorNo = HRIL_ERR_GENERIC_FAILURE;
584                 usleep(QUERY_DELAY_MS * DELAY_US_OFFSET);
585                 queryCount++;
586                 break;
587             }
588         }
589         if (errInfo.errorNo == HRIL_ERR_SUCCESS) {
590             break;
591         }
592     } while ((cid != DEFAULT_CID) && (queryCount < QUERY_MAX_COUNT));
593 
594     ModemReportErrorInfo errInfo = SendInquireCGDCONT(&validNum, dataCallNum, &pDataCalls);
595     if (errInfo.errorNo != HRIL_ERR_SUCCESS) {
596         TELEPHONY_LOGE("SendInquireCGDCONT send failed");
597         OnDataReportErrorMessages(requestInfo, errInfo.errorNo, NULL);
598         FreeDataCallResponse(pDataCalls, validNum);
599         return;
600     }
601     for (int32_t index = 0; index < validNum; index++) {
602         if (ACTIVATE == pDataCalls[index].active) {
603             errInfo = GetLinkInformation(index, &pDataCalls);
604             if (errInfo.errorNo != HRIL_ERR_SUCCESS) {
605                 TELEPHONY_LOGE("Get link information is failed!");
606                 OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
607                 FreeDataCallResponse(pDataCalls, validNum);
608                 return;
609             }
610         }
611     }
612     DataReportMessage(cid, requestInfo, errInfo, pDataCalls, validNum);
613 }
614 
SendCmdCGDCONT(int32_t cid,const ReqDataInfo * requestInfo,const HRilDataInfo * pDataInfo)615 static int32_t SendCmdCGDCONT(int32_t cid, const ReqDataInfo *requestInfo, const HRilDataInfo *pDataInfo)
616 {
617     if (pDataInfo == NULL) {
618         return -1;
619     }
620     int32_t ret;
621     int32_t err = HRIL_ERR_SUCCESS;
622     char cmd[MAX_CMD_LENGTH] = {0};
623     ResponseInfo *pResponse = NULL;
624     ret = GenerateCommand(
625         cmd, MAX_CMD_LENGTH, "AT+CGDCONT=%d,\"%s\",\"%s\",\"\",0,0", cid, pDataInfo->type, pDataInfo->apn);
626     if (ret < 0) {
627         TELEPHONY_LOGE("GenerateCommand is failed!");
628         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
629         return ret;
630     }
631     ret = SendCommandLock(cmd, NULL, 0, &pResponse);
632     if (ret != 0 || pResponse == NULL || !pResponse->success) {
633         err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
634         ret = OnDataReportPdpErrorMessages(requestInfo, err, pResponse);
635         TELEPHONY_LOGE("cmd send failed, err:%{public}d", ret);
636         return ret;
637     }
638     FreeResponseInfo(pResponse);
639     return HRIL_ERR_SUCCESS;
640 }
641 
SendCmdNDISDUP(int32_t cid,int32_t activate,const ReqDataInfo * requestInfo)642 static int32_t SendCmdNDISDUP(int32_t cid, int32_t activate, const ReqDataInfo *requestInfo)
643 {
644     int32_t ret;
645     int32_t err = HRIL_ERR_SUCCESS;
646     char cmd[MAX_CMD_LENGTH] = {0};
647     ResponseInfo *pResponse = NULL;
648 
649     ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT^NDISDUP=%d,%d", cid, activate);
650     if (ret < 0) {
651         TELEPHONY_LOGE("GenerateCommand is failed!");
652         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
653         return ret;
654     }
655     ret = SendCommandLock(cmd, NULL, 0, &pResponse);
656     if ((ret != HRIL_ERR_SUCCESS) || pResponse == NULL || !pResponse->success) {
657         err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
658         ret = OnDataReportPdpErrorMessages(requestInfo, err, pResponse);
659         TELEPHONY_LOGE("cmd send failed, err:%{public}d", ret);
660         return ret;
661     }
662     FreeResponseInfo(pResponse);
663     return HRIL_ERR_SUCCESS;
664 }
665 
RouteUp(void)666 static int32_t RouteUp(void)
667 {
668     int32_t ret = system("ifconfig usb0 up");
669     if (ret != 0) {
670         TELEPHONY_LOGE("exec system is failed! ret:%{public}d, %{public}s", ret, strerror(ret));
671         return ret;
672     }
673     TELEPHONY_LOGI("Open net device is finished!");
674     return HRIL_ERR_SUCCESS;
675 }
676 
RouteDown(void)677 static int32_t RouteDown(void)
678 {
679     int32_t ret = system("ifconfig usb0 down");
680     if (ret != 0) {
681         TELEPHONY_LOGE("exec system is failed! ret:%{public}d, %{public}s", ret, strerror(ret));
682         return ret;
683     }
684     TELEPHONY_LOGI("Close net device is finished!");
685     return HRIL_ERR_SUCCESS;
686 }
687 
ReqActivatePdpContext(const ReqDataInfo * requestInfo,const HRilDataInfo * data)688 void ReqActivatePdpContext(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
689 {
690     int32_t cid = INT_DEFAULT_VALUE;
691     const HRilDataInfo *pDataInfo = data;
692 
693     if (pDataInfo == NULL) {
694         TELEPHONY_LOGE("data is null!!!");
695         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
696         return;
697     }
698     if (RouteUp() != HRIL_ERR_SUCCESS) {
699         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
700         return;
701     }
702     cid = GetNeedActivateCid(pDataInfo->apn, pDataInfo->type);
703     if (cid == INT_DEFAULT_VALUE) {
704         TELEPHONY_LOGE("cid is invalid!!!");
705         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
706         RouteDown();
707         return;
708     }
709     if (SendCmdCGDCONT(cid, requestInfo, pDataInfo) != HRIL_ERR_SUCCESS) {
710         RouteDown();
711         return;
712     }
713     if (SendCmdNDISDUP(cid, ACTIVATE, requestInfo) != HRIL_ERR_SUCCESS) {
714         RouteDown();
715         return;
716     }
717     InquirePdpContextList(cid, requestInfo);
718 }
719 
ReqDeactivatePdpContext(const ReqDataInfo * requestInfo,const HRilDataInfo * data)720 void ReqDeactivatePdpContext(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
721 {
722     const HRilDataInfo *pDataInfo = data;
723     ModemReportErrorInfo errInfo = {};
724 
725     if (pDataInfo == NULL) {
726         TELEPHONY_LOGE("data is null!!!");
727         OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
728         return;
729     }
730     if (SendCmdNDISDUP(pDataInfo->cid, DEACTIVATE, requestInfo) != HRIL_ERR_SUCCESS) {
731         RouteDown();
732         return;
733     }
734     if (RouteDown() != HRIL_ERR_SUCCESS) {
735         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
736         return;
737     }
738     DataReportMessage(pDataInfo->cid, requestInfo, errInfo, NULL, 0);
739 }
740 
ReqGetPdpContextList(const ReqDataInfo * requestInfo)741 void ReqGetPdpContextList(const ReqDataInfo *requestInfo)
742 {
743     InquirePdpContextList(DEFAULT_CID, requestInfo);
744 }
745 
PdpContextListCallback(uint8_t * param)746 static void PdpContextListCallback(uint8_t *param)
747 {
748     InquirePdpContextList(DEFAULT_CID, NULL);
749 }
750 
PdpContextListUpdate(void)751 void PdpContextListUpdate(void)
752 {
753     struct timeval tv = {0, CALLBACK_DELAY_MS * DELAY_US_OFFSET};
754     OnTimerCallback(PdpContextListCallback, NULL, &tv);
755 }
756 
SetDataProfileInfo(int32_t cid,const ReqDataInfo * requestInfo,const HRilDataInfo * pDataInfo)757 static int32_t SetDataProfileInfo(int32_t cid, const ReqDataInfo *requestInfo, const HRilDataInfo *pDataInfo)
758 {
759     if (pDataInfo == NULL) {
760         return -1;
761     }
762     int32_t ret;
763     int32_t err = HRIL_ERR_SUCCESS;
764     char cmd[MAX_CMD_LENGTH] = {0};
765     ResponseInfo *pResponse = NULL;
766 
767     ret = GenerateCommand(
768         cmd, MAX_CMD_LENGTH, "AT+CGDCONT=%d,\"%s\",\"%s\",\"\",0,0", cid, pDataInfo->type, pDataInfo->apn);
769     if (ret < 0) {
770         TELEPHONY_LOGE("GenerateCommand is failed!");
771         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
772         return ret;
773     }
774     ret = SendCommandLock(cmd, NULL, 0, &pResponse);
775     if (ret != 0 || pResponse == NULL || !pResponse->success) {
776         err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
777         ret = OnDataReportErrorMessages(requestInfo, err, pResponse);
778         TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
779         return ret;
780     }
781     FreeResponseInfo(pResponse);
782     if ((pDataInfo->verType >= VERIFY_TYPE_MIN) && (pDataInfo->verType <= VERIFY_TYPE_MAX)) {
783         ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT^AUTHDATA=%d,%d,\"\",\"%s\",\"%s\"", cid, pDataInfo->verType,
784             pDataInfo->password, pDataInfo->userName);
785         if (ret < 0) {
786             TELEPHONY_LOGE("GenerateCommand is failed!");
787             OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
788             return ret;
789         }
790         ret = SendCommandLock(cmd, NULL, 0, &pResponse);
791         if (ret != 0 || pResponse == NULL || !pResponse->success) {
792             err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
793             ret = OnDataReportErrorMessages(requestInfo, err, pResponse);
794             TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
795             return ret;
796         }
797         FreeResponseInfo(pResponse);
798     }
799     return HRIL_ERR_SUCCESS;
800 }
801 
ReqSetInitApnInfo(const ReqDataInfo * requestInfo,const HRilDataInfo * data)802 void ReqSetInitApnInfo(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
803 {
804     int32_t cid = INT_DEFAULT_VALUE;
805     const HRilDataInfo *pDataInfo = data;
806     ModemReportErrorInfo errInfo = {};
807 
808     if (pDataInfo == NULL) {
809         TELEPHONY_LOGE("data is null!!!");
810         OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
811         return;
812     }
813     cid = GetNeedActivateCid(pDataInfo->apn, pDataInfo->type);
814     if (cid == INT_DEFAULT_VALUE) {
815         TELEPHONY_LOGE("cid is invalid!!!");
816         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
817         return;
818     }
819     if (SetDataProfileInfo(cid, requestInfo, pDataInfo) != HRIL_ERR_SUCCESS) {
820         TELEPHONY_LOGE("Set data profile info is failed!");
821         return;
822     }
823     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
824     reportInfo.modemErrInfo = errInfo;
825     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
826 }
827 
ReqSetLinkBandwidthReportingRule(const ReqDataInfo * requestInfo,const HRilLinkBandwidthReportingRule * data)828 void ReqSetLinkBandwidthReportingRule(const ReqDataInfo *requestInfo, const HRilLinkBandwidthReportingRule *data)
829 {
830     const HRilLinkBandwidthReportingRule *linkBandwidthRule = data;
831     ModemReportErrorInfo errInfo = {};
832 
833     if (linkBandwidthRule == NULL) {
834         TELEPHONY_LOGE("data is null!!!");
835         OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
836         return;
837     }
838     TELEPHONY_LOGI("rat:%{public}d, delayMs:%{public}d", linkBandwidthRule->rat, linkBandwidthRule->delayMs);
839     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
840     reportInfo.modemErrInfo = errInfo;
841     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
842 }
843 
CallCmdC5GQOSRDP(const char * lineCmd,HRilLinkBandwidthInfo * outCall)844 static int32_t CallCmdC5GQOSRDP(const char *lineCmd, HRilLinkBandwidthInfo *outCall)
845 {
846     char *pLine = (char *)lineCmd;
847     if (pLine == NULL || outCall == NULL) {
848         TELEPHONY_LOGE("pLine or outCall is null.");
849         return HRIL_ERR_NULL_POINT;
850     }
851     if (SkipATPrefix(&pLine) < 0) {
852         return HRIL_ERR_NULL_POINT;
853     }
854     if (NextInt(&pLine, &outCall->cid) < 0) {
855         return HRIL_ERR_NULL_POINT;
856     }
857     if (NextInt(&pLine, &outCall->qi) < 0) {
858         return HRIL_ERR_NULL_POINT;
859     }
860     if (NextInt(&pLine, &outCall->dlGfbr) < 0) {
861         return HRIL_ERR_NULL_POINT;
862     }
863     if (NextInt(&pLine, &outCall->ulGfbr) < 0) {
864         return HRIL_ERR_NULL_POINT;
865     }
866     if (NextInt(&pLine, &outCall->dlMfbr) < 0) {
867         return HRIL_ERR_NULL_POINT;
868     }
869     if (NextInt(&pLine, &outCall->ulMfbr) < 0) {
870         return HRIL_ERR_NULL_POINT;
871     }
872     if (NextInt(&pLine, &outCall->ulSambr) < 0) {
873         return HRIL_ERR_NULL_POINT;
874     }
875     if (NextInt(&pLine, &outCall->dlSambr) < 0) {
876         return HRIL_ERR_NULL_POINT;
877     }
878     if (NextInt(&pLine, &outCall->averagingWindow) < 0) {
879         return HRIL_ERR_NULL_POINT;
880     }
881     return HRIL_ERR_SUCCESS;
882 }
883 
ReqGetLinkBandwidthInfo(const ReqDataInfo * requestInfo,const int32_t cid)884 void ReqGetLinkBandwidthInfo(const ReqDataInfo *requestInfo, const int32_t cid)
885 {
886     int32_t ret;
887     char *line = NULL;
888     int32_t err = HRIL_ERR_SUCCESS;
889     HRilLinkBandwidthInfo uplinkAndDownlinkBandwidth = {0};
890     ResponseInfo *pResponse = NULL;
891     char cmd[MAX_CMD_LENGTH] = {0};
892 
893     ModemReportErrorInfo errInfo = InitModemReportErrorInfo();
894     ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT+C5GQOSRDP=%d", cid);
895     if (ret < 0) {
896         TELEPHONY_LOGE("GenerateCommand is failed!");
897         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
898         return;
899     }
900     ret = SendCommandLock(cmd, "+C5GQOSRDP:", 0, &pResponse);
901     if (ret || pResponse == NULL || !pResponse->success) {
902         err = ret ? ret : err;
903         TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
904         OnDataReportErrorMessages(requestInfo, err, pResponse);
905         return;
906     }
907     if (pResponse->head) {
908         line = pResponse->head->data;
909         ret = CallCmdC5GQOSRDP(line, &uplinkAndDownlinkBandwidth);
910         if (ret != 0) {
911             TELEPHONY_LOGE("Parse C5GQOSRDP data is fail. ret:%{public}d", ret);
912             return;
913         }
914         TELEPHONY_LOGI(
915             "+C5GQOSRDP:%{public}d, %{public}d", uplinkAndDownlinkBandwidth.cid, uplinkAndDownlinkBandwidth.qi);
916     } else {
917         TELEPHONY_LOGE("ERROR: pResponse->head is null");
918         err = HRIL_ERR_GENERIC_FAILURE;
919     }
920     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
921     reportInfo.modemErrInfo = errInfo;
922     OnDataReport(GetSlotId(requestInfo), reportInfo, (const uint8_t *)&uplinkAndDownlinkBandwidth,
923         sizeof(HRilLinkBandwidthInfo));
924     FreeResponseInfo(pResponse);
925 }
926 
ReqSetDataPermitted(const ReqDataInfo * requestInfo,const int32_t dataPermitted)927 void ReqSetDataPermitted(const ReqDataInfo *requestInfo, const int32_t dataPermitted)
928 {
929     TELEPHONY_LOGI("dataPermitted:%{public}d", dataPermitted);
930     ModemReportErrorInfo errInfo = {};
931     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
932     reportInfo.modemErrInfo = errInfo;
933     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
934 }
935 
ReqGetLinkCapability(const ReqDataInfo * requestInfo)936 void ReqGetLinkCapability(const ReqDataInfo *requestInfo)
937 {
938     ModemReportErrorInfo errInfo = { 0 };
939     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
940     reportInfo.modemErrInfo = errInfo;
941     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
942 }
943