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
ReqActivatePdpContextWithApnTypes(const ReqDataInfo *requestInfo, const HRilDataInfoWithApnTypes *data)720 void ReqActivatePdpContextWithApnTypes(const ReqDataInfo *requestInfo, const HRilDataInfoWithApnTypes *data)
721 {
722 TELEPHONY_LOGI("Call V1_1 ReqActivatePdpContext");
723 HRilDataInfo pDataInfo;
724 pDataInfo.cid = data->cid;
725 pDataInfo.reason = data->reason;
726 pDataInfo.roamingEnable = data->roamingEnable;
727 pDataInfo.verType = data->verType;
728 pDataInfo.userName = data->userName;
729 pDataInfo.password = data->password;
730 pDataInfo.apn = data->apn;
731 pDataInfo.type = data->type;
732 pDataInfo.roamingType = data->roamingType;
733 ReqActivatePdpContext(requestInfo, &pDataInfo);
734 }
735
ReqDeactivatePdpContext(const ReqDataInfo *requestInfo, const HRilDataInfo *data)736 void ReqDeactivatePdpContext(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
737 {
738 const HRilDataInfo *pDataInfo = data;
739 ModemReportErrorInfo errInfo = {};
740
741 if (pDataInfo == NULL) {
742 TELEPHONY_LOGE("data is null!!!");
743 OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
744 return;
745 }
746 if (SendCmdNDISDUP(pDataInfo->cid, DEACTIVATE, requestInfo) != HRIL_ERR_SUCCESS) {
747 RouteDown();
748 return;
749 }
750 if (RouteDown() != HRIL_ERR_SUCCESS) {
751 OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
752 return;
753 }
754 DataReportMessage(pDataInfo->cid, requestInfo, errInfo, NULL, 0);
755 }
756
ReqGetPdpContextList(const ReqDataInfo *requestInfo)757 void ReqGetPdpContextList(const ReqDataInfo *requestInfo)
758 {
759 InquirePdpContextList(DEFAULT_CID, requestInfo);
760 }
761
PdpContextListCallback(uint8_t *param)762 static void PdpContextListCallback(uint8_t *param)
763 {
764 InquirePdpContextList(DEFAULT_CID, NULL);
765 }
766
PdpContextListUpdate(void)767 void PdpContextListUpdate(void)
768 {
769 struct timeval tv = {0, CALLBACK_DELAY_MS * DELAY_US_OFFSET};
770 OnTimerCallback(PdpContextListCallback, NULL, &tv);
771 }
772
SetDataProfileInfo(int32_t cid, const ReqDataInfo *requestInfo, const HRilDataInfo *pDataInfo)773 static int32_t SetDataProfileInfo(int32_t cid, const ReqDataInfo *requestInfo, const HRilDataInfo *pDataInfo)
774 {
775 if (pDataInfo == NULL) {
776 return -1;
777 }
778 int32_t ret;
779 int32_t err = HRIL_ERR_SUCCESS;
780 char cmd[MAX_CMD_LENGTH] = {0};
781 ResponseInfo *pResponse = NULL;
782
783 ret = GenerateCommand(
784 cmd, MAX_CMD_LENGTH, "AT+CGDCONT=%d,\"%s\",\"%s\",\"\",0,0", cid, pDataInfo->type, pDataInfo->apn);
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 if ((pDataInfo->verType >= VERIFY_TYPE_MIN) && (pDataInfo->verType <= VERIFY_TYPE_MAX)) {
799 ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT^AUTHDATA=%d,%d,\"\",\"%s\",\"%s\"", cid, pDataInfo->verType,
800 pDataInfo->password, pDataInfo->userName);
801 if (ret < 0) {
802 TELEPHONY_LOGE("GenerateCommand is failed!");
803 OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
804 return ret;
805 }
806 ret = SendCommandLock(cmd, NULL, 0, &pResponse);
807 if (ret != 0 || pResponse == NULL || !pResponse->success) {
808 err = (ret != HRIL_ERR_SUCCESS) ? ret : err;
809 ret = OnDataReportErrorMessages(requestInfo, err, pResponse);
810 TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
811 return ret;
812 }
813 FreeResponseInfo(pResponse);
814 }
815 return HRIL_ERR_SUCCESS;
816 }
817
ReqSetInitApnInfo(const ReqDataInfo *requestInfo, const HRilDataInfo *data)818 void ReqSetInitApnInfo(const ReqDataInfo *requestInfo, const HRilDataInfo *data)
819 {
820 int32_t cid = INT_DEFAULT_VALUE;
821 const HRilDataInfo *pDataInfo = data;
822 ModemReportErrorInfo errInfo = {};
823
824 if (pDataInfo == NULL) {
825 TELEPHONY_LOGE("data is null!!!");
826 OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
827 return;
828 }
829 cid = GetNeedActivateCid(pDataInfo->apn, pDataInfo->type);
830 if (cid == INT_DEFAULT_VALUE) {
831 TELEPHONY_LOGE("cid is invalid!!!");
832 OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
833 return;
834 }
835 if (SetDataProfileInfo(cid, requestInfo, pDataInfo) != HRIL_ERR_SUCCESS) {
836 TELEPHONY_LOGE("Set data profile info is failed!");
837 return;
838 }
839 struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
840 reportInfo.modemErrInfo = errInfo;
841 OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
842 }
843
ReqSetLinkBandwidthReportingRule(const ReqDataInfo *requestInfo, const HRilLinkBandwidthReportingRule *data)844 void ReqSetLinkBandwidthReportingRule(const ReqDataInfo *requestInfo, const HRilLinkBandwidthReportingRule *data)
845 {
846 const HRilLinkBandwidthReportingRule *linkBandwidthRule = data;
847 ModemReportErrorInfo errInfo = {};
848
849 if (linkBandwidthRule == NULL) {
850 TELEPHONY_LOGE("data is null!!!");
851 OnDataReportErrorMessages(requestInfo, HRIL_ERR_INVALID_PARAMETER, NULL);
852 return;
853 }
854 TELEPHONY_LOGI("rat:%{public}d, delayMs:%{public}d", linkBandwidthRule->rat, linkBandwidthRule->delayMs);
855 struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
856 reportInfo.modemErrInfo = errInfo;
857 OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
858 }
859
CallCmdC5GQOSRDP(const char *lineCmd, HRilLinkBandwidthInfo *outCall)860 static int32_t CallCmdC5GQOSRDP(const char *lineCmd, HRilLinkBandwidthInfo *outCall)
861 {
862 char *pLine = (char *)lineCmd;
863 if (pLine == NULL || outCall == NULL) {
864 TELEPHONY_LOGE("pLine or outCall is null.");
865 return HRIL_ERR_NULL_POINT;
866 }
867 if (SkipATPrefix(&pLine) < 0) {
868 return HRIL_ERR_NULL_POINT;
869 }
870 if (NextInt(&pLine, &outCall->cid) < 0) {
871 return HRIL_ERR_NULL_POINT;
872 }
873 if (NextInt(&pLine, &outCall->qi) < 0) {
874 return HRIL_ERR_NULL_POINT;
875 }
876 if (NextInt(&pLine, &outCall->dlGfbr) < 0) {
877 return HRIL_ERR_NULL_POINT;
878 }
879 if (NextInt(&pLine, &outCall->ulGfbr) < 0) {
880 return HRIL_ERR_NULL_POINT;
881 }
882 if (NextInt(&pLine, &outCall->dlMfbr) < 0) {
883 return HRIL_ERR_NULL_POINT;
884 }
885 if (NextInt(&pLine, &outCall->ulMfbr) < 0) {
886 return HRIL_ERR_NULL_POINT;
887 }
888 if (NextInt(&pLine, &outCall->ulSambr) < 0) {
889 return HRIL_ERR_NULL_POINT;
890 }
891 if (NextInt(&pLine, &outCall->dlSambr) < 0) {
892 return HRIL_ERR_NULL_POINT;
893 }
894 if (NextInt(&pLine, &outCall->averagingWindow) < 0) {
895 return HRIL_ERR_NULL_POINT;
896 }
897 return HRIL_ERR_SUCCESS;
898 }
899
ReqGetLinkBandwidthInfo(const ReqDataInfo *requestInfo, const int32_t cid)900 void ReqGetLinkBandwidthInfo(const ReqDataInfo *requestInfo, const int32_t cid)
901 {
902 int32_t ret;
903 char *line = NULL;
904 int32_t err = HRIL_ERR_SUCCESS;
905 HRilLinkBandwidthInfo uplinkAndDownlinkBandwidth = {0};
906 ResponseInfo *pResponse = NULL;
907 char cmd[MAX_CMD_LENGTH] = {0};
908
909 ModemReportErrorInfo errInfo = InitModemReportErrorInfo();
910 ret = GenerateCommand(cmd, MAX_CMD_LENGTH, "AT+C5GQOSRDP=%d", cid);
911 if (ret < 0) {
912 TELEPHONY_LOGE("GenerateCommand is failed!");
913 OnDataReportErrorMessages(requestInfo, HRIL_ERR_GENERIC_FAILURE, NULL);
914 return;
915 }
916 ret = SendCommandLock(cmd, "+C5GQOSRDP:", 0, &pResponse);
917 if (ret || pResponse == NULL || !pResponse->success) {
918 err = ret ? ret : err;
919 TELEPHONY_LOGE("cmd send failed, err:%{public}d", err);
920 OnDataReportErrorMessages(requestInfo, err, pResponse);
921 return;
922 }
923 if (pResponse->head) {
924 line = pResponse->head->data;
925 ret = CallCmdC5GQOSRDP(line, &uplinkAndDownlinkBandwidth);
926 if (ret != 0) {
927 TELEPHONY_LOGE("Parse C5GQOSRDP data is fail. ret:%{public}d", ret);
928 return;
929 }
930 TELEPHONY_LOGI(
931 "+C5GQOSRDP:%{public}d, %{public}d", uplinkAndDownlinkBandwidth.cid, uplinkAndDownlinkBandwidth.qi);
932 } else {
933 TELEPHONY_LOGE("ERROR: pResponse->head is null");
934 err = HRIL_ERR_GENERIC_FAILURE;
935 }
936 struct ReportInfo reportInfo = CreateReportInfo(requestInfo, err, HRIL_RESPONSE, 0);
937 reportInfo.modemErrInfo = errInfo;
938 OnDataReport(GetSlotId(requestInfo), reportInfo, (const uint8_t *)&uplinkAndDownlinkBandwidth,
939 sizeof(HRilLinkBandwidthInfo));
940 FreeResponseInfo(pResponse);
941 }
942
ReqSetDataPermitted(const ReqDataInfo *requestInfo, const int32_t dataPermitted)943 void ReqSetDataPermitted(const ReqDataInfo *requestInfo, const int32_t dataPermitted)
944 {
945 TELEPHONY_LOGI("dataPermitted:%{public}d", dataPermitted);
946 ModemReportErrorInfo errInfo = {};
947 struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
948 reportInfo.modemErrInfo = errInfo;
949 OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
950 }
951
ReqGetLinkCapability(const ReqDataInfo *requestInfo)952 void ReqGetLinkCapability(const ReqDataInfo *requestInfo)
953 {
954 ModemReportErrorInfo errInfo = { 0 };
955 struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
956 reportInfo.modemErrInfo = errInfo;
957 OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
958 }
959
ReqCleanAllConnections(const ReqDataInfo *requestInfo)960 void ReqCleanAllConnections(const ReqDataInfo *requestInfo)
961 {
962 ModemReportErrorInfo errInfo = { 0 };
963 struct ReportInfo reportInfo = CreateReportInfo(requestInfo, errInfo.errorNo, HRIL_RESPONSE, 0);
964 reportInfo.modemErrInfo = errInfo;
965 OnDataReport(GetSlotId(requestInfo), reportInfo, NULL, 0);
966 }
967