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