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