• 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         if (index == validNum) {
554             OnDataReport(slotId, reportInfo, (const uint8_t *)pDataCalls, validNum * sizeof(HRilDataCallResponse));
555             FreeDataCallResponse(pDataCalls, validNum);
556             return;
557         }
558         OnDataReport(slotId, reportInfo, (const uint8_t *)&pDataCalls[index], sizeof(HRilDataCallResponse));
559     } else {
560         /* Change notice */
561         reportInfo.requestInfo = NULL;
562         reportInfo.error = errInfo.errorNo;
563         reportInfo.modemErrInfo = errInfo;
564         reportInfo.notifyId = HNOTI_DATA_PDP_CONTEXT_LIST_UPDATED;
565         reportInfo.type = HRIL_NOTIFICATION;
566         OnDataReport(GetSlotId(NULL), reportInfo, (const uint8_t *)pDataCalls, validNum * sizeof(HRilDataCallResponse));
567     }
568     FreeDataCallResponse(pDataCalls, validNum);
569 }
570 
InquirePdpContextList(int32_t cid,const ReqDataInfo * requestInfo)571 static void InquirePdpContextList(int32_t cid, const ReqDataInfo *requestInfo)
572 {
573     int32_t validNum = 0;
574     int32_t queryCount = 0;
575     int32_t dataCallNum = 0;
576     HRilDataCallResponse *pDataCalls = NULL;
577 
578     do {
579         ModemReportErrorInfo errInfo = SendInquireCGACT(&dataCallNum, &pDataCalls);
580         if (errInfo.errorNo != HRIL_ERR_SUCCESS) {
581             TELEPHONY_LOGE("SendInquireCGACT send failed");
582             OnDataReportErrorMessages(requestInfo, errInfo.errorNo, NULL);
583             FreeDataCallResponse(pDataCalls, validNum);
584             return;
585         }
586         for (int32_t i = 0; i < dataCallNum; i++) {
587             if ((pDataCalls[i].cid == cid) && (DEACTIVATE == pDataCalls[i].active)) {
588                 errInfo.errorNo = HRIL_ERR_GENERIC_FAILURE;
589                 usleep(QUERY_DELAY_MS * DELAY_US_OFFSET);
590                 queryCount++;
591                 break;
592             }
593         }
594         if (errInfo.errorNo == HRIL_ERR_SUCCESS) {
595             break;
596         }
597     } while ((cid != DEFAULT_CID) && (queryCount < QUERY_MAX_COUNT));
598 
599     ModemReportErrorInfo errInfo = SendInquireCGDCONT(&validNum, dataCallNum, &pDataCalls);
600     if (errInfo.errorNo != HRIL_ERR_SUCCESS) {
601         TELEPHONY_LOGE("SendInquireCGDCONT send failed");
602         OnDataReportErrorMessages(requestInfo, errInfo.errorNo, NULL);
603         FreeDataCallResponse(pDataCalls, validNum);
604         return;
605     }
606     for (int32_t index = 0; index < validNum; index++) {
607         if (ACTIVATE == pDataCalls[index].active) {
608             errInfo = GetLinkInformation(index, &pDataCalls);
609             if (errInfo.errorNo != HRIL_ERR_SUCCESS) {
610                 TELEPHONY_LOGE("Get link information is failed!");
611                 OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
612                 FreeDataCallResponse(pDataCalls, validNum);
613                 return;
614             }
615         }
616     }
617     DataReportMessage(cid, requestInfo, errInfo, pDataCalls, validNum);
618 }
619 
SendCmdCGDCONT(int32_t cid,const ReqDataInfo * requestInfo,const HRilDataInfo * pDataInfo)620 static int32_t SendCmdCGDCONT(int32_t cid, const ReqDataInfo *requestInfo, const HRilDataInfo *pDataInfo)
621 {
622     if (pDataInfo == NULL) {
623         return -1;
624     }
625     int32_t ret;
626     int32_t err = HRIL_ERR_SUCCESS;
627     char cmd[MAX_CMD_LENGTH] = {0};
628     ResponseInfo *pResponse = NULL;
629     ret = GenerateCommand(
630         cmd, MAX_CMD_LENGTH, "AT+CGDCONT=%d,\"%s\",\"%s\",\"\",0,0", cid, pDataInfo->type, pDataInfo->apn);
631     if (ret < 0) {
632         TELEPHONY_LOGE("GenerateCommand is failed!");
633         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
634         return ret;
635     }
636     ret = SendCommandLock(cmd, NULL, 0, &pResponse);
637     if (ret != 0 || pResponse == NULL || !pResponse->success) {
638         err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
639         ret = OnDataReportPdpErrorMessages(requestInfo, err, pResponse);
640         TELEPHONY_LOGE("cmd send failed, err:%{public}d", ret);
641         return ret;
642     }
643     FreeResponseInfo(pResponse);
644     return HRIL_ERR_SUCCESS;
645 }
646 
SendCmdNDISDUP(int32_t cid,int32_t activate,const ReqDataInfo * requestInfo)647 static int32_t SendCmdNDISDUP(int32_t cid, int32_t activate, const ReqDataInfo *requestInfo)
648 {
649     int32_t ret;
650     int32_t err = HRIL_ERR_SUCCESS;
651     char cmd[MAX_CMD_LENGTH] = {0};
652     ResponseInfo *pResponse = NULL;
653 
654     ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT^NDISDUP=%d,%d", cid, activate);
655     if (ret < 0) {
656         TELEPHONY_LOGE("GenerateCommand is failed!");
657         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
658         return ret;
659     }
660     ret = SendCommandLock(cmd, NULL, 0, &pResponse);
661     if ((ret != HRIL_ERR_SUCCESS) || pResponse == NULL || !pResponse->success) {
662         err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
663         ret = OnDataReportPdpErrorMessages(requestInfo, err, pResponse);
664         TELEPHONY_LOGE("cmd send failed, err:%{public}d", ret);
665         return ret;
666     }
667     FreeResponseInfo(pResponse);
668     return HRIL_ERR_SUCCESS;
669 }
670 
RouteUp(void)671 static int32_t RouteUp(void)
672 {
673     int32_t ret = system("ifconfig usb0 up");
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("Open net device is finished!");
679     return HRIL_ERR_SUCCESS;
680 }
681 
RouteDown(void)682 static int32_t RouteDown(void)
683 {
684     int32_t ret = system("ifconfig usb0 down");
685     if (ret != 0) {
686         TELEPHONY_LOGE("exec system is failed! ret:%{public}d, %{public}s", ret, strerror(ret));
687         return ret;
688     }
689     TELEPHONY_LOGI("Close net device is finished!");
690     return HRIL_ERR_SUCCESS;
691 }
692 
ReqActivatePdpContext(const ReqDataInfo * requestInfo,const HRilDataInfo * data)693 void ReqActivatePdpContext(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
694 {
695     int32_t cid = INT_DEFAULT_VALUE;
696     const HRilDataInfo *pDataInfo = data;
697 
698     if (pDataInfo == NULL) {
699         TELEPHONY_LOGE("data is null!!!");
700         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
701         return;
702     }
703     if (RouteUp() != HRIL_ERR_SUCCESS) {
704         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
705         return;
706     }
707     cid = GetNeedActivateCid(pDataInfo->apn, pDataInfo->type);
708     if (cid == INT_DEFAULT_VALUE) {
709         TELEPHONY_LOGE("cid is invalid!!!");
710         OnDataReportPdpErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
711         RouteDown();
712         return;
713     }
714     if (SendCmdCGDCONT(cid, requestInfo, pDataInfo) != HRIL_ERR_SUCCESS) {
715         RouteDown();
716         return;
717     }
718     if (SendCmdNDISDUP(cid, ACTIVATE, requestInfo) != HRIL_ERR_SUCCESS) {
719         RouteDown();
720         return;
721     }
722     InquirePdpContextList(cid, requestInfo);
723 }
724 
ReqActivatePdpContextWithApnTypes(const ReqDataInfo * requestInfo,const HRilDataInfoWithApnTypes * data)725 void ReqActivatePdpContextWithApnTypes(const ReqDataInfo *requestInfo, const HRilDataInfoWithApnTypes *data)
726 {
727     TELEPHONY_LOGI("Call V1_1 ReqActivatePdpContext");
728     HRilDataInfo pDataInfo;
729     pDataInfo.cid = data->cid;
730     pDataInfo.reason = data->reason;
731     pDataInfo.roamingEnable = data->roamingEnable;
732     pDataInfo.verType = data->verType;
733     pDataInfo.userName = data->userName;
734     pDataInfo.password = data->password;
735     pDataInfo.apn = data->apn;
736     pDataInfo.type = data->type;
737     pDataInfo.roamingType = data->roamingType;
738     ReqActivatePdpContext(requestInfo, &pDataInfo);
739 }
740 
ReqDeactivatePdpContext(const ReqDataInfo * requestInfo,const HRilDataInfo * data)741 void ReqDeactivatePdpContext(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
742 {
743     const HRilDataInfo *pDataInfo = data;
744     ModemReportErrorInfo errInfo = {};
745 
746     if (pDataInfo == NULL) {
747         TELEPHONY_LOGE("data is null!!!");
748         OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
749         return;
750     }
751     if (SendCmdNDISDUP(pDataInfo->cid, DEACTIVATE, requestInfo) != HRIL_ERR_SUCCESS) {
752         RouteDown();
753         return;
754     }
755     if (RouteDown() != HRIL_ERR_SUCCESS) {
756         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
757         return;
758     }
759     DataReportMessage(pDataInfo->cid, requestInfo, errInfo, NULL, 0);
760 }
761 
ReqGetPdpContextList(const ReqDataInfo * requestInfo)762 void ReqGetPdpContextList(const ReqDataInfo *requestInfo)
763 {
764     InquirePdpContextList(DEFAULT_CID, requestInfo);
765 }
766 
PdpContextListCallback(uint8_t * param)767 static void PdpContextListCallback(uint8_t *param)
768 {
769     InquirePdpContextList(DEFAULT_CID, NULL);
770 }
771 
PdpContextListUpdate(void)772 void PdpContextListUpdate(void)
773 {
774     struct timeval tv = {0, CALLBACK_DELAY_MS * DELAY_US_OFFSET};
775     OnTimerCallback(PdpContextListCallback, NULL, &tv);
776 }
777 
SetDataProfileInfo(int32_t cid,const ReqDataInfo * requestInfo,const HRilDataInfo * pDataInfo)778 static int32_t SetDataProfileInfo(int32_t cid, const ReqDataInfo *requestInfo, const HRilDataInfo *pDataInfo)
779 {
780     if (pDataInfo == NULL) {
781         return -1;
782     }
783     int32_t ret;
784     int32_t err = HRIL_ERR_SUCCESS;
785     char cmd[MAX_CMD_LENGTH] = {0};
786     ResponseInfo *pResponse = NULL;
787 
788     ret = GenerateCommand(
789         cmd, MAX_CMD_LENGTH, "AT+CGDCONT=%d,\"%s\",\"%s\",\"\",0,0", cid, pDataInfo->type, pDataInfo->apn);
790     if (ret < 0) {
791         TELEPHONY_LOGE("GenerateCommand is failed!");
792         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
793         return ret;
794     }
795     ret = SendCommandLock(cmd, NULL, 0, &pResponse);
796     if (ret != 0 || pResponse == NULL || !pResponse->success) {
797         err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
798         ret = OnDataReportErrorMessages(requestInfo, err, pResponse);
799         TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
800         return ret;
801     }
802     FreeResponseInfo(pResponse);
803     if ((pDataInfo->verType >= VERIFY_TYPE_MIN) && (pDataInfo->verType <= VERIFY_TYPE_MAX)) {
804         ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT^AUTHDATA=%d,%d,\"\",\"%s\",\"%s\"", cid, pDataInfo->verType,
805             pDataInfo->password, pDataInfo->userName);
806         if (ret < 0) {
807             TELEPHONY_LOGE("GenerateCommand is failed!");
808             OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
809             return ret;
810         }
811         ret = SendCommandLock(cmd, NULL, 0, &pResponse);
812         if (ret != 0 || pResponse == NULL || !pResponse->success) {
813             err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
814             ret = OnDataReportErrorMessages(requestInfo, err, pResponse);
815             TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
816             return ret;
817         }
818         FreeResponseInfo(pResponse);
819     }
820     return HRIL_ERR_SUCCESS;
821 }
822 
ReqSetInitApnInfo(const ReqDataInfo * requestInfo,const HRilDataInfo * data)823 void ReqSetInitApnInfo(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
824 {
825     int32_t cid = INT_DEFAULT_VALUE;
826     const HRilDataInfo *pDataInfo = data;
827     ModemReportErrorInfo errInfo = {};
828 
829     if (pDataInfo == NULL) {
830         TELEPHONY_LOGE("data is null!!!");
831         OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
832         return;
833     }
834     cid = GetNeedActivateCid(pDataInfo->apn, pDataInfo->type);
835     if (cid == INT_DEFAULT_VALUE) {
836         TELEPHONY_LOGE("cid is invalid!!!");
837         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
838         return;
839     }
840     if (SetDataProfileInfo(cid, requestInfo, pDataInfo) != HRIL_ERR_SUCCESS) {
841         TELEPHONY_LOGE("Set data profile info is failed!");
842         return;
843     }
844     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
845     reportInfo.modemErrInfo = errInfo;
846     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
847 }
848 
ReqSetLinkBandwidthReportingRule(const ReqDataInfo * requestInfo,const HRilLinkBandwidthReportingRule * data)849 void ReqSetLinkBandwidthReportingRule(const ReqDataInfo *requestInfo, const HRilLinkBandwidthReportingRule *data)
850 {
851     const HRilLinkBandwidthReportingRule *linkBandwidthRule = data;
852     ModemReportErrorInfo errInfo = {};
853 
854     if (linkBandwidthRule == NULL) {
855         TELEPHONY_LOGE("data is null!!!");
856         OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
857         return;
858     }
859     TELEPHONY_LOGI("rat:%{public}d, delayMs:%{public}d", linkBandwidthRule->rat, linkBandwidthRule->delayMs);
860     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
861     reportInfo.modemErrInfo = errInfo;
862     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
863 }
864 
CallCmdC5GQOSRDP(const char * lineCmd,HRilLinkBandwidthInfo * outCall)865 static int32_t CallCmdC5GQOSRDP(const char *lineCmd, HRilLinkBandwidthInfo *outCall)
866 {
867     char *pLine = (char *)lineCmd;
868     if (pLine == NULL || outCall == NULL) {
869         TELEPHONY_LOGE("pLine or outCall is null.");
870         return HRIL_ERR_NULL_POINT;
871     }
872     if (SkipATPrefix(&pLine) < 0) {
873         return HRIL_ERR_NULL_POINT;
874     }
875     if (NextInt(&pLine, &outCall->cid) < 0) {
876         return HRIL_ERR_NULL_POINT;
877     }
878     if (NextInt(&pLine, &outCall->qi) < 0) {
879         return HRIL_ERR_NULL_POINT;
880     }
881     if (NextInt(&pLine, &outCall->dlGfbr) < 0) {
882         return HRIL_ERR_NULL_POINT;
883     }
884     if (NextInt(&pLine, &outCall->ulGfbr) < 0) {
885         return HRIL_ERR_NULL_POINT;
886     }
887     if (NextInt(&pLine, &outCall->dlMfbr) < 0) {
888         return HRIL_ERR_NULL_POINT;
889     }
890     if (NextInt(&pLine, &outCall->ulMfbr) < 0) {
891         return HRIL_ERR_NULL_POINT;
892     }
893     if (NextInt(&pLine, &outCall->ulSambr) < 0) {
894         return HRIL_ERR_NULL_POINT;
895     }
896     if (NextInt(&pLine, &outCall->dlSambr) < 0) {
897         return HRIL_ERR_NULL_POINT;
898     }
899     if (NextInt(&pLine, &outCall->averagingWindow) < 0) {
900         return HRIL_ERR_NULL_POINT;
901     }
902     return HRIL_ERR_SUCCESS;
903 }
904 
ReqGetLinkBandwidthInfo(const ReqDataInfo * requestInfo,const int32_t cid)905 void ReqGetLinkBandwidthInfo(const ReqDataInfo *requestInfo, const int32_t cid)
906 {
907     int32_t ret;
908     char *line = NULL;
909     int32_t err = HRIL_ERR_SUCCESS;
910     HRilLinkBandwidthInfo uplinkAndDownlinkBandwidth = {0};
911     ResponseInfo *pResponse = NULL;
912     char cmd[MAX_CMD_LENGTH] = {0};
913 
914     ModemReportErrorInfo errInfo = InitModemReportErrorInfo();
915     ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT+C5GQOSRDP=%d", cid);
916     if (ret < 0) {
917         TELEPHONY_LOGE("GenerateCommand is failed!");
918         OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
919         return;
920     }
921     ret = SendCommandLock(cmd, "+C5GQOSRDP:", 0, &pResponse);
922     if (ret || pResponse == NULL || !pResponse->success) {
923         err = ret ? ret : err;
924         TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
925         OnDataReportErrorMessages(requestInfo, err, pResponse);
926         return;
927     }
928     if (pResponse->head) {
929         line = pResponse->head->data;
930         ret = CallCmdC5GQOSRDP(line, &uplinkAndDownlinkBandwidth);
931         if (ret != 0) {
932             TELEPHONY_LOGE("Parse C5GQOSRDP data is fail. ret:%{public}d", ret);
933             return;
934         }
935         TELEPHONY_LOGI(
936             "+C5GQOSRDP:%{public}d, %{public}d", uplinkAndDownlinkBandwidth.cid, uplinkAndDownlinkBandwidth.qi);
937     } else {
938         TELEPHONY_LOGE("ERROR: pResponse->head is null");
939         err = HRIL_ERR_GENERIC_FAILURE;
940     }
941     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
942     reportInfo.modemErrInfo = errInfo;
943     OnDataReport(GetSlotId(requestInfo), reportInfo, (const uint8_t *)&uplinkAndDownlinkBandwidth,
944         sizeof(HRilLinkBandwidthInfo));
945     FreeResponseInfo(pResponse);
946 }
947 
ReqSetDataPermitted(const ReqDataInfo * requestInfo,const int32_t dataPermitted)948 void ReqSetDataPermitted(const ReqDataInfo *requestInfo, const int32_t dataPermitted)
949 {
950     TELEPHONY_LOGI("dataPermitted:%{public}d", dataPermitted);
951     ModemReportErrorInfo errInfo = {};
952     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
953     reportInfo.modemErrInfo = errInfo;
954     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
955 }
956 
ReqGetLinkCapability(const ReqDataInfo * requestInfo)957 void ReqGetLinkCapability(const ReqDataInfo *requestInfo)
958 {
959     ModemReportErrorInfo errInfo = { 0 };
960     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
961     reportInfo.modemErrInfo = errInfo;
962     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
963 }
964 
ReqCleanAllConnections(const ReqDataInfo * requestInfo)965 void ReqCleanAllConnections(const ReqDataInfo *requestInfo)
966 {
967     ModemReportErrorInfo errInfo = { 0 };
968     struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
969     reportInfo.modemErrInfo = errInfo;
970     OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
971 }
972