1 /* 2 * Copyright (C) 2025 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <memory> 20 #include <string> 21 #include <source_location> 22 #include <string_view> 23 #include <variant> 24 25 #include <aidl/android/hardware/radio/RadioError.h> 26 #include <aidl/android/hardware/radio/modem/RadioState.h> 27 #include <aidl/android/hardware/radio/network/CellConnectionStatus.h> 28 #include <aidl/android/hardware/radio/network/CdmaRoamingType.h> 29 #include <aidl/android/hardware/radio/network/RegState.h> 30 #include <aidl/android/hardware/radio/network/SignalStrength.h> 31 #include <aidl/android/hardware/radio/RadioTechnology.h> 32 #include <aidl/android/hardware/radio/sim/CdmaSubscriptionSource.h> 33 #include <aidl/android/hardware/radio/voice/Call.h> 34 #include <aidl/android/hardware/radio/voice/CallForwardInfo.h> 35 #include <aidl/android/hardware/radio/voice/ClipStatus.h> 36 37 #include "ratUtils.h" 38 39 namespace aidl { 40 namespace android { 41 namespace hardware { 42 namespace radio { 43 namespace implementation { 44 45 struct AtResponse; 46 using AtResponsePtr = std::shared_ptr<const AtResponse>; 47 48 struct AtResponse { 49 using ParseResult = std::pair<int, AtResponsePtr>; 50 51 struct OK {}; 52 struct ERROR {}; 53 struct RING {}; 54 struct SmsPrompt {}; 55 56 struct CmeError { idAtResponse::CmeError57 static constexpr std::string_view id() { 58 using namespace std::literals; 59 return "CME ERROR"sv; 60 } 61 static AtResponsePtr parse(std::string_view str); 62 63 RadioError getErrorAndLog(const char* klass, 64 const char* func, int line) const; 65 66 RadioError error; 67 }; 68 69 struct CmsError { idAtResponse::CmsError70 static constexpr std::string_view id() { 71 using namespace std::literals; 72 return "CMS ERROR"sv; 73 } 74 static AtResponsePtr parse(std::string_view str); 75 76 std::string message; 77 }; 78 79 struct ParseError { 80 std::string_view cmd; 81 }; 82 83 struct CPIN { 84 enum class State { 85 ABSENT, NOT_READY, READY, PIN, PUK 86 }; 87 idAtResponse::CPIN88 static constexpr std::string_view id() { 89 using namespace std::literals; 90 return "CPIN"sv; 91 } 92 static AtResponsePtr parse(std::string_view str); 93 94 State state; 95 }; 96 97 struct CPINR { idAtResponse::CPINR98 static constexpr std::string_view id() { 99 using namespace std::literals; 100 return "CPINR"sv; 101 } 102 static AtResponsePtr parse(std::string_view str); 103 104 int remainingRetryTimes = -1; 105 int maxRetryTimes = -1; 106 }; 107 108 struct CRSM { idAtResponse::CRSM109 static constexpr std::string_view id() { 110 using namespace std::literals; 111 return "CRSM"sv; 112 } 113 static AtResponsePtr parse(std::string_view str); 114 115 std::string response; 116 int sw1 = -1; 117 int sw2 = -1; 118 }; 119 120 struct CFUN { idAtResponse::CFUN121 static constexpr std::string_view id() { 122 using namespace std::literals; 123 return "CFUN"sv; 124 } 125 static AtResponsePtr parse(std::string_view str); 126 127 modem::RadioState state; 128 }; 129 130 struct CIMI { idAtResponse::CIMI131 static constexpr std::string_view id() { 132 using namespace std::literals; 133 return "CIMI"sv; 134 } 135 }; 136 137 struct CREG { idAtResponse::CREG138 static constexpr std::string_view id() { 139 using namespace std::literals; 140 return "CREG"sv; 141 } 142 static AtResponsePtr parse(std::string_view str); 143 144 int areaCode = -1; 145 int cellId = -1; 146 int networkType = -1; 147 network::RegState state = network::RegState::NOT_REG_MT_NOT_SEARCHING_OP; 148 }; 149 150 struct CGREG { idAtResponse::CGREG151 static constexpr std::string_view id() { 152 using namespace std::literals; 153 return "CGREG"sv; 154 } 155 static AtResponsePtr parse(std::string_view str); 156 157 int areaCode = -1; 158 int cellId = -1; 159 int networkType = -1; 160 network::RegState state = network::RegState::NOT_REG_MT_NOT_SEARCHING_OP; 161 }; 162 163 struct CEREG { idAtResponse::CEREG164 static constexpr std::string_view id() { 165 using namespace std::literals; 166 return "CEREG"sv; 167 } 168 static AtResponsePtr parse(std::string_view str); 169 170 int areaCode = -1; 171 int cellId = -1; 172 int networkType = -1; 173 network::RegState state = network::RegState::NOT_REG_MT_NOT_SEARCHING_OP; 174 }; 175 176 struct CTEC { idAtResponse::CTEC177 static constexpr std::string_view id() { 178 using namespace std::literals; 179 return "CTEC"sv; 180 } 181 static AtResponsePtr parse(std::string_view str); 182 183 std::optional<ratUtils::ModemTechnology> getCurrentModemTechnology() const; 184 bool isDONE() const; 185 186 std::vector<std::string> values; 187 }; 188 189 struct COPS { 190 enum class NetworkSelectionMode { 191 AUTOMATIC, MANUAL, DEREGISTER, SET_FORMAT, MANUAL_AUTOMATIC 192 }; 193 idAtResponse::COPS194 static constexpr std::string_view id() { 195 using namespace std::literals; 196 return "COPS"sv; 197 } 198 static AtResponsePtr parse(std::string_view str); 199 200 struct OperatorInfo { 201 enum class State { 202 UNKNOWN, AVAILABLE, CURRENT, FORBIDDEN 203 }; 204 isCurrentAtResponse::COPS::OperatorInfo205 bool isCurrent() const { 206 return state == State::CURRENT; 207 } 208 mccAtResponse::COPS::OperatorInfo209 std::string mcc() const { 210 return numeric.substr(0, 3); 211 } 212 mncAtResponse::COPS::OperatorInfo213 std::string mnc() const { 214 return numeric.substr(3); 215 } 216 217 State state = State::UNKNOWN; 218 std::string longName; 219 std::string shortName; 220 std::string numeric; 221 }; 222 223 std::vector<OperatorInfo> operators; 224 std::string numeric; 225 NetworkSelectionMode networkSelectionMode = NetworkSelectionMode::AUTOMATIC; 226 }; 227 228 struct WRMP { idAtResponse::WRMP229 static constexpr std::string_view id() { 230 using namespace std::literals; 231 return "WRMP"sv; 232 } 233 static AtResponsePtr parse(std::string_view str); 234 235 network::CdmaRoamingType cdmaRoamingPreference; 236 }; 237 238 struct CCSS { idAtResponse::CCSS239 static constexpr std::string_view id() { 240 using namespace std::literals; 241 return "CCSS"sv; 242 } 243 static AtResponsePtr parse(std::string_view str); 244 245 sim::CdmaSubscriptionSource source; 246 }; 247 248 struct CSQ { 249 static constexpr int32_t kUnknown = INT32_MAX; 250 idAtResponse::CSQ251 static constexpr std::string_view id() { 252 using namespace std::literals; 253 return "CSQ"sv; 254 } 255 static AtResponsePtr parse(std::string_view str); 256 257 network::SignalStrength toSignalStrength() const; 258 259 int32_t gsm_signalStrength = kUnknown; 260 int32_t gsm_bitErrorRate = kUnknown; 261 int32_t gsm_timingAdvance = kUnknown; 262 int32_t cdma_dbm = kUnknown; 263 int32_t cdma_ecio = kUnknown; 264 int32_t evdo_dbm = kUnknown; 265 int32_t evdo_ecio = kUnknown; 266 int32_t evdo_signalNoiseRatio = kUnknown; 267 int32_t lte_signalStrength = kUnknown; 268 int32_t lte_rsrp = kUnknown; 269 int32_t lte_rsrq = kUnknown; 270 int32_t lte_rssnr = kUnknown; 271 int32_t lte_cqi = kUnknown; 272 int32_t lte_timingAdvance = kUnknown; 273 int32_t lte_cqiTableIndex = kUnknown; 274 int32_t tdscdma_signalStrength = kUnknown; 275 int32_t tdscdma_bitErrorRate = kUnknown; 276 int32_t tdscdma_rscp = kUnknown; 277 int32_t wcdma_signalStrength = kUnknown; 278 int32_t wcdma_bitErrorRate = kUnknown; 279 int32_t wcdma_rscp = kUnknown; 280 int32_t wcdma_ecno = kUnknown; 281 int32_t nr_ssRsrp = kUnknown; 282 int32_t nr_ssRsrq = kUnknown; 283 int32_t nr_ssSinr = kUnknown; 284 int32_t nr_csiRsrp = kUnknown; 285 int32_t nr_csiRsrq = kUnknown; 286 int32_t nr_csiSinr = kUnknown; 287 int32_t nr_csiCqiTableIndex = kUnknown; 288 int32_t nr_timingAdvance = kUnknown; 289 }; 290 291 struct CLCC { idAtResponse::CLCC292 static constexpr std::string_view id() { 293 using namespace std::literals; 294 return "CLCC"sv; 295 } 296 static AtResponsePtr parse(std::string_view str); 297 298 std::vector<voice::Call> calls; 299 }; 300 301 struct CCFCU { idAtResponse::CCFCU302 static constexpr std::string_view id() { 303 using namespace std::literals; 304 return "CCFCU"sv; 305 } 306 static AtResponsePtr parse(std::string_view str); 307 308 std::vector<voice::CallForwardInfo> callForwardInfos; 309 }; 310 311 struct CCWA { idAtResponse::CCWA312 static constexpr std::string_view id() { 313 using namespace std::literals; 314 return "CCWA"sv; 315 } 316 static AtResponsePtr parse(std::string_view str); 317 318 int serviceClass = -1; 319 bool enable = false; 320 }; 321 322 struct CGDCONT { 323 struct PdpContext { 324 std::string type; 325 std::string apn; 326 std::string addr; 327 int index = -1; 328 int dComp = 0; 329 int hComp = 0; 330 }; 331 idAtResponse::CGDCONT332 static constexpr std::string_view id() { 333 using namespace std::literals; 334 return "CGDCONT"sv; 335 } 336 static AtResponsePtr parse(std::string_view str); 337 338 std::vector<PdpContext> contexts; 339 }; 340 341 struct CGCONTRDP { idAtResponse::CGCONTRDP342 static constexpr std::string_view id() { 343 using namespace std::literals; 344 return "CGCONTRDP"sv; 345 } 346 static AtResponsePtr parse(std::string_view str); 347 348 std::string apn; 349 std::string localAddr; 350 std::string gwAddr; 351 std::string dns1; 352 std::string dns2; 353 int cid = -1; 354 int bearer = -1; 355 int localAddrSize = 0; 356 }; 357 358 struct CGFPCCFG { idAtResponse::CGFPCCFG359 static constexpr std::string_view id() { 360 using namespace std::literals; 361 return "CGFPCCFG"sv; 362 } 363 static AtResponsePtr parse(std::string_view str); 364 365 network::CellConnectionStatus status; 366 ratUtils::ModemTechnology mtech; 367 int contextId = -1; 368 int bandwidth = -1; 369 int freq = -1; 370 }; 371 372 struct CUSATD { idAtResponse::CUSATD373 static constexpr std::string_view id() { 374 using namespace std::literals; 375 return "CUSATD"sv; 376 } 377 static AtResponsePtr parse(std::string_view str); 378 379 int a = 0; 380 int b = 0; 381 }; 382 383 struct CUSATP { idAtResponse::CUSATP384 static constexpr std::string_view id() { 385 using namespace std::literals; 386 return "CUSATP"sv; 387 } 388 static AtResponsePtr parse(std::string_view str); 389 390 std::string cmd; 391 }; 392 393 struct CUSATE { idAtResponse::CUSATE394 static constexpr std::string_view id() { 395 using namespace std::literals; 396 return "CUSATE"sv; 397 } 398 static AtResponsePtr parse(std::string_view str); 399 400 std::string response; 401 }; 402 403 struct CUSATT { idAtResponse::CUSATT404 static constexpr std::string_view id() { 405 using namespace std::literals; 406 return "CUSATT"sv; 407 } 408 static AtResponsePtr parse(std::string_view str); 409 410 int value = 0; 411 }; 412 413 struct CUSATEND { idAtResponse::CUSATEND414 static constexpr std::string_view id() { 415 using namespace std::literals; 416 return "CUSATEND"sv; 417 } 418 static AtResponsePtr parse(std::string_view str); 419 }; 420 421 struct CLCK { idAtResponse::CLCK422 static constexpr std::string_view id() { 423 using namespace std::literals; 424 return "CLCK"sv; 425 } 426 static AtResponsePtr parse(std::string_view str); 427 428 bool locked = false; 429 }; 430 431 struct CSIM { idAtResponse::CSIM432 static constexpr std::string_view id() { 433 using namespace std::literals; 434 return "CSIM"sv; 435 } 436 static AtResponsePtr parse(std::string_view str); 437 438 std::string response; 439 }; 440 441 struct CGLA { idAtResponse::CGLA442 static constexpr std::string_view id() { 443 using namespace std::literals; 444 return "CGLA"sv; 445 } 446 static AtResponsePtr parse(std::string_view str); 447 448 std::string response; 449 }; 450 451 struct CCHC { idAtResponse::CCHC452 static constexpr std::string_view id() { 453 using namespace std::literals; 454 return "CCHC"sv; 455 } 456 static AtResponsePtr parse(std::string_view str); 457 }; 458 459 struct CLIP { idAtResponse::CLIP460 static constexpr std::string_view id() { 461 using namespace std::literals; 462 return "CLIP"sv; 463 } 464 static AtResponsePtr parse(std::string_view str); 465 466 bool enable = false; 467 voice::ClipStatus status = voice::ClipStatus::UNKNOWN; 468 }; 469 470 struct CLIR { idAtResponse::CLIR471 static constexpr std::string_view id() { 472 using namespace std::literals; 473 return "CLIR"sv; 474 } 475 static AtResponsePtr parse(std::string_view str); 476 477 int n = -1; 478 int m = -1; 479 }; 480 481 struct CMUT { idAtResponse::CMUT482 static constexpr std::string_view id() { 483 using namespace std::literals; 484 return "CMUT"sv; 485 } 486 static AtResponsePtr parse(std::string_view str); 487 488 bool on = false; 489 }; 490 491 struct WSOS { idAtResponse::WSOS492 static constexpr std::string_view id() { 493 using namespace std::literals; 494 return "WSOS"sv; 495 } 496 static AtResponsePtr parse(std::string_view str); 497 498 bool isEmergencyMode = false; 499 }; 500 501 struct CSCA { idAtResponse::CSCA502 static constexpr std::string_view id() { 503 using namespace std::literals; 504 return "CSCA"sv; 505 } 506 static AtResponsePtr parse(std::string_view str); 507 508 std::string sca; 509 int tosca = -1; 510 }; 511 512 struct CSCB { 513 struct Association { 514 int from; 515 int to; 516 }; 517 idAtResponse::CSCB518 static constexpr std::string_view id() { 519 using namespace std::literals; 520 return "CSCB"sv; 521 } 522 static AtResponsePtr parse(std::string_view str); 523 524 static std::optional<std::vector<Association>> parseIds(std::string_view str); 525 526 std::vector<Association> serviceId; 527 std::vector<Association> codeScheme; 528 int mode = -1; 529 }; 530 531 struct CMGS { idAtResponse::CMGS532 static constexpr std::string_view id() { 533 using namespace std::literals; 534 return "CMGS"sv; 535 } 536 static AtResponsePtr parse(std::string_view str); 537 538 int messageRef = -1; 539 }; 540 541 struct CMGW { idAtResponse::CMGW542 static constexpr std::string_view id() { 543 using namespace std::literals; 544 return "CMGW"sv; 545 } 546 static AtResponsePtr parse(std::string_view str); 547 548 int messageRef = -1; 549 }; 550 551 struct CMT { idAtResponse::CMT552 static constexpr std::string_view id() { 553 using namespace std::literals; 554 return "CMT"sv; 555 } 556 static std::pair<int, AtResponsePtr> parse(std::string_view str); 557 558 std::vector<uint8_t> pdu; 559 int something = -1; 560 }; 561 562 struct CDS { idAtResponse::CDS563 static constexpr std::string_view id() { 564 using namespace std::literals; 565 return "CDS"sv; 566 } 567 static std::pair<int, AtResponsePtr> parse(std::string_view str); 568 569 std::vector<uint8_t> pdu; 570 int pduSize = -1; 571 }; 572 573 struct MBAU { idAtResponse::MBAU574 static constexpr std::string_view id() { 575 using namespace std::literals; 576 return "MBAU"sv; 577 } 578 static AtResponsePtr parse(std::string_view str); 579 580 std::vector<uint8_t> kc; 581 std::vector<uint8_t> sres; 582 std::vector<uint8_t> ck; 583 std::vector<uint8_t> ik; 584 std::vector<uint8_t> resAuts; 585 int status; 586 }; 587 588 struct CTZV { idAtResponse::CTZV589 static constexpr std::string_view id() { 590 using namespace std::literals; 591 return "CTZV"sv; 592 } 593 static AtResponsePtr parse(std::string_view str); 594 595 std::string nitzString() const; 596 597 std::string tzName; 598 uint16_t year = 0; 599 uint8_t month = 0; 600 uint8_t day = 0; 601 uint8_t hour : 7 = 0; 602 uint8_t isDaylightSaving : 1 = 0; 603 uint8_t minute = 0; 604 uint8_t second = 0; 605 int8_t tzOffset15m = 0; 606 }; 607 608 static ParseResult parse(std::string_view str); 609 makeAtResponse610 template <class T> static AtResponsePtr make(T v) { 611 const auto r = std::make_shared<AtResponse>(std::move(v)); 612 const auto w = r->what(); 613 return r; 614 } 615 makeParseErrorForAtResponse616 template <class T> static AtResponsePtr makeParseErrorFor() { 617 ParseError parseError = { 618 .cmd = T::id(), 619 }; 620 621 return make(std::move(parseError)); 622 } 623 isOKAtResponse624 bool isOK() const { 625 return std::holds_alternative<OK>(value); 626 } 627 isERRORAtResponse628 bool isERROR() const { 629 return std::holds_alternative<ERROR>(value); 630 } 631 isParseErrorAtResponse632 bool isParseError() const { 633 return std::holds_alternative<ParseError>(value); 634 } 635 holdsAtResponse636 template <class T> bool holds() const { 637 if (std::holds_alternative<T>(value)) { 638 return true; 639 } else if (const ParseError* e = std::get_if<ParseError>(&value)) { 640 return e->cmd.compare(T::id()) == 0; 641 } else { 642 return false; 643 } 644 } 645 646 template <> bool holds<OK>() const { 647 return std::holds_alternative<OK>(value); 648 } 649 650 template <> bool holds<SmsPrompt>() const { 651 return std::holds_alternative<SmsPrompt>(value); 652 } 653 654 template <> bool holds<std::string>() const { 655 return std::holds_alternative<std::string>(value); 656 } 657 get_ifAtResponse658 template <class T> const T* get_if() const { 659 return std::get_if<T>(&value); 660 } 661 662 std::string_view what() const; 663 visitAtResponse664 template <class F> void visit(const F& f) const { 665 std::visit(f, value); 666 } 667 visitRAtResponse668 template <class R, class F> R visitR(const F& f) const { 669 return std::visit(f, value); 670 } 671 672 [[noreturn]] void unexpected( 673 const char* klass, const char* request, 674 std::source_location location = std::source_location::current()) const; 675 AtResponseAtResponse676 template <class T> AtResponse(T v) : value(std::move(v)) {} 677 678 private: 679 using Value = std::variant<OK, ParseError, 680 ERROR, RING, SmsPrompt, CmeError, CmsError, 681 CPIN, CPINR, CRSM, CFUN, 682 CREG, CEREG, CGREG, 683 CTEC, COPS, WRMP, CCSS, CSQ, 684 CLCC, CCFCU, CCWA, 685 CGDCONT, CGCONTRDP, CGFPCCFG, 686 CUSATD, CUSATP, CUSATE, CUSATT, CUSATEND, 687 CLCK, CSIM, CGLA, CCHC, 688 CLIP, CLIR, CMUT, WSOS, 689 CSCA, CSCB, CMGS, CMGW, CMT, CDS, 690 MBAU, 691 CTZV, 692 std::string 693 >; 694 Value value; 695 }; 696 697 } // namespace implementation 698 } // namespace radio 699 } // namespace hardware 700 } // namespace android 701 } // namespace aidl 702