• 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: str=%{public}p,outData=%{public}p", str, outData);
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     HRilDataCallResponse *pDataCall = *ppDcr;
201     for (pLine = pResponse->head; pLine != NULL; pLine = pLine->next) {
202         ret = ParsePdpCmd(pLine->data, pDataCall);
203         if (ret != 0) {
204             continue;
205         }
206         pDataCall++;
207     }
208     *outDataNum = dataCallNum;
209     FreeResponseInfo(pResponse);
210     return errInfo;
211 }
212 
BuildDataInfoList(int32_t * validCount,int32_t dataNum,ResponseInfo * response,HRilDataCallResponse ** ppDcr)213 static void BuildDataInfoList(
214     int32_t *validCount, int32_t dataNum, ResponseInfo *response, HRilDataCallResponse **ppDcr)
215 {
216     if (validCount == NULL || response == NULL || ppDcr == NULL || *ppDcr == NULL) {
217         return;
218     }
219     int32_t ret;
220     int32_t i = 0;
221     int32_t count = 0;
222     int32_t dataCallNum = 0;
223     Line *pLine = NULL;
224     ResponseInfo *pResponse = response;
225     HRilDataCallResponse *pDataCall = *ppDcr;
226     HRilDataCallResponse dataCGDCONT;
227 
228     dataCallNum = dataNum;
229     for (pLine = pResponse->head; pLine != NULL; pLine = pLine->next) {
230         ret = memset_s(&dataCGDCONT, sizeof(HRilDataCallResponse), 0, sizeof(HRilDataCallResponse));
231         if (ret != EOK) {
232             TELEPHONY_LOGE("memset_s is failed!");
233         }
234         ret = ParsePdpCmd(pLine->data, &dataCGDCONT);
235         if (ret != 0) {
236             TELEPHONY_LOGE("parser pdp command failed: [%{public}s],ret=%{public}d", pLine->data, ret);
237             continue;
238         }
239         for (i = 0; i < dataCallNum; i++) {
240             if ((*ppDcr)[i].cid == dataCGDCONT.cid) {
241                 break;
242             }
243         }
244         if (i >= dataCallNum) {
245             continue;
246         }
247         pDataCall->type = strdup(dataCGDCONT.type);
248         pDataCall->netPortName = strdup(NET_NODE);
249         pDataCall++;
250         count++;
251     }
252     *validCount = count;
253 }
254 
AddressFormat(uint64_t addr,char * outBuf,size_t bufLen)255 static int32_t AddressFormat(uint64_t addr, char *outBuf, size_t bufLen)
256 {
257     int32_t data[IPV4_INDEX_MAX] = { 0 };
258     const int32_t index1st = 0;
259     const int32_t index2nd = 1;
260     const int32_t index3rd = 2;
261     const int32_t index4th = 3;
262 
263     if ((outBuf == NULL) || !bufLen) {
264         TELEPHONY_LOGE("outBuf is Null or bufLen is zero!");
265         return -HRIL_ERR_GENERIC_FAILURE;
266     }
267     int32_t ret = memset_s(outBuf, bufLen, 0, bufLen);
268     if (ret != EOK) {
269         TELEPHONY_LOGE("memset_s outBuf is failed!");
270         return -HRIL_ERR_GENERIC_FAILURE;
271     }
272     data[index1st] = (int32_t)((addr >> ADDR_OFFSET_0BIT) & ADDR_MASK);
273     data[index2nd] = (int32_t)((addr >> ADDR_OFFSET_8BIT) & ADDR_MASK);
274     data[index3rd] = (int32_t)((addr >> ADDR_OFFSET_16BIT) & ADDR_MASK);
275     data[index4th] = (int32_t)((addr >> ADDR_OFFSET_24BIT) & ADDR_MASK);
276     GenerateCommand(
277         outBuf, MAX_CMD_LENGTH, "%d.%d.%d.%d", data[index1st], data[index2nd], data[index3rd], data[index4th]);
278     return HRIL_ERR_SUCCESS;
279 }
280 
NetMaskFormat(uint64_t addr,char * outBuf,size_t bufLen)281 static int32_t NetMaskFormat(uint64_t addr, char *outBuf, size_t bufLen)
282 {
283     if (addr < IPV4_MASK_MIN || addr > IPV4_MASK_MAX) {
284         return HRIL_ERR_NULL_POINT;
285     }
286     if ((outBuf == NULL) || !bufLen) {
287         TELEPHONY_LOGE("outBuf is Null or bufLen is zero!");
288         return HRIL_ERR_NULL_POINT;
289     }
290     int32_t ret = memset_s(outBuf, bufLen, 0, bufLen);
291     if (ret != EOK) {
292         TELEPHONY_LOGE("memset_s outBuf is failed!");
293         return HRIL_ERR_NULL_POINT;
294     }
295     int32_t prefixLen = IPV4_MASK_LEN_MIN;
296     for (int32_t i = ADDR_OFFSET_8BIT; i <= ADDR_OFFSET_24BIT; i += ADDR_OFFSET_8BIT) {
297         uint32_t maskValue = (addr >> i) & ADDR_MASK;
298         while ((maskValue & IPV4_BIT_MASK) != 0) {
299             prefixLen++;
300             maskValue = (maskValue << 1);
301         }
302     }
303     GenerateCommand(outBuf, MAX_CMD_LENGTH, "/%d", prefixLen);
304     return HRIL_ERR_SUCCESS;
305 }
306 
GetLinkInformation(int32_t activeIndex,HRilDataCallResponse ** ppDcr)307 static ModemReportErrorInfo GetLinkInformation(int32_t activeIndex, HRilDataCallResponse **ppDcr)
308 {
309     int32_t ret;
310     char readBuf[MAX_CMD_LENGTH] = {0};
311     char *lineStr = NULL;
312     Line *pLine = NULL;
313     ResponseInfo *pResponse = NULL;
314     ModemReportErrorInfo errInfo = {};
315 
316     ret = SendCommandLock("AT^DHCP?", "^DHCP:", 0, &pResponse);
317     if (ret != 0 || pResponse == NULL || pResponse->head == NULL || !pResponse->success) {
318         errInfo = GetReportErrorInfo(pResponse);
319         errInfo.errorNo = (ret != HRIL_ERR_SUCCESS) ? ret : errInfo.errorNo;
320         TELEPHONY_LOGE("send AT CMD failed! ret:%{public}d", errInfo.errorNo);
321         FreeResponseInfo(pResponse);
322         return errInfo;
323     }
324     if (ppDcr == NULL || *ppDcr == NULL) {
325         pResponse->success = 0;
326         errInfo = GetReportErrorInfo(pResponse);
327         FreeResponseInfo(pResponse);
328         TELEPHONY_LOGE("ppDcr is NULL! ret:%{public}d", errInfo.errorNo);
329         return errInfo;
330     }
331     pLine = pResponse->head;
332     lineStr = pLine->data;
333     uint64_t addr = 0;
334     SkipATPrefix(&lineStr);
335     NextULongFromHex(&lineStr, &addr); // ip
336     AddressFormat(addr, readBuf, MAX_CMD_LENGTH);
337     NextULongFromHex(&lineStr, &addr); // subnet mask
338     ret = strlen(readBuf);
339     NetMaskFormat(addr, &readBuf[ret], MAX_CMD_LENGTH - ret);
340     (*ppDcr)[activeIndex].address = strdup(readBuf);
341     NextULongFromHex(&lineStr, &addr); // default gateway
342     AddressFormat(addr, readBuf, MAX_CMD_LENGTH);
343     (*ppDcr)[activeIndex].gateway = strdup(readBuf);
344     NextULongFromHex(&lineStr, &addr); // DHCP server
345     NextULongFromHex(&lineStr, &addr); // primary DNS server
346     AddressFormat(addr, readBuf, MAX_CMD_LENGTH);
347     (*ppDcr)[activeIndex].dns = strdup(readBuf);
348     NextULongFromHex(&lineStr, &addr); // secondary DNS server
349     FreeResponseInfo(pResponse);
350     (*ppDcr)[activeIndex].reason = HRIL_PDP_ERR_NONE;
351     return errInfo;
352 }
353 
SendInquireCGDCONT(int32_t * validCount,int32_t dataNum,HRilDataCallResponse ** ppDcr)354 static ModemReportErrorInfo SendInquireCGDCONT(int32_t *validCount, int32_t dataNum, HRilDataCallResponse **ppDcr)
355 {
356     int32_t ret;
357     ResponseInfo *pResponse = NULL;
358     ModemReportErrorInfo errInfo = {};
359 
360     ret = SendCommandLock("AT+CGDCONT?", "+CGDCONT:", 0, &pResponse);
361     if (ret != 0 || pResponse == NULL || !pResponse->success) {
362         errInfo = GetReportErrorInfo(pResponse);
363         errInfo.errorNo = (ret != HRIL_ERR_SUCCESS) ? ret : errInfo.errorNo;
364         TELEPHONY_LOGE("send AT CMD failed! ret:%{public}d", errInfo.errorNo);
365         FreeResponseInfo(pResponse);
366         return errInfo;
367     }
368 
369     if (ppDcr == NULL || *ppDcr == NULL) {
370         pResponse->success = 0;
371         errInfo = GetReportErrorInfo(pResponse);
372         FreeResponseInfo(pResponse);
373         TELEPHONY_LOGE("ppDcr is NULL! ret:%{public}d", errInfo.errorNo);
374         return errInfo;
375     }
376     BuildDataInfoList(validCount, dataNum, pResponse, ppDcr);
377     FreeResponseInfo(pResponse);
378     return errInfo;
379 }
380 
QueryAllSupportPDNInfos(PDNInfo * pdnInfo)381 static int32_t QueryAllSupportPDNInfos(PDNInfo *pdnInfo)
382 {
383     if (pdnInfo == NULL) {
384         return -1;
385     }
386     char *pStr = NULL;
387     int32_t ret = -1;
388     int32_t err = HRIL_ERR_SUCCESS;
389     Line *pLine = NULL;
390     PDNInfo *pdns = pdnInfo;
391     ResponseInfo *pResponse = NULL;
392 
393     ret = SendCommandLock("AT+CGDCONT?", "+CGDCONT:", 0, &pResponse);
394     if (ret != 0 || pResponse == NULL || !pResponse->success) {
395         ModemReportErrorInfo errInfo = GetReportErrorInfo(pResponse);
396         errInfo.errorNo = (ret != HRIL_ERR_SUCCESS) ? ret : errInfo.errorNo;
397         TELEPHONY_LOGE("send AT CMD failed! ret:%{public}d", err);
398         FreeResponseInfo(pResponse);
399         return err;
400     }
401 
402     for (pLine = pResponse->head; pLine != NULL; pLine = pLine->next) {
403         pStr = pLine->data;
404         ret = SkipATPrefix(&pStr);
405         if (ret < 0) {
406             pdns->cid = INT_DEFAULT_VALUE;
407         }
408         ret = NextInt(&pStr, &pdns->cid);
409         if (ret < 0) {
410             pdns->cid = INT_DEFAULT_VALUE;
411         }
412         ret = NextStr(&pStr, &pdns->ipType);
413         if (ret < 0) {
414             pdns->cid = INT_DEFAULT_VALUE;
415         }
416         ret = NextStr(&pStr, &pdns->apn);
417         if (ret < 0) {
418             pdns->cid = INT_DEFAULT_VALUE;
419         }
420         pdns++;
421     }
422     FreeResponseInfo(pResponse);
423     return ret;
424 }
425 
IsStrEmpty(const char * str)426 static int32_t IsStrEmpty(const char *str)
427 {
428     if (str == NULL || strcmp(str, "") == 0) {
429         return TRUE;
430     }
431     return FALSE;
432 }
433 
IsStrEqual(const char * src1,const char * src2)434 static int32_t IsStrEqual(const char *src1, const char *src2)
435 {
436     int32_t ret = FALSE;
437     if (IsStrEmpty(src1) && IsStrEmpty(src2)) {
438         ret = TRUE;
439     } else if (!IsStrEmpty(src1) && !IsStrEmpty(src2)) {
440         if (strcasecmp(src1, src2) == 0) {
441             ret = TRUE;
442         } else {
443             TELEPHONY_LOGE("IsStrEqual src1=%{public}s, src2=%{public}s", src1, src2);
444         }
445     } else {
446         TELEPHONY_LOGE("IsStrEqual src1 or src2 is empty!");
447     }
448     return ret;
449 }
450 
QuerySupportCID(const PDNInfo * pdnInfos,int32_t pdnSize,const char * apn,const char * ipType)451 static int32_t QuerySupportCID(const PDNInfo *pdnInfos, int32_t pdnSize, const char *apn, const char *ipType)
452 {
453     int32_t i;
454     int32_t j;
455     int32_t isUsedCid = 0;
456     int32_t cid = INT_DEFAULT_VALUE;
457     if (pdnInfos == NULL) {
458         return cid;
459     }
460 
461     for (j = 0; j < pdnSize; j++) {
462         if (IsStrEqual(apn, pdnInfos[j].apn)) {
463             cid = pdnInfos[j].cid;
464             break;
465         }
466     }
467     if (cid > 0) {
468         return cid;
469     }
470     for (i = MIN_CID; i <= MAX_CID; i++) {
471         isUsedCid = 0;
472         for (j = 0; j < pdnSize; j++) {
473             if (pdnInfos[j].cid == i) {
474                 isUsedCid = 1;
475                 break;
476             }
477         }
478         if (isUsedCid == 1) {
479             break;
480         }
481     }
482     cid = i;
483     return cid;
484 }
485 
GetNeedActivateCid(const char * apn,const char * ipType)486 static int32_t GetNeedActivateCid(const char *apn, const char *ipType)
487 {
488     int32_t cid = DEFAULT_CID;
489     PDNInfo pdnInfos[MAX_PDP_NUM] = {{DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""},
490         {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""},
491         {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}, {DEFAULT_CID, "", ""}};
492 
493     if (!QueryAllSupportPDNInfos(pdnInfos)) {
494         cid = QuerySupportCID(pdnInfos, MAX_PDP_NUM, apn, ipType);
495     }
496     if (cid <= 0) {
497         cid = MIN_CID;
498     }
499     return cid;
500 }
501 
FreeDataCallResponse(HRilDataCallResponse * pDcrs,int32_t size)502 static void FreeDataCallResponse(HRilDataCallResponse *pDcrs, int32_t size)
503 {
504     int32_t i = 0;
505 
506     if (pDcrs == NULL) {
507         return;
508     }
509     for (i = 0; i < size; i++) {
510         if (pDcrs[i].address != NULL) {
511             free(pDcrs[i].address);
512         }
513         if (pDcrs[i].netPortName != NULL) {
514             free(pDcrs[i].netPortName);
515         }
516         if (pDcrs[i].type != NULL) {
517             free(pDcrs[i].type);
518         }
519         if (pDcrs[i].dns != NULL) {
520             free(pDcrs[i].dns);
521         }
522         if (pDcrs[i].gateway != NULL) {
523             free(pDcrs[i].gateway);
524         }
525     }
526     free(pDcrs);
527 }
528 
DataReportMessage(int32_t cid,const ReqDataInfo * requestInfo,ModemReportErrorInfo errInfo,HRilDataCallResponse * pDataCalls,int32_t validNum)529 static void DataReportMessage(int32_t cid, const ReqDataInfo *requestInfo, ModemReportErrorInfo errInfo,
530     HRilDataCallResponse *pDataCalls, int32_t validNum)
531 {
532     struct ReportInfo reportInfo = {};
533     int32_t slotId = GetSlotId(requestInfo);
534     if (requestInfo != NULL) {
535         /* Report results */
536         int32_t index;
537         reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
538         reportInfo.modemErrInfo = errInfo;
539         if ((cid == DEFAULT_CID) || (pDataCalls == NULL)) {
540             OnDataReport(slotId, reportInfo, (const uint8_t *)pDataCalls, validNum * sizeof(HRilDataCallResponse));
541             FreeDataCallResponse(pDataCalls, validNum);
542             return;
543         }
544         for (index = 0; index < validNum; index++) {
545             if (pDataCalls[index].cid == cid) {
546                 break;
547             }
548         }
549         OnDataReport(slotId, reportInfo, (const uint8_t *)&pDataCalls[index], sizeof(HRilDataCallResponse));
550     } else {
551         /* Change notice */
552         reportInfo.requestInfo = NULL;
553         reportInfo.error = errInfo.errorNo;
554         reportInfo.modemErrInfo = errInfo;
555         reportInfo.notifyId = HNOTI_DATA_PDP_CONTEXT_LIST_UPDATED;
556         reportInfo.type = HRIL_NOTIFICATION;
557         OnDataReport(GetSlotId(NULL), reportInfo, (const uint8_t *)pDataCalls, validNum * sizeof(HRilDataCallResponse));
558     }
559     FreeDataCallResponse(pDataCalls, validNum);
560 }
561 
InquirePdpContextList(int32_t cid,const ReqDataInfo * requestInfo)562 static void InquirePdpContextList(int32_t cid, const ReqDataInfo *requestInfo)
563 {
564     int32_t validNum = 0;
565     int32_t queryCount = 0;
566     int32_t dataCallNum = 0;
567     HRilDataCallResponse *pDataCalls = NULL;
568     ModemReportErrorInfo errInfo = {};
569 
570     do {
571         errInfo = SendInquireCGACT(&dataCallNum, &pDataCalls);
572         if (errInfo.errorNo != HRIL_ERR_SUCCESS) {
573             TELEPHONY_LOGE("SendInquireCGACT send failed");
574             OnDataReportErrorMessages(requestInfo, errInfo.errorNo, NULL);
575             FreeDataCallResponse(pDataCalls, validNum);
576             return;
577         }
578         for (int32_t i = 0; i < dataCallNum; i++) {
579             if ((pDataCalls[i].cid == cid) && (DEACTIVATE == pDataCalls[i].active)) {
580                 errInfo.errorNo = HRIL_ERR_GENERIC_FAILURE;
581                 usleep(QUERY_DELAY_MS * DELAY_US_OFFSET);
582                 queryCount++;
583                 break;
584             }
585         }
586     } while ((cid != DEFAULT_CID) && (errInfo.errorNo != HRIL_ERR_SUCCESS) && (queryCount < QUERY_MAX_COUNT));
587 
588     errInfo = SendInquireCGDCONT(&validNum, dataCallNum, &pDataCalls);
589     if (errInfo.errorNo != HRIL_ERR_SUCCESS) {
590         TELEPHONY_LOGE("SendInquireCGDCONT send failed");
591         OnDataReportErrorMessages(requestInfo, errInfo.errorNo, NULL);
592         FreeDataCallResponse(pDataCalls, validNum);
593         return;
594     }
595     for (int32_t index = 0; index < validNum; index++) {
596         if (ACTIVATE == pDataCalls[index].active) {
597             errInfo = GetLinkInformation(index, &pDataCalls);
598             if (errInfo.errorNo != HRIL_ERR_SUCCESS) {
599                 TELEPHONY_LOGE("Get link information is failed!");
600                 OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
601                 FreeDataCallResponse(pDataCalls, validNum);
602                 return;
603             }
604         }
605     }
606     DataReportMessage(cid, requestInfo, errInfo, pDataCalls, validNum);
607 }
608 
SendCmdCGDCONT(int32_t cid,const ReqDataInfo * requestInfo,const HRilDataInfo * pDataInfo)609 static int32_t SendCmdCGDCONT(int32_t cid, const ReqDataInfo *requestInfo, const HRilDataInfo *pDataInfo)
610 {
611     if (pDataInfo == NULL) {
612         return -1;
613     }
614     int32_t ret;
615     int32_t err = HRIL_ERR_SUCCESS;
616     char cmd[MAX_CMD_LENGTH] = {0};
617     ResponseInfo *pResponse = NULL;
618     ret = GenerateCommand(
619         cmd, MAX_CMD_LENGTH, "AT+CGDCONT=%d,\"%s\",\"%s\",\"\",0,0", cid, pDataInfo->type, pDataInfo->apn);
620     if (ret < 0) {
621         TELEPHONY_LOGE("GenerateCommand is failed!");
622         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
623         return ret;
624     }
625     ret = SendCommandLock(cmd, NULL, 0, &pResponse);
626     if (ret != 0 || pResponse == NULL || !pResponse->success) {
627         err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
628         ret = OnDataReportPdpErrorMessages(requestInfo, err, pResponse);
629         TELEPHONY_LOGE("cmd send failed, err:%{public}d", ret);
630         return ret;
631     }
632     FreeResponseInfo(pResponse);
633     return HRIL_ERR_SUCCESS;
634 }
635 
SendCmdNDISDUP(int32_t cid,int32_t activate,const ReqDataInfo * requestInfo)636 static int32_t SendCmdNDISDUP(int32_t cid, int32_t activate, const ReqDataInfo *requestInfo)
637 {
638     int32_t ret;
639     int32_t err = HRIL_ERR_SUCCESS;
640     char cmd[MAX_CMD_LENGTH] = {0};
641     ResponseInfo *pResponse = NULL;
642 
643     ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT^NDISDUP=%d,%d", cid, activate);
644     if (ret < 0) {
645         TELEPHONY_LOGE("GenerateCommand is failed!");
646         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
647         return ret;
648     }
649     ret = SendCommandLock(cmd, NULL, 0, &pResponse);
650     if ((ret != HRIL_ERR_SUCCESS) || pResponse == NULL || !pResponse->success) {
651         err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
652         ret = OnDataReportPdpErrorMessages(requestInfo, err, pResponse);
653         TELEPHONY_LOGE("cmd send failed, err:%{public}d", ret);
654         return ret;
655     }
656     FreeResponseInfo(pResponse);
657     return HRIL_ERR_SUCCESS;
658 }
659 
RouteUp(void)660 static int32_t RouteUp(void)
661 {
662     int32_t ret = system("ifconfig usb0 up");
663     if (ret != 0) {
664         TELEPHONY_LOGE("exec system is failed! ret:%{public}d, %{public}s", ret, strerror(ret));
665         return ret;
666     }
667     TELEPHONY_LOGI("Open net device is finished!");
668     return HRIL_ERR_SUCCESS;
669 }
670 
RouteDown(void)671 static int32_t RouteDown(void)
672 {
673     int32_t ret = system("ifconfig usb0 down");
674     if (ret != 0) {
675         TELEPHONY_LOGE("exec system is failed! ret:%{public}d, %{public}s", ret, strerror(ret));
676         return ret;
677     }
678     TELEPHONY_LOGI("Close net device is finished!");
679     return HRIL_ERR_SUCCESS;
680 }
681 
ReqActivatePdpContext(const ReqDataInfo * requestInfo,const HRilDataInfo * data)682 void ReqActivatePdpContext(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
683 {
684     int32_t cid = INT_DEFAULT_VALUE;
685     const HRilDataInfo *pDataInfo = data;
686 
687     if (pDataInfo == NULL) {
688         TELEPHONY_LOGE("data is null!!!");
689         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
690         return;
691     }
692     if (RouteUp() != HRIL_ERR_SUCCESS) {
693         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
694         return;
695     }
696     cid = GetNeedActivateCid(pDataInfo->apn, pDataInfo->type);
697     if (SendCmdCGDCONT(cid, requestInfo, pDataInfo) != HRIL_ERR_SUCCESS) {
698         RouteDown();
699         return;
700     }
701     if (SendCmdNDISDUP(cid, ACTIVATE, requestInfo) != HRIL_ERR_SUCCESS) {
702         RouteDown();
703         return;
704     }
705     InquirePdpContextList(cid, requestInfo);
706 }
707 
ReqDeactivatePdpContext(const ReqDataInfo * requestInfo,const HRilDataInfo * data)708 void ReqDeactivatePdpContext(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
709 {
710     const HRilDataInfo *pDataInfo = data;
711     ModemReportErrorInfo errInfo = {};
712 
713     if (pDataInfo == NULL) {
714         TELEPHONY_LOGE("data is null!!!");
715         OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
716         return;
717     }
718     if (SendCmdNDISDUP(pDataInfo->cid, DEACTIVATE, requestInfo) != HRIL_ERR_SUCCESS) {
719         RouteDown();
720         return;
721     }
722     if (RouteDown() != HRIL_ERR_SUCCESS) {
723         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
724         return;
725     }
726     DataReportMessage(pDataInfo->cid, requestInfo, errInfo, NULL, 0);
727 }
728 
ReqGetPdpContextList(const ReqDataInfo * requestInfo)729 void ReqGetPdpContextList(const ReqDataInfo *requestInfo)
730 {
731     InquirePdpContextList(DEFAULT_CID, requestInfo);
732 }
733 
PdpContextListCallback(uint8_t * param)734 static void PdpContextListCallback(uint8_t *param)
735 {
736     InquirePdpContextList(DEFAULT_CID, NULL);
737 }
738 
PdpContextListUpdate(void)739 void PdpContextListUpdate(void)
740 {
741     struct timeval tv = {0, CALLBACK_DELAY_MS * DELAY_US_OFFSET};
742     OnTimerCallback(PdpContextListCallback, NULL, &tv);
743 }
744 
SetDataProfileInfo(int32_t cid,const ReqDataInfo * requestInfo,const HRilDataInfo * pDataInfo)745 static int32_t SetDataProfileInfo(int32_t cid, const ReqDataInfo *requestInfo, const HRilDataInfo *pDataInfo)
746 {
747     if (pDataInfo == NULL) {
748         return -1;
749     }
750     int32_t ret;
751     int32_t err = HRIL_ERR_SUCCESS;
752     char cmd[MAX_CMD_LENGTH] = {0};
753     ResponseInfo *pResponse = NULL;
754 
755     ret = GenerateCommand(
756         cmd, MAX_CMD_LENGTH, "AT+CGDCONT=%d,\"%s\",\"%s\",\"\",0,0", cid, pDataInfo->type, pDataInfo->apn);
757     if (ret < 0) {
758         TELEPHONY_LOGE("GenerateCommand is failed!");
759         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
760         return ret;
761     }
762     ret = SendCommandLock(cmd, NULL, 0, &pResponse);
763     if (ret != 0 || pResponse == NULL || !pResponse->success) {
764         err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
765         ret = OnDataReportErrorMessages(requestInfo, err, pResponse);
766         TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
767         return ret;
768     }
769     FreeResponseInfo(pResponse);
770     if ((pDataInfo->verType >= VERIFY_TYPE_MIN) && (pDataInfo->verType <= VERIFY_TYPE_MAX)) {
771         ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT^AUTHDATA=%d,%d,\"\",\"%s\",\"%s\"", cid, pDataInfo->verType,
772             pDataInfo->password, pDataInfo->userName);
773         if (ret < 0) {
774             TELEPHONY_LOGE("GenerateCommand is failed!");
775             OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
776             return ret;
777         }
778         ret = SendCommandLock(cmd, NULL, 0, &pResponse);
779         if (ret != 0 || pResponse == NULL || !pResponse->success) {
780             err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
781             ret = OnDataReportErrorMessages(requestInfo, err, pResponse);
782             TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
783             return ret;
784         }
785         FreeResponseInfo(pResponse);
786     }
787     return HRIL_ERR_SUCCESS;
788 }
789 
ReqSetInitApnInfo(const ReqDataInfo * requestInfo,const HRilDataInfo * data)790 void ReqSetInitApnInfo(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
791 {
792     int32_t cid = INT_DEFAULT_VALUE;
793     const HRilDataInfo *pDataInfo = data;
794     ModemReportErrorInfo errInfo = {};
795 
796     if (pDataInfo == NULL) {
797         TELEPHONY_LOGE("data is null!!!");
798         OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
799         return;
800     }
801     cid = GetNeedActivateCid(pDataInfo->apn, pDataInfo->type);
802     if (SetDataProfileInfo(cid, requestInfo, pDataInfo) != HRIL_ERR_SUCCESS) {
803         TELEPHONY_LOGE("Set data profile info is failed!");
804         return;
805     }
806     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
807     reportInfo.modemErrInfo = errInfo;
808     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
809 }
810 
ReqSetLinkBandwidthReportingRule(const ReqDataInfo * requestInfo,const HRilLinkBandwidthReportingRule * data)811 void ReqSetLinkBandwidthReportingRule(const ReqDataInfo *requestInfo, const HRilLinkBandwidthReportingRule *data)
812 {
813     const HRilLinkBandwidthReportingRule *linkBandwidthRule = data;
814     ModemReportErrorInfo errInfo = {};
815 
816     if (linkBandwidthRule == NULL) {
817         TELEPHONY_LOGE("data is null!!!");
818         OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
819         return;
820     }
821     TELEPHONY_LOGI("rat:%{public}d, delayMs:%{public}d", linkBandwidthRule->rat, linkBandwidthRule->delayMs);
822     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
823     reportInfo.modemErrInfo = errInfo;
824     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
825 }
826 
CallCmdC5GQOSRDP(const char * lineCmd,HRilLinkBandwidthInfo * outCall)827 static int32_t CallCmdC5GQOSRDP(const char *lineCmd, HRilLinkBandwidthInfo *outCall)
828 {
829     char *pLine = (char *)lineCmd;
830     if (pLine == NULL || outCall == NULL) {
831         TELEPHONY_LOGE("pLine or outCall is null.");
832         return HRIL_ERR_NULL_POINT;
833     }
834     if (SkipATPrefix(&pLine) < 0) {
835         return HRIL_ERR_NULL_POINT;
836     }
837     if (NextInt(&pLine, &outCall->cid) < 0) {
838         return HRIL_ERR_NULL_POINT;
839     }
840     if (NextInt(&pLine, &outCall->qi) < 0) {
841         return HRIL_ERR_NULL_POINT;
842     }
843     if (NextInt(&pLine, &outCall->dlGfbr) < 0) {
844         return HRIL_ERR_NULL_POINT;
845     }
846     if (NextInt(&pLine, &outCall->ulGfbr) < 0) {
847         return HRIL_ERR_NULL_POINT;
848     }
849     if (NextInt(&pLine, &outCall->dlMfbr) < 0) {
850         return HRIL_ERR_NULL_POINT;
851     }
852     if (NextInt(&pLine, &outCall->ulMfbr) < 0) {
853         return HRIL_ERR_NULL_POINT;
854     }
855     if (NextInt(&pLine, &outCall->ulSambr) < 0) {
856         return HRIL_ERR_NULL_POINT;
857     }
858     if (NextInt(&pLine, &outCall->dlSambr) < 0) {
859         return HRIL_ERR_NULL_POINT;
860     }
861     if (NextInt(&pLine, &outCall->averagingWindow) < 0) {
862         return HRIL_ERR_NULL_POINT;
863     }
864     return HRIL_ERR_SUCCESS;
865 }
866 
ReqGetLinkBandwidthInfo(const ReqDataInfo * requestInfo,const int32_t cid)867 void ReqGetLinkBandwidthInfo(const ReqDataInfo *requestInfo, const int32_t cid)
868 {
869     int32_t ret;
870     char *line = NULL;
871     int32_t err = HRIL_ERR_SUCCESS;
872     HRilLinkBandwidthInfo uplinkAndDownlinkBandwidth = {0};
873     ResponseInfo *pResponse = NULL;
874     char cmd[MAX_CMD_LENGTH] = {0};
875 
876     ModemReportErrorInfo errInfo = InitModemReportErrorInfo();
877     ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT+C5GQOSRDP=%d", cid);
878     if (ret < 0) {
879         TELEPHONY_LOGE("GenerateCommand is failed!");
880         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
881         return;
882     }
883     ret = SendCommandLock(cmd, "+C5GQOSRDP:", 0, &pResponse);
884     if (ret || pResponse == NULL || !pResponse->success) {
885         err = ret ? ret : err;
886         TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
887         OnDataReportErrorMessages(requestInfo, err, pResponse);
888         return;
889     }
890     if (pResponse->head) {
891         line = pResponse->head->data;
892         ret = CallCmdC5GQOSRDP(line, &uplinkAndDownlinkBandwidth);
893         if (ret != 0) {
894             TELEPHONY_LOGE("Parse C5GQOSRDP data is fail. ret:%{public}d", ret);
895             return;
896         }
897         TELEPHONY_LOGI(
898             "+C5GQOSRDP:%{public}d, %{public}d", uplinkAndDownlinkBandwidth.cid, uplinkAndDownlinkBandwidth.qi);
899     } else {
900         TELEPHONY_LOGE("ERROR: pResponse->head is null");
901         err = HRIL_ERR_GENERIC_FAILURE;
902     }
903     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
904     reportInfo.modemErrInfo = errInfo;
905     OnDataReport(GetSlotId(requestInfo), reportInfo, (const uint8_t *)&uplinkAndDownlinkBandwidth,
906         sizeof(HRilLinkBandwidthInfo));
907     FreeResponseInfo(pResponse);
908 }
909 
ReqSetDataPermitted(const ReqDataInfo * requestInfo,const int32_t dataPermitted)910 void ReqSetDataPermitted(const ReqDataInfo *requestInfo, const int32_t dataPermitted)
911 {
912     TELEPHONY_LOGI("dataPermitted:%{public}d", dataPermitted);
913     ModemReportErrorInfo errInfo = {};
914     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
915     reportInfo.modemErrInfo = errInfo;
916     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
917 }
918