1 //
2 // Copyright (C) 2020 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 #pragma once
17 
18 #include <tinyxml2.h>
19 
20 #include "host/commands/modem_simulator/modem_service.h"
21 
22 namespace cuttlefish {
23 
24 using namespace tinyxml2;
25 
26 class NetworkService;
27 
28 class SimService : public ModemService, public std::enable_shared_from_this<SimService> {
29  public:
30   SimService(int32_t service_id, ChannelMonitor* channel_monitor,
31              ThreadLooper* thread_looper);
32   ~SimService() = default;
33 
34   SimService(const SimService &) = delete;
35   SimService &operator=(const SimService &) = delete;
36 
37   void SetupDependency(NetworkService* net);
38 
39   void HandleSIMStatusReq(const Client& client);
40   void HandleChangeOrEnterPIN(const Client& client, const std::string& command);
41   void HandleSIM_IO(const Client& client, const std::string& command);
42   void HandleGetIMSI(const Client& client);
43   void HandleGetIccId(const Client& client);
44   void HandleFacilityLock(const Client& client, const std::string& command);
45   void HandleOpenLogicalChannel(const Client& client,
46                                 const std::string& command);
47   void HandleCloseLogicalChannel(const Client& client,
48                                  const std::string& command);
49   void HandleTransmitLogicalChannel(const Client& client,
50                                     const std::string& command);
51   void HandleChangePassword(const Client& client, const std::string& command);
52   void HandleQueryRemainTimes(const Client& client, const std::string& command);
53   void HandleCdmaSubscriptionSource(const Client& client,
54                                     const std::string& command);
55   void HandleCdmaRoamingPreference(const Client& client,
56                                    const std::string& command);
57 
58   void SavePinStateToIccProfile();
59   void SaveFacilityLockToIccProfile();
60   bool IsFDNEnabled();
61   bool IsFixedDialNumber(std::string_view number);
62   XMLElement* GetIccProfile();
63   std::string GetPhoneNumber();
64 
65   enum SimStatus {
66     SIM_STATUS_ABSENT = 0,
67     SIM_STATUS_NOT_READY,
68     SIM_STATUS_READY,
69     SIM_STATUS_PIN,
70     SIM_STATUS_PUK,
71   };
72 
73   SimStatus GetSimStatus() const;
74   std::string GetSimOperator();
75 
76  private:
77   void InitializeServiceState();
78   std::vector<CommandHandler> InitializeCommandHandlers();
79   void InitializeSimFileSystemAndSimState();
80   void InitializeFacilityLock();
81   void OnSimStatusChanged();
82 
83   NetworkService* network_service_;
84 
85   /* SimStatus */
86   SimStatus sim_status_;
87 
88   /* SimFileSystem */
89   struct SimFileSystem {
90     enum EFId: int32_t {
91       EF_ADN = 0x6F3A,
92       EF_FDN = 0x6F3B,
93       EF_GID1 = 0x6F3E,
94       EF_GID2 = 0x6F3F,
95       EF_SDN = 0x6F49,
96       EF_EXT1 = 0x6F4A,
97       EF_EXT2 = 0x6F4B,
98       EF_EXT3 = 0x6F4C,
99       EF_EXT5 = 0x6F4E,
100       EF_EXT6 = 0x6FC8,   // Ext record for EF[MBDN]
101       EF_MWIS = 0x6FCA,
102       EF_MBDN = 0x6FC7,
103       EF_PNN = 0x6FC5,
104       EF_OPL = 0x6FC6,
105       EF_SPN = 0x6F46,
106       EF_SMS = 0x6F3C,
107       EF_ICCID = 0x2FE2,
108       EF_AD = 0x6FAD,
109       EF_MBI = 0x6FC9,
110       EF_MSISDN = 0x6F40,
111       EF_SPDI = 0x6FCD,
112       EF_SST = 0x6F38,
113       EF_CFIS = 0x6FCB,
114       EF_IMG = 0x4F20,
115 
116       // USIM SIM file ids from TS 131.102
117       EF_PBR = 0x4F30,
118       EF_LI = 0x6F05,
119 
120       // GSM SIM file ids from CPHS (phase 2, version 4.2) CPHS4_2.WW6
121       EF_MAILBOX_CPHS = 0x6F17,
122       EF_VOICE_MAIL_INDICATOR_CPHS = 0x6F11,
123       EF_CFF_CPHS = 0x6F13,
124       EF_SPN_CPHS = 0x6F14,
125       EF_SPN_SHORT_CPHS = 0x6F18,
126       EF_INFO_CPHS = 0x6F16,
127       EF_CSP_CPHS = 0x6F15,
128 
129       // CDMA RUIM file ids from 3GPP2 C.S0023-0
130       EF_CST = 0x6F32,
131       EF_RUIM_SPN =0x6F41,
132 
133       // ETSI TS.102.221
134       EF_PL = 0x2F05,
135       // 3GPP2 C.S0065
136       EF_CSIM_LI = 0x6F3A,
137       EF_CSIM_SPN =0x6F41,
138       EF_CSIM_MDN = 0x6F44,
139       EF_CSIM_IMSIM = 0x6F22,
140       EF_CSIM_CDMAHOME = 0x6F28,
141       EF_CSIM_EPRL = 0x6F5A,
142       EF_CSIM_MIPUPP = 0x6F4D,
143 
144       //ISIM access
145       EF_IMPU = 0x6F04,
146       EF_IMPI = 0x6F02,
147       EF_DOMAIN = 0x6F03,
148       EF_IST = 0x6F07,
149       EF_PCSCF = 0x6F09,
150       EF_PSI = 0x6FE5,
151 
152       //PLMN Selection Information w/ Access Technology TS 131.102
153       EF_PLMN_W_ACT = 0x6F60,
154       EF_OPLMN_W_ACT = 0x6F61,
155       EF_HPLMN_W_ACT = 0x6F62,
156 
157       //Equivalent Home and Forbidden PLMN Lists TS 131.102
158       EF_EHPLMN = 0x6FD9,
159       EF_FPLMN = 0x6F7B,
160 
161       // Last Roaming Selection Indicator
162       EF_LRPLMNSI = 0x6FDC,
163 
164       //Search interval for higher priority PLMNs
165       EF_HPPLMN = 0x6F31,
166     };
167 
168     XMLElement* GetRootElement();
169 
170     static std::string GetCommonIccEFPath(EFId efid);
171     static std::string GetUsimEFPath(EFId efid);
172 
173     static XMLElement *FindAttribute(XMLElement* parent,
174                                      const std::string& attr_name,
175                                      const std::string& attr_value);
176 
177     XMLElement* AppendNewElement(XMLElement* parent, const char* name);
178     XMLElement* AppendNewElementWithText(XMLElement* parent, const char* name,
179                                          const char* text);
180 
181     XMLDocument doc;
182     std::string file_path;
183   };
184   SimFileSystem sim_file_system_;
185 
186 
187   /* PinStatus */
188   struct PinStatus {
189     enum ChangeMode {WITH_PIN, WITH_PUK};
190 
191     std::string pin_;
192     std::string puk_;
193     int pin_remaining_times_;
194     int puk_remaining_times_;
195 
196     bool CheckPasswordValid(std::string_view password);
197 
198     bool VerifyPIN(const std::string_view pin);
199     bool VerifyPUK(const std::string_view puk);
200     bool ChangePIN(ChangeMode mode, const std::string_view pin_or_puk,
201                    const std::string_view new_pin);
202     bool ChangePUK(const std::string_view puk, const std::string_view new_puk);
203   };
204   PinStatus pin1_status_;
205   PinStatus pin2_status_;
206 
207   bool checkPin1AndAdjustSimStatus(std::string_view password);
208   bool ChangePin1AndAdjustSimStatus(PinStatus::ChangeMode mode,
209                                     std::string_view pin,
210                                     std::string_view new_pin);
211 
212   /*  FacilityLock */
213   struct FacilityLock {
214     enum LockType {
215       AO = 1,  // Barr all outgoing calls
216       OI = 2,  // Barr all outgoing international calls
217       OX = 3,  // Barr all outgoing international calls, except to Home Country
218       AI = 4,  // Barr all incoming calls
219       IR = 5,  // Barr all call, when roaming outside Home Country
220       AB = 6,  // All barring services
221       AG = 7,  // All outgoing barring services
222       AC = 8,  // All incoming barring services
223       SC = 9,  // PIN enable/disable
224       FD = 10,  // SIM fixed FDN dialing lock, PIN2 is required as a password
225     };
226 
227     enum Mode {
228       UNLOCK = 0,
229       LOCK = 1,
230       QUERY = 2,
231     };
232 
233     enum Class : int32_t {
234       DEFAULT = 7,      // all classes
235       VOICE = 1 << 0,   // telephony
236       DATA = 1 << 1,    // to all bear service
237       FAX = 1 << 2,     // facsimile services
238       SMS = 1 << 3,     // short message services
239     };
240 
241     enum LockStatus {
242       DISABLE,
243       ENABLE,
244     };
245 
246     LockStatus lock_status;  // Ignore class
247 
FacilityLockFacilityLock248     FacilityLock(LockStatus status) : lock_status(status) {}
249   };
250   std::map<std::string, FacilityLock> facility_lock_;
251 
252   /* LogicalChannel */
253   struct LogicalChannel {
254     std::string df_name;
255     bool is_open;
256     int session_id;
257 
LogicalChannelLogicalChannel258     LogicalChannel(int session_id) :
259       df_name(""), is_open(false), session_id(session_id) {};
260   };
261   std::vector<LogicalChannel> logical_channels_;
262 
263   int cdma_subscription_source_;
264   int cdma_roaming_preference_;
265 };
266 
267 }  // namespace cuttlefish
268