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 25static 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 75static 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 103static 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 124int32_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 160static 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 178static 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 220static 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 264static 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 290static 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 316static 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 363static 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 390static 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 433static int32_t IsStrEmpty(const char *str) 434{ 435 if (str == NULL || strcmp(str, "") == 0) { 436 return TRUE; 437 } 438 return FALSE; 439} 440 441static 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 458static 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 493static 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 506static 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 533static 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 566static 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 615static 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 642static 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 666static 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 677static 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 688void 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 720void 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 736void 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 757void ReqGetPdpContextList(const ReqDataInfo *requestInfo) 758{ 759 InquirePdpContextList(DEFAULT_CID, requestInfo); 760} 761 762static void PdpContextListCallback(uint8_t *param) 763{ 764 InquirePdpContextList(DEFAULT_CID, NULL); 765} 766 767void PdpContextListUpdate(void) 768{ 769 struct timeval tv = {0, CALLBACK_DELAY_MS * DELAY_US_OFFSET}; 770 OnTimerCallback(PdpContextListCallback, NULL, &tv); 771} 772 773static 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 818void 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 844void 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 860static 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 900void 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 943void 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 952void 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 960void 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