• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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