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