• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* //device/system/reference-ril/reference-ril.c
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #include <telephony/ril_cdma_sms.h>
19 #include <telephony/librilutils.h>
20 #include <stdio.h>
21 #include <assert.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <sys/cdefs.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <inttypes.h>
29 #include <fcntl.h>
30 #include <pthread.h>
31 #include <alloca.h>
32 #include "atchannel.h"
33 #include "at_tok.h"
34 #include "base64util.h"
35 #include "misc.h"
36 #include <getopt.h>
37 #include <sys/socket.h>
38 #include <cutils/properties.h>
39 #include <cutils/sockets.h>
40 #include <termios.h>
41 #include <sys/wait.h>
42 #include <stdbool.h>
43 #include <net/if.h>
44 #include <netinet/in.h>
45 #include <linux/vm_sockets.h>
46 #include <arpa/inet.h>
47 
48 #include "guest/hals/ril/reference-libril/ril.h"
49 #define LOG_TAG "RIL"
50 #include <utils/Log.h>
51 
noopRemoveWarning(void * a)52 static void *noopRemoveWarning( void *a ) { return a; }
53 #define RIL_UNUSED_PARM(a) noopRemoveWarning((void *)&(a));
54 
55 #define MAX_AT_RESPONSE 0x1000
56 
57 #define MAX_PDP         3
58 
59 /* pathname returned from RIL_REQUEST_SETUP_DATA_CALL / RIL_REQUEST_SETUP_DEFAULT_PDP */
60 // This is used if Wifi is not supported, plain old eth0
61 #ifdef CUTTLEFISH_ENABLE
62 #define PPP_TTY_PATH_ETH0 "rmnet0"
63 #else
64 #define PPP_TTY_PATH_ETH0 "eth0"
65 #endif
66 // This is used for emulator
67 #define EMULATOR_RADIO_INTERFACE "eth0"
68 
69 // for sim
70 #define AUTH_CONTEXT_EAP_SIM                    128
71 #define AUTH_CONTEXT_EAP_AKA                    129
72 #define SIM_AUTH_RESPONSE_SUCCESS               0
73 #define SIM_AUTH_RESPONSE_SYNC_FAILURE          3
74 
75 // Default MTU value
76 #define DEFAULT_MTU 1500
77 
78 #ifdef USE_TI_COMMANDS
79 
80 // Enable a workaround
81 // 1) Make incoming call, do not answer
82 // 2) Hangup remote end
83 // Expected: call should disappear from CLCC line
84 // Actual: Call shows as "ACTIVE" before disappearing
85 #define WORKAROUND_ERRONEOUS_ANSWER 1
86 
87 // Some variants of the TI stack do not support the +CGEV unsolicited
88 // response. However, they seem to send an unsolicited +CME ERROR: 150
89 #define WORKAROUND_FAKE_CGEV 1
90 #endif
91 
92 /* Modem Technology bits */
93 #define MDM_GSM         0x01
94 #define MDM_WCDMA       0x02
95 #define MDM_CDMA        0x04
96 #define MDM_EVDO        0x08
97 #define MDM_TDSCDMA     0x10
98 #define MDM_LTE         0x20
99 #define MDM_NR          0x40
100 
101 typedef struct {
102     int supportedTechs; // Bitmask of supported Modem Technology bits
103     int currentTech;    // Technology the modem is currently using (in the format used by modem)
104     int isMultimode;
105 
106     // Preferred mode bitmask. This is actually 4 byte-sized bitmasks with different priority values,
107     // in which the byte number from LSB to MSB give the priority.
108     //
109     //          |MSB|   |   |LSB
110     // value:   |00 |00 |00 |00
111     // byte #:  |3  |2  |1  |0
112     //
113     // Higher byte order give higher priority. Thus, a value of 0x0000000f represents
114     // a preferred mode of GSM, WCDMA, CDMA, and EvDo in which all are equally preferrable, whereas
115     // 0x00000201 represents a mode with GSM and WCDMA, in which WCDMA is preferred over GSM
116     int32_t preferredNetworkMode;
117     int subscription_source;
118 
119 } ModemInfo;
120 
121 static ModemInfo *sMdmInfo;
122 // TECH returns the current technology in the format used by the modem.
123 // It can be used as an l-value
124 #define TECH(mdminfo)                 ((mdminfo)->currentTech)
125 // TECH_BIT returns the bitmask equivalent of the current tech
126 #define TECH_BIT(mdminfo)            (1 << ((mdminfo)->currentTech))
127 #define IS_MULTIMODE(mdminfo)         ((mdminfo)->isMultimode)
128 #define TECH_SUPPORTED(mdminfo, tech) ((mdminfo)->supportedTechs & (tech))
129 #define PREFERRED_NETWORK(mdminfo)    ((mdminfo)->preferredNetworkMode)
130 // CDMA Subscription Source
131 #define SSOURCE(mdminfo)              ((mdminfo)->subscription_source)
132 
133 static int net2modem[] = {
134     MDM_GSM | MDM_WCDMA,                                 // 0  - GSM / WCDMA Pref
135     MDM_GSM,                                             // 1  - GSM only
136     MDM_WCDMA,                                           // 2  - WCDMA only
137     MDM_GSM | MDM_WCDMA,                                 // 3  - GSM / WCDMA Auto
138     MDM_CDMA | MDM_EVDO,                                 // 4  - CDMA / EvDo Auto
139     MDM_CDMA,                                            // 5  - CDMA only
140     MDM_EVDO,                                            // 6  - EvDo only
141     MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO,           // 7  - GSM/WCDMA, CDMA, EvDo
142     MDM_LTE | MDM_CDMA | MDM_EVDO,                       // 8  - LTE, CDMA and EvDo
143     MDM_LTE | MDM_GSM | MDM_WCDMA,                       // 9  - LTE, GSM/WCDMA
144     MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
145     MDM_LTE,                                             // 11 - LTE only
146     MDM_LTE | MDM_WCDMA,                                 // 12 - LTE and WCDMA
147     MDM_TDSCDMA,                                         // 13 - TD-SCDMA only
148     MDM_WCDMA | MDM_TDSCDMA,                             // 14 - TD-SCDMA and WCDMA
149     MDM_LTE | MDM_TDSCDMA,                               // 15 - LTE and TD-SCDMA
150     MDM_TDSCDMA | MDM_GSM,                               // 16 - TD-SCDMA and GSM
151     MDM_LTE | MDM_TDSCDMA | MDM_GSM,                     // 17 - TD-SCDMA, GSM and LTE
152     MDM_WCDMA | MDM_TDSCDMA | MDM_GSM,                   // 18 - TD-SCDMA, GSM and WCDMA
153     MDM_LTE | MDM_WCDMA | MDM_TDSCDMA,                   // 19 - LTE, TD-SCDMA and WCDMA
154     MDM_LTE | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM,         // 20 - LTE, TD-SCDMA, GSM, and WCDMA
155     MDM_EVDO | MDM_CDMA | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM,            // 21 - TD-SCDMA, CDMA, EVDO, GSM and WCDMA
156     MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM,  // 22 - LTE, TDCSDMA, CDMA, EVDO, GSM and WCDMA
157     MDM_NR,                                                             // 23 - NR 5G only mode
158     MDM_NR | MDM_LTE,                                                   // 24 - NR 5G, LTE
159     MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO,                             // 25 - NR 5G, LTE, CDMA and EvDo
160     MDM_NR | MDM_LTE | MDM_WCDMA | MDM_GSM,                             // 26 - NR 5G, LTE, GSM and WCDMA
161     MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM,       // 27 - NR 5G, LTE, CDMA, EvDo, GSM and WCDMA
162     MDM_NR | MDM_LTE | MDM_WCDMA,                                       // 28 - NR 5G, LTE and WCDMA
163     MDM_NR | MDM_LTE | MDM_TDSCDMA,                                     // 29 - NR 5G, LTE and TDSCDMA
164     MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_GSM,                           // 30 - NR 5G, LTE, TD-SCDMA and GSM
165     MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA,                         // 31 - NR 5G, LTE, TD-SCDMA, WCDMA
166     MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA | MDM_GSM,               // 32 - NR 5G, LTE, TD-SCDMA, GSM and WCDMA
167     MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM,  // 33 - NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA
168 };
169 
170 static int32_t net2pmask[] = {
171     MDM_GSM | (MDM_WCDMA << 8),                          // 0  - GSM / WCDMA Pref
172     MDM_GSM,                                             // 1  - GSM only
173     MDM_WCDMA,                                           // 2  - WCDMA only
174     MDM_GSM | MDM_WCDMA,                                 // 3  - GSM / WCDMA Auto
175     MDM_CDMA | MDM_EVDO,                                 // 4  - CDMA / EvDo Auto
176     MDM_CDMA,                                            // 5  - CDMA only
177     MDM_EVDO,                                            // 6  - EvDo only
178     MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO,           // 7  - GSM/WCDMA, CDMA, EvDo
179     MDM_LTE | MDM_CDMA | MDM_EVDO,                       // 8  - LTE, CDMA and EvDo
180     MDM_LTE | MDM_GSM | MDM_WCDMA,                       // 9  - LTE, GSM/WCDMA
181     MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
182     MDM_LTE,                                             // 11 - LTE only
183     MDM_LTE | MDM_WCDMA,                                 // 12 - LTE and WCDMA
184     MDM_TDSCDMA,                                         // 13 - TD-SCDMA only
185     MDM_WCDMA | MDM_TDSCDMA,                             // 14 - TD-SCDMA and WCDMA
186     MDM_LTE | MDM_TDSCDMA,                               // 15 - LTE and TD-SCDMA
187     MDM_TDSCDMA | MDM_GSM,                               // 16 - TD-SCDMA and GSM
188     MDM_LTE | MDM_TDSCDMA | MDM_GSM,                     // 17 - TD-SCDMA, GSM and LTE
189     MDM_WCDMA | MDM_TDSCDMA | MDM_GSM,                   // 18 - TD-SCDMA, GSM and WCDMA
190     MDM_LTE | MDM_WCDMA | MDM_TDSCDMA,                   // 19 - LTE, TD-SCDMA and WCDMA
191     MDM_LTE | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM,         // 20 - LTE, TD-SCDMA, GSM, and WCDMA
192     MDM_EVDO | MDM_CDMA | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM,            // 21 - TD-SCDMA, CDMA, EVDO, GSM and WCDMA
193     MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM,  // 22 - LTE, TDCSDMA, CDMA, EVDO, GSM and WCDMA
194     MDM_NR,                                                             // 23 - NR 5G only mode
195     MDM_NR | MDM_LTE,                                                   // 24 - NR 5G, LTE
196     MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO,                             // 25 - NR 5G, LTE, CDMA and EvDo
197     MDM_NR | MDM_LTE | MDM_WCDMA | MDM_GSM,                             // 26 - NR 5G, LTE, GSM and WCDMA
198     MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM,       // 27 - NR 5G, LTE, CDMA, EvDo, GSM and WCDMA
199     MDM_NR | MDM_LTE | MDM_WCDMA,                                       // 28 - NR 5G, LTE and WCDMA
200     MDM_NR | MDM_LTE | MDM_TDSCDMA,                                     // 29 - NR 5G, LTE and TDSCDMA
201     MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_GSM,                           // 30 - NR 5G, LTE, TD-SCDMA and GSM
202     MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA,                         // 31 - NR 5G, LTE, TD-SCDMA, WCDMA
203     MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA | MDM_GSM,               // 32 - NR 5G, LTE, TD-SCDMA, GSM and WCDMA
204     MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM,  // 33 - NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA
205 };
206 
207 #define GSM   (RAF_GSM | RAF_GPRS | RAF_EDGE)
208 #define CDMA  (RAF_IS95A | RAF_IS95B | RAF_1xRTT)
209 #define EVDO  (RAF_EVDO_0 | RAF_EVDO_A | RAF_EVDO_B | RAF_EHRPD)
210 #define WCDMA (RAF_HSUPA | RAF_HSDPA | RAF_HSPA | RAF_HSPAP | RAF_UMTS)
211 #define LTE   (RAF_LTE | RAF_LTE_CA)
212 #define NR    (RAF_NR)
213 
214 typedef struct {
215     int bitmap;
216     int type;
217 } NetworkTypeBitmap;
218 
219 static NetworkTypeBitmap s_networkMask[] = {
220     {WCDMA | GSM,                     MDM_GSM | (MDM_WCDMA << 8)},                // 0 - GSM / WCDMA Pref
221     {GSM,                             MDM_GSM},                                   // 1 - GSM only
222     {WCDMA,                           MDM_WCDMA},                                 // 2 - WCDMA only
223     {WCDMA | GSM,                     MDM_GSM | MDM_WCDMA},                       // 3 - GSM / WCDMA Auto
224     {CDMA | EVDO,                     MDM_CDMA | MDM_EVDO},                       // 4 - CDMA / EvDo Auto
225     {CDMA,                            MDM_CDMA},                                  // 5 - CDMA only
226     {EVDO,                            MDM_EVDO},                                  // 6 - EvDo only
227     {GSM | WCDMA | CDMA | EVDO,       MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO}, // 7 - GSM/WCDMA, CDMA, EvDo
228     {LTE | CDMA | EVDO,               MDM_LTE | MDM_CDMA | MDM_EVDO},             // 8 - LTE, CDMA and EvDo
229     {LTE | GSM | WCDMA,               MDM_LTE | MDM_GSM | MDM_WCDMA},             // 9 - LTE, GSM/WCDMA
230     {LTE | CDMA | EVDO | GSM | WCDMA, MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA}, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
231     {LTE,                             MDM_LTE},                                             // 11 - LTE only
232     {LTE | WCDMA,                     MDM_LTE | MDM_WCDMA},                                 // 12 - LTE and WCDMA
233     {RAF_TD_SCDMA,                    MDM_TDSCDMA},                                         // 13 - TD-SCDMA only
234     {RAF_TD_SCDMA | WCDMA,            MDM_WCDMA | MDM_TDSCDMA},                             // 14 - TD-SCDMA and WCDMA
235     {LTE | RAF_TD_SCDMA,              MDM_LTE | MDM_TDSCDMA},                               // 15 - LTE and TD-SCDMA
236     {RAF_TD_SCDMA | GSM,              MDM_TDSCDMA | MDM_GSM},                               // 16 - TD-SCDMA and GSM
237     {LTE | RAF_TD_SCDMA | GSM,        MDM_LTE | MDM_TDSCDMA | MDM_GSM},                     // 17 - TD-SCDMA, GSM and LTE
238     {RAF_TD_SCDMA | GSM | WCDMA,      MDM_WCDMA | MDM_TDSCDMA | MDM_GSM},                   // 18 - TD-SCDMA, GSM and WCDMA
239     {LTE | RAF_TD_SCDMA | WCDMA,      MDM_LTE | MDM_WCDMA | MDM_TDSCDMA},                   // 19 - LTE, TD-SCDMA and WCDMA
240     {LTE | RAF_TD_SCDMA | GSM | WCDMA,MDM_LTE | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM},         // 20 - LTE, TD-SCDMA, GSM, and WCDMA
241     {RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA,  MDM_EVDO | MDM_CDMA | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM},            // 21 - TD-SCDMA, CDMA, EVDO, GSM and WCDMA
242     {LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA, MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM},  // 22 - LTE, TDCSDMA, CDMA, EVDO, GSM and WCDMA
243     {NR,                              MDM_NR},                                                             // 23 - NR 5G only mode
244     {NR | LTE,                        MDM_NR | MDM_LTE},                                                   // 24 - NR 5G, LTE
245     {NR | LTE | CDMA | EVDO,          MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO},                             // 25 - NR 5G, LTE, CDMA and EvDo
246     {NR | LTE | GSM | WCDMA,          MDM_NR | MDM_LTE | MDM_WCDMA | MDM_GSM},                             // 26 - NR 5G, LTE, GSM and WCDMA
247     {NR | LTE | CDMA | EVDO | GSM | WCDMA, MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM},  // 27 - NR 5G, LTE, CDMA, EvDo, GSM and WCDMA
248     {NR | LTE | WCDMA,                MDM_NR | MDM_LTE | MDM_WCDMA},                                       // 28 - NR 5G, LTE and WCDMA
249     {NR | LTE | RAF_TD_SCDMA,         MDM_NR | MDM_LTE | MDM_TDSCDMA},                                     // 29 - NR 5G, LTE and TDSCDMA
250     {NR | LTE | RAF_TD_SCDMA | GSM,   MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_GSM},                           // 30 - NR 5G, LTE, TD-SCDMA and GSM
251     {NR | LTE | RAF_TD_SCDMA | WCDMA, MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA},                         // 31 - NR 5G, LTE, TD-SCDMA, WCDMA
252     {NR | LTE | RAF_TD_SCDMA | GSM | WCDMA, MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA | MDM_GSM},         // 32 - NR 5G, LTE, TD-SCDMA, GSM and WCDMA
253     {NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA, MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM},  // 33 - NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA
254 };
255 
is3gpp2(int radioTech)256 static int is3gpp2(int radioTech) {
257     switch (radioTech) {
258         case RADIO_TECH_IS95A:
259         case RADIO_TECH_IS95B:
260         case RADIO_TECH_1xRTT:
261         case RADIO_TECH_EVDO_0:
262         case RADIO_TECH_EVDO_A:
263         case RADIO_TECH_EVDO_B:
264         case RADIO_TECH_EHRPD:
265             return 1;
266         default:
267             return 0;
268     }
269 }
270 
271 typedef enum {
272     SIM_ABSENT = 0,
273     SIM_NOT_READY = 1,
274     SIM_READY = 2,
275     SIM_PIN = 3,
276     SIM_PUK = 4,
277     SIM_NETWORK_PERSONALIZATION = 5,
278     RUIM_ABSENT = 6,
279     RUIM_NOT_READY = 7,
280     RUIM_READY = 8,
281     RUIM_PIN = 9,
282     RUIM_PUK = 10,
283     RUIM_NETWORK_PERSONALIZATION = 11,
284     ISIM_ABSENT = 12,
285     ISIM_NOT_READY = 13,
286     ISIM_READY = 14,
287     ISIM_PIN = 15,
288     ISIM_PUK = 16,
289     ISIM_NETWORK_PERSONALIZATION = 17,
290 } SIM_Status;
291 
292 static void onRequest (int request, void *data, size_t datalen, RIL_Token t);
293 static RIL_RadioState currentState();
294 static int onSupports (int requestCode);
295 static void onCancel (RIL_Token t);
296 static const char *getVersion();
297 static int isRadioOn();
298 static SIM_Status getSIMStatus();
299 static int getCardStatus(RIL_CardStatus_v1_5 **pp_card_status);
300 static void freeCardStatus(RIL_CardStatus_v1_5 *p_card_status);
301 static void onDataCallListChanged(void *param);
302 bool areUiccApplicationsEnabled = true;
303 
304 extern const char * requestToString(int request);
305 extern uint8_t hexCharToInt(uint8_t c);
306 extern uint8_t * convertHexStringToBytes(void *response, size_t responseLen);
307 
308 /*** Static Variables ***/
309 static const RIL_RadioFunctions s_callbacks = {
310     RIL_VERSION,
311     onRequest,
312     currentState,
313     onSupports,
314     onCancel,
315     getVersion
316 };
317 
318 #ifdef RIL_SHLIB
319 static const struct RIL_Env *s_rilenv;
320 
321 #define RIL_onRequestComplete(t, e, response, responselen) s_rilenv->OnRequestComplete(t,e, response, responselen)
322 #define RIL_onUnsolicitedResponse(a,b,c) s_rilenv->OnUnsolicitedResponse(a,b,c)
323 #define RIL_requestTimedCallback(a,b,c) s_rilenv->RequestTimedCallback(a,b,c)
324 #endif
325 
326 static RIL_RadioState sState = RADIO_STATE_UNAVAILABLE;
327 static bool isNrDualConnectivityEnabled = true;
328 
329 static pthread_mutex_t s_state_mutex = PTHREAD_MUTEX_INITIALIZER;
330 static pthread_cond_t s_state_cond = PTHREAD_COND_INITIALIZER;
331 
332 static int s_port = -1;
333 static const char * s_device_path = NULL;
334 static int          s_device_socket = 0;
335 static uint32_t s_modem_simulator_port = -1;
336 
337 /* trigger change to this with s_state_cond */
338 static int s_closed = 0;
339 
340 static int sFD;     /* file desc of AT channel */
341 static char sATBuffer[MAX_AT_RESPONSE+1];
342 static char *sATBufferCur = NULL;
343 
344 static const struct timeval TIMEVAL_SIMPOLL = {1,0};
345 static const struct timeval TIMEVAL_CALLSTATEPOLL = {0,500000};
346 static const struct timeval TIMEVAL_0 = {0,0};
347 
348 static int s_ims_registered  = 0;        // 0==unregistered
349 static int s_ims_services    = 1;        // & 0x1 == sms over ims supported
350 static int s_ims_format    = 1;          // FORMAT_3GPP(1) vs FORMAT_3GPP2(2);
351 static int s_ims_cause_retry = 0;        // 1==causes sms over ims to temp fail
352 static int s_ims_cause_perm_failure = 0; // 1==causes sms over ims to permanent fail
353 static int s_ims_gsm_retry   = 0;        // 1==causes sms over gsm to temp fail
354 static int s_ims_gsm_fail    = 0;        // 1==causes sms over gsm to permanent fail
355 
356 #ifdef WORKAROUND_ERRONEOUS_ANSWER
357 // Max number of times we'll try to repoll when we think
358 // we have a AT+CLCC race condition
359 #define REPOLL_CALLS_COUNT_MAX 4
360 
361 // Line index that was incoming or waiting at last poll, or -1 for none
362 static int s_incomingOrWaitingLine = -1;
363 // Number of times we've asked for a repoll of AT+CLCC
364 static int s_repollCallsCount = 0;
365 // Should we expect a call to be answered in the next CLCC?
366 static int s_expectAnswer = 0;
367 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
368 
369 
370 static int s_cell_info_rate_ms = INT_MAX;
371 static int s_mcc = 0;
372 static int s_mnc = 0;
373 static int s_mncLength = 2;
374 static int s_lac = 0;
375 static int s_cid = 0;
376 
377 // STK
378 static bool s_stkServiceRunning = false;
379 static char *s_stkUnsolResponse = NULL;
380 
381 typedef enum {
382     STK_UNSOL_EVENT_UNKNOWN,
383     STK_UNSOL_EVENT_NOTIFY,
384     STK_UNSOL_PROACTIVE_CMD,
385 } StkUnsolEvent;
386 
387 typedef enum {
388     STK_RUN_AT        = 0x34,
389     STK_SEND_DTMF     = 0x14,
390     STK_SEND_SMS      = 0x13,
391     STK_SEND_SS       = 0x11,
392     STK_SEND_USSD     = 0x12,
393     STK_PLAY_TONE     = 0x20,
394     STK_OPEN_CHANNEL  = 0x40,
395     STK_CLOSE_CHANNEL = 0x41,
396     STK_RECEIVE_DATA  = 0x42,
397     STK_SEND_DATA     = 0x43,
398     STK_GET_CHANNEL_STATUS = 0x44,
399     STK_REFRESH       = 0x01,
400 } StkCmdType;
401 
402 enum PDPState {
403     PDP_IDLE,
404     PDP_BUSY,
405 };
406 
407 struct PDPInfo {
408     int cid;
409     enum PDPState state;
410 };
411 
412 struct PDPInfo s_PDP[] = {
413      {1, PDP_IDLE},
414      {2, PDP_IDLE},
415      {3, PDP_IDLE},
416 };
417 
418 static void pollSIMState (void *param);
419 static void setRadioState(RIL_RadioState newState);
420 static void setRadioTechnology(ModemInfo *mdm, int newtech);
421 static int query_ctec(ModemInfo *mdm, int *current, int32_t *preferred);
422 static int parse_technology_response(const char *response, int *current, int32_t *preferred);
423 static int techFromModemType(int mdmtype);
424 static void getIccId(char *iccid, int size);
425 
clccStateToRILState(int state,RIL_CallState * p_state)426 static int clccStateToRILState(int state, RIL_CallState *p_state)
427 {
428     switch(state) {
429         case 0: *p_state = RIL_CALL_ACTIVE;   return 0;
430         case 1: *p_state = RIL_CALL_HOLDING;  return 0;
431         case 2: *p_state = RIL_CALL_DIALING;  return 0;
432         case 3: *p_state = RIL_CALL_ALERTING; return 0;
433         case 4: *p_state = RIL_CALL_INCOMING; return 0;
434         case 5: *p_state = RIL_CALL_WAITING;  return 0;
435         default: return -1;
436     }
437 }
438 
convertBytesToHexString(char * bin_ptr,int length,unsigned char * hex_ptr)439 void convertBytesToHexString(char *bin_ptr, int length, unsigned char *hex_ptr) {
440     int i;
441     unsigned char tmp;
442 
443     if (bin_ptr == NULL || hex_ptr == NULL) {
444         return;
445     }
446     for (i = 0; i < length; i++) {
447         tmp = (unsigned char)((bin_ptr[i] & 0xf0) >> 4);
448         if (tmp <= 9) {
449             *hex_ptr = (unsigned char)(tmp + '0');
450         } else {
451             *hex_ptr = (unsigned char)(tmp + 'A' - 10);
452         }
453         hex_ptr++;
454         tmp = (unsigned char)(bin_ptr[i] & 0x0f);
455         if (tmp <= 9) {
456             *hex_ptr = (unsigned char)(tmp + '0');
457         } else {
458             *hex_ptr = (unsigned char)(tmp + 'A' - 10);
459         }
460         hex_ptr++;
461     }
462 }
463 
464 /**
465  * Note: directly modified line and has *p_call point directly into
466  * modified line
467  */
callFromCLCCLine(char * line,RIL_Call * p_call)468 static int callFromCLCCLine(char *line, RIL_Call *p_call)
469 {
470         //+CLCC: 1,0,2,0,0,\"+18005551212\",145
471         //     index,isMT,state,mode,isMpty(,number,TOA)?
472 
473     int err;
474     int state;
475     int mode;
476 
477     err = at_tok_start(&line);
478     if (err < 0) goto error;
479 
480     err = at_tok_nextint(&line, &(p_call->index));
481     if (err < 0) goto error;
482 
483     err = at_tok_nextbool(&line, &(p_call->isMT));
484     if (err < 0) goto error;
485 
486     err = at_tok_nextint(&line, &state);
487     if (err < 0) goto error;
488 
489     err = clccStateToRILState(state, &(p_call->state));
490     if (err < 0) goto error;
491 
492     err = at_tok_nextint(&line, &mode);
493     if (err < 0) goto error;
494 
495     p_call->isVoice = (mode == 0);
496 
497     err = at_tok_nextbool(&line, &(p_call->isMpty));
498     if (err < 0) goto error;
499 
500     if (at_tok_hasmore(&line)) {
501         err = at_tok_nextstr(&line, &(p_call->number));
502 
503         /* tolerate null here */
504         if (err < 0) return 0;
505 
506         // Some lame implementations return strings
507         // like "NOT AVAILABLE" in the CLCC line
508         if (p_call->number != NULL
509             && 0 == strspn(p_call->number, "+0123456789")
510         ) {
511             p_call->number = NULL;
512         }
513 
514         err = at_tok_nextint(&line, &p_call->toa);
515         if (err < 0) goto error;
516     }
517 
518     p_call->uusInfo = NULL;
519 
520     return 0;
521 
522 error:
523     RLOGE("invalid CLCC line\n");
524     return -1;
525 }
526 
parseSimResponseLine(char * line,RIL_SIM_IO_Response * response)527 static int parseSimResponseLine(char* line, RIL_SIM_IO_Response* response) {
528     int err;
529 
530     err = at_tok_start(&line);
531     if (err < 0) return err;
532     err = at_tok_nextint(&line, &response->sw1);
533     if (err < 0) return err;
534     err = at_tok_nextint(&line, &response->sw2);
535     if (err < 0) return err;
536 
537     if (at_tok_hasmore(&line)) {
538         err = at_tok_nextstr(&line, &response->simResponse);
539         if (err < 0) return err;
540     }
541     return 0;
542 }
543 
544 #ifdef CUTTLEFISH_ENABLE
set_Ip_Addr(const char * addr,const char * radioInterfaceName)545 static void set_Ip_Addr(const char *addr, const char* radioInterfaceName) {
546   RLOGD("%s %d setting ip addr %s on interface %s", __func__, __LINE__, addr,
547         radioInterfaceName);
548   struct ifreq request;
549   int status = 0;
550   int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
551   if (sock == -1) {
552     RLOGE("Failed to open interface socket: %s (%d)", strerror(errno), errno);
553     return;
554   }
555 
556   memset(&request, 0, sizeof(request));
557   strncpy(request.ifr_name, radioInterfaceName, sizeof(request.ifr_name));
558   request.ifr_name[sizeof(request.ifr_name) - 1] = '\0';
559 
560   char *myaddr = strdup(addr);
561   char *pch = NULL;
562   pch = strchr(myaddr, '/');
563   if (pch) {
564     *pch = '\0';
565   }
566 
567   struct sockaddr_in *sin = (struct sockaddr_in *)&request.ifr_addr;
568   sin->sin_family = AF_INET;
569   sin->sin_addr.s_addr = inet_addr(myaddr);
570   if (ioctl(sock, SIOCSIFADDR, &request) < 0) {
571     RLOGE("%s: failed.", __func__);
572   }
573 
574   close(sock);
575   free(myaddr);
576   RLOGD("%s %d done.", __func__, __LINE__);
577 }
578 #endif
579 
580 enum InterfaceState {
581     kInterfaceUp,
582     kInterfaceDown,
583 };
584 
setInterfaceState(const char * interfaceName,enum InterfaceState state)585 static RIL_Errno setInterfaceState(const char* interfaceName,
586                                    enum InterfaceState state) {
587     struct ifreq request;
588     int status = 0;
589     int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
590     if (sock == -1) {
591         RLOGE("Failed to open interface socket: %s (%d)",
592               strerror(errno), errno);
593         return RIL_E_GENERIC_FAILURE;
594     }
595 
596     memset(&request, 0, sizeof(request));
597     strncpy(request.ifr_name, interfaceName, sizeof(request.ifr_name));
598     request.ifr_name[sizeof(request.ifr_name) - 1] = '\0';
599     status = ioctl(sock, SIOCGIFFLAGS, &request);
600     if (status != 0) {
601         RLOGE("Failed to get interface flags for %s: %s (%d)",
602               interfaceName, strerror(errno), errno);
603         close(sock);
604         return RIL_E_RADIO_NOT_AVAILABLE;
605     }
606 
607     bool isUp = (request.ifr_flags & IFF_UP);
608     if ((state == kInterfaceUp && isUp) || (state == kInterfaceDown && !isUp)) {
609         // Interface already in desired state
610         close(sock);
611         return RIL_E_SUCCESS;
612     }
613 
614     // Simply toggle the flag since we know it's the opposite of what we want
615     request.ifr_flags ^= IFF_UP;
616 
617     status = ioctl(sock, SIOCSIFFLAGS, &request);
618     if (status != 0) {
619         RLOGE("Failed to set interface flags for %s: %s (%d)",
620               interfaceName, strerror(errno), errno);
621         close(sock);
622         return RIL_E_GENERIC_FAILURE;
623     }
624 
625     close(sock);
626     return RIL_E_SUCCESS;
627 }
628 
629 /** do post-AT+CFUN=1 initialization */
onRadioPowerOn()630 static void onRadioPowerOn()
631 {
632 #ifdef USE_TI_COMMANDS
633     /*  Must be after CFUN=1 */
634     /*  TI specific -- notifications for CPHS things such */
635     /*  as CPHS message waiting indicator */
636 
637     at_send_command("AT%CPHS=1", NULL);
638 
639     /*  TI specific -- enable NITZ unsol notifs */
640     at_send_command("AT%CTZV=1", NULL);
641 #endif
642 
643     pollSIMState(NULL);
644 }
645 
646 /** do post- SIM ready initialization */
onSIMReady()647 static void onSIMReady()
648 {
649     at_send_command_singleline("AT+CSMS=1", "+CSMS:", NULL);
650     /*
651      * Always send SMS messages directly to the TE
652      *
653      * mode = 1 // discard when link is reserved (link should never be
654      *             reserved)
655      * mt = 2   // most messages routed to TE
656      * bm = 2   // new cell BM's routed to TE
657      * ds = 1   // Status reports routed to TE
658      * bfr = 1  // flush buffer
659      */
660     at_send_command("AT+CNMI=1,2,2,1,1", NULL);
661 }
662 
requestRadioPower(void * data,size_t datalen __unused,RIL_Token t)663 static void requestRadioPower(void *data, size_t datalen __unused, RIL_Token t)
664 {
665     int onOff;
666 
667     int err;
668     ATResponse *p_response = NULL;
669 
670     assert (datalen >= sizeof(int *));
671     onOff = ((int *)data)[0];
672 
673     if (onOff == 0 && sState != RADIO_STATE_OFF) {
674         err = at_send_command("AT+CFUN=0", &p_response);
675         if (err < 0 || p_response->success == 0) goto error;
676         setRadioState(RADIO_STATE_OFF);
677     } else if (onOff > 0 && sState == RADIO_STATE_OFF) {
678         err = at_send_command("AT+CFUN=1", &p_response);
679         if (err < 0|| p_response->success == 0) {
680             // Some stacks return an error when there is no SIM,
681             // but they really turn the RF portion on
682             // So, if we get an error, let's check to see if it
683             // turned on anyway
684 
685             if (isRadioOn() != 1) {
686                 goto error;
687             }
688         }
689         setRadioState(RADIO_STATE_ON);
690     }
691 
692     at_response_free(p_response);
693     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
694     return;
695 error:
696     at_response_free(p_response);
697     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
698 }
699 
requestShutdown(RIL_Token t)700 static void requestShutdown(RIL_Token t)
701 {
702     int onOff;
703 
704     int err;
705     ATResponse *p_response = NULL;
706 
707     if (sState != RADIO_STATE_OFF) {
708         err = at_send_command("AT+CFUN=0", &p_response);
709         setRadioState(RADIO_STATE_UNAVAILABLE);
710     }
711 
712     at_response_free(p_response);
713     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
714     return;
715 }
716 
717 static void requestOrSendDataCallList(int cid, RIL_Token *t);
718 
onDataCallListChanged(void * param __unused)719 static void onDataCallListChanged(void *param __unused)
720 {
721     requestOrSendDataCallList(-1, NULL);
722 }
723 
requestDataCallList(void * data __unused,size_t datalen __unused,RIL_Token t)724 static void requestDataCallList(void *data __unused, size_t datalen __unused, RIL_Token t)
725 {
726     requestOrSendDataCallList(-1, &t);
727 }
728 
729 // Hang up, reject, conference, call waiting
requestCallSelection(void * data __unused,size_t datalen __unused,RIL_Token t,int request)730 static void requestCallSelection(
731                 void *data __unused, size_t datalen __unused, RIL_Token t, int request)
732 {
733     // 3GPP 22.030 6.5.5
734     static char hangupWaiting[]    = "AT+CHLD=0";
735     static char hangupForeground[] = "AT+CHLD=1";
736     static char switchWaiting[]    = "AT+CHLD=2";
737     static char conference[]       = "AT+CHLD=3";
738     static char reject[]           = "ATH";
739 
740     char* atCommand;
741 
742     if (getSIMStatus() == SIM_ABSENT) {
743         RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
744         return;
745     }
746 
747     switch(request) {
748         case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
749             // "Releases all held calls or sets User Determined User Busy
750             //  (UDUB) for a waiting call."
751             atCommand = hangupWaiting;
752             break;
753         case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
754             // "Releases all active calls (if any exist) and accepts
755             //  the other (held or waiting) call."
756             atCommand = hangupForeground;
757             break;
758         case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
759             // "Places all active calls (if any exist) on hold and accepts
760             //  the other (held or waiting) call."
761             atCommand = switchWaiting;
762 #ifdef WORKAROUND_ERRONEOUS_ANSWER
763             s_expectAnswer = 1;
764 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
765             break;
766         case RIL_REQUEST_CONFERENCE:
767             // "Adds a held call to the conversation"
768             atCommand = conference;
769             break;
770         case RIL_REQUEST_UDUB:
771             // User determined user busy (reject)
772             atCommand = reject;
773             break;
774         default:
775             assert(0);
776     }
777     at_send_command(atCommand, NULL);
778     // Success or failure is ignored by the upper layer here.
779     // It will call GET_CURRENT_CALLS and determine success that way.
780     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
781 }
782 
getRadioInterfaceName()783 static const char* getRadioInterfaceName()
784 {
785     if (isInEmulator()) {
786         return EMULATOR_RADIO_INTERFACE;
787     }
788     return PPP_TTY_PATH_ETH0;
789 }
790 
requestOrSendDataCallList(int cid,RIL_Token * t)791 static void requestOrSendDataCallList(int cid, RIL_Token *t)
792 {
793     ATResponse *p_response = NULL;
794     ATLine *p_cur = NULL;
795     int err = -1;
796     int n = 0;
797     char *out = NULL;
798     char propValue[PROP_VALUE_MAX] = {0};
799     const char* radioInterfaceName = getRadioInterfaceName();
800 
801     err = at_send_command_multiline ("AT+CGACT?", "+CGACT:", &p_response);
802     if (err != 0 || p_response->success == 0) {
803         if (t != NULL)
804             RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
805         else
806             RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
807                                       NULL, 0);
808         return;
809     }
810 
811     for (p_cur = p_response->p_intermediates; p_cur != NULL;
812          p_cur = p_cur->p_next)
813         n++;
814 
815     RIL_Data_Call_Response_v11 *responses =
816         alloca(n * sizeof(RIL_Data_Call_Response_v11));
817 
818     int i;
819     for (i = 0; i < n; i++) {
820         responses[i].status = -1;
821         responses[i].suggestedRetryTime = -1;
822         responses[i].cid = -1;
823         responses[i].active = -1;
824         responses[i].type = "";
825         responses[i].ifname = "";
826         responses[i].addresses = "";
827         responses[i].dnses = "";
828         responses[i].gateways = "";
829         responses[i].pcscf = "";
830         responses[i].mtu = 0;
831     }
832 
833     RIL_Data_Call_Response_v11 *response = responses;
834     for (p_cur = p_response->p_intermediates; p_cur != NULL;
835          p_cur = p_cur->p_next) {
836         char *line = p_cur->line;
837 
838         err = at_tok_start(&line);
839         if (err < 0)
840             goto error;
841 
842         err = at_tok_nextint(&line, &response->cid);
843         if (err < 0)
844             goto error;
845 
846         err = at_tok_nextint(&line, &response->active);
847         if (err < 0)
848             goto error;
849 
850         response++;
851     }
852 
853     at_response_free(p_response);
854 
855     err = at_send_command_multiline ("AT+CGDCONT?", "+CGDCONT:", &p_response);
856     if (err != 0 || p_response->success == 0) {
857         if (t != NULL)
858             RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
859         else
860             RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
861                                       NULL, 0);
862         return;
863     }
864 
865     for (p_cur = p_response->p_intermediates; p_cur != NULL;
866          p_cur = p_cur->p_next) {
867         char *line = p_cur->line;
868         int ncid;
869 
870         err = at_tok_start(&line);
871         if (err < 0)
872             goto error;
873 
874         err = at_tok_nextint(&line, &ncid);
875         if (err < 0)
876             goto error;
877 
878         if (cid != ncid)
879             continue;
880 
881         i = ncid - 1;
882         // Assume no error
883         responses[i].status = 0;
884 
885         // type
886         err = at_tok_nextstr(&line, &out);
887         if (err < 0)
888             goto error;
889 
890         int type_size = strlen(out) + 1;
891         responses[i].type = alloca(type_size);
892         strlcpy(responses[i].type, out, type_size);
893 
894         // APN ignored for v5
895         err = at_tok_nextstr(&line, &out);
896         if (err < 0)
897             goto error;
898 
899         int ifname_size = strlen(radioInterfaceName) + 1;
900         responses[i].ifname = alloca(ifname_size);
901         strlcpy(responses[i].ifname, radioInterfaceName, ifname_size);
902 
903         err = at_tok_nextstr(&line, &out);
904         if (err < 0)
905             goto error;
906 
907         int addresses_size = strlen(out) + 1;
908         responses[i].addresses = alloca(addresses_size);
909         strlcpy(responses[i].addresses, out, addresses_size);
910 #ifdef CUTTLEFISH_ENABLE
911         set_Ip_Addr(responses[i].addresses, radioInterfaceName);
912 #endif
913 
914         if (isInEmulator()) {
915             /* We are in the emulator - the dns servers are listed
916                 * by the following system properties, setup in
917                 * /system/etc/init.goldfish.sh:
918                 *  - vendor.net.eth0.dns1
919                 *  - vendor.net.eth0.dns2
920                 *  - vendor.net.eth0.dns3
921                 *  - vendor.net.eth0.dns4
922                 */
923             const int   dnslist_sz = 128;
924             char*       dnslist = alloca(dnslist_sz);
925             const char* separator = "";
926             int         nn;
927 
928             dnslist[0] = 0;
929             for (nn = 1; nn <= 4; nn++) {
930                 /* Probe vendor.net.eth0.dns<n> */
931                 char  propName[PROP_NAME_MAX];
932                 char  propValue[PROP_VALUE_MAX];
933 
934                 snprintf(propName, sizeof propName, "vendor.net.eth0.dns%d", nn);
935 
936                 /* Ignore if undefined */
937                 if (property_get(propName, propValue, "") <= 0) {
938                     continue;
939                 }
940 
941                 /* Append the DNS IP address */
942                 strlcat(dnslist, separator, dnslist_sz);
943                 strlcat(dnslist, propValue, dnslist_sz);
944                 separator = " ";
945             }
946             responses[i].dnses = dnslist;
947 
948             if (property_get("vendor.net.eth0.gw", propValue, "") > 0) {
949                 responses[i].gateways = propValue;
950             } else {
951                 responses[i].gateways = "";
952             }
953             responses[i].mtu = DEFAULT_MTU;
954         } else {
955             /* I don't know where we are, so use the public Google DNS
956                 * servers by default and no gateway.
957                 */
958             responses[i].dnses = "8.8.8.8 8.8.4.4";
959             responses[i].gateways = "";
960         }
961     }
962 
963     at_response_free(p_response);
964     p_response = NULL;
965 
966     char cmd[64] = {0};
967     snprintf(cmd, sizeof(cmd), "AT+CGCONTRDP=%d", cid);
968     err = at_send_command_singleline(cmd, "+CGCONTRDP:", &p_response);
969     if (err < 0 || p_response->success == 0) {
970         goto error;
971     }
972 
973     int skip = 0;
974     char *sskip = NULL;
975     char *input = p_response->p_intermediates->line;
976 
977     int ncid = -1;
978     err = at_tok_start(&input);
979     if (err < 0) goto error;
980 
981     err = at_tok_nextint(&input, &ncid);  // cid
982     if (err < 0) goto error;
983 
984     if (cid != ncid) goto error;
985 
986     i = ncid - 1;
987 
988     err = at_tok_nextint(&input, &skip);  // bearer_id
989     if (err < 0) goto error;
990 
991     err = at_tok_nextstr(&input, &sskip);  // apn
992     if (err < 0) goto error;
993 
994     err = at_tok_nextstr(&input, &sskip);  // local_addr_and_subnet_mask
995     if (err < 0) goto error;
996 
997     err = at_tok_nextstr(&input, &responses[i].gateways);  // gw_addr
998     if (err < 0) goto error;
999 
1000     err = at_tok_nextstr(&input, &responses[i].dnses);  // dns_prim_addr
1001     if (err < 0) goto error;
1002 
1003     if (t != NULL)
1004         RIL_onRequestComplete(*t, RIL_E_SUCCESS, &responses[i],
1005                                sizeof(RIL_Data_Call_Response_v11));
1006     else
1007         RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
1008                                   responses,
1009                                   n * sizeof(RIL_Data_Call_Response_v11));
1010 
1011     at_response_free(p_response);
1012     return;
1013 
1014 error:
1015     if (t != NULL)
1016         RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
1017     else
1018         RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
1019                                   NULL, 0);
1020     at_response_free(p_response);
1021 }
1022 
requestQueryNetworkSelectionMode(void * data __unused,size_t datalen __unused,RIL_Token t)1023 static void requestQueryNetworkSelectionMode(
1024                 void *data __unused, size_t datalen __unused, RIL_Token t)
1025 {
1026     int err;
1027     ATResponse *p_response = NULL;
1028     int response = 0;
1029     char *line;
1030 
1031     err = at_send_command_singleline("AT+COPS?", "+COPS:", &p_response);
1032 
1033     if (err < 0 || p_response->success == 0) {
1034         goto error;
1035     }
1036 
1037     line = p_response->p_intermediates->line;
1038 
1039     err = at_tok_start(&line);
1040 
1041     if (err < 0) {
1042         goto error;
1043     }
1044 
1045     err = at_tok_nextint(&line, &response);
1046 
1047     if (err < 0) {
1048         goto error;
1049     }
1050 
1051     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(int));
1052     at_response_free(p_response);
1053     return;
1054 error:
1055     at_response_free(p_response);
1056     RLOGE("requestQueryNetworkSelectionMode must never return error when radio is on");
1057     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1058 }
1059 
sendCallStateChanged(void * param __unused)1060 static void sendCallStateChanged(void *param __unused)
1061 {
1062     RIL_onUnsolicitedResponse (
1063         RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
1064         NULL, 0);
1065 }
1066 
requestGetCurrentCalls(void * data __unused,size_t datalen __unused,RIL_Token t)1067 static void requestGetCurrentCalls(void *data __unused, size_t datalen __unused, RIL_Token t)
1068 {
1069     int err;
1070     ATResponse *p_response;
1071     ATLine *p_cur;
1072     int countCalls;
1073     int countValidCalls;
1074     RIL_Call *p_calls;
1075     RIL_Call **pp_calls;
1076     int i;
1077     int needRepoll = 0;
1078 
1079 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1080     int prevIncomingOrWaitingLine;
1081 
1082     prevIncomingOrWaitingLine = s_incomingOrWaitingLine;
1083     s_incomingOrWaitingLine = -1;
1084 #endif /*WORKAROUND_ERRONEOUS_ANSWER*/
1085 
1086     err = at_send_command_multiline ("AT+CLCC", "+CLCC:", &p_response);
1087 
1088     if (err != 0 || p_response->success == 0) {
1089         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1090         return;
1091     }
1092 
1093     /* count the calls */
1094     for (countCalls = 0, p_cur = p_response->p_intermediates
1095             ; p_cur != NULL
1096             ; p_cur = p_cur->p_next
1097     ) {
1098         countCalls++;
1099     }
1100 
1101     /* yes, there's an array of pointers and then an array of structures */
1102 
1103     pp_calls = (RIL_Call **)alloca(countCalls * sizeof(RIL_Call *));
1104     p_calls = (RIL_Call *)alloca(countCalls * sizeof(RIL_Call));
1105     memset (p_calls, 0, countCalls * sizeof(RIL_Call));
1106 
1107     /* init the pointer array */
1108     for(i = 0; i < countCalls ; i++) {
1109         pp_calls[i] = &(p_calls[i]);
1110     }
1111 
1112     for (countValidCalls = 0, p_cur = p_response->p_intermediates
1113             ; p_cur != NULL
1114             ; p_cur = p_cur->p_next
1115     ) {
1116         err = callFromCLCCLine(p_cur->line, p_calls + countValidCalls);
1117 
1118         if (err != 0) {
1119             continue;
1120         }
1121 
1122 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1123         if (p_calls[countValidCalls].state == RIL_CALL_INCOMING
1124             || p_calls[countValidCalls].state == RIL_CALL_WAITING
1125         ) {
1126             s_incomingOrWaitingLine = p_calls[countValidCalls].index;
1127         }
1128 #endif /*WORKAROUND_ERRONEOUS_ANSWER*/
1129 
1130         if (p_calls[countValidCalls].state != RIL_CALL_ACTIVE
1131             && p_calls[countValidCalls].state != RIL_CALL_HOLDING
1132         ) {
1133             needRepoll = 1;
1134         }
1135 
1136         countValidCalls++;
1137     }
1138 
1139 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1140     // Basically:
1141     // A call was incoming or waiting
1142     // Now it's marked as active
1143     // But we never answered it
1144     //
1145     // This is probably a bug, and the call will probably
1146     // disappear from the call list in the next poll
1147     if (prevIncomingOrWaitingLine >= 0
1148             && s_incomingOrWaitingLine < 0
1149             && s_expectAnswer == 0
1150     ) {
1151         for (i = 0; i < countValidCalls ; i++) {
1152 
1153             if (p_calls[i].index == prevIncomingOrWaitingLine
1154                     && p_calls[i].state == RIL_CALL_ACTIVE
1155                     && s_repollCallsCount < REPOLL_CALLS_COUNT_MAX
1156             ) {
1157                 RLOGI(
1158                     "Hit WORKAROUND_ERRONOUS_ANSWER case."
1159                     " Repoll count: %d\n", s_repollCallsCount);
1160                 s_repollCallsCount++;
1161                 goto error;
1162             }
1163         }
1164     }
1165 
1166     s_expectAnswer = 0;
1167     s_repollCallsCount = 0;
1168 #endif /*WORKAROUND_ERRONEOUS_ANSWER*/
1169 
1170     RIL_onRequestComplete(t, RIL_E_SUCCESS, pp_calls,
1171             countValidCalls * sizeof (RIL_Call *));
1172 
1173     at_response_free(p_response);
1174 
1175 #ifdef POLL_CALL_STATE
1176     if (countValidCalls) {  // We don't seem to get a "NO CARRIER" message from
1177                             // smd, so we're forced to poll until the call ends.
1178 #else
1179     if (needRepoll) {
1180 #endif
1181         RIL_requestTimedCallback (sendCallStateChanged, NULL, &TIMEVAL_CALLSTATEPOLL);
1182     }
1183 
1184     return;
1185 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1186 error:
1187     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1188     at_response_free(p_response);
1189 #endif
1190 }
1191 
1192 static void requestDial(void *data, size_t datalen __unused, RIL_Token t)
1193 {
1194     RIL_Dial *p_dial;
1195     char *cmd;
1196     const char *clir;
1197     int ret;
1198 
1199     p_dial = (RIL_Dial *)data;
1200 
1201     switch (p_dial->clir) {
1202         case 1: clir = "I"; break;  /*invocation*/
1203         case 2: clir = "i"; break;  /*suppression*/
1204         default:
1205         case 0: clir = ""; break;   /*subscription default*/
1206     }
1207 
1208     asprintf(&cmd, "ATD%s%s;", p_dial->address, clir);
1209 
1210     ret = at_send_command(cmd, NULL);
1211 
1212     free(cmd);
1213 
1214     /* success or failure is ignored by the upper layer here.
1215        it will call GET_CURRENT_CALLS and determine success that way */
1216     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1217 }
1218 
1219 static void requestWriteSmsToSim(void *data, size_t datalen __unused, RIL_Token t)
1220 {
1221     RIL_SMS_WriteArgs *p_args;
1222     char *cmd;
1223     int length;
1224     int err;
1225     ATResponse *p_response = NULL;
1226 
1227     if (getSIMStatus() == SIM_ABSENT) {
1228         RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
1229         return;
1230     }
1231 
1232     p_args = (RIL_SMS_WriteArgs *)data;
1233 
1234     length = strlen(p_args->pdu)/2;
1235     asprintf(&cmd, "AT+CMGW=%d,%d", length, p_args->status);
1236 
1237     err = at_send_command_sms(cmd, p_args->pdu, "+CMGW:", &p_response);
1238 
1239     if (err != 0 || p_response->success == 0) goto error;
1240 
1241     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1242     at_response_free(p_response);
1243 
1244     return;
1245 error:
1246     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1247     at_response_free(p_response);
1248 }
1249 
1250 static void requestHangup(void *data, size_t datalen __unused, RIL_Token t)
1251 {
1252     int *p_line;
1253 
1254     int ret;
1255     char *cmd;
1256 
1257     if (getSIMStatus() == SIM_ABSENT) {
1258         RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
1259         return;
1260     }
1261     p_line = (int *)data;
1262 
1263     // 3GPP 22.030 6.5.5
1264     // "Releases a specific active call X"
1265     asprintf(&cmd, "AT+CHLD=1%d", p_line[0]);
1266 
1267     ret = at_send_command(cmd, NULL);
1268 
1269     free(cmd);
1270 
1271     /* success or failure is ignored by the upper layer here.
1272        it will call GET_CURRENT_CALLS and determine success that way */
1273     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1274 }
1275 
1276 static void requestSignalStrength(void *data __unused, size_t datalen __unused, RIL_Token t)
1277 {
1278     ATResponse *p_response = NULL;
1279     int err;
1280     char *line;
1281     int count = 0;
1282     // Accept a response that is at least v6, and up to v12
1283     int minNumOfElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
1284     int maxNumOfElements=sizeof(RIL_SignalStrength_v12)/sizeof(int);
1285     int response[maxNumOfElements];
1286 
1287     memset(response, 0, sizeof(response));
1288 
1289     err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response);
1290 
1291     if (err < 0 || p_response->success == 0) {
1292         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1293         goto error;
1294     }
1295 
1296     line = p_response->p_intermediates->line;
1297 
1298     err = at_tok_start(&line);
1299     if (err < 0) goto error;
1300 
1301     for (count = 0; count < maxNumOfElements; count++) {
1302         err = at_tok_nextint(&line, &(response[count]));
1303         if (err < 0 && count < minNumOfElements) goto error;
1304     }
1305 
1306     RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
1307 
1308     at_response_free(p_response);
1309     return;
1310 
1311 error:
1312     RLOGE("requestSignalStrength must never return an error when radio is on");
1313     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1314     at_response_free(p_response);
1315 }
1316 
1317 /**
1318  * networkModePossible. Decides whether the network mode is appropriate for the
1319  * specified modem
1320  */
1321 static int networkModePossible(ModemInfo *mdm, int nm)
1322 {
1323     const int asize = sizeof(net2modem) / sizeof(net2modem[0]);
1324     if (nm >= asize || nm < 0) {
1325         RLOGW("%s %d: invalid net2modem index: %d", __func__, __LINE__, nm);
1326         return 0;
1327     }
1328     if ((net2modem[nm] & mdm->supportedTechs) == net2modem[nm]) {
1329        return 1;
1330     }
1331     return 0;
1332 }
1333 
1334 int getPreferredFromBitmap(int value, int *index) {
1335     for (unsigned int i = 0; i < sizeof(s_networkMask) / sizeof(NetworkTypeBitmap); i++) {
1336         if (s_networkMask[i].bitmap == value) {
1337             if (index) *index = i;
1338             return s_networkMask[i].type;
1339         }
1340     }
1341     // set default value here, since there is no match found
1342     // ref.
1343     //{LTE | GSM | WCDMA,               MDM_LTE | MDM_GSM | MDM_WCDMA},             // 9 - LTE, GSM/WCDMA
1344     //
1345     const int DEFAULT_PREFERRED_INDEX = 9;
1346     const int DEFAULT_PREFERRED_BITMAP = MDM_LTE | MDM_GSM | MDM_WCDMA;
1347     assert(s_networkMask[DEFAULT_PREFERRED_INDEX] == DEFAULT_PREFERRED_BITMAP);
1348     if (index) {
1349         *index = DEFAULT_PREFERRED_INDEX;
1350     }
1351     RLOGD("getPreferredFromBitmap %d not match", value);
1352     return  DEFAULT_PREFERRED_BITMAP;
1353 }
1354 
1355 unsigned getBitmapFromPreferred(int value) {
1356     for (unsigned int i = 0; i < sizeof(s_networkMask) / sizeof(NetworkTypeBitmap); i++) {
1357         if (s_networkMask[i].type == value) {
1358             return s_networkMask[i].bitmap;
1359         }
1360     }
1361     RLOGD("getBitmapFromPreferred %d not match", value);
1362     return  LTE | GSM | WCDMA;
1363 }
1364 
1365 static void requestSetPreferredNetworkType(int request, void *data,
1366                                            size_t datalen __unused, RIL_Token t )
1367 {
1368     ATResponse *p_response = NULL;
1369     char *cmd = NULL;
1370     int value = *(int *)data;
1371     int index = value;
1372     int current, old;
1373     int err;
1374     int32_t preferred;
1375 
1376     if (request == RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE) {
1377         preferred = net2pmask[value];
1378     } else {
1379         preferred = getPreferredFromBitmap(value, &index);
1380     }
1381     RLOGD("requestSetPreferredNetworkType: current: %x. New: %x", PREFERRED_NETWORK(sMdmInfo), preferred);
1382 
1383     if (!networkModePossible(sMdmInfo, index)) {
1384         RIL_onRequestComplete(t, RIL_E_MODE_NOT_SUPPORTED, NULL, 0);
1385         return;
1386     }
1387 
1388     if (query_ctec(sMdmInfo, &current, NULL) < 0) {
1389         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1390         return;
1391     }
1392     old = PREFERRED_NETWORK(sMdmInfo);
1393     RLOGD("old != preferred: %d", old != preferred);
1394     if (old != preferred) {
1395         asprintf(&cmd, "AT+CTEC=%d,\"%x\"", current, preferred);
1396         RLOGD("Sending command: <%s>", cmd);
1397         err = at_send_command_singleline(cmd, "+CTEC:", &p_response);
1398         free(cmd);
1399         if (err || !p_response->success) {
1400             RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1401             return;
1402         }
1403         PREFERRED_NETWORK(sMdmInfo) = value;
1404         if (!strstr( p_response->p_intermediates->line, "DONE") ) {
1405             int current;
1406             int res = parse_technology_response(p_response->p_intermediates->line, &current, NULL);
1407             switch (res) {
1408                 case -1: // Error or unable to parse
1409                     break;
1410                 case 1: // Only able to parse current
1411                 case 0: // Both current and preferred were parsed
1412                     setRadioTechnology(sMdmInfo, current);
1413                     break;
1414             }
1415         }
1416     }
1417     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1418 }
1419 
1420 static void requestGetPreferredNetworkType(int request __unused, void *data __unused,
1421                                    size_t datalen __unused, RIL_Token t)
1422 {
1423     int preferred;
1424     unsigned i;
1425 
1426     switch ( query_ctec(sMdmInfo, NULL, &preferred) ) {
1427         case -1: // Error or unable to parse
1428         case 1: // Only able to parse current
1429             RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1430             break;
1431         case 0: // Both current and preferred were parsed
1432             for ( i = 0 ; i < sizeof(net2pmask) / sizeof(int32_t) ; i++ ) {
1433                 if (preferred == net2pmask[i]) {
1434                     goto done;
1435                 }
1436             }
1437             RLOGE("Unknown preferred mode received from modem: %d", preferred);
1438             RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1439             return;
1440     }
1441 done:
1442     if (request == RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP ||
1443             request == RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP) {
1444         i = getBitmapFromPreferred(preferred);
1445     }
1446     RIL_onRequestComplete(t, RIL_E_SUCCESS, &i, sizeof(i));
1447 }
1448 
1449 static void requestCdmaPrlVersion(int request __unused, void *data __unused,
1450                                    size_t datalen __unused, RIL_Token t)
1451 {
1452     int err;
1453     char * responseStr;
1454     ATResponse *p_response = NULL;
1455     const char *cmd;
1456     char *line;
1457 
1458     err = at_send_command_singleline("AT+WPRL?", "+WPRL:", &p_response);
1459     if (err < 0 || !p_response->success) goto error;
1460     line = p_response->p_intermediates->line;
1461     err = at_tok_start(&line);
1462     if (err < 0) goto error;
1463     err = at_tok_nextstr(&line, &responseStr);
1464     if (err < 0 || !responseStr) goto error;
1465     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, strlen(responseStr));
1466     at_response_free(p_response);
1467     return;
1468 error:
1469     at_response_free(p_response);
1470     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1471 }
1472 
1473 static void requestCdmaBaseBandVersion(int request __unused, void *data __unused,
1474                                    size_t datalen __unused, RIL_Token t)
1475 {
1476     int err;
1477     char * responseStr;
1478     ATResponse *p_response = NULL;
1479     const char *cmd;
1480     const char *prefix;
1481     char *line, *p;
1482     int commas;
1483     int skip;
1484     int count = 4;
1485 
1486     // Fixed values. TODO: query modem
1487     responseStr = strdup("1.0.0.0");
1488     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, sizeof(responseStr));
1489     free(responseStr);
1490 }
1491 
1492 static void requestDeviceIdentity(int request __unused, void *data __unused,
1493                                         size_t datalen __unused, RIL_Token t)
1494 {
1495     int err;
1496     int response[4];
1497     char * responseStr[4];
1498     ATResponse *p_response = NULL;
1499     const char *cmd;
1500     const char *prefix;
1501     char *line, *p;
1502     int commas;
1503     int skip;
1504     int count = 4;
1505 
1506     // Fixed values. TODO: Query modem
1507     responseStr[0] = "----";
1508     responseStr[1] = "----";
1509     responseStr[2] = "77777777";
1510     responseStr[3] = ""; // default empty for non-CDMA
1511 
1512     err = at_send_command_numeric("AT+CGSN", &p_response);
1513     if (err < 0 || p_response->success == 0) {
1514         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1515         return;
1516     } else {
1517         if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
1518             responseStr[3] = p_response->p_intermediates->line;
1519         } else {
1520             responseStr[0] = p_response->p_intermediates->line;
1521         }
1522     }
1523 
1524     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
1525     at_response_free(p_response);
1526 }
1527 
1528 static void requestCdmaGetSubscriptionSource(int request __unused, void *data,
1529                                         size_t datalen __unused, RIL_Token t)
1530 {
1531     int err;
1532     int *ss = (int *)data;
1533     ATResponse *p_response = NULL;
1534     char *cmd = NULL;
1535     char *line = NULL;
1536     int response;
1537 
1538     asprintf(&cmd, "AT+CCSS?");
1539     if (!cmd) goto error;
1540 
1541     err = at_send_command_singleline(cmd, "+CCSS:", &p_response);
1542     if (err < 0 || !p_response->success)
1543         goto error;
1544 
1545     line = p_response->p_intermediates->line;
1546     err = at_tok_start(&line);
1547     if (err < 0) goto error;
1548 
1549     err = at_tok_nextint(&line, &response);
1550     free(cmd);
1551     cmd = NULL;
1552 
1553     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1554 
1555     return;
1556 error:
1557     free(cmd);
1558     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1559 }
1560 
1561 static void requestCdmaSetSubscriptionSource(int request __unused, void *data,
1562                                         size_t datalen, RIL_Token t)
1563 {
1564     int err;
1565     int *ss = (int *)data;
1566     ATResponse *p_response = NULL;
1567     char *cmd = NULL;
1568 
1569     if (!ss || !datalen) {
1570         RLOGE("RIL_REQUEST_CDMA_SET_SUBSCRIPTION without data!");
1571         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1572         return;
1573     }
1574     asprintf(&cmd, "AT+CCSS=%d", ss[0]);
1575     if (!cmd) goto error;
1576 
1577     err = at_send_command(cmd, &p_response);
1578     if (err < 0 || !p_response->success)
1579         goto error;
1580     free(cmd);
1581     cmd = NULL;
1582 
1583     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1584 
1585     RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, ss, sizeof(ss[0]));
1586 
1587     return;
1588 error:
1589     free(cmd);
1590     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1591 }
1592 
1593 static void requestCdmaSubscription(int request __unused, void *data __unused,
1594                                         size_t datalen __unused, RIL_Token t)
1595 {
1596     int err;
1597     int response[5];
1598     char * responseStr[5];
1599     ATResponse *p_response = NULL;
1600     const char *cmd;
1601     const char *prefix;
1602     char *line, *p;
1603     int commas;
1604     int skip;
1605     int count = 5;
1606 
1607     // Fixed values. TODO: Query modem
1608     responseStr[0] = "8587777777"; // MDN
1609     responseStr[1] = "1"; // SID
1610     responseStr[2] = "1"; // NID
1611     responseStr[3] = "8587777777"; // MIN
1612     responseStr[4] = "1"; // PRL Version
1613     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
1614 }
1615 
1616 static void requestCdmaGetRoamingPreference(int request __unused, void *data __unused,
1617                                                  size_t datalen __unused, RIL_Token t)
1618 {
1619     int roaming_pref = -1;
1620     ATResponse *p_response = NULL;
1621     char *line;
1622     int res;
1623 
1624     res = at_send_command_singleline("AT+WRMP?", "+WRMP:", &p_response);
1625     if (res < 0 || !p_response->success) {
1626         goto error;
1627     }
1628     line = p_response->p_intermediates->line;
1629 
1630     res = at_tok_start(&line);
1631     if (res < 0) goto error;
1632 
1633     res = at_tok_nextint(&line, &roaming_pref);
1634     if (res < 0) goto error;
1635 
1636     RIL_onRequestComplete(t, RIL_E_SUCCESS, &roaming_pref, sizeof(roaming_pref));
1637     return;
1638 error:
1639     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1640 }
1641 
1642 static void requestCdmaSetRoamingPreference(int request __unused, void *data,
1643                                                  size_t datalen __unused, RIL_Token t)
1644 {
1645     int *pref = (int *)data;
1646     ATResponse *p_response = NULL;
1647     char *line;
1648     int res;
1649     char *cmd = NULL;
1650 
1651     asprintf(&cmd, "AT+WRMP=%d", *pref);
1652     if (cmd == NULL) goto error;
1653 
1654     res = at_send_command(cmd, &p_response);
1655     if (res < 0 || !p_response->success)
1656         goto error;
1657 
1658     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1659     free(cmd);
1660     return;
1661 error:
1662     free(cmd);
1663     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1664 }
1665 
1666 static int parseRegistrationState(char *str, int *type, int *items, int **response)
1667 {
1668     int err;
1669     char *line = str, *p;
1670     int *resp = NULL;
1671     int skip;
1672     int count = 3;
1673     int commas;
1674 
1675     RLOGD("parseRegistrationState. Parsing: %s",str);
1676     err = at_tok_start(&line);
1677     if (err < 0) goto error;
1678 
1679     /* Ok you have to be careful here
1680      * The solicited version of the CREG response is
1681      * +CREG: n, stat, [lac, cid]
1682      * and the unsolicited version is
1683      * +CREG: stat, [lac, cid]
1684      * The <n> parameter is basically "is unsolicited creg on?"
1685      * which it should always be
1686      *
1687      * Now we should normally get the solicited version here,
1688      * but the unsolicited version could have snuck in
1689      * so we have to handle both
1690      *
1691      * Also since the LAC and CID are only reported when registered,
1692      * we can have 1, 2, 3, or 4 arguments here
1693      *
1694      * finally, a +CGREG: answer may have a fifth value that corresponds
1695      * to the network type, as in;
1696      *
1697      *   +CGREG: n, stat [,lac, cid [,networkType]]
1698      */
1699 
1700     /* count number of commas */
1701     commas = 0;
1702     for (p = line ; *p != '\0' ;p++) {
1703         if (*p == ',') commas++;
1704     }
1705 
1706     resp = (int *)calloc(commas + 1, sizeof(int));
1707     if (!resp) goto error;
1708     switch (commas) {
1709         case 0: /* +CREG: <stat> */
1710             err = at_tok_nextint(&line, &resp[0]);
1711             if (err < 0) goto error;
1712             resp[1] = -1;
1713             resp[2] = -1;
1714         break;
1715 
1716         case 1: /* +CREG: <n>, <stat> */
1717             err = at_tok_nextint(&line, &skip);
1718             if (err < 0) goto error;
1719             err = at_tok_nextint(&line, &resp[0]);
1720             if (err < 0) goto error;
1721             resp[1] = -1;
1722             resp[2] = -1;
1723             if (err < 0) goto error;
1724         break;
1725 
1726         case 2: /* +CREG: <stat>, <lac>, <cid> */
1727             err = at_tok_nextint(&line, &resp[0]);
1728             if (err < 0) goto error;
1729             err = at_tok_nexthexint(&line, &resp[1]);
1730             if (err < 0) goto error;
1731             err = at_tok_nexthexint(&line, &resp[2]);
1732             if (err < 0) goto error;
1733         break;
1734         case 3: /* +CREG: <n>, <stat>, <lac>, <cid> */
1735             err = at_tok_nextint(&line, &skip);
1736             if (err < 0) goto error;
1737             err = at_tok_nextint(&line, &resp[0]);
1738             if (err < 0) goto error;
1739             err = at_tok_nexthexint(&line, &resp[1]);
1740             if (err < 0) goto error;
1741             err = at_tok_nexthexint(&line, &resp[2]);
1742             if (err < 0) goto error;
1743         break;
1744         /* special case for CGREG, there is a fourth parameter
1745          * that is the network type (unknown/gprs/edge/umts)
1746          */
1747         case 4: /* +CGREG: <n>, <stat>, <lac>, <cid>, <networkType> */
1748             err = at_tok_nextint(&line, &skip);
1749             if (err < 0) goto error;
1750             err = at_tok_nextint(&line, &resp[0]);
1751             if (err < 0) goto error;
1752             err = at_tok_nexthexint(&line, &resp[1]);
1753             if (err < 0) goto error;
1754             err = at_tok_nexthexint(&line, &resp[2]);
1755             if (err < 0) goto error;
1756             err = at_tok_nextint(&line, &resp[3]);
1757             if (err < 0) goto error;
1758             count = 4;
1759         break;
1760         default:
1761             goto error;
1762     }
1763     s_lac = resp[1];
1764     s_cid = resp[2];
1765     if (response)
1766         *response = resp;
1767     if (items)
1768         *items = commas + 1;
1769     if (type)
1770         *type = techFromModemType(TECH(sMdmInfo));
1771     return 0;
1772 error:
1773     free(resp);
1774     return -1;
1775 }
1776 
1777 static int mapNetworkRegistrationResponse(int in_response) {
1778     int out_response = 0;
1779 
1780     switch (in_response) {
1781         case 0:
1782             out_response = RADIO_TECH_GPRS;    /* GPRS */
1783             break;
1784         case 3:
1785             out_response = RADIO_TECH_EDGE;    /* EDGE */
1786             break;
1787         case 2:
1788             out_response = RADIO_TECH_UMTS;    /* TD */
1789             break;
1790         case 4:
1791             out_response = RADIO_TECH_HSDPA;   /* HSDPA */
1792             break;
1793         case 5:
1794             out_response = RADIO_TECH_HSUPA;   /* HSUPA */
1795             break;
1796         case 6:
1797             out_response = RADIO_TECH_HSPA;    /* HSPA */
1798             break;
1799         case 15:
1800             out_response = RADIO_TECH_HSPAP;   /* HSPA+ */
1801             break;
1802         case 7:
1803             out_response = RADIO_TECH_LTE;     /* LTE */
1804             break;
1805         case 16:
1806             out_response = RADIO_TECH_LTE_CA;  /* LTE_CA */
1807             break;
1808         case 11:  // NR connected to a 5GCN
1809         case 12:  // NG-RAN
1810         case 13:  // E-UTRA-NR dual connectivity
1811             out_response = RADIO_TECH_NR;      /* NR */
1812             break;
1813         default:
1814             out_response = RADIO_TECH_UNKNOWN; /* UNKNOWN */
1815             break;
1816     }
1817     return out_response;
1818 }
1819 
1820 #define REG_STATE_LEN 18
1821 #define REG_DATA_STATE_LEN 14
1822 static void requestRegistrationState(int request, void *data __unused,
1823                                         size_t datalen __unused, RIL_Token t)
1824 {
1825     int err;
1826     int *registration;
1827     char **responseStr = NULL;
1828     ATResponse *p_response = NULL;
1829     const char *cmd;
1830     const char *prefix;
1831     char *line;
1832     int i = 0, j, numElements = 0;
1833     int count = 3;
1834     int type, startfrom;
1835 
1836     RLOGD("requestRegistrationState");
1837     if (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1838         cmd = "AT+CREG?";
1839         prefix = "+CREG:";
1840         numElements = REG_STATE_LEN;
1841     } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1842         cmd = "AT+CGREG?";
1843         prefix = "+CGREG:";
1844         numElements = REG_DATA_STATE_LEN;
1845         if (TECH_BIT(sMdmInfo) == MDM_LTE) {
1846             cmd = "AT+CEREG?";
1847             prefix = "+CEREG:";
1848         }
1849     } else {
1850         assert(0);
1851         goto error;
1852     }
1853 
1854     err = at_send_command_singleline(cmd, prefix, &p_response);
1855 
1856     if (err < 0 || !p_response->success) goto error;
1857 
1858     line = p_response->p_intermediates->line;
1859 
1860     if (parseRegistrationState(line, &type, &count, &registration)) goto error;
1861 
1862     responseStr = malloc(numElements * sizeof(char *));
1863     if (!responseStr) goto error;
1864     memset(responseStr, 0, numElements * sizeof(char *));
1865     /**
1866      * The first '4' bytes for both registration states remain the same.
1867      * But if the request is 'DATA_REGISTRATION_STATE',
1868      * the 5th and 6th byte(s) are optional.
1869      */
1870     if (is3gpp2(type) == 1) {
1871         RLOGD("registration state type: 3GPP2");
1872         // TODO: Query modem
1873         startfrom = 3;
1874         if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1875             asprintf(&responseStr[3], "8");     // EvDo revA
1876             asprintf(&responseStr[4], "1");     // BSID
1877             asprintf(&responseStr[5], "123");   // Latitude
1878             asprintf(&responseStr[6], "222");   // Longitude
1879             asprintf(&responseStr[7], "0");     // CSS Indicator
1880             asprintf(&responseStr[8], "4");     // SID
1881             asprintf(&responseStr[9], "65535"); // NID
1882             asprintf(&responseStr[10], "0");    // Roaming indicator
1883             asprintf(&responseStr[11], "1");    // System is in PRL
1884             asprintf(&responseStr[12], "0");    // Default Roaming indicator
1885             asprintf(&responseStr[13], "0");    // Reason for denial
1886             asprintf(&responseStr[14], "0");    // Primary Scrambling Code of Current cell
1887       } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1888             asprintf(&responseStr[3], "8");   // Available data radio technology
1889       }
1890     } else { // type == RADIO_TECH_3GPP
1891         RLOGD("registration state type: 3GPP");
1892         startfrom = 0;
1893         asprintf(&responseStr[1], "%x", registration[1]);
1894         asprintf(&responseStr[2], "%x", registration[2]);
1895         if (count > 3) {
1896             asprintf(&responseStr[3], "%d", mapNetworkRegistrationResponse(registration[3]));
1897         }
1898     }
1899     asprintf(&responseStr[0], "%d", registration[0]);
1900 
1901     /**
1902      * Optional bytes for DATA_REGISTRATION_STATE request
1903      * 4th byte : Registration denial code
1904      * 5th byte : The max. number of simultaneous Data Calls
1905      */
1906     if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1907         // asprintf(&responseStr[4], "3");
1908         // asprintf(&responseStr[5], "1");
1909         asprintf(&responseStr[11], "%d", s_mcc);
1910         asprintf(&responseStr[12], "%d", s_mnc);
1911         if (s_mncLength == 2) {
1912           asprintf(&responseStr[13], "%03d%02d", s_mcc, s_mnc);
1913         } else {
1914           asprintf(&responseStr[13], "%03d%03d", s_mcc, s_mnc);
1915         }
1916     } else {  // Voice
1917         asprintf(&responseStr[15], "%d", s_mcc);
1918         asprintf(&responseStr[16], "%d", s_mnc);
1919         if (s_mncLength == 2) {
1920           asprintf(&responseStr[17], "%03d%02d", s_mcc, s_mnc);
1921         } else {
1922           asprintf(&responseStr[17], "%03d%03d", s_mcc, s_mnc);
1923         }
1924     }
1925 
1926 
1927     for (j = startfrom; j < numElements; j++) {
1928         if (!responseStr[i]) goto error;
1929     }
1930     free(registration);
1931     registration = NULL;
1932     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, numElements*sizeof(responseStr));
1933     for (j = 0; j < numElements; j++ ) {
1934         free(responseStr[j]);
1935         responseStr[j] = NULL;
1936     }
1937     free(responseStr);
1938     responseStr = NULL;
1939     at_response_free(p_response);
1940 
1941     return;
1942 error:
1943     if (responseStr) {
1944         for (j = 0; j < numElements; j++) {
1945             free(responseStr[j]);
1946             responseStr[j] = NULL;
1947         }
1948         free(responseStr);
1949         responseStr = NULL;
1950     }
1951     RLOGE("requestRegistrationState must never return an error when radio is on");
1952     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1953     at_response_free(p_response);
1954 }
1955 
1956 static void requestOperator(void *data __unused, size_t datalen __unused, RIL_Token t)
1957 {
1958     int err;
1959     int i;
1960     int skip;
1961     ATLine *p_cur;
1962     char *response[3];
1963 
1964     memset(response, 0, sizeof(response));
1965 
1966     ATResponse *p_response = NULL;
1967 
1968     err = at_send_command_multiline(
1969         "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
1970         "+COPS:", &p_response);
1971 
1972     /* we expect 3 lines here:
1973      * +COPS: 0,0,"T - Mobile"
1974      * +COPS: 0,1,"TMO"
1975      * +COPS: 0,2,"310170"
1976      */
1977 
1978     if (err != 0) goto error;
1979 
1980     for (i = 0, p_cur = p_response->p_intermediates
1981             ; p_cur != NULL
1982             ; p_cur = p_cur->p_next, i++
1983     ) {
1984         char *line = p_cur->line;
1985 
1986         err = at_tok_start(&line);
1987         if (err < 0) goto error;
1988 
1989         err = at_tok_nextint(&line, &skip);
1990         if (err < 0) goto error;
1991 
1992         // If we're unregistered, we may just get
1993         // a "+COPS: 0" response
1994         if (!at_tok_hasmore(&line)) {
1995             response[i] = NULL;
1996             continue;
1997         }
1998 
1999         err = at_tok_nextint(&line, &skip);
2000         if (err < 0) goto error;
2001 
2002         // a "+COPS: 0, n" response is also possible
2003         if (!at_tok_hasmore(&line)) {
2004             response[i] = NULL;
2005             continue;
2006         }
2007 
2008         err = at_tok_nextstr(&line, &(response[i]));
2009         if (err < 0) goto error;
2010         // Simple assumption that mcc and mnc are 3 digits each
2011         int length = strlen(response[i]);
2012         if (length == 6) {
2013             s_mncLength = 3;
2014             if (sscanf(response[i], "%3d%3d", &s_mcc, &s_mnc) != 2) {
2015                 RLOGE("requestOperator expected mccmnc to be 6 decimal digits");
2016             }
2017         } else if (length == 5) {
2018             s_mncLength = 2;
2019             if (sscanf(response[i], "%3d%2d", &s_mcc, &s_mnc) != 2) {
2020                 RLOGE("requestOperator expected mccmnc to be 5 decimal digits");
2021             }
2022         }
2023     }
2024 
2025     if (i != 3) {
2026         /* expect 3 lines exactly */
2027         goto error;
2028     }
2029 
2030     RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
2031     at_response_free(p_response);
2032 
2033     return;
2034 error:
2035     RLOGE("requestOperator must not return error when radio is on");
2036     s_mncLength = 0;
2037     s_mcc = 0;
2038     s_mnc = 0;
2039     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2040     at_response_free(p_response);
2041 }
2042 
2043 static void requestCdmaSendSMS(void *data, size_t datalen, RIL_Token t)
2044 {
2045     int err = 1; // Set to go to error:
2046     RIL_SMS_Response response;
2047     RIL_CDMA_SMS_Message* rcsm;
2048 
2049     memset(&response, 0, sizeof(response));
2050 
2051     if (getSIMStatus() == SIM_ABSENT) {
2052         RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
2053         return;
2054     }
2055 
2056     RLOGD("requestCdmaSendSMS datalen=%zu, sizeof(RIL_CDMA_SMS_Message)=%zu",
2057             datalen, sizeof(RIL_CDMA_SMS_Message));
2058 
2059     // verify data content to test marshalling/unmarshalling:
2060     rcsm = (RIL_CDMA_SMS_Message*)data;
2061     RLOGD("TeleserviceID=%d, bIsServicePresent=%d, \
2062             uServicecategory=%d, sAddress.digit_mode=%d, \
2063             sAddress.Number_mode=%d, sAddress.number_type=%d, ",
2064             rcsm->uTeleserviceID,  rcsm->bIsServicePresent,
2065             rcsm->uServicecategory,rcsm->sAddress.digit_mode,
2066             rcsm->sAddress.number_mode,rcsm->sAddress.number_type);
2067 
2068     if (err != 0) goto error;
2069 
2070     // Cdma Send SMS implementation will go here:
2071     // But it is not implemented yet.
2072 
2073     response.messageRef = 1;
2074     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
2075     return;
2076 
2077 error:
2078     // Cdma Send SMS will always cause send retry error.
2079     response.messageRef = -1;
2080     RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
2081 }
2082 
2083 static void requestSendSMS(void *data, size_t datalen, RIL_Token t)
2084 {
2085     int err;
2086     const char *smsc;
2087     const char *pdu;
2088     int tpLayerLength;
2089     char *cmd1, *cmd2;
2090     RIL_SMS_Response response;
2091     ATResponse *p_response = NULL;
2092 
2093     if (getSIMStatus() == SIM_ABSENT) {
2094         RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
2095         return;
2096     }
2097 
2098     memset(&response, 0, sizeof(response));
2099     RLOGD("requestSendSMS datalen =%zu", datalen);
2100 
2101     if (s_ims_gsm_fail != 0) goto error;
2102     if (s_ims_gsm_retry != 0) goto error2;
2103 
2104     smsc = ((const char **)data)[0];
2105     pdu = ((const char **)data)[1];
2106 
2107     tpLayerLength = strlen(pdu)/2;
2108 
2109     // "NULL for default SMSC"
2110     if (smsc == NULL) {
2111         smsc= "00";
2112     }
2113 
2114     asprintf(&cmd1, "AT+CMGS=%d", tpLayerLength);
2115     asprintf(&cmd2, "%s%s", smsc, pdu);
2116 
2117     err = at_send_command_sms(cmd1, cmd2, "+CMGS:", &p_response);
2118 
2119     free(cmd1);
2120     free(cmd2);
2121 
2122     if (err != 0 || p_response->success == 0) goto error;
2123 
2124     int messageRef = 1;
2125     char *line = p_response->p_intermediates->line;
2126 
2127     err = at_tok_start(&line);
2128     if (err < 0) goto error;
2129 
2130     err = at_tok_nextint(&line, &messageRef);
2131     if (err < 0) goto error;
2132 
2133     /* FIXME fill in ackPDU */
2134     response.messageRef = messageRef;
2135     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
2136     at_response_free(p_response);
2137 
2138     return;
2139 error:
2140     response.messageRef = -2;
2141     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response));
2142     at_response_free(p_response);
2143     return;
2144 error2:
2145     // send retry error.
2146     response.messageRef = -1;
2147     RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
2148     at_response_free(p_response);
2149     return;
2150 }
2151 
2152 static void requestImsSendSMS(void *data, size_t datalen, RIL_Token t)
2153 {
2154     RIL_IMS_SMS_Message *p_args;
2155     RIL_SMS_Response response;
2156 
2157     memset(&response, 0, sizeof(response));
2158 
2159     RLOGD("requestImsSendSMS: datalen=%zu, "
2160         "registered=%d, service=%d, format=%d, ims_perm_fail=%d, "
2161         "ims_retry=%d, gsm_fail=%d, gsm_retry=%d",
2162         datalen, s_ims_registered, s_ims_services, s_ims_format,
2163         s_ims_cause_perm_failure, s_ims_cause_retry, s_ims_gsm_fail,
2164         s_ims_gsm_retry);
2165 
2166     // figure out if this is gsm/cdma format
2167     // then route it to requestSendSMS vs requestCdmaSendSMS respectively
2168     p_args = (RIL_IMS_SMS_Message *)data;
2169 
2170     if (0 != s_ims_cause_perm_failure ) goto error;
2171 
2172     // want to fail over ims and this is first request over ims
2173     if (0 != s_ims_cause_retry && 0 == p_args->retry) goto error2;
2174 
2175     if (RADIO_TECH_3GPP == p_args->tech) {
2176         return requestSendSMS(p_args->message.gsmMessage,
2177                 datalen - sizeof(RIL_RadioTechnologyFamily),
2178                 t);
2179     } else if (RADIO_TECH_3GPP2 == p_args->tech) {
2180         return requestCdmaSendSMS(p_args->message.cdmaMessage,
2181                 datalen - sizeof(RIL_RadioTechnologyFamily),
2182                 t);
2183     } else {
2184         RLOGE("requestImsSendSMS invalid format value =%d", p_args->tech);
2185     }
2186 
2187 error:
2188     response.messageRef = -2;
2189     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response));
2190     return;
2191 
2192 error2:
2193     response.messageRef = -1;
2194     RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
2195 }
2196 
2197 /**
2198  * Add for CTS test
2199  * If open logical channel with AID NULL, this means open logical channel to MF.
2200  * If there is P2 value, this P2 value is used for SELECT command.
2201  * In addition, if SELECT command returns 61xx, GET RESPONSE command needs to send to get data.
2202  */
2203 static int sendCmdAgainForOpenChannelWithP2( char *data,
2204                                         int p2, int *response, int *rspLen) {
2205     int len = 0;
2206     int err = -1;
2207     char *line = NULL;
2208     char cmd[64] = {0};
2209     RIL_Errno errType = RIL_E_GENERIC_FAILURE;
2210     ATResponse *p_response = NULL;
2211     RIL_SIM_IO_Response sr;
2212 
2213     memset(&sr, 0, sizeof(sr));
2214     sscanf(data, "%2x", &(response[0]));  // response[0] is channel number
2215 
2216     // Send SELECT command to MF
2217     snprintf(cmd, sizeof(cmd), "AT+CGLA=%d,14,00A400%02X023F00", response[0],
2218              p2);
2219 
2220     err = at_send_command_singleline(cmd, "+CGLA:", &p_response);
2221     if (err < 0) goto done;
2222     if (p_response->success == 0) {
2223         if (!strcmp(p_response->finalResponse, "+CME ERROR: 21") ||
2224             !strcmp(p_response->finalResponse, "+CME ERROR: 50")) {
2225             errType = RIL_E_GENERIC_FAILURE;
2226         }
2227         goto done;
2228     }
2229 
2230     line = p_response->p_intermediates->line;
2231 
2232     if (at_tok_start(&line) < 0 || at_tok_nextint(&line, &len) < 0 ||
2233         at_tok_nextstr(&line, &(sr.simResponse)) < 0) {
2234         goto done;
2235     }
2236 
2237     sscanf(&(sr.simResponse[len - 4]), "%02x%02x", &(sr.sw1), &(sr.sw2));
2238 
2239     if (sr.sw1 == 0x90 && sr.sw2 == 0x00) {  // 9000 is successful
2240         int length = len / 2;
2241         for (*rspLen = 1; *rspLen <= length; (*rspLen)++) {
2242             sscanf(sr.simResponse, "%02x", &(response[*rspLen]));
2243             sr.simResponse += 2;
2244         }
2245         errType = RIL_E_SUCCESS;
2246     } else {  // close channel
2247         snprintf(cmd, sizeof(cmd), "AT+CCHC=%d", response[0]);
2248         at_send_command( cmd, NULL);
2249     }
2250 
2251 done:
2252     at_response_free(p_response);
2253     return errType;
2254 }
2255 
2256 static void requestSimOpenChannel(void *data, size_t datalen, RIL_Token t)
2257 {
2258     RIL_UNUSED_PARM(datalen);
2259 
2260     ATResponse *p_response = NULL;
2261     int response[260] = {0};
2262     int responseLen = 1;
2263     int32_t session_id;
2264     int err;
2265     char cmd[64] = {0};
2266     char complex;
2267     char *line = NULL;
2268     int skip = 0;
2269     char *statusWord = NULL;
2270     int err_no = RIL_E_GENERIC_FAILURE;
2271 
2272     RIL_OpenChannelParams *params = (RIL_OpenChannelParams *)data;
2273 
2274     // Max length is 16 bytes according to 3GPP spec 27.007 section 8.45
2275     if (params->aidPtr == NULL) {
2276           err = at_send_command_singleline("AT+CSIM=10,\"0070000001\"", "+CSIM:", &p_response);
2277     } else {
2278         snprintf(cmd, sizeof(cmd), "AT+CCHO=%s", params->aidPtr);
2279         err = at_send_command_numeric(cmd, &p_response);
2280     }
2281 
2282     if (err < 0 || p_response == NULL || p_response->success == 0) {
2283         ALOGE("Error %d opening logical channel: %d",
2284               err, p_response ? p_response->success : 0);
2285         goto error;
2286     }
2287 
2288     // Ensure integer only by scanning for an extra char but expect one result
2289     line = p_response->p_intermediates->line;
2290     if (params->aidPtr == NULL) {
2291 
2292         err = at_tok_start(&line);
2293         if (err < 0) goto error;
2294 
2295         err = at_tok_nextint(&line, &skip);
2296         if (err < 0) goto error;
2297 
2298         err = at_tok_nextstr(&line, &statusWord);
2299         if (err < 0) goto error;
2300 
2301         if (params->p2 < 0) {
2302             int length = strlen(statusWord) / 2;
2303             for (responseLen = 0; responseLen < length; responseLen++) {
2304                 sscanf(statusWord, "%02x", &(response[responseLen]));
2305                 statusWord += 2;
2306             }
2307             err_no = RIL_E_SUCCESS;
2308         } else {
2309             response[0] = 1;
2310             err_no = sendCmdAgainForOpenChannelWithP2(statusWord,
2311                                         params->p2, response, &responseLen);
2312             if (err_no != RIL_E_SUCCESS) {
2313                 goto error;
2314             }
2315         }
2316         RIL_onRequestComplete(t, err_no, response, responseLen * sizeof(int));
2317         at_response_free(p_response);
2318         return;
2319     } else {
2320         if (sscanf(line, "%" SCNd32 "%c", &session_id, &complex) != 1) {
2321            ALOGE("Invalid AT response, expected integer, was '%s'", line);
2322            goto error;
2323         }
2324     }
2325 
2326     RIL_onRequestComplete(t, RIL_E_SUCCESS, &session_id, sizeof(session_id));
2327     at_response_free(p_response);
2328     return;
2329 
2330 error:
2331     RIL_onRequestComplete(t, err_no, NULL, 0);
2332     at_response_free(p_response);
2333     return;
2334 }
2335 
2336 static void requestSimCloseChannel(void *data, size_t datalen, RIL_Token t)
2337 {
2338     ATResponse *p_response = NULL;
2339     int32_t session_id;
2340     int err;
2341     char cmd[32];
2342 
2343     if (data == NULL || datalen != sizeof(session_id)) {
2344         ALOGE("Invalid data passed to requestSimCloseChannel");
2345         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2346         return;
2347     }
2348     session_id = ((int32_t *)data)[0];
2349     if (session_id == 0) {
2350         RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
2351         return;
2352     }
2353 
2354     snprintf(cmd, sizeof(cmd), "AT+CCHC=%" PRId32, session_id);
2355     err = at_send_command_singleline(cmd, "+CCHC", &p_response);
2356 
2357     if (err < 0 || p_response == NULL || p_response->success == 0) {
2358         ALOGE("Error %d closing logical channel %d: %d",
2359               err, session_id, p_response ? p_response->success : 0);
2360         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2361         at_response_free(p_response);
2362         return;
2363     }
2364 
2365     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2366 
2367     at_response_free(p_response);
2368 }
2369 
2370 static void requestSimTransmitApduChannel(void *data,
2371                                           size_t datalen,
2372                                           RIL_Token t)
2373 {
2374     ATResponse *p_response = NULL;
2375     int err;
2376     int len = 0;
2377     char *cmd;
2378     char *line = NULL;
2379     size_t cmd_size;
2380     RIL_SIM_IO_Response sr = {0};
2381     RIL_SIM_APDU *apdu = (RIL_SIM_APDU *)data;
2382 
2383     if (apdu == NULL || datalen != sizeof(RIL_SIM_APDU)) {
2384         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2385         return;
2386     }
2387 
2388     cmd_size = 10 + (apdu->data ? strlen(apdu->data) : 0);
2389     asprintf(&cmd, "AT+CGLA=%d,%zu,%02x%02x%02x%02x%02x%s",
2390              apdu->sessionid, cmd_size, apdu->cla, apdu->instruction,
2391              apdu->p1, apdu->p2, apdu->p3, apdu->data ? apdu->data : "");
2392 
2393     err = at_send_command_singleline(cmd, "+CGLA:", &p_response);
2394     free(cmd);
2395     if (err < 0 || p_response == NULL || p_response->success == 0) {
2396         ALOGE("Error %d transmitting APDU: %d",
2397               err, p_response ? p_response->success : 0);
2398         goto error;
2399     }
2400 
2401     line = p_response->p_intermediates->line;
2402     err = at_tok_start(&line);
2403     if (err < 0) goto error;
2404 
2405     err = at_tok_nextint(&line, &len);
2406     if (err < 0) goto error;
2407 
2408     err = at_tok_nextstr(&line, &(sr.simResponse));
2409     if (err < 0) goto error;
2410 
2411     len = strlen(sr.simResponse);
2412     if (len < 4) goto error;
2413 
2414     sscanf(&(sr.simResponse[len - 4]), "%02x%02x", &(sr.sw1), &(sr.sw2));
2415     sr.simResponse[len - 4] = '\0';
2416 
2417     RIL_onRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
2418     at_response_free(p_response);
2419     return;
2420 
2421 error:
2422     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2423     at_response_free(p_response);
2424 }
2425 
2426 static void requestSimAuthentication(int authContext, char* authData, RIL_Token t) {
2427     int err = -1, ret = 0;
2428     int status = 0;
2429     int binSimResponseLen = 0;
2430     char *cmd = NULL;
2431     char *line = NULL;
2432     // Input data
2433     int randLen = 0, autnLen = 0;
2434     char *rand = NULL, *autn = NULL;
2435     // EAP-SIM response data
2436     int kcLen = 0, sresLen = 0;
2437     char *kc = NULL, *sres = NULL;
2438     // EAP-AKA response data
2439     int ckLen = 0, ikLen = 0, resAutsLen = 0;
2440     char *ck = NULL, *ik = NULL, *resAuts = NULL;
2441     unsigned char *binSimResponse = NULL;
2442     unsigned char *binAuthData = NULL;
2443     unsigned char *hexAuthData = NULL;
2444     ATResponse *p_response = NULL;
2445     RIL_SIM_IO_Response response;
2446 
2447     memset(&response, 0, sizeof(response));
2448     response.sw1 = 0x90;
2449     response.sw2 = 0;
2450 
2451     binAuthData  =
2452             (unsigned char *)malloc(sizeof(*binAuthData) * strlen(authData));
2453     if (binAuthData == NULL) {
2454         goto error;
2455     }
2456     if(base64_decode(authData, binAuthData) <= 0) {
2457         RLOGE("base64_decode failed %s %d", __func__, __LINE__);
2458         goto error;
2459     }
2460     hexAuthData =
2461             (unsigned char *)malloc(strlen(authData) * 2 + sizeof(char));
2462     if (hexAuthData == NULL) {
2463         goto error;
2464     }
2465     memset(hexAuthData, 0, strlen(authData) * 2 + sizeof(char));
2466     convertBytesToHexString((char *)binAuthData, strlen(authData), hexAuthData);
2467 
2468     randLen = binAuthData[0];
2469     rand = (char *)malloc(sizeof(char) * (randLen * 2 + sizeof(char)));
2470     if (rand == NULL) {
2471         goto error;
2472     }
2473     memcpy(rand, hexAuthData + 2, randLen * 2);
2474     memcpy(rand + randLen * 2, "\0", 1);
2475 
2476     if (authContext == AUTH_CONTEXT_EAP_AKA) {
2477         // There's the autn value to parse as well.
2478         autnLen = binAuthData[1 + randLen];
2479         autn = (char*)malloc(sizeof(char) * (autnLen * 2 + sizeof(char)));
2480         if (autn == NULL) {
2481             goto error;
2482         }
2483         memcpy(autn, hexAuthData + 2 + randLen * 2 + 2, autnLen * 2);
2484         memcpy(autn + autnLen * 2, "\0", 1);
2485     }
2486 
2487     if (authContext == AUTH_CONTEXT_EAP_SIM) {
2488         ret = asprintf(&cmd, "AT^MBAU=\"%s\"", rand);
2489     } else {
2490         ret = asprintf(&cmd, "AT^MBAU=\"%s,%s\"", rand, autn);
2491     }
2492     if (ret < 0) {
2493         RLOGE("Failed to asprintf");
2494         goto error;
2495     }
2496     err = at_send_command_singleline( cmd, "^MBAU:", &p_response);
2497     free(cmd);
2498 
2499     if (err < 0 || p_response->success == 0) {
2500         goto error;
2501     }
2502     line = p_response->p_intermediates->line;
2503     err = at_tok_start(&line);
2504     if (err < 0) goto error;
2505 
2506     err = at_tok_nextint(&line, &status);
2507     if (err < 0) goto error;
2508     if (status != SIM_AUTH_RESPONSE_SUCCESS) {
2509         goto error;
2510     }
2511 
2512     if (authContext == AUTH_CONTEXT_EAP_SIM) {
2513         err = at_tok_nextstr(&line, &kc);
2514         if (err < 0) goto error;
2515         kcLen = strlen(kc);
2516 
2517         err = at_tok_nextstr(&line, &sres);
2518         if (err < 0) goto error;
2519         sresLen = strlen(sres);
2520 
2521         // sresLen + sres + kcLen + kc + '\0'
2522         binSimResponseLen = (kcLen + sresLen) / 2 + 3 * sizeof(char);
2523         binSimResponse = (unsigned char*)malloc(binSimResponseLen + sizeof(char));
2524         if (binSimResponse == NULL) goto error;
2525         memset(binSimResponse, 0, binSimResponseLen);
2526         // set sresLen and sres
2527         binSimResponse[0] = (sresLen / 2) & 0xFF;
2528         uint8_t* tmpBinSimResponse = convertHexStringToBytes(sres, sresLen);
2529         snprintf((char*)(binSimResponse + 1), sresLen / 2, "%s", tmpBinSimResponse);
2530         free(tmpBinSimResponse);
2531         tmpBinSimResponse = NULL;
2532         // set kcLen and kc
2533         binSimResponse[1 + sresLen / 2] = (kcLen / 2) & 0xFF;
2534         tmpBinSimResponse = convertHexStringToBytes(kc, kcLen);
2535         snprintf((char*)(binSimResponse + 1 + sresLen / 2 + 1), kcLen / 2, "%s", tmpBinSimResponse);
2536         free(tmpBinSimResponse);
2537         tmpBinSimResponse = NULL;
2538     } else {  // AUTH_CONTEXT_EAP_AKA
2539         err = at_tok_nextstr(&line, &ck);
2540         if (err < 0) goto error;
2541         ckLen = strlen(ck);
2542 
2543         err = at_tok_nextstr(&line, &ik);
2544         if (err < 0) goto error;
2545         ikLen = strlen(ik);
2546 
2547         err = at_tok_nextstr(&line, &resAuts);
2548         if (err < 0) goto error;
2549         resAutsLen = strlen(resAuts);
2550 
2551         // 0xDB + ckLen + ck + ikLen + ik + resAutsLen + resAuts + '\0'
2552         binSimResponseLen = (ckLen + ikLen + resAutsLen) / 2 + 5 * sizeof(char);
2553         binSimResponse = (unsigned char*)malloc(binSimResponseLen + sizeof(char));
2554         if (binSimResponse == NULL) goto error;
2555         memset(binSimResponse, 0, binSimResponseLen);
2556         // The DB prefix indicates successful auth. Not produced by the SIM.
2557         binSimResponse[0] = 0xDB;
2558         // Set ckLen and ck
2559         binSimResponse[1] = (ckLen / 2) & 0xFF;
2560         uint8_t* tmpBinSimResponse = convertHexStringToBytes(ck, ckLen);
2561         snprintf((char*)(binSimResponse + 2), ckLen / 2 + 1, "%s", tmpBinSimResponse);
2562         free(tmpBinSimResponse);
2563         tmpBinSimResponse = NULL;
2564         // Set ikLen and ik
2565         binSimResponse[2 + ckLen / 2] = (ikLen / 2) & 0xFF;
2566         tmpBinSimResponse = convertHexStringToBytes(ik, ikLen);
2567         snprintf((char*)(binSimResponse + 2 + ckLen / 2 + 1), ikLen / 2 + 1, "%s",
2568                  tmpBinSimResponse);
2569         free(tmpBinSimResponse);
2570         tmpBinSimResponse = NULL;
2571         // Set resAutsLen and resAuts
2572         binSimResponse[2 + ckLen / 2 + 1 + ikLen / 2] = (resAutsLen / 2) & 0xFF;
2573         tmpBinSimResponse = convertHexStringToBytes(resAuts, resAutsLen);
2574         snprintf((char*)(binSimResponse + 2 + ckLen / 2 + 1 + ikLen / 2 + 1), resAutsLen / 2 + 1,
2575                  "%s", tmpBinSimResponse);
2576         free(tmpBinSimResponse);
2577         tmpBinSimResponse = NULL;
2578     }
2579 
2580     response.simResponse = (char*)malloc(2 * binSimResponseLen + sizeof(char));
2581     if (response.simResponse == NULL) goto error;
2582     if (NULL == base64_encode(binSimResponse, response.simResponse, binSimResponseLen - 1)) {
2583         RLOGE("Failed to call base64_encode %s %d", __func__, __LINE__);
2584         goto error;
2585     }
2586 
2587     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
2588     at_response_free(p_response);
2589 
2590     free(binAuthData);
2591     free(hexAuthData);
2592     free(rand);
2593     free(autn);
2594     free(response.simResponse);
2595     free(binSimResponse);
2596     return;
2597 
2598 error:
2599     free(binAuthData);
2600     free(hexAuthData);
2601     free(rand);
2602     free(autn);
2603     free(response.simResponse);
2604     free(binSimResponse);
2605 
2606     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2607     at_response_free(p_response);
2608 }
2609 
2610 static void requestTransmitApduBasic( void *data, size_t datalen,
2611                                       RIL_Token t) {
2612     RIL_UNUSED_PARM(datalen);
2613 
2614     int err, len;
2615     int instruction = 0;
2616     char *cmd = NULL;
2617     char *line = NULL;
2618     RIL_SIM_APDU *p_args = NULL;
2619     ATResponse *p_response = NULL;
2620     RIL_SIM_IO_Response sr;
2621 
2622     memset(&sr, 0, sizeof(sr));
2623 
2624     p_args = (RIL_SIM_APDU *)data;
2625 
2626     if ((p_args->data == NULL) || (strlen(p_args->data) == 0)) {
2627         if (p_args->p3 < 0) {
2628             asprintf(&cmd, "AT+CSIM=%d,\"%02x%02x%02x%02x\"", 8, p_args->cla,
2629                     p_args->instruction, p_args->p1, p_args->p2);
2630         } else {
2631             asprintf(&cmd, "AT+CSIM=%d,\"%02x%02x%02x%02x%02x\"", 10,
2632                     p_args->cla, p_args->instruction, p_args->p1, p_args->p2,
2633                     p_args->p3);
2634         }
2635     } else {
2636         asprintf(&cmd, "AT+CSIM=%d,\"%02x%02x%02x%02x%02x%s\"",
2637                 10 + (int)strlen(p_args->data), p_args->cla,
2638                 p_args->instruction, p_args->p1, p_args->p2, p_args->p3,
2639                 p_args->data);
2640     }
2641     err = at_send_command_singleline(cmd, "+CSIM:", &p_response);
2642     free(cmd);
2643     if (err < 0 || p_response->success == 0) {
2644         goto error;
2645     }
2646 
2647     line = p_response->p_intermediates->line;
2648     err = at_tok_start(&line);
2649     if (err < 0) goto error;
2650 
2651     err = at_tok_nextint(&line, &len);
2652     if (err < 0) goto error;
2653 
2654     err = at_tok_nextstr(&line, &(sr.simResponse));
2655     if (err < 0) goto error;
2656 
2657     sscanf(&(sr.simResponse[len - 4]), "%02x%02x", &(sr.sw1), &(sr.sw2));
2658     sr.simResponse[len - 4] = '\0';
2659 
2660     instruction = p_args->instruction;
2661     RIL_onRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
2662     at_response_free(p_response);
2663     return;
2664 
2665 error:
2666     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2667     at_response_free(p_response);
2668 }
2669 
2670 static int getPDP() {
2671     int ret = -1;
2672 
2673     for (int i = 0; i < MAX_PDP; i++) {
2674         if (s_PDP[i].state == PDP_IDLE) {
2675             s_PDP[i].state = PDP_BUSY;
2676             ret = s_PDP[i].cid;
2677             break;
2678         }
2679     }
2680     return ret;
2681 }
2682 
2683 static void putPDP(int cid) {
2684     if (cid < 1 || cid > MAX_PDP ) {
2685         return;
2686     }
2687 
2688     s_PDP[cid - 1].state = PDP_IDLE;
2689 }
2690 
2691 static void requestSetupDataCall(void *data, size_t datalen, RIL_Token t)
2692 {
2693     const char *apn = NULL;
2694     char *cmd = NULL;
2695     int err = -1;
2696     int cid = -1;
2697     ATResponse *p_response = NULL;
2698 
2699     apn = ((const char **)data)[2];
2700 
2701 #ifdef USE_TI_COMMANDS
2702     // Config for multislot class 10 (probably default anyway eh?)
2703     err = at_send_command("AT%CPRIM=\"GMM\",\"CONFIG MULTISLOT_CLASS=<10>\"",
2704                         NULL);
2705 
2706     err = at_send_command("AT%DATA=2,\"UART\",1,,\"SER\",\"UART\",0", NULL);
2707 #endif /* USE_TI_COMMANDS */
2708 
2709     int fd, qmistatus;
2710     size_t cur = 0;
2711     size_t len;
2712     ssize_t written, rlen;
2713     char status[32] = {0};
2714     int retry = 10;
2715     const char *pdp_type;
2716 
2717     RLOGD("requesting data connection to APN '%s'", apn);
2718 
2719     fd = open ("/dev/qmi", O_RDWR);
2720     if (fd >= 0) { /* the device doesn't exist on the emulator */
2721 
2722         RLOGD("opened the qmi device\n");
2723         asprintf(&cmd, "up:%s", apn);
2724         len = strlen(cmd);
2725 
2726         while (cur < len) {
2727             do {
2728                 written = write (fd, cmd + cur, len - cur);
2729             } while (written < 0 && errno == EINTR);
2730 
2731             if (written < 0) {
2732                 RLOGE("### ERROR writing to /dev/qmi");
2733                 close(fd);
2734                 goto error;
2735             }
2736 
2737             cur += written;
2738         }
2739 
2740         // wait for interface to come online
2741 
2742         do {
2743             sleep(1);
2744             do {
2745                 rlen = read(fd, status, 31);
2746             } while (rlen < 0 && errno == EINTR);
2747 
2748             if (rlen < 0) {
2749                 RLOGE("### ERROR reading from /dev/qmi");
2750                 close(fd);
2751                 goto error;
2752             } else {
2753                 status[rlen] = '\0';
2754                 RLOGD("### status: %s", status);
2755             }
2756         } while (strncmp(status, "STATE=up", 8) && strcmp(status, "online") && --retry);
2757 
2758         close(fd);
2759 
2760         if (retry == 0) {
2761             RLOGE("### Failed to get data connection up\n");
2762             goto error;
2763         }
2764 
2765         qmistatus = system("netcfg rmnet0 dhcp");
2766 
2767         RLOGD("netcfg rmnet0 dhcp: status %d\n", qmistatus);
2768 
2769         if (qmistatus < 0) goto error;
2770 
2771     } else {
2772         const char* radioInterfaceName = getRadioInterfaceName();
2773         if (setInterfaceState(radioInterfaceName, kInterfaceUp) != RIL_E_SUCCESS) {
2774             goto error;
2775         }
2776 
2777         if (datalen > 6 * sizeof(char *)) {
2778             pdp_type = ((const char **)data)[6];
2779         } else {
2780             pdp_type = "IP";
2781         }
2782 
2783         cid = getPDP();
2784         if (cid < 1 ) goto error;
2785 
2786         asprintf(&cmd, "AT+CGDCONT=%d,\"%s\",\"%s\",,0,0", cid, pdp_type, apn);
2787         //FIXME check for error here
2788         err = at_send_command(cmd, NULL);
2789         free(cmd);
2790 
2791         // Set required QoS params to default
2792         err = at_send_command("AT+CGQREQ=1", NULL);
2793 
2794         // Set minimum QoS params to default
2795         err = at_send_command("AT+CGQMIN=1", NULL);
2796 
2797         // packet-domain event reporting
2798         err = at_send_command("AT+CGEREP=1,0", NULL);
2799 
2800         // Hangup anything that's happening there now
2801         err = at_send_command("AT+CGACT=1,0", NULL);
2802 
2803         // Start data on PDP context 1
2804         err = at_send_command("ATD*99***1#", &p_response);
2805 
2806         if (err < 0 || p_response->success == 0) {
2807             goto error;
2808         }
2809     }
2810 
2811     requestOrSendDataCallList(cid, &t);
2812 
2813     at_response_free(p_response);
2814 
2815     return;
2816 error:
2817     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2818     at_response_free(p_response);
2819 }
2820 
2821 static void requestDeactivateDataCall(void *data, RIL_Token t)
2822 {
2823     const char *p_cid = ((const char **)data)[0];
2824     int cid = p_cid ? atoi(p_cid) : -1;
2825     RIL_Errno rilErrno = RIL_E_GENERIC_FAILURE;
2826     if (cid < 1  || cid > MAX_PDP) {
2827         RIL_onRequestComplete(t, rilErrno, NULL, 0);
2828         return;
2829     }
2830 
2831     const char* radioInterfaceName = getRadioInterfaceName();
2832     rilErrno = setInterfaceState(radioInterfaceName, kInterfaceDown);
2833     RIL_onRequestComplete(t, rilErrno, NULL, 0);
2834     putPDP(cid);
2835 }
2836 
2837 static void requestSMSAcknowledge(void *data, size_t datalen __unused, RIL_Token t)
2838 {
2839     int ackSuccess;
2840     int err;
2841 
2842     if (getSIMStatus() == SIM_ABSENT) {
2843         RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2844         return;
2845     }
2846 
2847     ackSuccess = ((int *)data)[0];
2848 
2849     if (ackSuccess == 1) {
2850         err = at_send_command("AT+CNMA=1", NULL);
2851     } else if (ackSuccess == 0)  {
2852         err = at_send_command("AT+CNMA=2", NULL);
2853     } else {
2854         RLOGE("unsupported arg to RIL_REQUEST_SMS_ACKNOWLEDGE\n");
2855         goto error;
2856     }
2857 
2858     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2859 error:
2860     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2861 }
2862 
2863 void convertBytesToHex(uint8_t *bytes, int length, uint8_t *hex_str) {
2864     int i;
2865     unsigned char tmp;
2866 
2867     if (bytes == NULL || hex_str == NULL) {
2868         return;
2869     }
2870     for (i = 0; i < length; i++) {
2871         tmp = (unsigned char)((bytes[i] & 0xf0) >> 4);
2872         if (tmp <= 9) {
2873             *hex_str = (unsigned char)(tmp + '0');
2874         } else {
2875             *hex_str = (unsigned char)(tmp + 'A' - 10);
2876         }
2877         hex_str++;
2878         tmp = (unsigned char)(bytes[i] & 0x0f);
2879         if (tmp <= 9) {
2880             *hex_str = (unsigned char)(tmp + '0');
2881         } else {
2882             *hex_str = (unsigned char)(tmp + 'A' - 10);
2883         }
2884         hex_str++;
2885     }
2886 }
2887 
2888 #define TYPE_EF                                 4
2889 #define RESPONSE_EF_SIZE                        15
2890 #define TYPE_FILE_DES_LEN                       5
2891 #define RESPONSE_DATA_FILE_DES_FLAG             2
2892 #define RESPONSE_DATA_FILE_DES_LEN_FLAG         3
2893 #define RESPONSE_DATA_FILE_TYPE                 6
2894 #define RESPONSE_DATA_FILE_SIZE_1               2
2895 #define RESPONSE_DATA_FILE_SIZE_2               3
2896 #define RESPONSE_DATA_STRUCTURE                 13
2897 #define RESPONSE_DATA_RECORD_LENGTH             14
2898 #define RESPONSE_DATA_FILE_RECORD_LEN_1         6
2899 #define RESPONSE_DATA_FILE_RECORD_LEN_2         7
2900 #define EF_TYPE_TRANSPARENT                     0x01
2901 #define EF_TYPE_LINEAR_FIXED                    0x02
2902 #define EF_TYPE_CYCLIC                          0x06
2903 #define USIM_DATA_OFFSET_2                      2
2904 #define USIM_DATA_OFFSET_3                      3
2905 #define USIM_FILE_DES_TAG                       0x82
2906 #define USIM_FILE_SIZE_TAG                      0x80
2907 
2908 bool convertUsimToSim(uint8_t *byteUSIM, int len, uint8_t *hexSIM) {
2909     int desIndex = 0;
2910     int sizeIndex = 0;
2911     int i = 0;
2912     uint8_t byteSIM[RESPONSE_EF_SIZE] = {0};
2913     for (i = 0; i < len; i++) {
2914         if (byteUSIM[i] == USIM_FILE_DES_TAG) {
2915             desIndex = i;
2916             break;
2917         }
2918     }
2919     for (i = desIndex; i < len;) {
2920         if (byteUSIM[i] == USIM_FILE_SIZE_TAG) {
2921             sizeIndex = i;
2922             break;
2923         } else {
2924             i += (byteUSIM[i + 1] + 2);
2925         }
2926     }
2927     byteSIM[RESPONSE_DATA_FILE_SIZE_1] =
2928             byteUSIM[sizeIndex + USIM_DATA_OFFSET_2];
2929     byteSIM[RESPONSE_DATA_FILE_SIZE_2] =
2930             byteUSIM[sizeIndex + USIM_DATA_OFFSET_3];
2931     byteSIM[RESPONSE_DATA_FILE_TYPE] = TYPE_EF;
2932     if ((byteUSIM[desIndex + RESPONSE_DATA_FILE_DES_FLAG] & 0x07) ==
2933         EF_TYPE_TRANSPARENT) {
2934         byteSIM[RESPONSE_DATA_STRUCTURE] = 0;
2935     } else if ((byteUSIM[desIndex + RESPONSE_DATA_FILE_DES_FLAG] & 0x07) ==
2936                 EF_TYPE_LINEAR_FIXED) {
2937         if (USIM_FILE_DES_TAG != byteUSIM[RESPONSE_DATA_FILE_DES_FLAG]) {
2938             RLOGE("USIM_FILE_DES_TAG != ...");
2939             goto error;
2940         }
2941         if (TYPE_FILE_DES_LEN != byteUSIM[RESPONSE_DATA_FILE_DES_LEN_FLAG]) {
2942             goto error;
2943         }
2944         byteSIM[RESPONSE_DATA_STRUCTURE] = 1;
2945         byteSIM[RESPONSE_DATA_RECORD_LENGTH] =
2946                 ((byteUSIM[RESPONSE_DATA_FILE_RECORD_LEN_1] & 0xff) << 8) +
2947                 (byteUSIM[RESPONSE_DATA_FILE_RECORD_LEN_2] & 0xff);
2948     } else if ((byteUSIM[desIndex + RESPONSE_DATA_FILE_DES_FLAG] & 0x07) ==
2949                 EF_TYPE_CYCLIC) {
2950         byteSIM[RESPONSE_DATA_STRUCTURE] = 3;
2951         byteSIM[RESPONSE_DATA_RECORD_LENGTH] =
2952                 ((byteUSIM[RESPONSE_DATA_FILE_RECORD_LEN_1] & 0xff) << 8) +
2953                 (byteUSIM[RESPONSE_DATA_FILE_RECORD_LEN_2] & 0xff);
2954     }
2955 
2956     convertBytesToHex(byteSIM, RESPONSE_EF_SIZE, hexSIM);
2957     return true;
2958 
2959 error:
2960     return false;
2961 }
2962 
2963 static void  requestSIM_IO(void *data, size_t datalen __unused, RIL_Token t)
2964 {
2965     ATResponse *p_response = NULL;
2966     RIL_SIM_IO_Response sr;
2967     int err;
2968     char *cmd = NULL;
2969     RIL_SIM_IO_v6 *p_args;
2970     char *line;
2971 
2972     /* For Convert USIM to SIM */
2973     uint8_t hexSIM[RESPONSE_EF_SIZE * 2 + sizeof(char)] = {0};
2974 
2975     memset(&sr, 0, sizeof(sr));
2976 
2977     p_args = (RIL_SIM_IO_v6 *)data;
2978 
2979     /* FIXME handle pin2 */
2980 
2981     if (p_args->data == NULL) {
2982         asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d",
2983                     p_args->command, p_args->fileid,
2984                     p_args->p1, p_args->p2, p_args->p3);
2985     } else {
2986         asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d,%s",
2987                     p_args->command, p_args->fileid,
2988                     p_args->p1, p_args->p2, p_args->p3, p_args->data);
2989     }
2990 
2991     err = at_send_command_singleline(cmd, "+CRSM:", &p_response);
2992 
2993     if (err < 0 || p_response->success == 0) {
2994         goto error;
2995     }
2996 
2997     line = p_response->p_intermediates->line;
2998 
2999     err = parseSimResponseLine(line, &sr);
3000     if (err < 0) {
3001         goto error;
3002     }
3003     if (sr.simResponse != NULL &&  // Default to be USIM card
3004         p_args->command == 192) {  // Get response
3005         uint8_t *bytes = convertHexStringToBytes(sr.simResponse, strlen(sr.simResponse));
3006         if (bytes == NULL) {
3007             RLOGE("Failed to convert sim response to bytes");
3008             goto error;
3009         }
3010         if (bytes[0] != 0x62) {
3011             RLOGE("Wrong FCP flag, unable to convert to sim ");
3012             free(bytes);
3013             goto error;
3014         }
3015         if (convertUsimToSim(bytes, strlen(sr.simResponse) / 2, hexSIM)) {
3016           sr.simResponse = (char *)hexSIM;
3017         }
3018         free(bytes);
3019     }
3020 
3021     RIL_onRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
3022     at_response_free(p_response);
3023     free(cmd);
3024     return;
3025 
3026 error:
3027     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3028     at_response_free(p_response);
3029     free(cmd);
3030 }
3031 
3032 static int getSimlockRemainTimes(const char* type) {
3033     int err = -1;
3034     int remain_times = -1;
3035     char cmd[32] = {0};
3036     char *line = NULL;
3037     char *lock_type = NULL;
3038     ATResponse *p_response = NULL;
3039 
3040     snprintf(cmd, sizeof(cmd), "AT+CPINR=\"%s\"", type);
3041     err = at_send_command_multiline(cmd, "+CPINR:", &p_response);
3042     if (err < 0 || p_response->success == 0) {
3043         goto error;
3044     }
3045 
3046     line = p_response->p_intermediates->line;
3047     err = at_tok_start(&line);
3048     if (err < 0) goto error;
3049 
3050     err = at_tok_nextstr(&line, &lock_type);
3051     if (err < 0) goto error;
3052 
3053     err = at_tok_nextint(&line, &remain_times);
3054     if (err < 0) goto error;
3055 
3056 error:
3057     at_response_free(p_response);
3058     return remain_times;
3059 }
3060 
3061 static void  requestEnterSimPin(int request, void*  data, size_t  datalen, RIL_Token  t)
3062 {
3063     ATResponse   *p_response = NULL;
3064     int           err;
3065     int           remaintimes = -1;
3066     char*         cmd = NULL;
3067     const char**  strings = (const char**)data;;
3068 
3069     if (datalen == sizeof(char*) || datalen == 2 * sizeof(char*)) {
3070         asprintf(&cmd, "AT+CPIN=%s", strings[0]);
3071     } else
3072         goto error;
3073 
3074     err = at_send_command_singleline(cmd, "+CPIN:", &p_response);
3075     free(cmd);
3076 
3077     if (err < 0 || p_response->success == 0) {
3078 error:
3079         if (request == RIL_REQUEST_ENTER_SIM_PIN) {
3080             remaintimes = getSimlockRemainTimes("SIM PIN");
3081         } else if (request == RIL_REQUEST_ENTER_SIM_PIN2) {
3082             remaintimes = getSimlockRemainTimes("SIM PIN2");
3083         }
3084         RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &remaintimes,
3085             sizeof(remaintimes));
3086     } else {
3087         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3088     }
3089     at_response_free(p_response);
3090 }
3091 
3092 static void  requestChangeSimPin(int request, void*  data, size_t  datalen, RIL_Token  t)
3093 {
3094     ATResponse   *p_response = NULL;
3095     int           err;
3096     int           remaintimes = -1;
3097     char*         cmd = NULL;
3098     const char**  strings = (const char**)data;;
3099 
3100     if (datalen == 2 * sizeof(char*) || datalen == 3 * sizeof(char*)) {
3101         asprintf(&cmd, "AT+CPIN=%s,%s", strings[0], strings[1]);
3102     } else
3103         goto error;
3104 
3105     err = at_send_command_singleline(cmd, "+CPIN:", &p_response);
3106     free(cmd);
3107 
3108     if (err < 0 || p_response->success == 0) {
3109 error:
3110         if (request == RIL_REQUEST_CHANGE_SIM_PIN) {
3111             remaintimes = getSimlockRemainTimes("SIM PIN");
3112         } else if (request == RIL_REQUEST_ENTER_SIM_PUK) {
3113             remaintimes = getSimlockRemainTimes("SIM PUK");
3114         } else if (request == RIL_REQUEST_ENTER_SIM_PUK2) {
3115           remaintimes = getSimlockRemainTimes("SIM PUK2");
3116         }
3117         RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &remaintimes,
3118             sizeof(remaintimes));
3119     } else {
3120         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3121     }
3122     at_response_free(p_response);
3123 }
3124 
3125 static void requestChangeSimPin2(void *data, size_t datalen, RIL_Token t) {
3126     int err, ret;
3127     int remaintime = -1;
3128     char cmd[64] = {0};
3129     const char **strings = (const char **)data;
3130     ATResponse *p_response = NULL;
3131 
3132     if (datalen != 3 * sizeof(char *)) {
3133         goto error;
3134     }
3135 
3136     snprintf(cmd, sizeof(cmd), "AT+CPWD=\"P2\",\"%s\",\"%s\"", strings[0],
3137              strings[1]);
3138     err = at_send_command(cmd, &p_response);
3139     if (err < 0 || p_response->success == 0) {
3140         remaintime = getSimlockRemainTimes("SIM PIN2");
3141         goto error;
3142     }
3143 
3144     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3145     at_response_free(p_response);
3146     return;
3147 
3148 error:
3149     RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &remaintime,
3150                           sizeof(remaintime));
3151     at_response_free(p_response);
3152 }
3153 
3154 static void  requestSendUSSD(void *data, size_t datalen, RIL_Token t)
3155 {
3156     RIL_UNUSED_PARM(datalen);
3157 
3158     int err = -1;
3159     char cmd[128] = {0};
3160     const char *ussdRequest = (char *)(data);
3161     ATResponse *p_response = NULL;
3162 
3163     snprintf(cmd, sizeof(cmd), "AT+CUSD=1,\"%s\"", ussdRequest);
3164     err = at_send_command(cmd, &p_response);
3165     if (err < 0 || p_response->success == 0) {
3166         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3167     } else {
3168         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3169     }
3170     at_response_free(p_response);
3171 }
3172 
3173 static void requestExitEmergencyMode(void *data __unused, size_t datalen __unused, RIL_Token t)
3174 {
3175     int err;
3176     ATResponse *p_response = NULL;
3177 
3178     err = at_send_command("AT+WSOS=0", &p_response);
3179 
3180     if (err < 0 || p_response->success == 0) {
3181         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3182         return;
3183     }
3184 
3185     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3186 }
3187 
3188 static uint64_t s_last_activity_info_query = 0;
3189 
3190 static void requestGetActivityInfo(void *data __unused, size_t datalen __unused, RIL_Token t)
3191 {
3192     uint64_t curTime = ril_nano_time();
3193     RIL_ActivityStatsInfo stats =
3194     {
3195         0, // sleep_mode_time_ms
3196         ((curTime - s_last_activity_info_query) / 1000000) - 1, // idle_mode_time_ms
3197         {0, 0, 0, 0, 0}, // tx_mode_time_ms
3198         0 // rx_mode_time_ms
3199     };
3200     s_last_activity_info_query = curTime;
3201 
3202     RIL_onRequestComplete(t, RIL_E_SUCCESS, &stats, sizeof(stats));
3203 }
3204 
3205 // TODO: Use all radio types
3206 static int techFromModemType(int mdmtype)
3207 {
3208     int ret = -1;
3209     switch (mdmtype) {
3210         case MDM_CDMA:
3211             ret = RADIO_TECH_1xRTT;
3212             break;
3213         case MDM_EVDO:
3214             ret = RADIO_TECH_EVDO_A;
3215             break;
3216         case MDM_GSM:
3217             ret = RADIO_TECH_GPRS;
3218             break;
3219         case MDM_WCDMA:
3220             ret = RADIO_TECH_HSPA;
3221             break;
3222         case MDM_LTE:
3223             ret = RADIO_TECH_LTE;
3224         case MDM_NR:
3225             ret = RADIO_TECH_NR;
3226             break;
3227     }
3228     return ret;
3229 }
3230 
3231 static void requestGetCellInfoList(void *data __unused, size_t datalen __unused, RIL_Token t)
3232 {
3233     uint64_t curTime = ril_nano_time();
3234     RIL_CellInfo_v12 ci[1] =
3235     {
3236         { // ci[0]
3237             1, // cellInfoType
3238             1, // registered
3239             RIL_TIMESTAMP_TYPE_MODEM,
3240             curTime - 1000, // Fake some time in the past
3241             { // union CellInfo
3242                 {  // RIL_CellInfoGsm gsm
3243                     {  // gsm.cellIdneityGsm
3244                         s_mcc, // mcc
3245                         s_mnc, // mnc
3246                         s_lac, // lac
3247                         s_cid, // cid
3248                         0, //arfcn unknown
3249                         0x1, // Base Station Identity Code set to arbitrarily 1
3250                     },
3251                     {  // gsm.signalStrengthGsm
3252                         10, // signalStrength
3253                         0  // bitErrorRate
3254                         , INT_MAX // timingAdvance invalid value
3255                     }
3256                 }
3257             }
3258         }
3259     };
3260 
3261     RIL_onRequestComplete(t, RIL_E_SUCCESS, ci, sizeof(ci));
3262 }
3263 
3264 
3265 static void requestSetCellInfoListRate(void *data, size_t datalen __unused, RIL_Token t)
3266 {
3267     // For now we'll save the rate but no RIL_UNSOL_CELL_INFO_LIST messages
3268     // will be sent.
3269     assert (datalen == sizeof(int));
3270     s_cell_info_rate_ms = ((int *)data)[0];
3271 
3272     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3273 }
3274 
3275 static void requestGetHardwareConfig(void *data, size_t datalen, RIL_Token t)
3276 {
3277    // TODO - hook this up with real query/info from radio.
3278 
3279    RIL_HardwareConfig hwCfg;
3280 
3281    RIL_UNUSED_PARM(data);
3282    RIL_UNUSED_PARM(datalen);
3283 
3284    hwCfg.type = -1;
3285 
3286    RIL_onRequestComplete(t, RIL_E_SUCCESS, &hwCfg, sizeof(hwCfg));
3287 }
3288 
3289 static void requestGetTtyMode(void *data, size_t datalen, RIL_Token t)
3290 {
3291    int  ttyModeResponse;
3292 
3293    RIL_UNUSED_PARM(data);
3294    RIL_UNUSED_PARM(datalen);
3295 
3296    ttyModeResponse = (getSIMStatus() == SIM_READY) ? 1  // TTY Full
3297                                                    : 0; // TTY Off
3298 
3299    RIL_onRequestComplete(t, RIL_E_SUCCESS, &ttyModeResponse, sizeof(ttyModeResponse));
3300 }
3301 
3302 static void requestGetRadioCapability(void *data, size_t datalen, RIL_Token t)
3303 {
3304    RIL_RadioCapability radioCapability;
3305 
3306    RIL_UNUSED_PARM(data);
3307    RIL_UNUSED_PARM(datalen);
3308 
3309    radioCapability.version = RIL_RADIO_CAPABILITY_VERSION;
3310    radioCapability.session = 0;
3311    radioCapability.phase   = 0;
3312    radioCapability.rat     = NR | LTE | WCDMA | GSM;
3313    strncpy(radioCapability.logicalModemUuid, "com.android.modem.simulator", MAX_UUID_LENGTH);
3314    radioCapability.status  = RC_STATUS_SUCCESS;
3315 
3316    RIL_onRequestComplete(t, RIL_E_SUCCESS, &radioCapability, sizeof(radioCapability));
3317 }
3318 
3319 static void requestSetRadioCapability(void *data, size_t datalen, RIL_Token t)
3320 {
3321   RIL_RadioCapability* rc = (RIL_RadioCapability*)data;
3322   RLOGV(
3323       "RadioCapability version %d session %d phase %d rat %d "
3324       "logicalModemUuid %s status %d",
3325       rc->version, rc->session, rc->phase, rc->rat, rc->logicalModemUuid,
3326       rc->status);
3327   // TODO(ender): do something about these numbers.
3328   RIL_onRequestComplete(t, RIL_E_SUCCESS, rc, datalen);
3329 }
3330 
3331 static void requestGetMute(void *data, size_t datalen, RIL_Token t)
3332 {
3333     RIL_UNUSED_PARM(data);
3334     RIL_UNUSED_PARM(datalen);
3335 
3336     int err = -1;
3337     int muteResponse = 0;  // Mute disabled
3338     char *line = NULL;
3339     ATResponse *p_response = NULL;
3340 
3341     err = at_send_command_singleline("AT+CMUT?", "+CMUT:", &p_response);
3342     if (err < 0 || p_response->success) {
3343         goto done;
3344     }
3345 
3346     line = p_response->p_intermediates->line;
3347     err = at_tok_start(&line);
3348     if (err < 0) goto done;
3349 
3350     at_tok_nextint(&line, &muteResponse);
3351 
3352 done:
3353     RIL_onRequestComplete(t, RIL_E_SUCCESS, &muteResponse, sizeof(muteResponse));
3354     at_response_free(p_response);
3355 }
3356 
3357 static void requestSetMute(void *data, size_t datalen, RIL_Token t)
3358 {
3359     RIL_UNUSED_PARM(datalen);
3360 
3361     int err = -1;
3362     char cmd[64] = {0};
3363     ATResponse *p_response = NULL;
3364 
3365     snprintf(cmd, sizeof(cmd), "AT+CMUT=%d", ((int *)data)[0]);
3366     err = at_send_command(cmd, &p_response);
3367     if (err < 0 || p_response->success) {
3368       RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3369     } else {
3370       RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3371     }
3372     at_response_free(p_response);
3373 }
3374 
3375 static void requestScreenState(void *data, RIL_Token t)
3376 {
3377     int status = *((int *)data);
3378 
3379     if (!status) {
3380         /* Suspend */
3381         at_send_command("AT+CEREG=1", NULL);
3382         at_send_command("AT+CREG=1", NULL);
3383         at_send_command("AT+CGREG=1", NULL);
3384     } else {
3385        /* Resume */
3386         at_send_command("AT+CEREG=2", NULL);
3387         at_send_command("AT+CREG=2", NULL);
3388         at_send_command("AT+CGREG=2", NULL);
3389     }
3390 
3391    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3392 }
3393 
3394 static void requestQueryClip(void *data, size_t datalen, RIL_Token t)
3395 {
3396     RIL_UNUSED_PARM(datalen);
3397     RIL_UNUSED_PARM(data);
3398 
3399     int err = -1;
3400     int skip = 0;
3401     int response = 0;
3402     char *line = NULL;
3403     ATResponse *p_response = NULL;
3404 
3405     if (getSIMStatus() == SIM_ABSENT) {
3406         RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
3407         return;
3408     }
3409 
3410     err = at_send_command_singleline("AT+CLIP?", "+CLIP:", &p_response);
3411     if (err < 0 || p_response->success == 0) {
3412         goto error;
3413     }
3414 
3415     line = p_response->p_intermediates->line;
3416     err = at_tok_start(&line);
3417     if (err < 0) goto error;
3418 
3419     err = at_tok_nextint(&line, &skip);
3420     if (err < 0) goto error;
3421 
3422     err = at_tok_nextint(&line, &response);
3423     if (err < 0) goto error;
3424 
3425     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
3426     at_response_free(p_response);
3427     return;
3428 
3429 error:
3430     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3431     at_response_free(p_response);
3432 }
3433 
3434 static void requestQueryClir(void *data, size_t datalen, RIL_Token t)
3435 {
3436     RIL_UNUSED_PARM(datalen);
3437     RIL_UNUSED_PARM(data);
3438 
3439     int err = -1;
3440     int response[2] = {1, 1};
3441     char *line = NULL;
3442     ATResponse *p_response = NULL;
3443 
3444     if (getSIMStatus() == SIM_ABSENT) {
3445         RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
3446         return;
3447     }
3448 
3449     err = at_send_command_singleline("AT+CLIR?", "+CLIR:", &p_response);
3450     if (err < 0 || p_response->success == 0) {
3451         goto error;
3452     }
3453 
3454     line = p_response->p_intermediates->line;
3455     err = at_tok_start(&line);
3456     if (err < 0) goto error;
3457 
3458     err = at_tok_nextint(&line, &response[0]);
3459     if (err < 0) goto error;
3460 
3461     err = at_tok_nextint(&line, &response[1]);
3462     if (err < 0) goto error;
3463 
3464     RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
3465     at_response_free(p_response);
3466     return;
3467 
3468 error:
3469     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3470     at_response_free(p_response);
3471 }
3472 
3473 static void requestSetClir(void *data, size_t datalen, RIL_Token t)
3474 {
3475     RIL_UNUSED_PARM(datalen);
3476 
3477     int err = -1;
3478     int n = ((int *)data)[0];
3479     char cmd[64] = {0};
3480     ATResponse *p_response = NULL;
3481 
3482     snprintf(cmd, sizeof(cmd), "AT+CLIR=%d", n);
3483     err = at_send_command(cmd, &p_response);
3484     if (err < 0 || p_response->success == 0) {
3485         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3486     } else {
3487         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3488     }
3489     at_response_free(p_response);
3490 }
3491 
3492 static int forwardFromCCFCULine(char *line, RIL_CallForwardInfo *p_forward) {
3493     int err = -1;
3494     int i = 0;
3495 
3496     if (line == NULL || p_forward == NULL) {
3497       goto error;
3498     }
3499 
3500     err = at_tok_start(&line);
3501     if (err < 0) goto error;
3502 
3503     err = at_tok_nextint(&line, &(p_forward->status));
3504     if (err < 0) goto error;
3505 
3506     err = at_tok_nextint(&line, &(p_forward->serviceClass));
3507     if (err < 0) goto error;
3508 
3509     if (at_tok_hasmore(&line)) {
3510         int numberType = 0;
3511         err = at_tok_nextint(&line, &numberType);
3512         if (err < 0) goto error;
3513 
3514         err = at_tok_nextint(&line, &p_forward->toa);
3515         if (err < 0) goto error;
3516 
3517         err = at_tok_nextstr(&line, &(p_forward->number));
3518 
3519         /* tolerate null here */
3520         if (err < 0) return 0;
3521 
3522         if (at_tok_hasmore(&line)) {
3523             for (i = 0; i < 2; i++) {
3524                 skipNextComma(&line);
3525             }
3526 
3527             if (at_tok_hasmore(&line)) {
3528                 err = at_tok_nextint(&line, &p_forward->timeSeconds);
3529                 if (err < 0) {
3530                     p_forward->timeSeconds = 0;
3531                 }
3532             }
3533         }
3534     }
3535 
3536     return 0;
3537 
3538 error:
3539     return -1;
3540 }
3541 
3542 static void requestSetCallForward(RIL_CallForwardInfo *data,
3543                                   size_t datalen, RIL_Token t) {
3544     int err = -1;
3545     char cmd[128] = {0};
3546     size_t offset = 0;
3547     ATResponse *p_response = NULL;
3548 
3549     if (datalen != sizeof(*data) ||
3550             (data->status == 3 && data->number == NULL)) {
3551         goto error;
3552     }
3553 
3554     snprintf(cmd, sizeof(cmd), "AT+CCFCU=%d,%d,%d,%d,\"%s\",%d",
3555                             data->reason,
3556                             data->status,
3557                             2,
3558                             data->toa,
3559                             data->number ? data->number : "",
3560                             data->serviceClass);
3561     offset += strlen(cmd);
3562 
3563     if (data->serviceClass == 0) {
3564         if (data->timeSeconds != 0 && data->status == 3) {
3565             snprintf(cmd + offset, sizeof(cmd) - offset, ",\"\",\"\",,%d",
3566                 data->timeSeconds);
3567         }
3568     } else {
3569         if (data->timeSeconds != 0 && data->status == 3) {
3570             snprintf(cmd + offset, sizeof(cmd) - offset, ",\"\",\"\",,%d",
3571                 data->timeSeconds);
3572         } else {
3573             strlcat(cmd, ",\"\"", sizeof(cmd) - offset);
3574         }
3575     }
3576 
3577     err = at_send_command_multiline(cmd, "+CCFCU:", &p_response);
3578     if (err < 0 || p_response->success == 0) {
3579         goto error;
3580     }
3581 
3582     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3583     at_response_free(p_response);
3584     return;
3585 
3586 error:
3587     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3588     at_response_free(p_response);
3589 }
3590 
3591 static void requestQueryCallForward(RIL_CallForwardInfo *data,
3592                                     size_t datalen, RIL_Token t) {
3593     int err = -1;
3594     char cmd[128] = {0};
3595     ATResponse *p_response = NULL;
3596     ATLine *p_cur = NULL;
3597 
3598     if (datalen != sizeof(*data)) {
3599         goto error;
3600     }
3601 
3602     snprintf(cmd, sizeof(cmd), "AT+CCFCU=%d,2,%d,%d,\"%s\",%d", data->reason, 2,
3603             data->toa, data->number ? data->number : "", data->serviceClass);
3604 
3605     err = at_send_command_multiline(cmd, "+CCFCU:", &p_response);
3606     if (err < 0 || p_response->success == 0) {
3607         goto error;
3608     }
3609 
3610     RIL_CallForwardInfo **forwardList = NULL, *forwardPool = NULL;
3611     int forwardCount = 0;
3612     int validCount = 0;
3613     int i = 0;
3614 
3615     for (p_cur = p_response->p_intermediates; p_cur != NULL;
3616          p_cur = p_cur->p_next, forwardCount++) {
3617     }
3618 
3619     forwardList = (RIL_CallForwardInfo **)
3620         alloca(forwardCount * sizeof(RIL_CallForwardInfo *));
3621 
3622     forwardPool = (RIL_CallForwardInfo *)
3623         alloca(forwardCount * sizeof(RIL_CallForwardInfo));
3624 
3625     memset(forwardPool, 0, forwardCount * sizeof(RIL_CallForwardInfo));
3626 
3627     /* init the pointer array */
3628     for (i = 0; i < forwardCount; i++) {
3629         forwardList[i] = &(forwardPool[i]);
3630     }
3631 
3632     for (p_cur = p_response->p_intermediates; p_cur != NULL;
3633          p_cur = p_cur->p_next) {
3634         err = forwardFromCCFCULine(p_cur->line, forwardList[validCount]);
3635         forwardList[validCount]->reason = data->reason;
3636         if (err == 0) validCount++;
3637     }
3638 
3639     RIL_onRequestComplete(t, RIL_E_SUCCESS, validCount ? forwardList : NULL,
3640                           validCount * sizeof (RIL_CallForwardInfo *));
3641     at_response_free(p_response);
3642     return;
3643 
3644 error:
3645     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3646     at_response_free(p_response);
3647 }
3648 
3649 static void requestQueryCallWaiting(void *data, size_t datalen, RIL_Token t) {
3650     RIL_UNUSED_PARM(datalen);
3651 
3652     int err = -1, mode = 0;
3653     int serviceClass = ((int *)data)[0];
3654     int response[2] = {0, 0};
3655     char cmd[32] = {0};
3656     char *line;
3657     ATLine *p_cur;
3658     ATResponse *p_response = NULL;
3659 
3660     if (serviceClass == 0) {
3661         snprintf(cmd, sizeof(cmd), "AT+CCWA=1,2");
3662     } else {
3663         snprintf(cmd, sizeof(cmd), "AT+CCWA=1,2,%d", serviceClass);
3664     }
3665     err = at_send_command_multiline(cmd, "+CCWA:", &p_response);
3666     if (err < 0 || p_response->success == 0) {
3667         goto error;
3668     }
3669 
3670     for (p_cur = p_response->p_intermediates; p_cur != NULL;
3671          p_cur = p_cur->p_next) {
3672         line = p_cur->line;
3673         err = at_tok_start(&line);
3674         if (err < 0) goto error;
3675 
3676         err = at_tok_nextint(&line, &mode);
3677         if (err < 0) goto error;
3678 
3679         err = at_tok_nextint(&line, &serviceClass);
3680         if (err < 0) goto error;
3681 
3682         response[0] = mode;
3683         response[1] |= serviceClass;
3684     }
3685     RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
3686     at_response_free(p_response);
3687     return;
3688 
3689 error:
3690     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3691     at_response_free(p_response);
3692 }
3693 
3694 static void requestSetCallWaiting(void *data, size_t datalen, RIL_Token t) {
3695     RIL_UNUSED_PARM(datalen);
3696 
3697     ATResponse *p_response = NULL;
3698     int err = -1;
3699     char cmd[32] = {0};
3700     int enable = ((int *)data)[0];
3701     int serviceClass = ((int *)data)[1];
3702 
3703     if (serviceClass == 0) {
3704         snprintf(cmd, sizeof(cmd), "AT+CCWA=1,%d", enable);
3705     } else {
3706         snprintf(cmd, sizeof(cmd), "AT+CCWA=1,%d,%d", enable, serviceClass);
3707     }
3708 
3709     err = at_send_command(cmd,  &p_response);
3710     if (err < 0 || p_response->success == 0) {
3711         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3712     } else {
3713         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3714     }
3715     at_response_free(p_response);
3716 }
3717 
3718 static void requestSetSuppServiceNotifications(void *data, size_t datalen,
3719                                                RIL_Token t) {
3720     RIL_UNUSED_PARM(datalen);
3721 
3722     int err = 0;
3723     ATResponse *p_response = NULL;
3724     int mode = ((int *)data)[0];
3725     char cmd[32] = {0};
3726 
3727     snprintf(cmd, sizeof(cmd), "AT+CSSN=%d,%d", mode, mode);
3728     err = at_send_command(cmd, &p_response);
3729     if (err < 0 || p_response->success == 0) {
3730         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3731     } else {
3732         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3733     }
3734     at_response_free(p_response);
3735 }
3736 
3737 static void requestChangeBarringPassword(char **data, size_t datalen, RIL_Token t) {
3738     int err = -1;
3739     int result;
3740     char cmd[64] = {0};
3741     ATResponse *p_response = NULL;
3742 
3743     if (datalen != 3 * sizeof(char *) || data[0] == NULL || data[1] == NULL ||
3744         data[2] == NULL || strlen(data[0]) == 0 ||  strlen(data[1]) == 0 ||
3745         strlen(data[2]) == 0) {
3746         RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
3747         return;
3748     }
3749 
3750     snprintf(cmd, sizeof(cmd), "AT+CPWD=\"%s\",\"%s\",\"%s\"", data[0], data[1],
3751              data[2]);
3752 
3753     err = at_send_command(cmd, &p_response);
3754     if (err < 0 || p_response->success == 0) {
3755         goto error;
3756     }
3757     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3758     at_response_free(p_response);
3759     return;
3760 
3761 error:
3762     RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, NULL, 0);
3763     at_response_free(p_response);
3764 }
3765 
3766 static void requestFacilityLock(int request, char **data,
3767                                 size_t datalen, RIL_Token t) {
3768     int err = -1;
3769     int status = 0;
3770     int serviceClass = 0;
3771     int remainTimes = 10;
3772     char cmd[128] = {0};
3773     char *line = NULL;
3774     ATLine *p_cur = NULL;
3775     ATResponse *p_response = NULL;
3776     RIL_Errno errnoType = RIL_E_GENERIC_FAILURE;
3777 
3778     char *type = data[0];
3779 
3780     if (datalen != 5 * sizeof(char *)) {
3781         goto error;
3782     }
3783     if (data[0] == NULL || data[1] == NULL ||
3784        (data[2] == NULL && request == RIL_REQUEST_SET_FACILITY_LOCK) ||
3785         strlen(data[0]) == 0 || strlen(data[1]) == 0 ||
3786        (request == RIL_REQUEST_SET_FACILITY_LOCK && strlen(data[2]) == 0 )) {
3787         errnoType = RIL_E_INVALID_ARGUMENTS;
3788         RLOGE("FacilityLock invalid arguments");
3789         goto error;
3790     }
3791 
3792     serviceClass = atoi(data[3]);
3793     if (serviceClass == 0) {
3794         snprintf(cmd, sizeof(cmd), "AT+CLCK=\"%s\",%c,\"%s\"", data[0], *data[1],
3795                  data[2]);
3796     } else {
3797         snprintf(cmd, sizeof(cmd), "AT+CLCK=\"%s\",%c,\"%s\",%s", data[0],
3798                  *data[1], data[2], data[3]);
3799     }
3800 
3801     if (*data[1] == '2') {  // query status
3802         err = at_send_command_multiline(cmd, "+CLCK: ", &p_response);
3803         if (err < 0 || p_response->success == 0) {
3804             goto error;
3805         }
3806         line = p_response->p_intermediates->line;
3807 
3808         err = at_tok_start(&line);
3809         if (err < 0) goto error;
3810 
3811         err = at_tok_nextint(&line, &status);
3812         if (err < 0) goto error;
3813 
3814         RIL_onRequestComplete(t, RIL_E_SUCCESS, &status, sizeof(int));
3815         at_response_free(p_response);
3816         return;
3817     } else {  // unlock/lock this facility
3818         err = at_send_command(cmd, &p_response);
3819         if (err < 0 || p_response->success == 0) {
3820             errnoType = RIL_E_PASSWORD_INCORRECT;
3821             goto error;
3822         }
3823         errnoType = RIL_E_SUCCESS;
3824     }
3825 
3826 error:
3827     if (!strcmp(data[0], "SC")) {
3828         remainTimes = getSimlockRemainTimes("SIM PIN");
3829     } else if (!strcmp(data[0], "FD")) {
3830         remainTimes = getSimlockRemainTimes("SIM PIN2");
3831     } else {
3832         remainTimes = 1;
3833     }
3834 
3835     RIL_onRequestComplete(t, errnoType, &remainTimes, sizeof(remainTimes));
3836     at_response_free(p_response);
3837 }
3838 
3839 static void requestSetSmscAddress(void *data, size_t datalen, RIL_Token t)
3840 {
3841     ATResponse   *p_response = NULL;
3842     char          cmd[64] = {0};
3843     int           err = -1;
3844 
3845     if (getSIMStatus() != SIM_READY) {
3846          RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
3847          return;
3848     }
3849 
3850     if (data == NULL || strlen(data) == 0) {
3851         RLOGE("SET_SMSC_ADDRESS invalid address: %s", (char *)data);
3852         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3853         return;
3854     }
3855 
3856     snprintf(cmd, sizeof(cmd), "AT+CSCA=%s,%d", (char *)data, (int)datalen);
3857 
3858     err = at_send_command_singleline(cmd, "+CSCA:", &p_response);
3859     if (err < 0 || p_response->success == 0) {
3860         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3861     } else {
3862         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3863     }
3864     at_response_free(p_response);
3865 }
3866 
3867 static void requestGetSmscAddress(void *data, size_t datalen, RIL_Token t)
3868 {
3869     RIL_UNUSED_PARM(data);
3870     RIL_UNUSED_PARM(datalen);
3871 
3872     ATResponse   *p_response = NULL;
3873     int           err = -1;
3874     char         *decidata = NULL;
3875 
3876     err = at_send_command_singleline( "AT+CSCA?", "+CSCA:", &p_response);
3877     if (err < 0 || p_response->success == 0) {
3878        goto error;
3879     }
3880 
3881     char *line = p_response->p_intermediates->line;
3882     err = at_tok_start(&line);
3883     if (err < 0) goto error;
3884 
3885     err = at_tok_nextstr(&line, &decidata);
3886     if (err < 0) goto error;
3887 
3888     RIL_onRequestComplete(t, RIL_E_SUCCESS, decidata, strlen(decidata) + 1);
3889     at_response_free(p_response);
3890     return;
3891 
3892 error:
3893     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3894     at_response_free(p_response);
3895 }
3896 
3897 static void setGsmBroadcastConfigData(int from, int to, int id, int outStrSize, char *outStr) {
3898     if (from < 0 || from > 0xffff || to < 0 || to > 0xffff) {
3899         RLOGE("setGsmBroadcastConfig data is invalid, [%d, %d]", from, to);
3900         return;
3901     }
3902 
3903     if (id != 0) {
3904         strlcat(outStr, ",", outStrSize);
3905     }
3906 
3907     int len = strlen(outStr);
3908     if (from == to) {
3909         snprintf(outStr + len, outStrSize - len, "%d", from);
3910     } else {
3911         snprintf(outStr + len, outStrSize - len, "%d-%d", from, to);
3912     }
3913 }
3914 
3915 static void requestSetSmsBroadcastConfig(void *data, size_t datalen,
3916                                          RIL_Token t) {
3917     int i = 0;
3918     int count = datalen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
3919     int size = count * 16;
3920     char cmd[256] = {0};
3921     char *channel = (char *)alloca(size);
3922     char *languageId = (char *)alloca(size);
3923     ATResponse *p_response = NULL;
3924     RIL_GSM_BroadcastSmsConfigInfo **pGsmBci =
3925             (RIL_GSM_BroadcastSmsConfigInfo **)data;
3926     RIL_GSM_BroadcastSmsConfigInfo gsmBci = {0};
3927 
3928     memset(channel, 0, size);
3929     memset(languageId, 0, size);
3930     RLOGD("requestSetGsmBroadcastConfig %zu, count %d", datalen, count);
3931 
3932     for (i = 0; i < count; i++) {
3933         gsmBci = *(pGsmBci[i]);
3934         setGsmBroadcastConfigData(gsmBci.fromServiceId, gsmBci.toServiceId, i,
3935                                   size, channel);
3936         setGsmBroadcastConfigData(gsmBci.fromCodeScheme, gsmBci.toCodeScheme, i,
3937                                   size, languageId);
3938     }
3939 
3940     snprintf(cmd, sizeof(cmd), "AT+CSCB=%d,\"%s\",\"%s\"",
3941             (*pGsmBci[0]).selected ? 0 : 1, channel, languageId);
3942     int err = at_send_command_singleline( cmd, "+CSCB:", &p_response);
3943 
3944     if (err < 0 || p_response->success == 0) {
3945         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3946     } else {
3947         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3948     }
3949     at_response_free(p_response);
3950 }
3951 
3952 static void requestGetSmsBroadcastConfig(void *data, size_t datalen,
3953                                          RIL_Token t) {
3954     RIL_UNUSED_PARM(data);
3955     RIL_UNUSED_PARM(datalen);
3956 
3957     ATResponse *p_response = NULL;
3958     int err = -1, mode, commas = 0, i = 0;
3959     char *line = NULL;
3960     char *serviceIds = NULL, *codeSchemes = NULL, *p = NULL;
3961     char *serviceId = NULL, *codeScheme = NULL;
3962 
3963     err = at_send_command_singleline("AT+CSCB?", "+CSCB:", &p_response);
3964     if (err < 0 || p_response->success == 0) {
3965         goto error;
3966     }
3967 
3968     line = p_response->p_intermediates->line;
3969     err = at_tok_start(&line);
3970     if (err < 0) goto error;
3971 
3972     err = at_tok_nextint(&line, &mode);
3973     if (err < 0) goto error;
3974 
3975     err = at_tok_nextstr(&line, &serviceIds);
3976     if (err < 0) goto error;
3977 
3978     err = at_tok_nextstr(&line, &codeSchemes);
3979     if (err < 0) goto error;
3980 
3981     for (p = serviceIds; *p != '\0'; p++) {
3982         if (*p == ',') {
3983             commas++;
3984         }
3985     }
3986     RIL_GSM_BroadcastSmsConfigInfo **pGsmBci =
3987         (RIL_GSM_BroadcastSmsConfigInfo **)alloca((commas + 1) *
3988             sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
3989     memset(pGsmBci, 0, (commas + 1) * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
3990 
3991     for (i = 0; i < commas + 1; i++) {
3992         pGsmBci[i] = (RIL_GSM_BroadcastSmsConfigInfo *)alloca(
3993                 sizeof(RIL_GSM_BroadcastSmsConfigInfo));
3994         memset(pGsmBci[i], 0, sizeof(RIL_GSM_BroadcastSmsConfigInfo));
3995 
3996         err = at_tok_nextstr(&serviceIds, &serviceId);
3997         if (err < 0) goto error;
3998         pGsmBci[i]->toServiceId = pGsmBci[i]->fromServiceId = 0;
3999         if (strstr(serviceId, "-")) {
4000             sscanf(serviceId,"%d-%d", &pGsmBci[i]->fromServiceId,
4001                    &pGsmBci[i]->toServiceId);
4002         }
4003 
4004         err = at_tok_nextstr(&codeSchemes, &codeScheme);
4005         if (err < 0) goto error;
4006         pGsmBci[i]->toCodeScheme = pGsmBci[i]->fromCodeScheme = 0;
4007         if (strstr(codeScheme, "-")) {
4008             sscanf(codeScheme, "%d-%d", &pGsmBci[i]->fromCodeScheme,
4009                    &pGsmBci[i]->toCodeScheme);
4010         }
4011 
4012         pGsmBci[i]->selected = (mode == 0 ? false : true);
4013     }
4014     RIL_onRequestComplete(t, RIL_E_SUCCESS, pGsmBci,
4015         (commas + 1) * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
4016     at_response_free(p_response);
4017     return;
4018 
4019 error:
4020     at_response_free(p_response);
4021     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4022 }
4023 
4024 /**
4025  * <AcT>: integer type; access technology selected
4026  * 0 GSM
4027  * 1 GSM Compact
4028  * 2 UTRAN
4029  * 3 GSM w/EGPRS (see NOTE 1)
4030  * 4 UTRAN w/HSDPA (see NOTE 2)
4031  * 5 UTRAN w/HSUPA (see NOTE 2)
4032  * 6 UTRAN w/HSDPA and HSUPA (see NOTE 2)
4033  * 7 E-UTRAN
4034  * 8 EC-GSM-IoT (A/Gb mode) (see NOTE 3)
4035  * 9 E-UTRAN (NB-S1 mode) (see NOTE 4)
4036  * 10  E-UTRA connected to a 5GCN (see NOTE 5)
4037  * 11  NR connected to a 5GCN (see NOTE 5)
4038  * 12  NG-RAN
4039  * 13  E-UTRA-NR dual connectivity (see NOTE 6)
4040  */
4041 int mapRadioAccessNetworkToTech(RIL_RadioAccessNetworks network) {
4042     switch (network) {
4043         case GERAN:  // GSM EDGE
4044             return 3;
4045         case UTRAN:
4046             return 6;
4047         case EUTRAN:
4048             return 7;
4049         case NGRAN:
4050             return 11;
4051         default:
4052             return 7;  // LTE
4053     }
4054 }
4055 
4056 static void requestSetNetworlSelectionManual(void *data, RIL_Token t) {
4057     int err = -1;
4058     char cmd[64] = {0};
4059     ATResponse *p_response = NULL;
4060     RIL_NetworkOperator *operator = (RIL_NetworkOperator *)data;
4061 
4062     if (operator->act != UNKNOWN) {
4063         snprintf(cmd, sizeof(cmd), "AT+COPS=1,2,\"%s\"", operator->operatorNumeric);
4064     } else {
4065         snprintf(cmd, sizeof(cmd), "AT+COPS=1,2,\"%s\",%d",
4066             operator->operatorNumeric, operator->act);
4067     }
4068     err = at_send_command(cmd, &p_response);
4069     if (err < 0 || p_response->success == 0) {
4070         goto error;
4071     }
4072 
4073     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4074     at_response_free(p_response);
4075     return;
4076 
4077 error:
4078     if (p_response != NULL &&
4079         !strcmp(p_response->finalResponse, "+CME ERROR: 30")) {
4080           RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
4081     } else {
4082         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4083     }
4084     at_response_free(p_response);
4085 }
4086 
4087 static void requestStkServiceIsRunning(RIL_Token t)
4088 {
4089     int err = -1;
4090     ATResponse *p_response = NULL;
4091 
4092     s_stkServiceRunning = true;
4093     if (NULL != s_stkUnsolResponse) {
4094        RIL_onUnsolicitedResponse(RIL_UNSOL_STK_PROACTIVE_COMMAND,
4095                             s_stkUnsolResponse, strlen(s_stkUnsolResponse) + 1);
4096        free(s_stkUnsolResponse);
4097        s_stkUnsolResponse = NULL;
4098        RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4099        return;
4100     }
4101 
4102     err = at_send_command_singleline("AT+CUSATD?", "+CUSATD:", &p_response);
4103 
4104     if (err < 0 || p_response->success == 0) {
4105         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4106     } else {
4107         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4108     }
4109     at_response_free(p_response);
4110 }
4111 
4112 static void requestStkSendEnvelope(void *data, RIL_Token t)
4113 {
4114     int ret = -1, err = -1;
4115     char cmd[128] = {0};
4116     ATResponse *p_response = NULL;
4117 
4118     if (data == NULL || strlen((char *)data) == 0) {
4119         RLOGE("STK sendEnvelope data is invalid");
4120         RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
4121         return;
4122     }
4123 
4124     snprintf(cmd, sizeof(cmd), "AT+CUSATE=\"%s\"", (char *)data);
4125     err = at_send_command_singleline(cmd, "+CUSATE:", &p_response);
4126     if (err < 0 || p_response->success == 0) {
4127         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4128     } else {
4129         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4130 
4131         // type of alpha data is 85, such as 850C546F6F6C6B6974204D656E75
4132         char *p = strstr(p_response->p_intermediates->line, "85");
4133         if (p != NULL) {
4134             char alphaStrHexLen[3] = {0};
4135             char alphaStr[1024] = {0};
4136             uint8_t *alphaBytes = NULL;
4137             int len = 0;
4138 
4139             p = p + strlen("85");
4140             strncpy(alphaStrHexLen, p, 2);
4141             len = strtoul(alphaStrHexLen, NULL, 16);
4142             strncpy(alphaStr, p + 2, len * 2);
4143             alphaBytes = convertHexStringToBytes(alphaStr, strlen(alphaStr));
4144             RIL_onUnsolicitedResponse(RIL_UNSOL_STK_CC_ALPHA_NOTIFY, alphaBytes,
4145                                       strlen((char *)alphaBytes));
4146             free(alphaBytes);
4147         }
4148     }
4149     at_response_free(p_response);
4150 }
4151 
4152 static void requestStksendTerminalResponse(void *data, RIL_Token t)
4153 {
4154     int ret = -1, err = -1;
4155     char cmd[128] = {0};
4156     ATResponse *p_response = NULL;
4157 
4158     if (data == NULL || strlen((char *)data) == 0) {
4159         RLOGE("STK sendTerminalResponse data is invalid");
4160         RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
4161         return;
4162     }
4163 
4164     snprintf(cmd, sizeof(cmd), "AT+CUSATT=\"%s\"", (char *)data);
4165     err = at_send_command_singleline( cmd, "+CUSATT:", &p_response);
4166     if (err < 0 || p_response->success == 0) {
4167         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4168     } else {
4169         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4170     }
4171     at_response_free(p_response);
4172 }
4173 
4174 static void requestEccDial(void *data, RIL_Token t) {
4175     char cmd[64] = {0};
4176     const char *clir = NULL;
4177     int err = -1;
4178     RIL_EmergencyDial *p_eccDial = (RIL_EmergencyDial *)data;
4179 
4180     switch (p_eccDial->dialInfo.clir) {
4181         case 0:  /* subscription default */
4182             clir = "";
4183             break;
4184         case 1:  /* invocation */
4185             clir = "I";
4186             break;
4187         case 2:  /* suppression */
4188             clir = "i";
4189             break;
4190         default:
4191             break;
4192     }
4193 
4194     if (p_eccDial->routing == ROUTING_MERGENCY ||
4195         p_eccDial->routing ==  ROUTING_UNKNOWN) {
4196       if (p_eccDial->categories == CATEGORY_UNSPECIFIED) {
4197           snprintf(cmd, sizeof(cmd), "ATD%s@,#%s;", p_eccDial->dialInfo.address, clir);
4198       } else {
4199           snprintf(cmd, sizeof(cmd), "ATD%s@%d,#%s;", p_eccDial->dialInfo.address,
4200               p_eccDial->categories, clir);
4201       }
4202     } else {  // ROUTING_NORMAL
4203         snprintf(cmd, sizeof(cmd), "ATD%s%s;", p_eccDial->dialInfo.address, clir);
4204     }
4205 
4206     err = at_send_command(cmd, NULL);
4207     if (err != 0) goto error;
4208 
4209     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4210     return;
4211 
4212 error:
4213     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4214 }
4215 
4216 void getConfigSlotStatus(RIL_SimSlotStatus_V1_2 *pSimSlotStatus) {
4217     if (pSimSlotStatus == NULL) {
4218         return;
4219     }
4220     if (getSIMStatus() == SIM_ABSENT) {
4221         pSimSlotStatus->base.cardState = RIL_CARDSTATE_ABSENT;
4222     } else {
4223         pSimSlotStatus->base.cardState = RIL_CARDSTATE_PRESENT;
4224     }
4225     // TODO: slot state is always active now
4226     pSimSlotStatus->base.slotState = SLOT_STATE_ACTIVE;
4227 
4228     if (pSimSlotStatus->base.cardState != RIL_CARDSTATE_ABSENT) {
4229         pSimSlotStatus->base.atr = "";
4230         pSimSlotStatus->base.iccid = (char *)calloc(64, sizeof(char));
4231         getIccId(pSimSlotStatus->base.iccid, 64);
4232     }
4233 
4234     pSimSlotStatus->base.logicalSlotId = 0;
4235     pSimSlotStatus->eid = "";
4236 }
4237 
4238 void onIccSlotStatus(RIL_Token t) {
4239     RIL_SimSlotStatus_V1_2 *pSimSlotStatusList =
4240         (RIL_SimSlotStatus_V1_2 *)calloc(SIM_COUNT, sizeof(RIL_SimSlotStatus_V1_2));
4241 
4242     getConfigSlotStatus(pSimSlotStatusList);
4243 
4244     if (t == NULL) {
4245         RIL_onUnsolicitedResponse(RIL_UNSOL_CONFIG_ICC_SLOT_STATUS, pSimSlotStatusList,
4246                  SIM_COUNT * sizeof(RIL_SimSlotStatus_V1_2));
4247     } else {
4248         RIL_onRequestComplete(t, RIL_E_SUCCESS, pSimSlotStatusList,
4249                 SIM_COUNT * sizeof(RIL_SimSlotStatus_V1_2));
4250     }
4251 
4252     if (pSimSlotStatusList != NULL) {
4253         free(pSimSlotStatusList->base.iccid);
4254         free(pSimSlotStatusList);
4255     }
4256 }
4257 
4258 /*** Callback methods from the RIL library to us ***/
4259 
4260 /**
4261  * Call from RIL to us to make a RIL_REQUEST
4262  *
4263  * Must be completed with a call to RIL_onRequestComplete()
4264  *
4265  * RIL_onRequestComplete() may be called from any thread, before or after
4266  * this function returns.
4267  *
4268  * Because onRequest function could be called from multiple different thread,
4269  * we must ensure that the underlying at_send_command_* function
4270  * is atomic.
4271  */
4272 static void
4273 onRequest (int request, void *data, size_t datalen, RIL_Token t)
4274 {
4275     ATResponse *p_response;
4276     int err;
4277 
4278     RLOGD("onRequest: %s, sState: %d", requestToString(request), sState);
4279 
4280     /* Ignore all requests except RIL_REQUEST_GET_SIM_STATUS
4281      * when RADIO_STATE_UNAVAILABLE.
4282      */
4283     if (sState == RADIO_STATE_UNAVAILABLE
4284         && request != RIL_REQUEST_GET_SIM_STATUS
4285     ) {
4286         RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
4287         return;
4288     }
4289 
4290     /* Ignore all non-power requests when RADIO_STATE_OFF
4291      * (except RIL_REQUEST_GET_SIM_STATUS)
4292      */
4293     if (sState == RADIO_STATE_OFF) {
4294         switch(request) {
4295             case RIL_REQUEST_BASEBAND_VERSION:
4296             case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
4297             case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
4298             case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
4299             case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
4300             case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
4301             case RIL_REQUEST_CDMA_SUBSCRIPTION:
4302             case RIL_REQUEST_DEVICE_IDENTITY:
4303             case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
4304             case RIL_REQUEST_GET_ACTIVITY_INFO:
4305             case RIL_REQUEST_GET_CARRIER_RESTRICTIONS:
4306             case RIL_REQUEST_GET_CURRENT_CALLS:
4307             case RIL_REQUEST_GET_IMEI:
4308             case RIL_REQUEST_GET_MUTE:
4309             case RIL_REQUEST_SET_MUTE:
4310             case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
4311             case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
4312             case RIL_REQUEST_GET_RADIO_CAPABILITY:
4313             case RIL_REQUEST_GET_SIM_STATUS:
4314             case RIL_REQUEST_NV_RESET_CONFIG:
4315             case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
4316             case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
4317             case RIL_REQUEST_QUERY_TTY_MODE:
4318             case RIL_REQUEST_RADIO_POWER:
4319             case RIL_REQUEST_SET_BAND_MODE:
4320             case RIL_REQUEST_SET_CARRIER_RESTRICTIONS:
4321             case RIL_REQUEST_SET_LOCATION_UPDATES:
4322             case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
4323             case RIL_REQUEST_SET_TTY_MODE:
4324             case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
4325             case RIL_REQUEST_STOP_LCE:
4326             case RIL_REQUEST_VOICE_RADIO_TECH:
4327             case RIL_REQUEST_SCREEN_STATE:
4328                 // Process all the above, even though the radio is off
4329                 break;
4330 
4331             default:
4332                 // For all others, say NOT_AVAILABLE because the radio is off
4333                 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
4334                 return;
4335         }
4336     }
4337 
4338     switch (request) {
4339         case RIL_REQUEST_GET_SIM_STATUS: {
4340             RIL_CardStatus_v1_5 *p_card_status;
4341             char *p_buffer;
4342             int buffer_size;
4343 
4344             int result = getCardStatus(&p_card_status);
4345             if (result == RIL_E_SUCCESS) {
4346                 p_buffer = (char *)p_card_status;
4347                 buffer_size = sizeof(*p_card_status);
4348             } else {
4349                 p_buffer = NULL;
4350                 buffer_size = 0;
4351             }
4352             RIL_onRequestComplete(t, result, p_buffer, buffer_size);
4353             freeCardStatus(p_card_status);
4354             break;
4355         }
4356         case RIL_REQUEST_GET_CURRENT_CALLS:
4357             requestGetCurrentCalls(data, datalen, t);
4358             break;
4359         case RIL_REQUEST_DIAL:
4360             requestDial(data, datalen, t);
4361             break;
4362         case RIL_REQUEST_HANGUP:
4363             requestHangup(data, datalen, t);
4364             break;
4365         case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
4366         case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
4367         case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
4368         case RIL_REQUEST_CONFERENCE:
4369         case RIL_REQUEST_UDUB:
4370              requestCallSelection(data, datalen, t, request);
4371              break;
4372         case RIL_REQUEST_ANSWER:
4373             at_send_command("ATA", NULL);
4374 
4375 #ifdef WORKAROUND_ERRONEOUS_ANSWER
4376             s_expectAnswer = 1;
4377 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
4378 
4379             if (getSIMStatus() != SIM_READY) {
4380                 RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
4381             } else {
4382                 // Success or failure is ignored by the upper layer here.
4383                 // It will call GET_CURRENT_CALLS and determine success that way.
4384                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4385             }
4386             break;
4387 
4388         case RIL_REQUEST_SEPARATE_CONNECTION:
4389             {
4390                 char  cmd[12];
4391                 int   party = ((int*)data)[0];
4392 
4393                 if (getSIMStatus() == SIM_ABSENT) {
4394                     RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
4395                     return;
4396                 }
4397                 // Make sure that party is in a valid range.
4398                 // (Note: The Telephony middle layer imposes a range of 1 to 7.
4399                 // It's sufficient for us to just make sure it's single digit.)
4400                 if (party > 0 && party < 10) {
4401                     sprintf(cmd, "AT+CHLD=2%d", party);
4402                     at_send_command(cmd, NULL);
4403                     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4404                 } else {
4405                     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4406                 }
4407             }
4408             break;
4409 
4410         case RIL_REQUEST_SIGNAL_STRENGTH:
4411             requestSignalStrength(data, datalen, t);
4412             break;
4413         case RIL_REQUEST_VOICE_REGISTRATION_STATE:
4414         case RIL_REQUEST_DATA_REGISTRATION_STATE:
4415             requestRegistrationState(request, data, datalen, t);
4416             break;
4417         case RIL_REQUEST_OPERATOR:
4418             requestOperator(data, datalen, t);
4419             break;
4420         case RIL_REQUEST_RADIO_POWER:
4421             requestRadioPower(data, datalen, t);
4422             break;
4423         case RIL_REQUEST_DTMF: {
4424             char c = ((char *)data)[0];
4425             char *cmd;
4426             asprintf(&cmd, "AT+VTS=%c", (int)c);
4427             at_send_command(cmd, NULL);
4428             free(cmd);
4429             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4430             break;
4431         }
4432         case RIL_REQUEST_SEND_SMS:
4433         case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
4434             requestSendSMS(data, datalen, t);
4435             break;
4436         case RIL_REQUEST_CDMA_SEND_SMS:
4437             requestCdmaSendSMS(data, datalen, t);
4438             break;
4439         case RIL_REQUEST_IMS_SEND_SMS:
4440             requestImsSendSMS(data, datalen, t);
4441             break;
4442         case RIL_REQUEST_SIM_OPEN_CHANNEL:
4443             requestSimOpenChannel(data, datalen, t);
4444             break;
4445         case RIL_REQUEST_SIM_CLOSE_CHANNEL:
4446             requestSimCloseChannel(data, datalen, t);
4447             break;
4448         case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
4449             requestSimTransmitApduChannel(data, datalen, t);
4450             break;
4451         case RIL_REQUEST_SIM_AUTHENTICATION: {
4452             RIL_SimAuthentication *sim_auth = (RIL_SimAuthentication *)data;
4453             if ((sim_auth->authContext == AUTH_CONTEXT_EAP_SIM ||
4454                  sim_auth->authContext == AUTH_CONTEXT_EAP_AKA) &&
4455                 sim_auth->authData != NULL) {
4456                 requestSimAuthentication(sim_auth->authContext, sim_auth->authData, t);
4457             } else {
4458                 RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
4459             }
4460             break;
4461         }
4462         case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC:
4463             requestTransmitApduBasic(data, datalen, t);
4464             break;
4465         case RIL_REQUEST_SETUP_DATA_CALL:
4466             requestSetupDataCall(data, datalen, t);
4467             break;
4468         case RIL_REQUEST_DEACTIVATE_DATA_CALL:
4469             requestDeactivateDataCall(data, t);
4470             break;
4471         case RIL_REQUEST_SMS_ACKNOWLEDGE:
4472             requestSMSAcknowledge(data, datalen, t);
4473             break;
4474 
4475         case RIL_REQUEST_GET_IMSI:
4476             p_response = NULL;
4477             err = at_send_command_numeric("AT+CIMI", &p_response);
4478 
4479             if (err < 0 || p_response->success == 0) {
4480                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4481             } else {
4482                 RIL_onRequestComplete(t, RIL_E_SUCCESS,
4483                     p_response->p_intermediates->line, sizeof(char *));
4484             }
4485             at_response_free(p_response);
4486             break;
4487 
4488         case RIL_REQUEST_GET_IMEI:
4489             p_response = NULL;
4490             err = at_send_command_numeric("AT+CGSN", &p_response);
4491 
4492             if (err < 0 || p_response->success == 0) {
4493                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4494             } else {
4495                 RIL_onRequestComplete(t, RIL_E_SUCCESS,
4496                     p_response->p_intermediates->line, sizeof(char *));
4497             }
4498             at_response_free(p_response);
4499             break;
4500 
4501 
4502         case RIL_REQUEST_SIM_IO:
4503             requestSIM_IO(data,datalen,t);
4504             break;
4505 
4506         case RIL_REQUEST_SEND_USSD:
4507             requestSendUSSD(data, datalen, t);
4508             break;
4509 
4510         case RIL_REQUEST_CANCEL_USSD:
4511             if (getSIMStatus() == SIM_ABSENT) {
4512                 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
4513                 break;
4514             }
4515             p_response = NULL;
4516             err = at_send_command_numeric("AT+CUSD=2", &p_response);
4517 
4518             if (err < 0 || p_response->success == 0) {
4519                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4520             } else {
4521                 RIL_onRequestComplete(t, RIL_E_SUCCESS,
4522                     p_response->p_intermediates->line, sizeof(char *));
4523             }
4524             at_response_free(p_response);
4525             break;
4526 
4527         case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
4528             if (getSIMStatus() == SIM_ABSENT) {
4529                 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
4530                 break;
4531             }
4532             p_response = NULL;
4533             err = at_send_command("AT+COPS=0", &p_response);
4534             if (err < 0 || p_response->success == 0) {
4535                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4536             } else {
4537                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4538             }
4539             at_response_free(p_response);
4540             break;
4541 
4542         case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
4543             requestSetNetworlSelectionManual(data, t);
4544             break;
4545 
4546         case RIL_REQUEST_DATA_CALL_LIST:
4547             requestDataCallList(data, datalen, t);
4548             break;
4549 
4550         case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
4551             requestQueryNetworkSelectionMode(data, datalen, t);
4552             break;
4553 
4554         case RIL_REQUEST_OEM_HOOK_RAW:
4555             // echo back data
4556             RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
4557             break;
4558 
4559 
4560         case RIL_REQUEST_OEM_HOOK_STRINGS: {
4561             int i;
4562             const char ** cur;
4563 
4564             RLOGD("got OEM_HOOK_STRINGS: 0x%8p %lu", data, (long)datalen);
4565 
4566 
4567             for (i = (datalen / sizeof (char *)), cur = (const char **)data ;
4568                     i > 0 ; cur++, i --) {
4569                 RLOGD("> '%s'", *cur);
4570             }
4571 
4572             // echo back strings
4573             RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
4574             break;
4575         }
4576 
4577         case RIL_REQUEST_WRITE_SMS_TO_SIM:
4578             requestWriteSmsToSim(data, datalen, t);
4579             break;
4580 
4581         case RIL_REQUEST_DELETE_SMS_ON_SIM: {
4582             char * cmd;
4583             p_response = NULL;
4584             asprintf(&cmd, "AT+CMGD=%d", ((int *)data)[0]);
4585             err = at_send_command(cmd, &p_response);
4586             free(cmd);
4587             if (err < 0 || p_response->success == 0) {
4588                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4589             } else {
4590                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4591             }
4592             at_response_free(p_response);
4593             break;
4594         }
4595 
4596         case RIL_REQUEST_ENTER_SIM_PIN:
4597         case RIL_REQUEST_ENTER_SIM_PIN2:
4598             requestEnterSimPin(request, data, datalen, t);
4599             break;
4600 
4601         case RIL_REQUEST_ENTER_SIM_PUK:
4602         case RIL_REQUEST_ENTER_SIM_PUK2:
4603         case RIL_REQUEST_CHANGE_SIM_PIN:
4604             requestChangeSimPin(request, data, datalen, t);
4605             break;
4606 
4607         case RIL_REQUEST_CHANGE_SIM_PIN2:
4608             requestChangeSimPin2(data, datalen, t);
4609             break;
4610 
4611         case RIL_REQUEST_IMS_REGISTRATION_STATE: {
4612             int reply[2];
4613             //0==unregistered, 1==registered
4614             reply[0] = s_ims_registered;
4615 
4616             //to be used when changed to include service supporated info
4617             //reply[1] = s_ims_services;
4618 
4619             // FORMAT_3GPP(1) vs FORMAT_3GPP2(2);
4620             reply[1] = s_ims_format;
4621 
4622             RLOGD("IMS_REGISTRATION=%d, format=%d ",
4623                     reply[0], reply[1]);
4624             if (reply[1] != -1) {
4625                 RIL_onRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply));
4626             } else {
4627                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4628             }
4629             break;
4630         }
4631 
4632         case RIL_REQUEST_VOICE_RADIO_TECH:
4633             {
4634                 int tech = techFromModemType(TECH(sMdmInfo));
4635                 if (tech < 0 )
4636                     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4637                 else
4638                     RIL_onRequestComplete(t, RIL_E_SUCCESS, &tech, sizeof(tech));
4639             }
4640             break;
4641         case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
4642             requestSetPreferredNetworkType(request, data, datalen, t);
4643             break;
4644 
4645         case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
4646             requestGetPreferredNetworkType(request, data, datalen, t);
4647             break;
4648 
4649         case RIL_REQUEST_GET_CELL_INFO_LIST:
4650             requestGetCellInfoList(data, datalen, t);
4651             break;
4652 
4653         case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
4654             requestSetCellInfoListRate(data, datalen, t);
4655             break;
4656 
4657         case RIL_REQUEST_GET_HARDWARE_CONFIG:
4658             requestGetHardwareConfig(data, datalen, t);
4659             break;
4660 
4661         case RIL_REQUEST_SHUTDOWN:
4662             requestShutdown(t);
4663             break;
4664 
4665         case RIL_REQUEST_QUERY_TTY_MODE:
4666             requestGetTtyMode(data, datalen, t);
4667             break;
4668 
4669         case RIL_REQUEST_GET_RADIO_CAPABILITY:
4670             requestGetRadioCapability(data, datalen, t);
4671             break;
4672 
4673         case RIL_REQUEST_SET_RADIO_CAPABILITY:
4674             requestSetRadioCapability(data, datalen, t);
4675             break;
4676 
4677         case RIL_REQUEST_GET_MUTE:
4678             requestGetMute(data, datalen, t);
4679             break;
4680 
4681         case RIL_REQUEST_SET_MUTE:
4682             requestSetMute(data, datalen, t);
4683             break;
4684 
4685         case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: {
4686           int size = 5;
4687           int response[20] = {0};
4688           for (int i = 1; i <= size; i++) {
4689             response[i] = i - 1;
4690           }
4691           RIL_onRequestComplete(t, RIL_E_SUCCESS, response, (size + 1) * sizeof(int));
4692           break;
4693         }
4694 
4695         case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
4696         case RIL_REQUEST_ALLOW_DATA:
4697         case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
4698         case RIL_REQUEST_SET_BAND_MODE:
4699         case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
4700         case RIL_REQUEST_SET_LOCATION_UPDATES:
4701         case RIL_REQUEST_SET_TTY_MODE:
4702         case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
4703             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4704             break;
4705 
4706         case RIL_REQUEST_BASEBAND_VERSION:
4707             requestCdmaBaseBandVersion(request, data, datalen, t);
4708             break;
4709 
4710         case RIL_REQUEST_DEVICE_IDENTITY:
4711             requestDeviceIdentity(request, data, datalen, t);
4712             break;
4713 
4714         case RIL_REQUEST_CDMA_SUBSCRIPTION:
4715             requestCdmaSubscription(request, data, datalen, t);
4716             break;
4717 
4718         case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
4719             requestCdmaGetSubscriptionSource(request, data, datalen, t);
4720             break;
4721 
4722         case RIL_REQUEST_START_LCE:
4723         case RIL_REQUEST_STOP_LCE:
4724         case RIL_REQUEST_PULL_LCEDATA:
4725             if (getSIMStatus() == SIM_ABSENT) {
4726                 RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
4727             } else {
4728                 RIL_onRequestComplete(t, RIL_E_LCE_NOT_SUPPORTED, NULL, 0);
4729             }
4730             break;
4731 
4732         case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
4733             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
4734                 requestCdmaGetRoamingPreference(request, data, datalen, t);
4735             } else {
4736                 RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
4737             }
4738             break;
4739 
4740         case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
4741             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
4742                 requestCdmaSetSubscriptionSource(request, data, datalen, t);
4743             } else {
4744                 // VTS tests expect us to silently do nothing
4745                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4746             }
4747             break;
4748 
4749         case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
4750             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
4751                 requestCdmaSetRoamingPreference(request, data, datalen, t);
4752             } else {
4753                 // VTS tests expect us to silently do nothing
4754                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4755             }
4756             break;
4757 
4758         case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
4759             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
4760                 requestExitEmergencyMode(data, datalen, t);
4761             } else {
4762                 // VTS tests expect us to silently do nothing
4763                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4764             }
4765             break;
4766 
4767         case RIL_REQUEST_GET_ACTIVITY_INFO:
4768             requestGetActivityInfo(data, datalen, t);
4769             break;
4770 
4771         case RIL_REQUEST_SCREEN_STATE:
4772             requestScreenState(data, t);
4773             break;
4774 
4775         case RIL_REQUEST_SET_DATA_PROFILE:
4776             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4777             break;
4778 
4779         case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS:
4780             requestQueryCallForward(data, datalen, t);
4781             break;
4782 
4783         case RIL_REQUEST_SET_CALL_FORWARD:
4784             requestSetCallForward(data, datalen, t);
4785             break;
4786 
4787         case RIL_REQUEST_QUERY_CLIP:
4788             requestQueryClip(data, datalen, t);
4789             break;
4790 
4791         case RIL_REQUEST_GET_CLIR:
4792             requestQueryClir(data, datalen, t);
4793             break;
4794 
4795         case RIL_REQUEST_SET_CLIR:
4796             requestSetClir(data, datalen, t);
4797             break;
4798 
4799         case RIL_REQUEST_QUERY_CALL_WAITING:
4800             requestQueryCallWaiting(data, datalen, t);
4801             break;
4802 
4803         case RIL_REQUEST_SET_CALL_WAITING:
4804             requestSetCallWaiting(data, datalen, t);
4805             break;
4806 
4807         case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
4808             requestSetSuppServiceNotifications(data, datalen, t);
4809             break;
4810 
4811         case RIL_REQUEST_CHANGE_BARRING_PASSWORD:
4812             requestChangeBarringPassword(data, datalen, t);
4813             break;
4814 
4815         case RIL_REQUEST_QUERY_FACILITY_LOCK: {
4816             char *lockData[4];
4817             lockData[0] = ((char **)data)[0];
4818             lockData[1] = "2";
4819             lockData[2] = ((char **)data)[1];
4820             lockData[3] = ((char **)data)[2];
4821             requestFacilityLock(request, lockData, datalen + sizeof(char *), t);
4822             break;
4823         }
4824 
4825         case RIL_REQUEST_SET_FACILITY_LOCK:
4826             requestFacilityLock(request, data, datalen, t);
4827             break;
4828 
4829         case RIL_REQUEST_GET_SMSC_ADDRESS:
4830             requestGetSmscAddress(data, datalen, t);
4831             break;
4832 
4833         case RIL_REQUEST_SET_SMSC_ADDRESS:
4834             requestSetSmscAddress(data, datalen, t);
4835             break;
4836 
4837         case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:
4838             requestSetSmsBroadcastConfig(data, datalen, t);
4839             break;
4840 
4841         case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:
4842             requestGetSmsBroadcastConfig(data, datalen, t);
4843             break;
4844 
4845         case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
4846             requestStkServiceIsRunning(t);
4847             break;
4848 
4849         case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
4850             requestStkSendEnvelope(data, t);
4851             break;
4852 
4853         case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
4854             requestStksendTerminalResponse(data, t);
4855             break;
4856 
4857         // New requests after P.
4858         case RIL_REQUEST_START_NETWORK_SCAN:
4859             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4860             break;
4861         case RIL_REQUEST_GET_MODEM_STACK_STATUS:
4862             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4863             break;
4864         case RIL_REQUEST_ENABLE_MODEM:
4865             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4866             break;
4867         case RIL_REQUEST_EMERGENCY_DIAL:
4868             requestEccDial(data, t);
4869             break;
4870         case RIL_REQUEST_SET_SIM_CARD_POWER:
4871             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4872             break;
4873         case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP:
4874             requestSetPreferredNetworkType(request, data, datalen, t);
4875             break;
4876         case RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP:
4877             requestSetPreferredNetworkType(request, data, datalen, t);
4878             break;
4879         case RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP:
4880             requestGetPreferredNetworkType(request, data, datalen, t);
4881         case RIL_REQUEST_ENABLE_NR_DUAL_CONNECTIVITY:
4882             if (data == NULL || datalen != sizeof(int)) {
4883                 RIL_onRequestComplete(t, RIL_E_INTERNAL_ERR, NULL, 0);
4884                 break;
4885             }
4886             int nrDualConnectivityState = *(int *)(data);
4887             isNrDualConnectivityEnabled = (nrDualConnectivityState == 1) ? true : false;
4888             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4889             break;
4890         case RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED:
4891             RIL_onRequestComplete(t, RIL_E_SUCCESS, &isNrDualConnectivityEnabled,
4892                     sizeof(isNrDualConnectivityEnabled));
4893             break;
4894         case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP:
4895             requestGetPreferredNetworkType(request, data, datalen, t);
4896             break;
4897         case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS:
4898             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4899             break;
4900         case RIL_REQUEST_GET_SLICING_CONFIG:
4901             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4902             break;
4903 
4904         // Radio config requests
4905         case RIL_REQUEST_CONFIG_GET_SLOT_STATUS:
4906             RIL_requestTimedCallback(onIccSlotStatus, (void *)t, NULL);
4907             break;
4908         case RIL_REQUEST_CONFIG_SET_SLOT_MAPPING:
4909             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4910             break;
4911         case RIL_REQUEST_CONFIG_GET_PHONE_CAPABILITY: {
4912             RIL_PhoneCapability *phoneCapability =
4913                     (RIL_PhoneCapability *)alloca(sizeof(RIL_PhoneCapability));
4914             phoneCapability->maxActiveData = 1;
4915             // DSDS is 1, and DSDA is 2, now only support DSDS
4916             phoneCapability->maxActiveInternetData = 1;
4917             // DSDA can support internet lingering
4918             phoneCapability->isInternetLingeringSupported = false;
4919             for (int num = 0; num < SIM_COUNT; num++) {
4920                 phoneCapability->logicalModemList[num].modemId = num;
4921             }
4922             RIL_onRequestComplete(t, RIL_E_SUCCESS,
4923                             phoneCapability, sizeof(RIL_PhoneCapability));
4924             break;
4925         }
4926         case RIL_REQUEST_CONFIG_SET_MODEM_CONFIG: {
4927             RIL_ModemConfig *mdConfig = (RIL_ModemConfig*)(data);
4928             if (mdConfig == NULL || mdConfig->numOfLiveModems != 1) {
4929                 RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
4930             } else {
4931                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4932             }
4933             break;
4934         }
4935         case RIL_REQUEST_CONFIG_GET_MODEM_CONFIG: {
4936             RIL_ModemConfig mdConfig;
4937             mdConfig.numOfLiveModems = 1;
4938 
4939             RIL_onRequestComplete(t, RIL_E_SUCCESS, &mdConfig, sizeof(RIL_ModemConfig));
4940             break;
4941         }
4942         case RIL_REQUEST_CONFIG_SET_PREFER_DATA_MODEM: {
4943             int *modemId = (int*)(data);
4944             if (modemId == NULL || *modemId != 0) {
4945                 RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
4946             } else {
4947                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4948             }
4949             break;
4950         }
4951         case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA:
4952             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4953             break;
4954         case RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA:
4955             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4956             break;
4957         case RIL_REQUEST_ENABLE_UICC_APPLICATIONS: {
4958             if (data == NULL || datalen != sizeof(int)) {
4959                 RIL_onRequestComplete(t, RIL_E_INTERNAL_ERR, NULL, 0);
4960                 break;
4961             }
4962             areUiccApplicationsEnabled = *(int *)(data);
4963             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4964             break;
4965         }
4966         case RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED:
4967             RIL_onRequestComplete(t, RIL_E_SUCCESS, &areUiccApplicationsEnabled,
4968                     sizeof(areUiccApplicationsEnabled));
4969             break;
4970         case RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE:
4971             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4972             break;
4973         case RIL_REQUEST_GET_BARRING_INFO:
4974             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4975             break;
4976         case RIL_REQUEST_SET_DATA_THROTTLING:
4977             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4978             break;
4979         default:
4980             RLOGD("Request not supported. Tech: %d",TECH(sMdmInfo));
4981             RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
4982             break;
4983     }
4984 }
4985 
4986 /**
4987  * Synchronous call from the RIL to us to return current radio state.
4988  * RADIO_STATE_UNAVAILABLE should be the initial state.
4989  */
4990 static RIL_RadioState
4991 currentState()
4992 {
4993     return sState;
4994 }
4995 /**
4996  * Call from RIL to us to find out whether a specific request code
4997  * is supported by this implementation.
4998  *
4999  * Return 1 for "supported" and 0 for "unsupported"
5000  */
5001 
5002 static int
5003 onSupports (int requestCode __unused)
5004 {
5005     //@@@ todo
5006 
5007     return 1;
5008 }
5009 
5010 static void onCancel (RIL_Token t __unused)
5011 {
5012     //@@@todo
5013 
5014 }
5015 
5016 static const char * getVersion(void)
5017 {
5018     return "android reference-ril 1.0";
5019 }
5020 
5021 static void
5022 setRadioTechnology(ModemInfo *mdm, int newtech)
5023 {
5024     RLOGD("setRadioTechnology(%d)", newtech);
5025 
5026     int oldtech = TECH(mdm);
5027 
5028     if (newtech != oldtech) {
5029         RLOGD("Tech change (%d => %d)", oldtech, newtech);
5030         TECH(mdm) = newtech;
5031         if (techFromModemType(newtech) != techFromModemType(oldtech)) {
5032             int tech = techFromModemType(TECH(sMdmInfo));
5033             if (tech > 0 ) {
5034                 RIL_onUnsolicitedResponse(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
5035                                           &tech, sizeof(tech));
5036             }
5037         }
5038     }
5039 }
5040 
5041 static void
5042 setRadioState(RIL_RadioState newState)
5043 {
5044     RLOGD("setRadioState(%d)", newState);
5045     RIL_RadioState oldState;
5046 
5047     pthread_mutex_lock(&s_state_mutex);
5048 
5049     oldState = sState;
5050 
5051     if (s_closed > 0) {
5052         // If we're closed, the only reasonable state is
5053         // RADIO_STATE_UNAVAILABLE
5054         // This is here because things on the main thread
5055         // may attempt to change the radio state after the closed
5056         // event happened in another thread
5057         newState = RADIO_STATE_UNAVAILABLE;
5058     }
5059 
5060     if (sState != newState || s_closed > 0) {
5061         sState = newState;
5062 
5063         pthread_cond_broadcast (&s_state_cond);
5064     }
5065 
5066     pthread_mutex_unlock(&s_state_mutex);
5067 
5068 
5069     /* do these outside of the mutex */
5070     if (sState != oldState) {
5071         RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
5072                                     NULL, 0);
5073         // Sim state can change as result of radio state change
5074         RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
5075                                     NULL, 0);
5076 
5077         /* FIXME onSimReady() and onRadioPowerOn() cannot be called
5078          * from the AT reader thread
5079          * Currently, this doesn't happen, but if that changes then these
5080          * will need to be dispatched on the request thread
5081          */
5082         if (sState == RADIO_STATE_ON) {
5083             onRadioPowerOn();
5084         }
5085     }
5086 }
5087 
5088 /** Returns RUIM_NOT_READY on error */
5089 static SIM_Status
5090 getRUIMStatus()
5091 {
5092     ATResponse *p_response = NULL;
5093     int err;
5094     int ret;
5095     char *cpinLine;
5096     char *cpinResult;
5097 
5098     if (sState == RADIO_STATE_OFF || sState == RADIO_STATE_UNAVAILABLE) {
5099         ret = SIM_NOT_READY;
5100         goto done;
5101     }
5102 
5103     err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
5104 
5105     if (err != 0) {
5106         ret = SIM_NOT_READY;
5107         goto done;
5108     }
5109 
5110     switch (at_get_cme_error(p_response)) {
5111         case CME_SUCCESS:
5112             break;
5113 
5114         case CME_SIM_NOT_INSERTED:
5115             ret = SIM_ABSENT;
5116             goto done;
5117 
5118         default:
5119             ret = SIM_NOT_READY;
5120             goto done;
5121     }
5122 
5123     /* CPIN? has succeeded, now look at the result */
5124 
5125     cpinLine = p_response->p_intermediates->line;
5126     err = at_tok_start (&cpinLine);
5127 
5128     if (err < 0) {
5129         ret = SIM_NOT_READY;
5130         goto done;
5131     }
5132 
5133     err = at_tok_nextstr(&cpinLine, &cpinResult);
5134 
5135     if (err < 0) {
5136         ret = SIM_NOT_READY;
5137         goto done;
5138     }
5139 
5140     if (0 == strcmp (cpinResult, "SIM PIN")) {
5141         ret = SIM_PIN;
5142         goto done;
5143     } else if (0 == strcmp (cpinResult, "SIM PUK")) {
5144         ret = SIM_PUK;
5145         goto done;
5146     } else if (0 == strcmp (cpinResult, "PH-NET PIN")) {
5147         return SIM_NETWORK_PERSONALIZATION;
5148     } else if (0 != strcmp (cpinResult, "READY"))  {
5149         /* we're treating unsupported lock types as "sim absent" */
5150         ret = SIM_ABSENT;
5151         goto done;
5152     }
5153 
5154     at_response_free(p_response);
5155     p_response = NULL;
5156     cpinResult = NULL;
5157 
5158     ret = SIM_READY;
5159 
5160 done:
5161     at_response_free(p_response);
5162     return ret;
5163 }
5164 
5165 /** Returns SIM_NOT_READY on error */
5166 static SIM_Status
5167 getSIMStatus()
5168 {
5169     ATResponse *p_response = NULL;
5170     int err;
5171     int ret;
5172     char *cpinLine;
5173     char *cpinResult;
5174 
5175     RLOGD("getSIMStatus(). sState: %d",sState);
5176     err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
5177 
5178     if (err != 0) {
5179         ret = SIM_NOT_READY;
5180         goto done;
5181     }
5182 
5183     switch (at_get_cme_error(p_response)) {
5184         case CME_SUCCESS:
5185             break;
5186 
5187         case CME_SIM_NOT_INSERTED:
5188             ret = SIM_ABSENT;
5189             goto done;
5190 
5191         default:
5192             ret = SIM_NOT_READY;
5193             goto done;
5194     }
5195 
5196     /* CPIN? has succeeded, now look at the result */
5197 
5198     cpinLine = p_response->p_intermediates->line;
5199     err = at_tok_start (&cpinLine);
5200 
5201     if (err < 0) {
5202         ret = SIM_NOT_READY;
5203         goto done;
5204     }
5205 
5206     err = at_tok_nextstr(&cpinLine, &cpinResult);
5207 
5208     if (err < 0) {
5209         ret = SIM_NOT_READY;
5210         goto done;
5211     }
5212 
5213     if (0 == strcmp (cpinResult, "SIM PIN")) {
5214         ret = SIM_PIN;
5215         goto done;
5216     } else if (0 == strcmp (cpinResult, "SIM PUK")) {
5217         ret = SIM_PUK;
5218         goto done;
5219     } else if (0 == strcmp (cpinResult, "PH-NET PIN")) {
5220         return SIM_NETWORK_PERSONALIZATION;
5221     } else if (0 != strcmp (cpinResult, "READY"))  {
5222         /* we're treating unsupported lock types as "sim absent" */
5223         ret = SIM_ABSENT;
5224         goto done;
5225     }
5226 
5227     at_response_free(p_response);
5228     p_response = NULL;
5229     cpinResult = NULL;
5230 
5231     ret = (sState == RADIO_STATE_ON) ? SIM_READY : SIM_NOT_READY;
5232 
5233 done:
5234     at_response_free(p_response);
5235     return ret;
5236 }
5237 
5238 static void getIccId(char *iccid, int size) {
5239     int err = 0;
5240     ATResponse *p_response = NULL;
5241 
5242     if (iccid == NULL) {
5243         RLOGE("iccid buffer is null");
5244         return;
5245     }
5246     err = at_send_command_numeric("AT+CICCID", &p_response);
5247     if (err < 0 || p_response->success == 0) {
5248         goto error;
5249     }
5250 
5251     snprintf(iccid, size, "%s", p_response->p_intermediates->line);
5252 
5253 error:
5254     at_response_free(p_response);
5255 }
5256 
5257 /**
5258  * Get the current card status.
5259  *
5260  * This must be freed using freeCardStatus.
5261  * @return: On success returns RIL_E_SUCCESS
5262  */
5263 static int getCardStatus(RIL_CardStatus_v1_5 **pp_card_status) {
5264     static RIL_AppStatus app_status_array[] = {
5265         // SIM_ABSENT = 0
5266         { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
5267           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
5268         // SIM_NOT_READY = 1
5269         { RIL_APPTYPE_USIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
5270           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
5271         // SIM_READY = 2
5272         { RIL_APPTYPE_USIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
5273           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
5274         // SIM_PIN = 3
5275         { RIL_APPTYPE_USIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
5276           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
5277         // SIM_PUK = 4
5278         { RIL_APPTYPE_USIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
5279           NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
5280         // SIM_NETWORK_PERSONALIZATION = 5
5281         { RIL_APPTYPE_USIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
5282           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
5283         // RUIM_ABSENT = 6
5284         { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
5285           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
5286         // RUIM_NOT_READY = 7
5287         { RIL_APPTYPE_RUIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
5288           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
5289         // RUIM_READY = 8
5290         { RIL_APPTYPE_RUIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
5291           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
5292         // RUIM_PIN = 9
5293         { RIL_APPTYPE_RUIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
5294           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
5295         // RUIM_PUK = 10
5296         { RIL_APPTYPE_RUIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
5297           NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
5298         // RUIM_NETWORK_PERSONALIZATION = 11
5299         { RIL_APPTYPE_RUIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
5300            NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
5301         // ISIM_ABSENT = 12
5302         { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
5303           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
5304         // ISIM_NOT_READY = 13
5305         { RIL_APPTYPE_ISIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
5306           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
5307         // ISIM_READY = 14
5308         { RIL_APPTYPE_ISIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
5309           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
5310         // ISIM_PIN = 15
5311         { RIL_APPTYPE_ISIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
5312           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
5313         // ISIM_PUK = 16
5314         { RIL_APPTYPE_ISIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
5315           NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
5316         // ISIM_NETWORK_PERSONALIZATION = 17
5317         { RIL_APPTYPE_ISIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
5318           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
5319 
5320     };
5321     RIL_CardState card_state;
5322     int num_apps;
5323 
5324     int sim_status = getSIMStatus();
5325     if (sim_status == SIM_ABSENT) {
5326         card_state = RIL_CARDSTATE_ABSENT;
5327         num_apps = 0;
5328     } else {
5329         card_state = RIL_CARDSTATE_PRESENT;
5330         num_apps = 3;
5331     }
5332 
5333     // Allocate and initialize base card status.
5334     RIL_CardStatus_v1_5 *p_card_status = calloc(1, sizeof(RIL_CardStatus_v1_5));
5335     p_card_status->base.base.base.card_state = card_state;
5336     p_card_status->base.base.base.universal_pin_state = RIL_PINSTATE_UNKNOWN;
5337     p_card_status->base.base.base.gsm_umts_subscription_app_index = -1;
5338     p_card_status->base.base.base.cdma_subscription_app_index = -1;
5339     p_card_status->base.base.base.ims_subscription_app_index = -1;
5340     p_card_status->base.base.base.num_applications = num_apps;
5341     p_card_status->base.base.physicalSlotId = 0;
5342     p_card_status->base.base.atr = NULL;
5343     p_card_status->base.base.iccid = NULL;
5344     p_card_status->base.eid = "";
5345     if (sim_status != SIM_ABSENT) {
5346         p_card_status->base.base.iccid = (char *)calloc(64, sizeof(char));
5347         getIccId(p_card_status->base.base.iccid, 64);
5348     }
5349 
5350     // Initialize application status
5351     int i;
5352     for (i = 0; i < RIL_CARD_MAX_APPS; i++) {
5353         p_card_status->base.base.base.applications[i] = app_status_array[SIM_ABSENT];
5354     }
5355     RLOGD("enter getCardStatus module, num_apps= %d",num_apps);
5356     // Pickup the appropriate application status
5357     // that reflects sim_status for gsm.
5358     if (num_apps != 0) {
5359         p_card_status->base.base.base.num_applications = 3;
5360         p_card_status->base.base.base.gsm_umts_subscription_app_index = 0;
5361         p_card_status->base.base.base.cdma_subscription_app_index = 1;
5362         p_card_status->base.base.base.ims_subscription_app_index = 2;
5363 
5364         // Get the correct app status
5365         p_card_status->base.base.base.applications[0] = app_status_array[sim_status];
5366         p_card_status->base.base.base.applications[1] = app_status_array[sim_status + RUIM_ABSENT];
5367         p_card_status->base.base.base.applications[2] = app_status_array[sim_status + ISIM_ABSENT];
5368     }
5369 
5370     *pp_card_status = p_card_status;
5371     return RIL_E_SUCCESS;
5372 }
5373 
5374 /**
5375  * Free the card status returned by getCardStatus
5376  */
5377 static void freeCardStatus(RIL_CardStatus_v1_5 *p_card_status) {
5378     if (p_card_status == NULL) {
5379         return;
5380     }
5381     free(p_card_status->base.base.iccid);
5382     free(p_card_status);
5383 }
5384 
5385 /**
5386  * SIM ready means any commands that access the SIM will work, including:
5387  *  AT+CPIN, AT+CSMS, AT+CNMI, AT+CRSM
5388  *  (all SMS-related commands)
5389  */
5390 
5391 static void pollSIMState (void *param __unused)
5392 {
5393     ATResponse *p_response;
5394     int ret;
5395 
5396     if (sState != RADIO_STATE_UNAVAILABLE) {
5397         // no longer valid to poll
5398         return;
5399     }
5400 
5401     switch(getSIMStatus()) {
5402         case SIM_ABSENT:
5403         case SIM_PIN:
5404         case SIM_PUK:
5405         case SIM_NETWORK_PERSONALIZATION:
5406         default:
5407             RLOGI("SIM ABSENT or LOCKED");
5408             RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
5409         return;
5410 
5411         case SIM_NOT_READY:
5412             RIL_requestTimedCallback (pollSIMState, NULL, &TIMEVAL_SIMPOLL);
5413         return;
5414 
5415         case SIM_READY:
5416             RLOGI("SIM_READY");
5417             onSIMReady();
5418             RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
5419         return;
5420     }
5421 }
5422 
5423 /** returns 1 if on, 0 if off, and -1 on error */
5424 static int isRadioOn()
5425 {
5426     ATResponse *p_response = NULL;
5427     int err;
5428     char *line;
5429     char ret;
5430 
5431     err = at_send_command_singleline("AT+CFUN?", "+CFUN:", &p_response);
5432 
5433     if (err < 0 || p_response->success == 0) {
5434         // assume radio is off
5435         goto error;
5436     }
5437 
5438     line = p_response->p_intermediates->line;
5439 
5440     err = at_tok_start(&line);
5441     if (err < 0) goto error;
5442 
5443     err = at_tok_nextbool(&line, &ret);
5444     if (err < 0) goto error;
5445 
5446     at_response_free(p_response);
5447 
5448     return (int)ret;
5449 
5450 error:
5451 
5452     at_response_free(p_response);
5453     return -1;
5454 }
5455 
5456 /**
5457  * Parse the response generated by a +CTEC AT command
5458  * The values read from the response are stored in current and preferred.
5459  * Both current and preferred may be null. The corresponding value is ignored in that case.
5460  *
5461  * @return: -1 if some error occurs (or if the modem doesn't understand the +CTEC command)
5462  *          1 if the response includes the current technology only
5463  *          0 if the response includes both current technology and preferred mode
5464  */
5465 int parse_technology_response( const char *response, int *current, int32_t *preferred )
5466 {
5467     int err;
5468     char *line, *p;
5469     int ct;
5470     int32_t pt = 0;
5471     char *str_pt;
5472 
5473     line = p = strdup(response);
5474     RLOGD("Response: %s", line);
5475     err = at_tok_start(&p);
5476     if (err || !at_tok_hasmore(&p)) {
5477         RLOGD("err: %d. p: %s", err, p);
5478         free(line);
5479         return -1;
5480     }
5481 
5482     err = at_tok_nextint(&p, &ct);
5483     if (err) {
5484         free(line);
5485         return -1;
5486     }
5487     if (current) *current = ct;
5488 
5489     RLOGD("line remaining after int: %s", p);
5490 
5491     err = at_tok_nexthexint(&p, &pt);
5492     if (err) {
5493         free(line);
5494         return 1;
5495     }
5496     if (preferred) {
5497         *preferred = pt;
5498     }
5499     free(line);
5500 
5501     return 0;
5502 }
5503 
5504 int query_supported_techs( ModemInfo *mdm __unused, int *supported )
5505 {
5506     ATResponse *p_response;
5507     int err, val, techs = 0;
5508     char *tok;
5509     char *line;
5510 
5511     RLOGD("query_supported_techs");
5512     err = at_send_command_singleline("AT+CTEC=?", "+CTEC:", &p_response);
5513     if (err || !p_response->success)
5514         goto error;
5515     line = p_response->p_intermediates->line;
5516     err = at_tok_start(&line);
5517     if (err || !at_tok_hasmore(&line))
5518         goto error;
5519     while (!at_tok_nextint(&line, &val)) {
5520         techs |= ( 1 << val );
5521     }
5522     if (supported) *supported = techs;
5523     return 0;
5524 error:
5525     at_response_free(p_response);
5526     return -1;
5527 }
5528 
5529 /**
5530  * query_ctec. Send the +CTEC AT command to the modem to query the current
5531  * and preferred modes. It leaves values in the addresses pointed to by
5532  * current and preferred. If any of those pointers are NULL, the corresponding value
5533  * is ignored, but the return value will still reflect if retrieving and parsing of the
5534  * values succeeded.
5535  *
5536  * @mdm Currently unused
5537  * @current A pointer to store the current mode returned by the modem. May be null.
5538  * @preferred A pointer to store the preferred mode returned by the modem. May be null.
5539  * @return -1 on error (or failure to parse)
5540  *         1 if only the current mode was returned by modem (or failed to parse preferred)
5541  *         0 if both current and preferred were returned correctly
5542  */
5543 int query_ctec(ModemInfo *mdm __unused, int *current, int32_t *preferred)
5544 {
5545     ATResponse *response = NULL;
5546     int err;
5547     int res;
5548 
5549     RLOGD("query_ctec. current: %p, preferred: %p", current, preferred);
5550     err = at_send_command_singleline("AT+CTEC?", "+CTEC:", &response);
5551     if (!err && response->success) {
5552         res = parse_technology_response(response->p_intermediates->line, current, preferred);
5553         at_response_free(response);
5554         return res;
5555     }
5556     RLOGE("Error executing command: %d. response: %p. status: %d", err, response, response? response->success : -1);
5557     at_response_free(response);
5558     return -1;
5559 }
5560 
5561 int is_multimode_modem(ModemInfo *mdm)
5562 {
5563     ATResponse *response;
5564     int err;
5565     char *line;
5566     int tech;
5567     int32_t preferred;
5568 
5569     if (query_ctec(mdm, &tech, &preferred) == 0) {
5570         mdm->currentTech = tech;
5571         mdm->preferredNetworkMode = preferred;
5572         if (query_supported_techs(mdm, &mdm->supportedTechs)) {
5573             return 0;
5574         }
5575         return 1;
5576     }
5577     return 0;
5578 }
5579 
5580 /**
5581  * Find out if our modem is GSM, CDMA or both (Multimode)
5582  */
5583 static void probeForModemMode(ModemInfo *info)
5584 {
5585     ATResponse *response;
5586     int err;
5587     assert (info);
5588     // Currently, our only known multimode modem is qemu's android modem,
5589     // which implements the AT+CTEC command to query and set mode.
5590     // Try that first
5591 
5592     if (is_multimode_modem(info)) {
5593         RLOGI("Found Multimode Modem. Supported techs mask: %8.8x. Current tech: %d",
5594             info->supportedTechs, info->currentTech);
5595         return;
5596     }
5597 
5598     /* Being here means that our modem is not multimode */
5599     info->isMultimode = 0;
5600 
5601     /* CDMA Modems implement the AT+WNAM command */
5602     err = at_send_command_singleline("AT+WNAM","+WNAM:", &response);
5603     if (!err && response->success) {
5604         at_response_free(response);
5605         // TODO: find out if we really support EvDo
5606         info->supportedTechs = MDM_CDMA | MDM_EVDO;
5607         info->currentTech = MDM_CDMA;
5608         RLOGI("Found CDMA Modem");
5609         return;
5610     }
5611     if (!err) at_response_free(response);
5612     // TODO: find out if modem really supports WCDMA/LTE
5613     info->supportedTechs = MDM_GSM | MDM_WCDMA | MDM_LTE;
5614     info->currentTech = MDM_GSM;
5615     RLOGI("Found GSM Modem");
5616 }
5617 
5618 /**
5619  * Initialize everything that can be configured while we're still in
5620  * AT+CFUN=0
5621  */
5622 static void initializeCallback(void *param __unused)
5623 {
5624     ATResponse *p_response = NULL;
5625     int err;
5626 
5627     setRadioState (RADIO_STATE_OFF);
5628 
5629     at_handshake();
5630 
5631     probeForModemMode(sMdmInfo);
5632     /* note: we don't check errors here. Everything important will
5633        be handled in onATTimeout and onATReaderClosed */
5634 
5635     /*  atchannel is tolerant of echo but it must */
5636     /*  have verbose result codes */
5637     at_send_command("ATE0Q0V1", NULL);
5638 
5639     /*  No auto-answer */
5640     at_send_command("ATS0=0", NULL);
5641 
5642     /*  Extended errors */
5643     at_send_command("AT+CMEE=1", NULL);
5644 
5645     /*  Network registration events */
5646     err = at_send_command("AT+CREG=2", &p_response);
5647 
5648     /* some handsets -- in tethered mode -- don't support CREG=2 */
5649     if (err < 0 || p_response->success == 0) {
5650         at_send_command("AT+CREG=1", NULL);
5651     }
5652 
5653     at_response_free(p_response);
5654 
5655     /*  GPRS registration events */
5656     at_send_command("AT+CGREG=1", NULL);
5657 
5658     /*  Call Waiting notifications */
5659     at_send_command("AT+CCWA=1", NULL);
5660 
5661     /*  Alternating voice/data off */
5662     at_send_command("AT+CMOD=0", NULL);
5663 
5664     /*  Not muted */
5665     at_send_command("AT+CMUT=0", NULL);
5666 
5667     /*  +CSSU unsolicited supp service notifications */
5668     at_send_command("AT+CSSN=0,1", NULL);
5669 
5670     /*  no connected line identification */
5671     at_send_command("AT+COLP=0", NULL);
5672 
5673     /*  HEX character set */
5674     at_send_command("AT+CSCS=\"HEX\"", NULL);
5675 
5676     /*  USSD unsolicited */
5677     at_send_command("AT+CUSD=1", NULL);
5678 
5679     /*  Enable +CGEV GPRS event notifications, but don't buffer */
5680     at_send_command("AT+CGEREP=1,0", NULL);
5681 
5682     /*  SMS PDU mode */
5683     at_send_command("AT+CMGF=0", NULL);
5684 
5685 #ifdef USE_TI_COMMANDS
5686 
5687     at_send_command("AT%CPI=3", NULL);
5688 
5689     /*  TI specific -- notifications when SMS is ready (currently ignored) */
5690     at_send_command("AT%CSTAT=1", NULL);
5691 
5692 #endif /* USE_TI_COMMANDS */
5693 
5694 
5695     /* assume radio is off on error */
5696     if (isRadioOn() > 0) {
5697         setRadioState (RADIO_STATE_ON);
5698     }
5699 }
5700 
5701 static void waitForClose()
5702 {
5703     pthread_mutex_lock(&s_state_mutex);
5704 
5705     while (s_closed == 0) {
5706         pthread_cond_wait(&s_state_cond, &s_state_mutex);
5707     }
5708 
5709     pthread_mutex_unlock(&s_state_mutex);
5710 }
5711 
5712 static void sendUnsolImsNetworkStateChanged()
5713 {
5714 #if 0 // to be used when unsol is changed to return data.
5715     int reply[2];
5716     reply[0] = s_ims_registered;
5717     reply[1] = s_ims_services;
5718     reply[1] = s_ims_format;
5719 #endif
5720     RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED,
5721             NULL, 0);
5722 }
5723 
5724 static int parseProactiveCmdInd(char *response) {
5725     int typePos = 0;
5726     int cmdType = 0;
5727     char tempStr[3] = {0};
5728     char *end = NULL;
5729     StkUnsolEvent ret = STK_UNSOL_EVENT_UNKNOWN;
5730 
5731     if (response == NULL || strlen(response) < 3) {
5732       return ret;
5733     }
5734 
5735     if (response[2] <= '7') {
5736        typePos = 10;
5737     } else {
5738        typePos = 12;
5739     }
5740 
5741     if ((int)strlen(response) < typePos + 1) {
5742       return ret;
5743     }
5744 
5745     memcpy(tempStr, &(response[typePos]), 2);
5746     cmdType = strtoul(tempStr, &end, 16);
5747     cmdType = 0xFF & cmdType;
5748     RLOGD("cmdType: %d",cmdType);
5749 
5750     switch (cmdType) {
5751        case STK_RUN_AT:
5752        case STK_SEND_DTMF:
5753        case STK_SEND_SMS:
5754        case STK_SEND_SS:
5755        case STK_SEND_USSD:
5756        case STK_PLAY_TONE:
5757        case STK_CLOSE_CHANNEL:
5758            ret = STK_UNSOL_EVENT_NOTIFY;
5759            break;
5760        case STK_REFRESH:
5761            if (strncasecmp(&(response[typePos + 2]), "04", 2) == 0) {  // SIM_RESET
5762                RLOGD("Type of Refresh is SIM_RESET");
5763                s_stkServiceRunning = false;
5764                ret = STK_UNSOL_PROACTIVE_CMD;
5765            } else {
5766                ret = STK_UNSOL_EVENT_NOTIFY;
5767            }
5768            break;
5769        default:
5770            ret = STK_UNSOL_PROACTIVE_CMD;
5771            break;
5772     }
5773 
5774     if (getSIMStatus() == SIM_ABSENT && s_stkServiceRunning) {
5775         s_stkServiceRunning = false;
5776     }
5777 
5778     if (false == s_stkServiceRunning) {
5779         ret = STK_UNSOL_EVENT_UNKNOWN;
5780         s_stkUnsolResponse = (char *)calloc((strlen(response) + 1), sizeof(char));
5781         snprintf(s_stkUnsolResponse, strlen(response) + 1, "%s", response);
5782         RLOGD("STK service is not running [%s]", s_stkUnsolResponse);
5783     }
5784 
5785     return ret;
5786 }
5787 
5788 /**
5789  * Called by atchannel when an unsolicited line appears
5790  * This is called on atchannel's reader thread. AT commands may
5791  * not be issued here
5792  */
5793 static void onUnsolicited (const char *s, const char *sms_pdu)
5794 {
5795     char *line = NULL, *p;
5796     int err;
5797 
5798     /* Ignore unsolicited responses until we're initialized.
5799      * This is OK because the RIL library will poll for initial state
5800      */
5801     if (sState == RADIO_STATE_UNAVAILABLE) {
5802         return;
5803     }
5804 
5805 #define  CGFPCCFG "%CGFPCCFG:"
5806     if (strStartsWith(s, CGFPCCFG)) {
5807         /* cuttlefish/goldfish specific
5808         */
5809         char *response;
5810         line = p = strdup(s);
5811         RLOGD("got CGFPCCFG line %s and %s\n", s, p);
5812         err = at_tok_start(&line);
5813         if(err) {
5814             RLOGE("invalid CGFPCCFG line %s and %s\n", s, p);
5815         }
5816 #define kSize 5
5817         int configs[kSize];
5818         for (int i=0; i < kSize && !err; ++i) {
5819             err = at_tok_nextint(&line, &(configs[i]));
5820             RLOGD("got i %d, val = %d", i, configs[i]);
5821         }
5822         if(err) {
5823             RLOGE("invalid CGFPCCFG line %s and %s\n", s, p);
5824         } else {
5825             int modem_tech = configs[2];
5826             configs[2] = techFromModemType(modem_tech);
5827             RIL_onUnsolicitedResponse (
5828                 RIL_UNSOL_PHYSICAL_CHANNEL_CONFIGS,
5829                 configs, kSize);
5830         }
5831         free(p);
5832     } else if (strStartsWith(s, "%CTZV:")) {
5833         /* TI specific -- NITZ time */
5834         char *response;
5835 
5836         line = p = strdup(s);
5837         at_tok_start(&p);
5838 
5839         err = at_tok_nextstr(&p, &response);
5840 
5841         if (err != 0) {
5842             RLOGE("invalid NITZ line %s\n", s);
5843         } else {
5844             RIL_onUnsolicitedResponse (
5845                 RIL_UNSOL_NITZ_TIME_RECEIVED,
5846                 response, strlen(response) + 1);
5847         }
5848         free(line);
5849     } else if (strStartsWith(s,"+CRING:")
5850                 || strStartsWith(s,"RING")
5851                 || strStartsWith(s,"NO CARRIER")
5852                 || strStartsWith(s,"+CCWA")
5853     ) {
5854         RIL_onUnsolicitedResponse (
5855             RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
5856             NULL, 0);
5857 #ifdef WORKAROUND_FAKE_CGEV
5858         RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL); //TODO use new function
5859 #endif /* WORKAROUND_FAKE_CGEV */
5860     } else if (strStartsWith(s,"+CREG:")
5861                 || strStartsWith(s,"+CGREG:")
5862     ) {
5863         RIL_onUnsolicitedResponse (
5864             RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
5865             NULL, 0);
5866 #ifdef WORKAROUND_FAKE_CGEV
5867         RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
5868 #endif /* WORKAROUND_FAKE_CGEV */
5869     } else if (strStartsWith(s, "+CMT:")) {
5870         RIL_onUnsolicitedResponse (
5871             RIL_UNSOL_RESPONSE_NEW_SMS,
5872             sms_pdu, strlen(sms_pdu));
5873     } else if (strStartsWith(s, "+CDS:")) {
5874         RIL_onUnsolicitedResponse (
5875             RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
5876             sms_pdu, strlen(sms_pdu));
5877     } else if (strStartsWith(s, "+CGEV:")) {
5878         /* Really, we can ignore NW CLASS and ME CLASS events here,
5879          * but right now we don't since extranous
5880          * RIL_UNSOL_DATA_CALL_LIST_CHANGED calls are tolerated
5881          */
5882         /* can't issue AT commands here -- call on main thread */
5883         RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
5884 #ifdef WORKAROUND_FAKE_CGEV
5885     } else if (strStartsWith(s, "+CME ERROR: 150")) {
5886         RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
5887 #endif /* WORKAROUND_FAKE_CGEV */
5888     } else if (strStartsWith(s, "+CTEC: ")) {
5889         int tech, mask;
5890         switch (parse_technology_response(s, &tech, NULL))
5891         {
5892             case -1: // no argument could be parsed.
5893                 RLOGE("invalid CTEC line %s\n", s);
5894                 break;
5895             case 1: // current mode correctly parsed
5896             case 0: // preferred mode correctly parsed
5897                 mask = 1 << tech;
5898                 if (mask != MDM_GSM && mask != MDM_CDMA &&
5899                      mask != MDM_WCDMA && mask != MDM_LTE) {
5900                     RLOGE("Unknown technology %d\n", tech);
5901                 } else {
5902                     setRadioTechnology(sMdmInfo, tech);
5903                 }
5904                 break;
5905         }
5906     } else if (strStartsWith(s, "+CCSS: ")) {
5907         int source = 0;
5908         line = p = strdup(s);
5909         if (!line) {
5910             RLOGE("+CCSS: Unable to allocate memory");
5911             return;
5912         }
5913         if (at_tok_start(&p) < 0) {
5914             free(line);
5915             return;
5916         }
5917         if (at_tok_nextint(&p, &source) < 0) {
5918             RLOGE("invalid +CCSS response: %s", line);
5919             free(line);
5920             return;
5921         }
5922         SSOURCE(sMdmInfo) = source;
5923         RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
5924                                   &source, sizeof(source));
5925         free(line);
5926     } else if (strStartsWith(s, "+WSOS: ")) {
5927         char state = 0;
5928         int unsol;
5929         line = p = strdup(s);
5930         if (!line) {
5931             RLOGE("+WSOS: Unable to allocate memory");
5932             return;
5933         }
5934         if (at_tok_start(&p) < 0) {
5935             free(line);
5936             return;
5937         }
5938         if (at_tok_nextbool(&p, &state) < 0) {
5939             RLOGE("invalid +WSOS response: %s", line);
5940             free(line);
5941             return;
5942         }
5943         free(line);
5944 
5945         unsol = state ?
5946                 RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE : RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE;
5947 
5948         RIL_onUnsolicitedResponse(unsol, NULL, 0);
5949 
5950     } else if (strStartsWith(s, "+WPRL: ")) {
5951         int version = -1;
5952         line = p = strdup(s);
5953         if (!line) {
5954             RLOGE("+WPRL: Unable to allocate memory");
5955             return;
5956         }
5957         if (at_tok_start(&p) < 0) {
5958             RLOGE("invalid +WPRL response: %s", s);
5959             free(line);
5960             return;
5961         }
5962         if (at_tok_nextint(&p, &version) < 0) {
5963             RLOGE("invalid +WPRL response: %s", s);
5964             free(line);
5965             return;
5966         }
5967         free(line);
5968         RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_PRL_CHANGED, &version, sizeof(version));
5969     } else if (strStartsWith(s, "+CFUN: 0")) {
5970         setRadioState(RADIO_STATE_OFF);
5971     } else if (strStartsWith(s, "+CSQ: ")) {
5972         // Accept a response that is at least v6, and up to v12
5973         int minNumOfElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
5974         int maxNumOfElements=sizeof(RIL_SignalStrength_v12)/sizeof(int);
5975         int response[maxNumOfElements];
5976         memset(response, 0, sizeof(response));
5977 
5978         line = p = strdup(s);
5979         at_tok_start(&p);
5980 
5981         for (int count = 0; count < maxNumOfElements; count++) {
5982             err = at_tok_nextint(&p, &(response[count]));
5983             if (err < 0 && count < minNumOfElements) {
5984               free(line);
5985               return;
5986             }
5987         }
5988 
5989         RIL_onUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH,
5990             response, sizeof(response));
5991         free(line);
5992     } else if (strStartsWith(s, "+CUSATEND")) {  // session end
5993       RIL_onUnsolicitedResponse(RIL_UNSOL_STK_SESSION_END, NULL, 0);
5994     } else if (strStartsWith(s, "+CUSATP:")) {
5995         line = p = strdup(s);
5996         if (!line) {
5997             RLOGE("+CUSATP: Unable to allocate memory");
5998             return;
5999         }
6000         if (at_tok_start(&p) < 0) {
6001             RLOGE("invalid +CUSATP response: %s", s);
6002             free(line);
6003             return;
6004         }
6005 
6006         char *response = NULL;
6007         if (at_tok_nextstr(&p, &response) < 0) {
6008             RLOGE("%s fail", s);
6009             free(line);
6010             return;
6011         }
6012 
6013         StkUnsolEvent ret = parseProactiveCmdInd(response);
6014         if (ret == STK_UNSOL_EVENT_NOTIFY) {
6015             RIL_onUnsolicitedResponse(RIL_UNSOL_STK_EVENT_NOTIFY, response,
6016                                       strlen(response) + 1);
6017         } else if (ret == STK_UNSOL_PROACTIVE_CMD) {
6018             RIL_onUnsolicitedResponse(RIL_UNSOL_STK_PROACTIVE_COMMAND, response,
6019                                       strlen(response) + 1);
6020         }
6021 
6022         free(line);
6023     }
6024 }
6025 
6026 /* Called on command or reader thread */
6027 static void onATReaderClosed()
6028 {
6029     RLOGI("AT channel closed\n");
6030     at_close();
6031     s_closed = 1;
6032 
6033     setRadioState (RADIO_STATE_UNAVAILABLE);
6034 }
6035 
6036 /* Called on command thread */
6037 static void onATTimeout()
6038 {
6039     RLOGI("AT channel timeout; closing\n");
6040     at_close();
6041 
6042     s_closed = 1;
6043 
6044     /* FIXME cause a radio reset here */
6045 
6046     setRadioState (RADIO_STATE_UNAVAILABLE);
6047 }
6048 
6049 /* Called to pass hardware configuration information to telephony
6050  * framework.
6051  */
6052 static void setHardwareConfiguration(int num, RIL_HardwareConfig *cfg)
6053 {
6054    RIL_onUnsolicitedResponse(RIL_UNSOL_HARDWARE_CONFIG_CHANGED, cfg, num*sizeof(*cfg));
6055 }
6056 
6057 static void usage(char *s __unused)
6058 {
6059 #ifdef RIL_SHLIB
6060     fprintf(stderr, "reference-ril requires: -p <tcp port> or -d /dev/tty_device\n");
6061 #else
6062     fprintf(stderr, "usage: %s [-p <tcp port>] [-d /dev/tty_device]\n", s);
6063     exit(-1);
6064 #endif
6065 }
6066 
6067 static void *
6068 mainLoop(void *param __unused)
6069 {
6070     int fd;
6071     int ret;
6072 
6073     AT_DUMP("== ", "entering mainLoop()", -1 );
6074     at_set_on_reader_closed(onATReaderClosed);
6075     at_set_on_timeout(onATTimeout);
6076 
6077     for (;;) {
6078         fd = -1;
6079         while  (fd < 0) {
6080             if (isInEmulator()) {
6081                 fd = qemu_open_modem_port();
6082                 RLOGD("opening qemu_modem_port %d!", fd);
6083             } else if (s_port > 0) {
6084                 fd = socket_network_client("localhost", s_port, SOCK_STREAM);
6085             } else if (s_modem_simulator_port >= 0) {
6086               fd = socket(AF_VSOCK, SOCK_STREAM, 0);
6087               if (fd < 0) {
6088                  RLOGD("Can't create AF_VSOCK socket!");
6089                  continue;
6090               }
6091               struct sockaddr_vm sa;
6092               memset(&sa, 0, sizeof(struct sockaddr_vm));
6093               sa.svm_family = AF_VSOCK;
6094               sa.svm_cid = VMADDR_CID_HOST;
6095               sa.svm_port = s_modem_simulator_port;
6096 
6097               if (connect(fd, (struct sockaddr *)(&sa), sizeof(sa)) < 0) {
6098                   RLOGD("Can't connect to port:%ud, errno: %s",
6099                       s_modem_simulator_port, strerror(errno));
6100                   close(fd);
6101                   fd = -1;
6102                   continue;
6103               }
6104             } else if (s_device_socket) {
6105                 fd = socket_local_client(s_device_path,
6106                                          ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
6107                                          SOCK_STREAM);
6108             } else if (s_device_path != NULL) {
6109                 fd = open (s_device_path, O_RDWR);
6110                 if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
6111                     /* disable echo on serial ports */
6112                     struct termios  ios;
6113                     tcgetattr( fd, &ios );
6114                     ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
6115                     tcsetattr( fd, TCSANOW, &ios );
6116                 }
6117             }
6118 
6119             if (fd < 0) {
6120                 perror ("opening AT interface. retrying...");
6121                 sleep(10);
6122                 /* never returns */
6123             }
6124         }
6125 
6126         s_closed = 0;
6127         ret = at_open(fd, onUnsolicited);
6128 
6129         if (ret < 0) {
6130             RLOGE ("AT error %d on at_open\n", ret);
6131             return 0;
6132         }
6133 
6134         RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);
6135 
6136         // Give initializeCallback a chance to dispatched, since
6137         // we don't presently have a cancellation mechanism
6138         sleep(1);
6139 
6140         waitForClose();
6141         RLOGI("Re-opening after close");
6142     }
6143 }
6144 
6145 #ifdef RIL_SHLIB
6146 
6147 pthread_t s_tid_mainloop;
6148 
6149 const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
6150 {
6151     int ret;
6152     int fd = -1;
6153     int opt;
6154     pthread_attr_t attr;
6155 
6156     s_rilenv = env;
6157 
6158     RLOGD("RIL_Init");
6159     while ( -1 != (opt = getopt(argc, argv, "p:d:s:c:m:"))) {
6160         switch (opt) {
6161             case 'p':
6162                 s_port = atoi(optarg);
6163                 if (s_port == 0) {
6164                     usage(argv[0]);
6165                     return NULL;
6166                 }
6167                 RLOGI("Opening loopback port %d\n", s_port);
6168             break;
6169 
6170             case 'd':
6171                 s_device_path = optarg;
6172                 RLOGI("Opening tty device %s\n", s_device_path);
6173             break;
6174 
6175             case 's':
6176                 s_device_path   = optarg;
6177                 s_device_socket = 1;
6178                 RLOGI("Opening socket %s\n", s_device_path);
6179             break;
6180 
6181             case 'c':
6182                 RLOGI("Client id received %s\n", optarg);
6183             break;
6184 
6185             case 'm':
6186               s_modem_simulator_port = strtoul(optarg, NULL, 10);
6187               RLOGI("Opening modem simulator port %ud\n", s_modem_simulator_port);
6188             break;
6189 
6190             default:
6191                 usage(argv[0]);
6192                 return NULL;
6193         }
6194     }
6195 
6196     if (s_port < 0 && s_device_path == NULL && !isInEmulator() &&
6197         s_modem_simulator_port < 0) {
6198         usage(argv[0]);
6199         return NULL;
6200     }
6201 
6202     sMdmInfo = calloc(1, sizeof(ModemInfo));
6203     if (!sMdmInfo) {
6204         RLOGE("Unable to alloc memory for ModemInfo");
6205         return NULL;
6206     }
6207     pthread_attr_init (&attr);
6208     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
6209     ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);
6210 
6211     return &s_callbacks;
6212 }
6213 #else /* RIL_SHLIB */
6214 int main (int argc, char **argv)
6215 {
6216     int ret;
6217     int fd = -1;
6218     int opt;
6219 
6220     while ( -1 != (opt = getopt(argc, argv, "p:d:"))) {
6221         switch (opt) {
6222             case 'p':
6223                 s_port = atoi(optarg);
6224                 if (s_port == 0) {
6225                     usage(argv[0]);
6226                 }
6227                 RLOGI("Opening loopback port %d\n", s_port);
6228             break;
6229 
6230             case 'd':
6231                 s_device_path = optarg;
6232                 RLOGI("Opening tty device %s\n", s_device_path);
6233             break;
6234 
6235             case 's':
6236                 s_device_path   = optarg;
6237                 s_device_socket = 1;
6238                 RLOGI("Opening socket %s\n", s_device_path);
6239             break;
6240 
6241             default:
6242                 usage(argv[0]);
6243         }
6244     }
6245 
6246     if (s_port < 0 && s_device_path == NULL && !isInEmulator()) {
6247         usage(argv[0]);
6248     }
6249 
6250     RIL_register(&s_callbacks);
6251 
6252     mainLoop(NULL);
6253 
6254     return 0;
6255 }
6256 
6257 #endif /* RIL_SHLIB */
6258