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