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 #define LOG_TAG "RIL"
19 
20 #include <telephony/ril_cdma_sms.h>
21 #include <telephony/librilutils.h>
22 #include <stdio.h>
23 #include <assert.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h>
27 #include <sys/cdefs.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <inttypes.h>
31 #include <fcntl.h>
32 #include <pthread.h>
33 #include <alloca.h>
34 #include "atchannel.h"
35 #include "at_tok.h"
36 #include "misc.h"
37 #include <getopt.h>
38 #include <sys/socket.h>
39 #include <cutils/properties.h>
40 #include <cutils/sockets.h>
41 #include <termios.h>
42 #include <qemud.h>
43 #include <sys/wait.h>
44 #include <stdbool.h>
45 #include <net/if.h>
46 #include <arpa/inet.h>
47 #include <netinet/in.h>
48 
49 #include "if_monitor.h"
50 #include "ipv6_monitor.h"
51 #include "ril.h"
52 
53 #define EMULATOR_DUMMY_SIM_CHANNEL_NAME "A00000015144414300"
54 #include <utils/Log.h>
55 
56 #define MAX(x, y) ({\
57     __typeof__(x) _x = (x); \
58     __typeof__(y) _y = (y); \
59     _x > _y ? _x : _y; })
60 
noopRemoveWarning(void * a)61 static void *noopRemoveWarning( void *a ) { return a; }
62 #define RIL_UNUSED_PARM(a) noopRemoveWarning((void *)&(a));
63 
64 #define MAX_AT_RESPONSE 0x1000
65 
66 /* pathname returned from RIL_REQUEST_SETUP_DATA_CALL / RIL_REQUEST_SETUP_DEFAULT_PDP */
67 // This is used if Wifi is not supported, plain old eth0
68 #define PPP_TTY_PATH_ETH0 "eth0"
69 // This is used if Wifi is supported to separate radio and wifi interface
70 #define PPP_TTY_PATH_RADIO0 "radio0"
71 
72 // This is the IP address to provide for radio0 when WiFi is enabled
73 // When WiFi is not enabled the RIL should provide the address given by
74 // the modem.
75 #define RADIO0_IPV4_ADDRESS "192.168.200.2/24"
76 
77 // Default MTU value
78 #define DEFAULT_MTU 1500
79 
80 #ifdef USE_TI_COMMANDS
81 
82 // Enable a workaround
83 // 1) Make incoming call, do not answer
84 // 2) Hangup remote end
85 // Expected: call should disappear from CLCC line
86 // Actual: Call shows as "ACTIVE" before disappearing
87 #define WORKAROUND_ERRONEOUS_ANSWER 1
88 
89 // Some varients of the TI stack do not support the +CGEV unsolicited
90 // response. However, they seem to send an unsolicited +CME ERROR: 150
91 #define WORKAROUND_FAKE_CGEV 1
92 #endif
93 
94 /* Modem Technology bits */
95 #define MDM_GSM         0x01
96 #define MDM_WCDMA       0x02
97 #define MDM_CDMA        0x04
98 #define MDM_EVDO        0x08
99 #define MDM_LTE         0x10
100 
101 typedef struct {
102     int supportedTechs; // Bitmask of supported Modem Technology bits
103     int currentTech;    // Technology the modem is currently using (in the format used by modem)
104     int isMultimode;
105 
106     // Preferred mode bitmask. This is actually 4 byte-sized bitmasks with different priority values,
107     // in which the byte number from LSB to MSB give the priority.
108     //
109     //          |MSB|   |   |LSB
110     // value:   |00 |00 |00 |00
111     // byte #:  |3  |2  |1  |0
112     //
113     // Higher byte order give higher priority. Thus, a value of 0x0000000f represents
114     // a preferred mode of GSM, WCDMA, CDMA, and EvDo in which all are equally preferrable, whereas
115     // 0x00000201 represents a mode with GSM and WCDMA, in which WCDMA is preferred over GSM
116     int32_t preferredNetworkMode;
117     int subscription_source;
118 
119 } ModemInfo;
120 
121 static ModemInfo *sMdmInfo;
122 // TECH returns the current technology in the format used by the modem.
123 // It can be used as an l-value
124 #define TECH(mdminfo)                 ((mdminfo)->currentTech)
125 // TECH_BIT returns the bitmask equivalent of the current tech
126 #define TECH_BIT(mdminfo)            (1 << ((mdminfo)->currentTech))
127 #define IS_MULTIMODE(mdminfo)         ((mdminfo)->isMultimode)
128 #define TECH_SUPPORTED(mdminfo, tech) ((mdminfo)->supportedTechs & (tech))
129 #define PREFERRED_NETWORK(mdminfo)    ((mdminfo)->preferredNetworkMode)
130 // CDMA Subscription Source
131 #define SSOURCE(mdminfo)              ((mdminfo)->subscription_source)
132 
133 static int net2modem[] = {
134     MDM_GSM | MDM_WCDMA,                                 // 0  - GSM / WCDMA Pref
135     MDM_GSM,                                             // 1  - GSM only
136     MDM_WCDMA,                                           // 2  - WCDMA only
137     MDM_GSM | MDM_WCDMA,                                 // 3  - GSM / WCDMA Auto
138     MDM_CDMA | MDM_EVDO,                                 // 4  - CDMA / EvDo Auto
139     MDM_CDMA,                                            // 5  - CDMA only
140     MDM_EVDO,                                            // 6  - EvDo only
141     MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO,           // 7  - GSM/WCDMA, CDMA, EvDo
142     MDM_LTE | MDM_CDMA | MDM_EVDO,                       // 8  - LTE, CDMA and EvDo
143     MDM_LTE | MDM_GSM | MDM_WCDMA,                       // 9  - LTE, GSM/WCDMA
144     MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
145     MDM_LTE,                                             // 11 - LTE only
146 };
147 
148 static int32_t net2pmask[] = {
149     MDM_GSM | (MDM_WCDMA << 8),                          // 0  - GSM / WCDMA Pref
150     MDM_GSM,                                             // 1  - GSM only
151     MDM_WCDMA,                                           // 2  - WCDMA only
152     MDM_GSM | MDM_WCDMA,                                 // 3  - GSM / WCDMA Auto
153     MDM_CDMA | MDM_EVDO,                                 // 4  - CDMA / EvDo Auto
154     MDM_CDMA,                                            // 5  - CDMA only
155     MDM_EVDO,                                            // 6  - EvDo only
156     MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO,           // 7  - GSM/WCDMA, CDMA, EvDo
157     MDM_LTE | MDM_CDMA | MDM_EVDO,                       // 8  - LTE, CDMA and EvDo
158     MDM_LTE | MDM_GSM | MDM_WCDMA,                       // 9  - LTE, GSM/WCDMA
159     MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
160     MDM_LTE,                                             // 11 - LTE only
161 };
162 
is3gpp2(int radioTech)163 static int is3gpp2(int radioTech) {
164     switch (radioTech) {
165         case RADIO_TECH_IS95A:
166         case RADIO_TECH_IS95B:
167         case RADIO_TECH_1xRTT:
168         case RADIO_TECH_EVDO_0:
169         case RADIO_TECH_EVDO_A:
170         case RADIO_TECH_EVDO_B:
171         case RADIO_TECH_EHRPD:
172             return 1;
173         default:
174             return 0;
175     }
176 }
177 
178 typedef enum {
179     SIM_ABSENT = 0,
180     SIM_NOT_READY = 1,
181     SIM_READY = 2,
182     SIM_PIN = 3,
183     SIM_PUK = 4,
184     SIM_NETWORK_PERSONALIZATION = 5,
185     SIM_RESTRICTED = 6,
186 
187     RUIM_ABSENT = 7,
188     RUIM_NOT_READY = 8,
189     RUIM_READY = 9,
190     RUIM_PIN = 10,
191     RUIM_PUK = 11,
192     RUIM_NETWORK_PERSONALIZATION = 12,
193     RUIM_RESTRICTED = 13,
194 
195     ISIM_ABSENT = 14,
196     ISIM_NOT_READY = 15,
197     ISIM_READY = 16,
198     ISIM_PIN = 17,
199     ISIM_PUK = 18,
200     ISIM_NETWORK_PERSONALIZATION = 19,
201     ISIM_RESTRICTED = 20
202 
203 } SIM_Status;
204 
205 static void onRequest (int request, void *data, size_t datalen, RIL_Token t);
206 static RIL_RadioState currentState();
207 static int onSupports (int requestCode);
208 static void onCancel (RIL_Token t);
209 static const char *getVersion();
210 static int isRadioOn();
211 static SIM_Status getSIMStatus();
212 static int getCardStatus(RIL_CardStatus_v6 **pp_card_status);
213 static void freeCardStatus(RIL_CardStatus_v6 *p_card_status);
214 static void onDataCallListChanged(void *param);
215 
216 extern const char * requestToString(int request);
217 
218 /*** Static Variables ***/
219 static const RIL_RadioFunctions s_callbacks = {
220     RIL_VERSION,
221     onRequest,
222     currentState,
223     onSupports,
224     onCancel,
225     getVersion
226 };
227 
228 #ifdef RIL_SHLIB
229 static const struct RIL_Env *s_rilenv;
230 
231 #define RIL_onRequestComplete(t, e, response, responselen) s_rilenv->OnRequestComplete(t,e, response, responselen)
232 #define RIL_onUnsolicitedResponse(a,b,c) s_rilenv->OnUnsolicitedResponse(a,b,c)
233 #define RIL_requestTimedCallback(a,b,c) s_rilenv->RequestTimedCallback(a,b,c)
234 #endif
235 
236 static RIL_RadioState sState = RADIO_STATE_UNAVAILABLE;
237 
238 static int s_sim_update_started = 0;
239 
240 static pthread_mutex_t s_state_mutex = PTHREAD_MUTEX_INITIALIZER;
241 static pthread_cond_t s_state_cond = PTHREAD_COND_INITIALIZER;
242 
243 static int s_port = -1;
244 static const char * s_device_path = NULL;
245 static int          s_device_socket = 0;
246 
247 /* trigger change to this with s_state_cond */
248 static int s_closed = 0;
249 
250 static int sFD;     /* file desc of AT channel */
251 static char sATBuffer[MAX_AT_RESPONSE+1];
252 static char *sATBufferCur = NULL;
253 
254 static const struct timeval TIMEVAL_SIMPOLL = {1,0};
255 static const struct timeval TIMEVAL_CALLSTATEPOLL = {0,500000};
256 static const struct timeval TIMEVAL_0 = {0,0};
257 
258 static int s_ims_registered  = 0;        // 0==unregistered
259 static int s_ims_services    = 1;        // & 0x1 == sms over ims supported
260 static int s_ims_format    = 1;          // FORMAT_3GPP(1) vs FORMAT_3GPP2(2);
261 static int s_ims_cause_retry = 0;        // 1==causes sms over ims to temp fail
262 static int s_ims_cause_perm_failure = 0; // 1==causes sms over ims to permanent fail
263 static int s_ims_gsm_retry   = 0;        // 1==causes sms over gsm to temp fail
264 static int s_ims_gsm_fail    = 0;        // 1==causes sms over gsm to permanent fail
265 
266 #ifdef WORKAROUND_ERRONEOUS_ANSWER
267 // Max number of times we'll try to repoll when we think
268 // we have a AT+CLCC race condition
269 #define REPOLL_CALLS_COUNT_MAX 4
270 
271 // Line index that was incoming or waiting at last poll, or -1 for none
272 static int s_incomingOrWaitingLine = -1;
273 // Number of times we've asked for a repoll of AT+CLCC
274 static int s_repollCallsCount = 0;
275 // Should we expect a call to be answered in the next CLCC?
276 static int s_expectAnswer = 0;
277 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
278 
279 
280 static int s_cell_info_rate_ms = INT_MAX;
281 static int s_mcc = 0;
282 static int s_mnc = 0;
283 static int s_lac = 0;
284 static int s_cid = 0;
285 
286 // A string containing all IP addresses of the radio interface
287 static char s_if_addresses[8192];
288 // A string containing the IPv6 gateway of the radio interface
289 static char s_ipv6_gateway[INET6_ADDRSTRLEN];
290 // A string containing the IPv6 DNS servers of the radio interface
291 static char s_ipv6_dns[8192];
292 static pthread_mutex_t s_addresses_mutex = PTHREAD_MUTEX_INITIALIZER;
293 
294 static void pollSIMState (void *param);
295 static void setRadioState(RIL_RadioState newState);
296 static void setRadioTechnology(ModemInfo *mdm, int newtech);
297 static int query_ctec(ModemInfo *mdm, int *current, int32_t *preferred);
298 static int parse_technology_response(const char *response, int *current, int32_t *preferred);
299 static int techFromModemType(int mdmtype);
300 
clccStateToRILState(int state,RIL_CallState * p_state)301 static int clccStateToRILState(int state, RIL_CallState *p_state)
302 
303 {
304     switch(state) {
305         case 0: *p_state = RIL_CALL_ACTIVE;   return 0;
306         case 1: *p_state = RIL_CALL_HOLDING;  return 0;
307         case 2: *p_state = RIL_CALL_DIALING;  return 0;
308         case 3: *p_state = RIL_CALL_ALERTING; return 0;
309         case 4: *p_state = RIL_CALL_INCOMING; return 0;
310         case 5: *p_state = RIL_CALL_WAITING;  return 0;
311         default: return -1;
312     }
313 }
314 
315 /**
316  * Note: directly modified line and has *p_call point directly into
317  * modified line
318  */
callFromCLCCLine(char * line,RIL_Call * p_call)319 static int callFromCLCCLine(char *line, RIL_Call *p_call)
320 {
321         //+CLCC: 1,0,2,0,0,\"+18005551212\",145
322         //     index,isMT,state,mode,isMpty(,number,TOA)?
323 
324     int err;
325     int state;
326     int mode;
327 
328     err = at_tok_start(&line);
329     if (err < 0) goto error;
330 
331     err = at_tok_nextint(&line, &(p_call->index));
332     if (err < 0) goto error;
333 
334     err = at_tok_nextbool(&line, &(p_call->isMT));
335     if (err < 0) goto error;
336 
337     err = at_tok_nextint(&line, &state);
338     if (err < 0) goto error;
339 
340     err = clccStateToRILState(state, &(p_call->state));
341     if (err < 0) goto error;
342 
343     err = at_tok_nextint(&line, &mode);
344     if (err < 0) goto error;
345 
346     p_call->isVoice = (mode == 0);
347 
348     err = at_tok_nextbool(&line, &(p_call->isMpty));
349     if (err < 0) goto error;
350 
351     if (at_tok_hasmore(&line)) {
352         err = at_tok_nextstr(&line, &(p_call->number));
353 
354         /* tolerate null here */
355         if (err < 0) return 0;
356 
357         // Some lame implementations return strings
358         // like "NOT AVAILABLE" in the CLCC line
359         if (p_call->number != NULL
360             && 0 == strspn(p_call->number, "+0123456789")
361         ) {
362             p_call->number = NULL;
363         }
364 
365         err = at_tok_nextint(&line, &p_call->toa);
366         if (err < 0) goto error;
367     }
368 
369     p_call->uusInfo = NULL;
370 
371     return 0;
372 
373 error:
374     RLOGE("invalid CLCC line\n");
375     return -1;
376 }
377 
parseSimResponseLine(char * line,RIL_SIM_IO_Response * response)378 static int parseSimResponseLine(char* line, RIL_SIM_IO_Response* response) {
379     int err;
380 
381     err = at_tok_start(&line);
382     if (err < 0) return err;
383     err = at_tok_nextint(&line, &response->sw1);
384     if (err < 0) return err;
385     err = at_tok_nextint(&line, &response->sw2);
386     if (err < 0) return err;
387 
388     if (at_tok_hasmore(&line)) {
389         err = at_tok_nextstr(&line, &response->simResponse);
390         if (err < 0) return err;
391     }
392     return 0;
393 }
394 
395 enum InterfaceState {
396     kInterfaceUp,
397     kInterfaceDown,
398 };
399 
setInterfaceState(const char * interfaceName,enum InterfaceState state)400 static RIL_Errno setInterfaceState(const char* interfaceName,
401                                    enum InterfaceState state) {
402     struct ifreq request;
403     int status = 0;
404     int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
405     if (sock == -1) {
406         RLOGE("Failed to open interface socket: %s (%d)",
407               strerror(errno), errno);
408         return RIL_E_GENERIC_FAILURE;
409     }
410 
411     memset(&request, 0, sizeof(request));
412     strncpy(request.ifr_name, interfaceName, sizeof(request.ifr_name));
413     request.ifr_name[sizeof(request.ifr_name) - 1] = '\0';
414     status = ioctl(sock, SIOCGIFFLAGS, &request);
415     if (status != 0) {
416         RLOGE("Failed to get interface flags for %s: %s (%d)",
417               interfaceName, strerror(errno), errno);
418         close(sock);
419         return RIL_E_RADIO_NOT_AVAILABLE;
420     }
421 
422     bool isUp = (request.ifr_flags & IFF_UP);
423     if ((state == kInterfaceUp && isUp) || (state == kInterfaceDown && !isUp)) {
424         // Interface already in desired state
425         close(sock);
426         return RIL_E_SUCCESS;
427     }
428 
429     // Simply toggle the flag since we know it's the opposite of what we want
430     request.ifr_flags ^= IFF_UP;
431 
432     status = ioctl(sock, SIOCSIFFLAGS, &request);
433     if (status != 0) {
434         RLOGE("Failed to set interface flags for %s: %s (%d)",
435               interfaceName, strerror(errno), errno);
436         close(sock);
437         return RIL_E_GENERIC_FAILURE;
438     }
439 
440     close(sock);
441     return RIL_E_SUCCESS;
442 }
443 
parseAuthResponse(char * line,RIL_SIM_IO_Response * response)444 static void parseAuthResponse(char* line, RIL_SIM_IO_Response* response) {
445     // example string +CSIM=number, "<base64string>9000"
446     // get the status first
447     int len = strlen(line);
448     char* first_double_quote = strchr(line, '"');
449     if (first_double_quote == NULL) {
450         RLOGE("%s bad response %s", __func__, line);
451         return;
452     }
453     char* data_ptr = first_double_quote + 1;
454     sscanf(line + (len -5), "%2x%2x", &(response->sw1), &(response->sw2));
455     line[len-5] = '\0';
456     response->simResponse = strdup(data_ptr);
457 }
458 
459 /** do post-AT+CFUN=1 initialization */
onRadioPowerOn()460 static void onRadioPowerOn()
461 {
462 #ifdef USE_TI_COMMANDS
463     /*  Must be after CFUN=1 */
464     /*  TI specific -- notifications for CPHS things such */
465     /*  as CPHS message waiting indicator */
466 
467     at_send_command("AT%CPHS=1", NULL);
468 
469     /*  TI specific -- enable NITZ unsol notifs */
470     at_send_command("AT%CTZV=1", NULL);
471 #endif
472 
473     /*  Golfish specific -- enable physical channel config unsol notifs
474         for 5g support
475      */
476     at_send_command("AT%CGFPCCFG=1", NULL);
477     pollSIMState(NULL);
478 }
479 
480 /** do post- SIM ready initialization */
onSIMReady()481 static void onSIMReady()
482 {
483     at_send_command_singleline("AT+CSMS=1", "+CSMS:", NULL);
484     /*
485      * Always send SMS messages directly to the TE
486      *
487      * mode = 1 // discard when link is reserved (link should never be
488      *             reserved)
489      * mt = 2   // most messages routed to TE
490      * bm = 2   // new cell BM's routed to TE
491      * ds = 1   // Status reports routed to TE
492      * bfr = 1  // flush buffer
493      */
494     at_send_command("AT+CNMI=1,2,2,1,1", NULL);
495 }
496 
requestRadioPower(void * data,size_t datalen __unused,RIL_Token t)497 static void requestRadioPower(void *data, size_t datalen __unused, RIL_Token t)
498 {
499     int onOff;
500 
501     int err;
502     ATResponse *p_response = NULL;
503 
504     assert (datalen >= sizeof(int *));
505     onOff = ((int *)data)[0];
506 
507     if (onOff == 0 && sState != RADIO_STATE_OFF) {
508         err = at_send_command("AT+CFUN=0", &p_response);
509         if (err < 0 || p_response->success == 0) goto error;
510         setRadioState(RADIO_STATE_OFF);
511     } else if (onOff > 0 && sState == RADIO_STATE_OFF) {
512         err = at_send_command("AT+CFUN=1", &p_response);
513         if (err < 0|| p_response->success == 0) {
514             // Some stacks return an error when there is no SIM,
515             // but they really turn the RF portion on
516             // So, if we get an error, let's check to see if it
517             // turned on anyway
518 
519             if (isRadioOn() != 1) {
520                 goto error;
521             }
522         }
523         setRadioState(RADIO_STATE_ON);
524     }
525 
526     at_response_free(p_response);
527     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
528     return;
529 error:
530     at_response_free(p_response);
531     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
532 }
533 
requestShutdown(RIL_Token t)534 static void requestShutdown(RIL_Token t)
535 {
536     int onOff;
537 
538     int err;
539     ATResponse *p_response = NULL;
540 
541     if (sState != RADIO_STATE_OFF) {
542         err = at_send_command("AT+CFUN=0", &p_response);
543         setRadioState(RADIO_STATE_UNAVAILABLE);
544     }
545 
546     at_response_free(p_response);
547     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
548     return;
549 }
550 
551 static void requestOrSendDataCallList(RIL_Token *t);
552 
onDataCallListChanged(void * param __unused)553 static void onDataCallListChanged(void *param __unused)
554 {
555     requestOrSendDataCallList(NULL);
556 }
557 
requestDataCallList(void * data __unused,size_t datalen __unused,RIL_Token t)558 static void requestDataCallList(void *data __unused, size_t datalen __unused, RIL_Token t)
559 {
560     requestOrSendDataCallList(&t);
561 }
562 
563 // Hang up, reject, conference, call waiting
requestCallSelection(void * data __unused,size_t datalen __unused,RIL_Token t,int request)564 static void requestCallSelection(
565                 void *data __unused, size_t datalen __unused, RIL_Token t, int request)
566 {
567     // 3GPP 22.030 6.5.5
568     static char hangupWaiting[]    = "AT+CHLD=0";
569     static char hangupForeground[] = "AT+CHLD=1";
570     static char switchWaiting[]    = "AT+CHLD=2";
571     static char conference[]       = "AT+CHLD=3";
572     static char reject[]           = "ATH";
573 
574     char* atCommand;
575 
576     if (getSIMStatus() == SIM_ABSENT) {
577         RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
578         return;
579     }
580 
581     switch(request) {
582         case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
583             // "Releases all held calls or sets User Determined User Busy
584             //  (UDUB) for a waiting call."
585             atCommand = hangupWaiting;
586             break;
587         case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
588             // "Releases all active calls (if any exist) and accepts
589             //  the other (held or waiting) call."
590             atCommand = hangupForeground;
591             break;
592         case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
593             // "Places all active calls (if any exist) on hold and accepts
594             //  the other (held or waiting) call."
595             atCommand = switchWaiting;
596 #ifdef WORKAROUND_ERRONEOUS_ANSWER
597             s_expectAnswer = 1;
598 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
599             break;
600         case RIL_REQUEST_CONFERENCE:
601             // "Adds a held call to the conversation"
602             atCommand = conference;
603             break;
604         case RIL_REQUEST_UDUB:
605             // User determined user busy (reject)
606             atCommand = reject;
607             break;
608         default:
609             assert(0);
610     }
611     at_send_command(atCommand, NULL);
612     // Success or failure is ignored by the upper layer here.
613     // It will call GET_CURRENT_CALLS and determine success that way.
614     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
615 }
616 
hasWifiCapability()617 static bool hasWifiCapability()
618 {
619     char propValue[PROP_VALUE_MAX];
620     return property_get("ro.kernel.qemu.wifi", propValue, "") > 0 &&
621            strcmp("1", propValue) == 0;
622 }
623 
getRadioInterfaceName(bool hasWifi)624 static const char* getRadioInterfaceName(bool hasWifi)
625 {
626     return hasWifi ? PPP_TTY_PATH_RADIO0 : PPP_TTY_PATH_ETH0;
627 }
628 
requestOrSendDataCallList(RIL_Token * t)629 static void requestOrSendDataCallList(RIL_Token *t)
630 {
631     ATResponse *p_response;
632     ATLine *p_cur;
633     int err;
634     int n = 0;
635     char *out;
636     char propValue[PROP_VALUE_MAX];
637     bool hasWifi = hasWifiCapability();
638     const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
639     char ipv6Gateway[INET6_ADDRSTRLEN];
640     char ipv6Dns[8192];
641 
642     err = at_send_command_multiline ("AT+CGACT?", "+CGACT:", &p_response);
643     if (err != 0 || p_response->success == 0) {
644         if (t != NULL)
645             RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
646         else
647             RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
648                                       NULL, 0);
649         return;
650     }
651 
652     for (p_cur = p_response->p_intermediates; p_cur != NULL;
653          p_cur = p_cur->p_next)
654         n++;
655 
656     RIL_Data_Call_Response_v11 *responses =
657         alloca(n * sizeof(RIL_Data_Call_Response_v11));
658 
659     int i;
660     for (i = 0; i < n; i++) {
661         responses[i].status = -1;
662         responses[i].suggestedRetryTime = -1;
663         responses[i].cid = -1;
664         responses[i].active = -1;
665         responses[i].type = "";
666         responses[i].ifname = "";
667         responses[i].addresses = "";
668         responses[i].dnses = "";
669         responses[i].gateways = "";
670         responses[i].pcscf = "";
671         responses[i].mtu = 0;
672     }
673 
674     RIL_Data_Call_Response_v11 *response = responses;
675     for (p_cur = p_response->p_intermediates; p_cur != NULL;
676          p_cur = p_cur->p_next) {
677         char *line = p_cur->line;
678 
679         err = at_tok_start(&line);
680         if (err < 0)
681             goto error;
682 
683         err = at_tok_nextint(&line, &response->cid);
684         if (err < 0)
685             goto error;
686 
687         err = at_tok_nextint(&line, &response->active);
688         if (err < 0)
689             goto error;
690 
691         response++;
692     }
693 
694     at_response_free(p_response);
695 
696     err = at_send_command_multiline ("AT+CGDCONT?", "+CGDCONT:", &p_response);
697     if (err != 0 || p_response->success == 0) {
698         if (t != NULL)
699             RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
700         else
701             RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
702                                       NULL, 0);
703         return;
704     }
705 
706     for (p_cur = p_response->p_intermediates; p_cur != NULL;
707          p_cur = p_cur->p_next) {
708         char *line = p_cur->line;
709         int cid;
710 
711         err = at_tok_start(&line);
712         if (err < 0)
713             goto error;
714 
715         err = at_tok_nextint(&line, &cid);
716         if (err < 0)
717             goto error;
718 
719         for (i = 0; i < n; i++) {
720             if (responses[i].cid == cid)
721                 break;
722         }
723 
724         if (i >= n) {
725             /* details for a context we didn't hear about in the last request */
726             continue;
727         }
728 
729         // Assume no error
730         responses[i].status = 0;
731 
732         // type
733         err = at_tok_nextstr(&line, &out);
734         if (err < 0)
735             goto error;
736 
737         int type_size = strlen(out) + 1;
738         responses[i].type = alloca(type_size);
739         strlcpy(responses[i].type, out, type_size);
740 
741         // APN ignored for v5
742         err = at_tok_nextstr(&line, &out);
743         if (err < 0)
744             goto error;
745 
746         int ifname_size = strlen(radioInterfaceName) + 1;
747         responses[i].ifname = alloca(ifname_size);
748         strlcpy(responses[i].ifname, radioInterfaceName, ifname_size);
749 
750         // The next token is the IPv4 address provided by the emulator, only use
751         // it if WiFi is not enabled. When WiFi is enabled the network setup is
752         // specific to the system image and the emulator only provides the
753         // IP address for the external interface in the router namespace.
754         err = at_tok_nextstr(&line, &out);
755         if (err < 0)
756             goto error;
757 
758         pthread_mutex_lock(&s_addresses_mutex);
759 
760         // Extra space for null terminator
761         int addresses_size = MAX(strlen(out), strlen(s_if_addresses)) + 1;
762         responses[i].addresses = alloca(addresses_size);
763         if (*s_if_addresses) {
764             // Interface addresses exist, use them.
765             strlcpy(responses[i].addresses, s_if_addresses, addresses_size);
766         } else {
767             // No known interface address, use whatever the modem provided
768             strlcpy(responses[i].addresses, out, addresses_size);
769         }
770 
771         strlcpy(ipv6Gateway, s_ipv6_gateway, sizeof(ipv6Gateway));
772         strlcpy(ipv6Dns, s_ipv6_dns, sizeof(ipv6Dns));
773 
774         pthread_mutex_unlock(&s_addresses_mutex);
775 
776         if (isInEmulator()) {
777             /* We are in the emulator - the dns servers are listed
778                 * by the following system properties, setup in
779                 * /system/etc/init.goldfish.sh:
780                 *  - net.eth0.dns1
781                 *  - net.eth0.dns2
782                 *  - net.eth0.dns3
783                 *  - net.eth0.dns4
784                 */
785             const int   dnslist_sz = 256;
786             char*       dnslist = alloca(dnslist_sz);
787             const char* separator = "";
788             int         nn;
789             char  propName[PROP_NAME_MAX];
790             char  propValue[PROP_VALUE_MAX];
791             char* gateways = NULL;
792             size_t gatewaysSize = 0;
793 
794             dnslist[0] = 0;
795             for (nn = 1; nn <= 4; nn++) {
796                 /* Probe net.eth0.dns<n> */
797 
798                 snprintf(propName, sizeof propName, "net.%s.dns%d",
799                          radioInterfaceName, nn);
800 
801                 /* Ignore if undefined */
802                 if (property_get(propName, propValue, "") <= 0) {
803                     continue;
804                 }
805 
806                 /* Append the DNS IP address */
807                 strlcat(dnslist, separator, dnslist_sz);
808                 strlcat(dnslist, propValue, dnslist_sz);
809                 separator = " ";
810             }
811             for (nn = 1; nn <= 4; ++nn) {
812                 /* Probe net.eth0.ipv6dns<n> for IPv6 DNS servers */
813                 snprintf(propName, sizeof propName, "net.%s.ipv6dns%d",
814                          radioInterfaceName, nn);
815                 /* Ignore if undefined */
816                 if (property_get(propName, propValue, "") <= 0) {
817                     continue;
818                 }
819                 strlcat(dnslist, separator, dnslist_sz);
820                 strlcat(dnslist, propValue, dnslist_sz);
821                 separator = " ";
822             }
823 
824             responses[i].dnses = dnslist;
825 
826             /* There is only one gateway in the emulator. */
827             snprintf(propName, sizeof propName, "net.%s.gw",
828                      radioInterfaceName);
829 
830             gatewaysSize = strlen(ipv6Gateway);
831             if (property_get(propName, propValue, "") > 0) {
832                 if (gatewaysSize > 0) {
833                     // Room for a separating space
834                     ++gatewaysSize;
835                 }
836                 gatewaysSize += strlen(propValue);
837             }
838             if (gatewaysSize > 0) {
839                 // Room for a terminating null byte
840                 ++gatewaysSize;
841                 responses[i].gateways = alloca(gatewaysSize);
842                 if (ipv6Gateway[0]) {
843                     strlcpy(responses[i].gateways, ipv6Gateway, gatewaysSize);
844                 }
845                 if (propValue[0]) {
846                     if (responses[i].gateways[0] != '\0') {
847                         strlcat(responses[i].gateways, " ", gatewaysSize);
848                     }
849                     strlcat(responses[i].gateways, propValue, gatewaysSize);
850                 }
851             } else {
852                 responses[i].gateways = "";
853             }
854             responses[i].mtu = DEFAULT_MTU;
855         }
856         else {
857             /* I don't know where we are, so use the public Google DNS
858                 * servers by default and no gateway.
859                 */
860             responses[i].dnses = "8.8.8.8 8.8.4.4";
861             responses[i].gateways = "";
862         }
863     }
864 
865     at_response_free(p_response);
866 
867     if (t != NULL) {
868         RIL_onRequestComplete(*t, RIL_E_SUCCESS, responses,
869                               n * sizeof(RIL_Data_Call_Response_v11));
870     } else {
871         RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
872                                   responses,
873                                   n * sizeof(RIL_Data_Call_Response_v11));
874     }
875 
876     return;
877 
878 error:
879     if (t != NULL)
880         RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
881     else
882         RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
883                                   NULL, 0);
884 
885     at_response_free(p_response);
886 }
887 
setNetworkSelectionAutomatic(RIL_Token t)888 static void setNetworkSelectionAutomatic(RIL_Token t)
889 {
890     int err;
891     ATResponse *p_response = NULL;
892 
893     if (getSIMStatus() == SIM_ABSENT) {
894         RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
895         return;
896     }
897 
898     err = at_send_command("AT+COPS=0", &p_response);
899 
900     if (err < 0 || p_response == NULL || p_response->success == 0) {
901         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
902     } else {
903         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
904     }
905 
906     at_response_free(p_response);
907 }
908 
requestQueryNetworkSelectionMode(void * data __unused,size_t datalen __unused,RIL_Token t)909 static void requestQueryNetworkSelectionMode(
910                 void *data __unused, size_t datalen __unused, RIL_Token t)
911 {
912     int err;
913     ATResponse *p_response = NULL;
914     int response = 0;
915     char *line;
916 
917     err = at_send_command_singleline("AT+COPS?", "+COPS:", &p_response);
918 
919     if (err < 0 || p_response->success == 0) {
920         goto error;
921     }
922 
923     line = p_response->p_intermediates->line;
924 
925     err = at_tok_start(&line);
926 
927     if (err < 0) {
928         goto error;
929     }
930 
931     err = at_tok_nextint(&line, &response);
932 
933     if (err < 0) {
934         goto error;
935     }
936 
937     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(int));
938     at_response_free(p_response);
939     return;
940 error:
941     at_response_free(p_response);
942     RLOGE("requestQueryNetworkSelectionMode must never return error when radio is on");
943     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
944 }
945 
sendCallStateChanged(void * param __unused)946 static void sendCallStateChanged(void *param __unused)
947 {
948     RIL_onUnsolicitedResponse (
949         RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
950         NULL, 0);
951 }
952 
requestGetCurrentCalls(void * data __unused,size_t datalen __unused,RIL_Token t)953 static void requestGetCurrentCalls(void *data __unused, size_t datalen __unused, RIL_Token t)
954 {
955     int err;
956     ATResponse *p_response;
957     ATLine *p_cur;
958     int countCalls;
959     int countValidCalls;
960     RIL_Call *p_calls;
961     RIL_Call **pp_calls;
962     int i;
963     int needRepoll = 0;
964 
965 #ifdef WORKAROUND_ERRONEOUS_ANSWER
966     int prevIncomingOrWaitingLine;
967 
968     prevIncomingOrWaitingLine = s_incomingOrWaitingLine;
969     s_incomingOrWaitingLine = -1;
970 #endif /*WORKAROUND_ERRONEOUS_ANSWER*/
971 
972     err = at_send_command_multiline ("AT+CLCC", "+CLCC:", &p_response);
973 
974     if (err != 0 || p_response->success == 0) {
975         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
976         return;
977     }
978 
979     /* count the calls */
980     for (countCalls = 0, p_cur = p_response->p_intermediates
981             ; p_cur != NULL
982             ; p_cur = p_cur->p_next
983     ) {
984         countCalls++;
985     }
986 
987     /* yes, there's an array of pointers and then an array of structures */
988 
989     pp_calls = (RIL_Call **)alloca(countCalls * sizeof(RIL_Call *));
990     p_calls = (RIL_Call *)alloca(countCalls * sizeof(RIL_Call));
991     memset (p_calls, 0, countCalls * sizeof(RIL_Call));
992 
993     /* init the pointer array */
994     for(i = 0; i < countCalls ; i++) {
995         pp_calls[i] = &(p_calls[i]);
996     }
997 
998     for (countValidCalls = 0, p_cur = p_response->p_intermediates
999             ; p_cur != NULL
1000             ; p_cur = p_cur->p_next
1001     ) {
1002         err = callFromCLCCLine(p_cur->line, p_calls + countValidCalls);
1003 
1004         if (err != 0) {
1005             continue;
1006         }
1007 
1008 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1009         if (p_calls[countValidCalls].state == RIL_CALL_INCOMING
1010             || p_calls[countValidCalls].state == RIL_CALL_WAITING
1011         ) {
1012             s_incomingOrWaitingLine = p_calls[countValidCalls].index;
1013         }
1014 #endif /*WORKAROUND_ERRONEOUS_ANSWER*/
1015 
1016         if (p_calls[countValidCalls].state != RIL_CALL_ACTIVE
1017             && p_calls[countValidCalls].state != RIL_CALL_HOLDING
1018         ) {
1019             needRepoll = 1;
1020         }
1021 
1022         countValidCalls++;
1023     }
1024 
1025 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1026     // Basically:
1027     // A call was incoming or waiting
1028     // Now it's marked as active
1029     // But we never answered it
1030     //
1031     // This is probably a bug, and the call will probably
1032     // disappear from the call list in the next poll
1033     if (prevIncomingOrWaitingLine >= 0
1034             && s_incomingOrWaitingLine < 0
1035             && s_expectAnswer == 0
1036     ) {
1037         for (i = 0; i < countValidCalls ; i++) {
1038 
1039             if (p_calls[i].index == prevIncomingOrWaitingLine
1040                     && p_calls[i].state == RIL_CALL_ACTIVE
1041                     && s_repollCallsCount < REPOLL_CALLS_COUNT_MAX
1042             ) {
1043                 RLOGI(
1044                     "Hit WORKAROUND_ERRONOUS_ANSWER case."
1045                     " Repoll count: %d\n", s_repollCallsCount);
1046                 s_repollCallsCount++;
1047                 goto error;
1048             }
1049         }
1050     }
1051 
1052     s_expectAnswer = 0;
1053     s_repollCallsCount = 0;
1054 #endif /*WORKAROUND_ERRONEOUS_ANSWER*/
1055 
1056     RIL_onRequestComplete(t, RIL_E_SUCCESS, pp_calls,
1057             countValidCalls * sizeof (RIL_Call *));
1058 
1059     at_response_free(p_response);
1060 
1061 #ifdef POLL_CALL_STATE
1062     if (countValidCalls) {  // We don't seem to get a "NO CARRIER" message from
1063                             // smd, so we're forced to poll until the call ends.
1064 #else
1065     if (needRepoll) {
1066 #endif
1067         RIL_requestTimedCallback (sendCallStateChanged, NULL, &TIMEVAL_CALLSTATEPOLL);
1068     }
1069 
1070     return;
1071 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1072 error:
1073     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1074     at_response_free(p_response);
1075 #endif
1076 }
1077 
1078 static void requestDial(void *data, size_t datalen __unused, RIL_Token t)
1079 {
1080     RIL_Dial *p_dial;
1081     char *cmd;
1082     const char *clir;
1083     int ret;
1084 
1085     p_dial = (RIL_Dial *)data;
1086 
1087     switch (p_dial->clir) {
1088         case 1: clir = "I"; break;  /*invocation*/
1089         case 2: clir = "i"; break;  /*suppression*/
1090         default:
1091         case 0: clir = ""; break;   /*subscription default*/
1092     }
1093 
1094     asprintf(&cmd, "ATD%s%s;", p_dial->address, clir);
1095 
1096     ret = at_send_command(cmd, NULL);
1097 
1098     free(cmd);
1099 
1100     /* success or failure is ignored by the upper layer here.
1101        it will call GET_CURRENT_CALLS and determine success that way */
1102     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1103 }
1104 
1105 static void requestWriteSmsToSim(void *data, size_t datalen __unused, RIL_Token t)
1106 {
1107     RIL_SMS_WriteArgs *p_args;
1108     char *cmd;
1109     int length;
1110     int err;
1111     ATResponse *p_response = NULL;
1112 
1113     if (getSIMStatus() == SIM_ABSENT) {
1114         RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
1115         return;
1116     }
1117 
1118     p_args = (RIL_SMS_WriteArgs *)data;
1119 
1120     length = strlen(p_args->pdu)/2;
1121     asprintf(&cmd, "AT+CMGW=%d,%d", length, p_args->status);
1122 
1123     err = at_send_command_sms(cmd, p_args->pdu, "+CMGW:", &p_response);
1124 
1125     if (err != 0 || p_response->success == 0) goto error;
1126 
1127     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1128     at_response_free(p_response);
1129 
1130     return;
1131 error:
1132     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1133     at_response_free(p_response);
1134 }
1135 
1136 static void requestHangup(void *data, size_t datalen __unused, RIL_Token t)
1137 {
1138     int *p_line;
1139 
1140     int ret;
1141     char *cmd;
1142 
1143     if (getSIMStatus() == SIM_ABSENT) {
1144         RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
1145         return;
1146     }
1147     p_line = (int *)data;
1148 
1149     // 3GPP 22.030 6.5.5
1150     // "Releases a specific active call X"
1151     asprintf(&cmd, "AT+CHLD=1%d", p_line[0]);
1152 
1153     ret = at_send_command(cmd, NULL);
1154 
1155     free(cmd);
1156 
1157     /* success or failure is ignored by the upper layer here.
1158        it will call GET_CURRENT_CALLS and determine success that way */
1159     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1160 }
1161 
1162 static void requestSignalStrength(void *data __unused, size_t datalen __unused, RIL_Token t)
1163 {
1164     ATResponse *p_response = NULL;
1165     int err;
1166     char *line;
1167     int count = 0;
1168     // Accept a response that is at least v6, and up to v10
1169     int minNumOfElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
1170     int maxNumOfElements=sizeof(RIL_SignalStrength_v10)/sizeof(int);
1171     int response[maxNumOfElements];
1172 
1173     memset(response, 0, sizeof(response));
1174 
1175     err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response);
1176 
1177     if (err < 0 || p_response->success == 0) {
1178         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1179         goto error;
1180     }
1181 
1182     line = p_response->p_intermediates->line;
1183 
1184     err = at_tok_start(&line);
1185     if (err < 0) goto error;
1186 
1187     for (count = 0; count < maxNumOfElements; count++) {
1188         err = at_tok_nextint(&line, &(response[count]));
1189         if (err < 0 && count < minNumOfElements) goto error;
1190     }
1191 
1192     // remove gsm/cdma/evdo,just keep LTE
1193     int numSignalsToIgnore = sizeof(RIL_SignalStrength_v5)/sizeof(int);
1194     for (int i=0; i < numSignalsToIgnore; ++i) {
1195         response[i] = INT_MAX;
1196     }
1197 
1198     RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
1199 
1200     at_response_free(p_response);
1201     return;
1202 
1203 error:
1204     RLOGE("requestSignalStrength must never return an error when radio is on");
1205     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1206     at_response_free(p_response);
1207 }
1208 
1209 /**
1210  * networkModePossible. Decides whether the network mode is appropriate for the
1211  * specified modem
1212  */
1213 static int networkModePossible(ModemInfo *mdm, int nm)
1214 {
1215     if ((net2modem[nm] & mdm->supportedTechs) == net2modem[nm]) {
1216        return 1;
1217     }
1218     return 0;
1219 }
1220 static void requestSetPreferredNetworkType( int request __unused, void *data,
1221                                             size_t datalen __unused, RIL_Token t )
1222 {
1223     ATResponse *p_response = NULL;
1224     char *cmd = NULL;
1225     int value = *(int *)data;
1226     int current, old;
1227     int err;
1228     int32_t preferred = net2pmask[value];
1229 
1230     RLOGD("requestSetPreferredNetworkType: current: %x. New: %x", PREFERRED_NETWORK(sMdmInfo), preferred);
1231     if (!networkModePossible(sMdmInfo, value)) {
1232         RIL_onRequestComplete(t, RIL_E_MODE_NOT_SUPPORTED, NULL, 0);
1233         return;
1234     }
1235     if (query_ctec(sMdmInfo, &current, NULL) < 0) {
1236         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1237         return;
1238     }
1239     old = PREFERRED_NETWORK(sMdmInfo);
1240     RLOGD("old != preferred: %d", old != preferred);
1241     if (old != preferred) {
1242         asprintf(&cmd, "AT+CTEC=%d,\"%x\"", current, preferred);
1243         RLOGD("Sending command: <%s>", cmd);
1244         err = at_send_command_singleline(cmd, "+CTEC:", &p_response);
1245         free(cmd);
1246         if (err || !p_response->success) {
1247             RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1248             return;
1249         }
1250         PREFERRED_NETWORK(sMdmInfo) = value;
1251         if (!strstr( p_response->p_intermediates->line, "DONE") ) {
1252             int current;
1253             int res = parse_technology_response(p_response->p_intermediates->line, &current, NULL);
1254             switch (res) {
1255                 case -1: // Error or unable to parse
1256                     break;
1257                 case 1: // Only able to parse current
1258                 case 0: // Both current and preferred were parsed
1259                     setRadioTechnology(sMdmInfo, current);
1260                     break;
1261             }
1262         }
1263     }
1264     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1265 }
1266 
1267 static void requestGetPreferredNetworkType(int request __unused, void *data __unused,
1268                                    size_t datalen __unused, RIL_Token t)
1269 {
1270     int preferred;
1271     unsigned i;
1272 
1273     switch ( query_ctec(sMdmInfo, NULL, &preferred) ) {
1274         case -1: // Error or unable to parse
1275         case 1: // Only able to parse current
1276             RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1277             break;
1278         case 0: // Both current and preferred were parsed
1279             for ( i = 0 ; i < sizeof(net2pmask) / sizeof(int32_t) ; i++ ) {
1280                 if (preferred == net2pmask[i]) {
1281                     RIL_onRequestComplete(t, RIL_E_SUCCESS, &i, sizeof(int));
1282                     return;
1283                 }
1284             }
1285             RLOGE("Unknown preferred mode received from modem: %d", preferred);
1286             RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1287             break;
1288     }
1289 
1290 }
1291 
1292 static void requestCdmaPrlVersion(int request __unused, void *data __unused,
1293                                    size_t datalen __unused, RIL_Token t)
1294 {
1295     int err;
1296     char * responseStr;
1297     ATResponse *p_response = NULL;
1298     const char *cmd;
1299     char *line;
1300 
1301     err = at_send_command_singleline("AT+WPRL?", "+WPRL:", &p_response);
1302     if (err < 0 || !p_response->success) goto error;
1303     line = p_response->p_intermediates->line;
1304     err = at_tok_start(&line);
1305     if (err < 0) goto error;
1306     err = at_tok_nextstr(&line, &responseStr);
1307     if (err < 0 || !responseStr) goto error;
1308     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, strlen(responseStr));
1309     at_response_free(p_response);
1310     return;
1311 error:
1312     at_response_free(p_response);
1313     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1314 }
1315 
1316 static void requestCdmaBaseBandVersion(int request __unused, void *data __unused,
1317                                    size_t datalen __unused, RIL_Token t)
1318 {
1319     int err;
1320     char * responseStr;
1321     ATResponse *p_response = NULL;
1322     const char *cmd;
1323     const char *prefix;
1324     char *line, *p;
1325     int commas;
1326     int skip;
1327     int count = 4;
1328 
1329     // Fixed values. TODO: query modem
1330     responseStr = strdup("1.0.0.0");
1331     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, sizeof(responseStr));
1332     free(responseStr);
1333 }
1334 
1335 static void requestDeviceIdentity(int request __unused, void *data __unused,
1336                                         size_t datalen __unused, RIL_Token t)
1337 {
1338     int err;
1339     int response[4];
1340     char * responseStr[4];
1341     ATResponse *p_response = NULL;
1342     const char *cmd;
1343     const char *prefix;
1344     char *line, *p;
1345     int commas;
1346     int skip;
1347     int count = 4;
1348 
1349     // Fixed values. TODO: Query modem
1350     responseStr[0] = "----";
1351     responseStr[1] = "----";
1352     responseStr[2] = "77777777";
1353     responseStr[3] = ""; // default empty for non-CDMA
1354 
1355     err = at_send_command_numeric("AT+CGSN", &p_response);
1356     if (err < 0 || p_response->success == 0) {
1357         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1358         return;
1359     } else {
1360         if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
1361             responseStr[3] = p_response->p_intermediates->line;
1362         } else {
1363             responseStr[0] = p_response->p_intermediates->line;
1364         }
1365     }
1366 
1367     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
1368     at_response_free(p_response);
1369 }
1370 
1371 static void requestCdmaGetSubscriptionSource(int request __unused, void *data,
1372                                         size_t datalen __unused, RIL_Token t)
1373 {
1374     int err;
1375     int *ss = (int *)data;
1376     ATResponse *p_response = NULL;
1377     char *cmd = NULL;
1378     char *line = NULL;
1379     int response;
1380 
1381     asprintf(&cmd, "AT+CCSS?");
1382     if (!cmd) goto error;
1383 
1384     err = at_send_command_singleline(cmd, "+CCSS:", &p_response);
1385     if (err < 0 || !p_response->success)
1386         goto error;
1387 
1388     line = p_response->p_intermediates->line;
1389     err = at_tok_start(&line);
1390     if (err < 0) goto error;
1391 
1392     err = at_tok_nextint(&line, &response);
1393     free(cmd);
1394     cmd = NULL;
1395 
1396     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1397 
1398     return;
1399 error:
1400     free(cmd);
1401     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1402 }
1403 
1404 static void requestCdmaSetSubscriptionSource(int request __unused, void *data,
1405                                         size_t datalen, RIL_Token t)
1406 {
1407     int err;
1408     int *ss = (int *)data;
1409     ATResponse *p_response = NULL;
1410     char *cmd = NULL;
1411 
1412     if (!ss || !datalen) {
1413         RLOGE("RIL_REQUEST_CDMA_SET_SUBSCRIPTION without data!");
1414         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1415         return;
1416     }
1417     asprintf(&cmd, "AT+CCSS=%d", ss[0]);
1418     if (!cmd) goto error;
1419 
1420     err = at_send_command(cmd, &p_response);
1421     if (err < 0 || !p_response->success)
1422         goto error;
1423     free(cmd);
1424     cmd = NULL;
1425 
1426     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1427 
1428     RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, ss, sizeof(ss[0]));
1429 
1430     return;
1431 error:
1432     free(cmd);
1433     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1434 }
1435 
1436 static void requestCdmaSubscription(int request __unused, void *data __unused,
1437                                         size_t datalen __unused, RIL_Token t)
1438 {
1439     int err;
1440     int response[5];
1441     char * responseStr[5];
1442     ATResponse *p_response = NULL;
1443     const char *cmd;
1444     const char *prefix;
1445     char *line, *p;
1446     int commas;
1447     int skip;
1448     int count = 5;
1449 
1450     // Fixed values. TODO: Query modem
1451     responseStr[0] = "8587777777"; // MDN
1452     responseStr[1] = "1"; // SID
1453     responseStr[2] = "1"; // NID
1454     responseStr[3] = "8587777777"; // MIN
1455     responseStr[4] = "1"; // PRL Version
1456     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
1457 }
1458 
1459 static void requestCdmaGetRoamingPreference(int request __unused, void *data __unused,
1460                                                  size_t datalen __unused, RIL_Token t)
1461 {
1462     int roaming_pref = -1;
1463     ATResponse *p_response = NULL;
1464     char *line;
1465     int res;
1466 
1467     res = at_send_command_singleline("AT+WRMP?", "+WRMP:", &p_response);
1468     if (res < 0 || !p_response->success) {
1469         goto error;
1470     }
1471     line = p_response->p_intermediates->line;
1472 
1473     res = at_tok_start(&line);
1474     if (res < 0) goto error;
1475 
1476     res = at_tok_nextint(&line, &roaming_pref);
1477     if (res < 0) goto error;
1478 
1479     RIL_onRequestComplete(t, RIL_E_SUCCESS, &roaming_pref, sizeof(roaming_pref));
1480     return;
1481 error:
1482     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1483 }
1484 
1485 static void requestCdmaSetRoamingPreference(int request __unused, void *data,
1486                                                  size_t datalen __unused, RIL_Token t)
1487 {
1488     int *pref = (int *)data;
1489     ATResponse *p_response = NULL;
1490     char *line;
1491     int res;
1492     char *cmd = NULL;
1493 
1494     asprintf(&cmd, "AT+WRMP=%d", *pref);
1495     if (cmd == NULL) goto error;
1496 
1497     res = at_send_command(cmd, &p_response);
1498     if (res < 0 || !p_response->success)
1499         goto error;
1500 
1501     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1502     free(cmd);
1503     return;
1504 error:
1505     free(cmd);
1506     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1507 }
1508 
1509 static int parseRegistrationState(char *str, int *type, int *items, int **response)
1510 {
1511     int err;
1512     char *line = str, *p;
1513     int *resp = NULL;
1514     int skip;
1515     int count = 3;
1516     int commas;
1517 
1518     RLOGD("parseRegistrationState. Parsing: %s",str);
1519     err = at_tok_start(&line);
1520     if (err < 0) goto error;
1521 
1522     /* Ok you have to be careful here
1523      * The solicited version of the CREG response is
1524      * +CREG: n, stat, [lac, cid]
1525      * and the unsolicited version is
1526      * +CREG: stat, [lac, cid]
1527      * The <n> parameter is basically "is unsolicited creg on?"
1528      * which it should always be
1529      *
1530      * Now we should normally get the solicited version here,
1531      * but the unsolicited version could have snuck in
1532      * so we have to handle both
1533      *
1534      * Also since the LAC and CID are only reported when registered,
1535      * we can have 1, 2, 3, or 4 arguments here
1536      *
1537      * finally, a +CGREG: answer may have a fifth value that corresponds
1538      * to the network type, as in;
1539      *
1540      *   +CGREG: n, stat [,lac, cid [,networkType]]
1541      */
1542 
1543     /* count number of commas */
1544     commas = 0;
1545     for (p = line ; *p != '\0' ;p++) {
1546         if (*p == ',') commas++;
1547     }
1548 
1549     resp = (int *)calloc(commas + 1, sizeof(int));
1550     if (!resp) goto error;
1551     switch (commas) {
1552         case 0: /* +CREG: <stat> */
1553             err = at_tok_nextint(&line, &resp[0]);
1554             if (err < 0) goto error;
1555             resp[1] = -1;
1556             resp[2] = -1;
1557         break;
1558 
1559         case 1: /* +CREG: <n>, <stat> */
1560             err = at_tok_nextint(&line, &skip);
1561             if (err < 0) goto error;
1562             err = at_tok_nextint(&line, &resp[0]);
1563             if (err < 0) goto error;
1564             resp[1] = -1;
1565             resp[2] = -1;
1566             if (err < 0) goto error;
1567         break;
1568 
1569         case 2: /* +CREG: <stat>, <lac>, <cid> */
1570             err = at_tok_nextint(&line, &resp[0]);
1571             if (err < 0) goto error;
1572             err = at_tok_nexthexint(&line, &resp[1]);
1573             if (err < 0) goto error;
1574             err = at_tok_nexthexint(&line, &resp[2]);
1575             if (err < 0) goto error;
1576         break;
1577         case 3: /* +CREG: <n>, <stat>, <lac>, <cid> */
1578             err = at_tok_nextint(&line, &skip);
1579             if (err < 0) goto error;
1580             err = at_tok_nextint(&line, &resp[0]);
1581             if (err < 0) goto error;
1582             err = at_tok_nexthexint(&line, &resp[1]);
1583             if (err < 0) goto error;
1584             err = at_tok_nexthexint(&line, &resp[2]);
1585             if (err < 0) goto error;
1586         break;
1587         /* special case for CGREG, there is a fourth parameter
1588          * that is the network type (unknown/gprs/edge/umts)
1589          */
1590         case 4: /* +CGREG: <n>, <stat>, <lac>, <cid>, <networkType> */
1591             err = at_tok_nextint(&line, &skip);
1592             if (err < 0) goto error;
1593             err = at_tok_nextint(&line, &resp[0]);
1594             if (err < 0) goto error;
1595             err = at_tok_nexthexint(&line, &resp[1]);
1596             if (err < 0) goto error;
1597             err = at_tok_nexthexint(&line, &resp[2]);
1598             if (err < 0) goto error;
1599             err = at_tok_nexthexint(&line, &resp[3]);
1600             if (err < 0) goto error;
1601             count = 4;
1602         break;
1603         default:
1604             goto error;
1605     }
1606     s_lac = resp[1];
1607     s_cid = resp[2];
1608     if (response)
1609         *response = resp;
1610     if (items)
1611         *items = commas + 1;
1612     if (type)
1613         *type = techFromModemType(TECH(sMdmInfo));
1614     return 0;
1615 error:
1616     free(resp);
1617     return -1;
1618 }
1619 
1620 #define REG_STATE_LEN 15
1621 #define REG_DATA_STATE_LEN 6
1622 static void requestRegistrationState(int request, void *data __unused,
1623                                         size_t datalen __unused, RIL_Token t)
1624 {
1625     int err;
1626     int *registration;
1627     char **responseStr = NULL;
1628     ATResponse *p_response = NULL;
1629     const char *cmd;
1630     const char *prefix;
1631     char *line;
1632     int i = 0, j, numElements = 0;
1633     int count = 3;
1634     int type, startfrom;
1635 
1636     RLOGD("requestRegistrationState");
1637     if(s_sim_update_started == 0) {
1638         RLOGD("too early, sim card is not done yet");
1639         goto error;
1640     }
1641 
1642     if (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1643         cmd = "AT+CREG?";
1644         prefix = "+CREG:";
1645         numElements = REG_STATE_LEN;
1646     } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1647         cmd = "AT+CGREG?";
1648         prefix = "+CGREG:";
1649         numElements = REG_DATA_STATE_LEN;
1650     } else {
1651         assert(0);
1652         goto error;
1653     }
1654 
1655     err = at_send_command_singleline(cmd, prefix, &p_response);
1656 
1657     if (err != 0) goto error;
1658 
1659     line = p_response->p_intermediates->line;
1660 
1661     if (parseRegistrationState(line, &type, &count, &registration)) goto error;
1662 
1663     responseStr = malloc(numElements * sizeof(char *));
1664     if (!responseStr) goto error;
1665     memset(responseStr, 0, numElements * sizeof(char *));
1666     /**
1667      * The first '4' bytes for both registration states remain the same.
1668      * But if the request is 'DATA_REGISTRATION_STATE',
1669      * the 5th and 6th byte(s) are optional.
1670      */
1671     if (is3gpp2(type) == 1) {
1672         RLOGD("registration state type: 3GPP2");
1673         // TODO: Query modem
1674         startfrom = 3;
1675         if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1676             asprintf(&responseStr[3], "8");     // EvDo revA
1677             asprintf(&responseStr[4], "1");     // BSID
1678             asprintf(&responseStr[5], "123");   // Latitude
1679             asprintf(&responseStr[6], "222");   // Longitude
1680             asprintf(&responseStr[7], "0");     // CSS Indicator
1681             asprintf(&responseStr[8], "4");     // SID
1682             asprintf(&responseStr[9], "65535"); // NID
1683             asprintf(&responseStr[10], "0");    // Roaming indicator
1684             asprintf(&responseStr[11], "1");    // System is in PRL
1685             asprintf(&responseStr[12], "0");    // Default Roaming indicator
1686             asprintf(&responseStr[13], "0");    // Reason for denial
1687             asprintf(&responseStr[14], "0");    // Primary Scrambling Code of Current cell
1688       } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1689             asprintf(&responseStr[3], "8");   // Available data radio technology
1690       }
1691     } else { // type == RADIO_TECH_3GPP
1692         RLOGD("registration state type: 3GPP");
1693         startfrom = 0;
1694         asprintf(&responseStr[1], "%x", registration[1]);
1695         asprintf(&responseStr[2], "%x", registration[2]);
1696         if (count > 3)
1697             asprintf(&responseStr[3], "%d", registration[3]);
1698     }
1699     asprintf(&responseStr[0], "%d", registration[0]);
1700 
1701     /**
1702      * Optional bytes for DATA_REGISTRATION_STATE request
1703      * 4th byte : Registration denial code
1704      * 5th byte : The max. number of simultaneous Data Calls
1705      */
1706     if(request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1707         // asprintf(&responseStr[4], "3");
1708         // asprintf(&responseStr[5], "1");
1709     }
1710 
1711     for (j = startfrom; j < numElements; j++) {
1712         if (!responseStr[i]) goto error;
1713     }
1714     free(registration);
1715     registration = NULL;
1716 
1717     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, numElements*sizeof(responseStr));
1718     for (j = 0; j < numElements; j++ ) {
1719         free(responseStr[j]);
1720         responseStr[j] = NULL;
1721     }
1722     free(responseStr);
1723     responseStr = NULL;
1724     at_response_free(p_response);
1725 
1726     return;
1727 error:
1728     if (responseStr) {
1729         for (j = 0; j < numElements; j++) {
1730             free(responseStr[j]);
1731             responseStr[j] = NULL;
1732         }
1733         free(responseStr);
1734         responseStr = NULL;
1735     }
1736     RLOGE("requestRegistrationState must never return an error when radio is on");
1737     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1738     at_response_free(p_response);
1739 }
1740 
1741 static void requestOperator(void *data __unused, size_t datalen __unused, RIL_Token t)
1742 {
1743     int err;
1744     int i;
1745     int skip;
1746     ATLine *p_cur;
1747     char *response[3];
1748 
1749     memset(response, 0, sizeof(response));
1750 
1751     ATResponse *p_response = NULL;
1752 
1753     err = at_send_command_multiline(
1754         "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
1755         "+COPS:", &p_response);
1756 
1757     /* we expect 3 lines here:
1758      * +COPS: 0,0,"T - Mobile"
1759      * +COPS: 0,1,"TMO"
1760      * +COPS: 0,2,"310170"
1761      */
1762 
1763     if (err != 0) goto error;
1764 
1765     for (i = 0, p_cur = p_response->p_intermediates
1766             ; p_cur != NULL
1767             ; p_cur = p_cur->p_next, i++
1768     ) {
1769         char *line = p_cur->line;
1770 
1771         err = at_tok_start(&line);
1772         if (err < 0) goto error;
1773 
1774         err = at_tok_nextint(&line, &skip);
1775         if (err < 0) goto error;
1776 
1777         // If we're unregistered, we may just get
1778         // a "+COPS: 0" response
1779         if (!at_tok_hasmore(&line)) {
1780             response[i] = NULL;
1781             continue;
1782         }
1783 
1784         err = at_tok_nextint(&line, &skip);
1785         if (err < 0) goto error;
1786 
1787         // a "+COPS: 0, n" response is also possible
1788         if (!at_tok_hasmore(&line)) {
1789             response[i] = NULL;
1790             continue;
1791         }
1792 
1793         err = at_tok_nextstr(&line, &(response[i]));
1794         if (err < 0) goto error;
1795         // Simple assumption that mcc and mnc are 3 digits each
1796         if (strlen(response[i]) == 6) {
1797             if (sscanf(response[i], "%3d%3d", &s_mcc, &s_mnc) != 2) {
1798                 RLOGE("requestOperator expected mccmnc to be 6 decimal digits");
1799             }
1800         }
1801     }
1802 
1803     if (i != 3) {
1804         /* expect 3 lines exactly */
1805         goto error;
1806     }
1807 
1808     RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
1809     at_response_free(p_response);
1810 
1811     return;
1812 error:
1813     RLOGE("requestOperator must not return error when radio is on");
1814     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1815     at_response_free(p_response);
1816 }
1817 
1818 static void requestCdmaSendSMS(void *data, size_t datalen, RIL_Token t)
1819 {
1820     int err = 1; // Set to go to error:
1821     RIL_SMS_Response response;
1822     RIL_CDMA_SMS_Message* rcsm;
1823 
1824     if (getSIMStatus() == SIM_ABSENT) {
1825         RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
1826         return;
1827     }
1828 
1829     RLOGD("requestCdmaSendSMS datalen=%zu, sizeof(RIL_CDMA_SMS_Message)=%zu",
1830             datalen, sizeof(RIL_CDMA_SMS_Message));
1831 
1832     // verify data content to test marshalling/unmarshalling:
1833     rcsm = (RIL_CDMA_SMS_Message*)data;
1834     RLOGD("TeleserviceID=%d, bIsServicePresent=%d, \
1835             uServicecategory=%d, sAddress.digit_mode=%d, \
1836             sAddress.Number_mode=%d, sAddress.number_type=%d, ",
1837             rcsm->uTeleserviceID,  rcsm->bIsServicePresent,
1838             rcsm->uServicecategory,rcsm->sAddress.digit_mode,
1839             rcsm->sAddress.number_mode,rcsm->sAddress.number_type);
1840 
1841     if (err != 0) goto error;
1842 
1843     // Cdma Send SMS implementation will go here:
1844     // But it is not implemented yet.
1845 
1846     memset(&response, 0, sizeof(response));
1847     response.messageRef = 1;
1848     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1849     return;
1850 
1851 error:
1852     // Cdma Send SMS will always cause send retry error.
1853     response.messageRef = -1;
1854     RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
1855 }
1856 
1857 static void requestSendSMS(void *data, size_t datalen, RIL_Token t)
1858 {
1859     int err;
1860     const char *smsc;
1861     const char *pdu;
1862     int tpLayerLength;
1863     char *cmd1, *cmd2;
1864     RIL_SMS_Response response;
1865     ATResponse *p_response = NULL;
1866 
1867     if (getSIMStatus() == SIM_ABSENT) {
1868         RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
1869         return;
1870     }
1871 
1872     memset(&response, 0, sizeof(response));
1873     RLOGD("requestSendSMS datalen =%zu", datalen);
1874 
1875     if (s_ims_gsm_fail != 0) goto error;
1876     if (s_ims_gsm_retry != 0) goto error2;
1877 
1878     smsc = ((const char **)data)[0];
1879     pdu = ((const char **)data)[1];
1880 
1881     tpLayerLength = strlen(pdu)/2;
1882 
1883     // "NULL for default SMSC"
1884     if (smsc == NULL) {
1885         smsc= "00";
1886     }
1887 
1888     asprintf(&cmd1, "AT+CMGS=%d", tpLayerLength);
1889     asprintf(&cmd2, "%s%s", smsc, pdu);
1890 
1891     err = at_send_command_sms(cmd1, cmd2, "+CMGS:", &p_response);
1892 
1893     free(cmd1);
1894     free(cmd2);
1895 
1896     if (err != 0 || p_response->success == 0) goto error;
1897 
1898     /* FIXME fill in messageRef and ackPDU */
1899     response.messageRef = 1;
1900     RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1901     at_response_free(p_response);
1902 
1903     return;
1904 error:
1905     response.messageRef = -2;
1906     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response));
1907     at_response_free(p_response);
1908     return;
1909 error2:
1910     // send retry error.
1911     response.messageRef = -1;
1912     RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
1913     at_response_free(p_response);
1914     return;
1915 }
1916 
1917 static void requestImsSendSMS(void *data, size_t datalen, RIL_Token t)
1918 {
1919     RIL_IMS_SMS_Message *p_args;
1920     RIL_SMS_Response response;
1921 
1922     memset(&response, 0, sizeof(response));
1923 
1924     RLOGD("requestImsSendSMS: datalen=%zu, "
1925         "registered=%d, service=%d, format=%d, ims_perm_fail=%d, "
1926         "ims_retry=%d, gsm_fail=%d, gsm_retry=%d",
1927         datalen, s_ims_registered, s_ims_services, s_ims_format,
1928         s_ims_cause_perm_failure, s_ims_cause_retry, s_ims_gsm_fail,
1929         s_ims_gsm_retry);
1930 
1931     // figure out if this is gsm/cdma format
1932     // then route it to requestSendSMS vs requestCdmaSendSMS respectively
1933     p_args = (RIL_IMS_SMS_Message *)data;
1934 
1935     if (0 != s_ims_cause_perm_failure ) goto error;
1936 
1937     // want to fail over ims and this is first request over ims
1938     if (0 != s_ims_cause_retry && 0 == p_args->retry) goto error2;
1939 
1940     if (RADIO_TECH_3GPP == p_args->tech) {
1941         return requestSendSMS(p_args->message.gsmMessage,
1942                 datalen - sizeof(RIL_RadioTechnologyFamily),
1943                 t);
1944     } else if (RADIO_TECH_3GPP2 == p_args->tech) {
1945         return requestCdmaSendSMS(p_args->message.cdmaMessage,
1946                 datalen - sizeof(RIL_RadioTechnologyFamily),
1947                 t);
1948     } else {
1949         RLOGE("requestImsSendSMS invalid format value =%d", p_args->tech);
1950     }
1951 
1952 error:
1953     response.messageRef = -2;
1954     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response));
1955     return;
1956 
1957 error2:
1958     response.messageRef = -1;
1959     RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
1960 }
1961 
1962 static void requestSimOpenChannel(void *data, size_t datalen, RIL_Token t)
1963 {
1964     ATResponse *p_response = NULL;
1965     int32_t session_id[3];
1966     int err;
1967     char cmd[32];
1968     char dummy;
1969     char *line;
1970 
1971     const char *pdata = data ? data : EMULATOR_DUMMY_SIM_CHANNEL_NAME;
1972 
1973     // Max length is 16 bytes according to 3GPP spec 27.007 section 8.45
1974     if (pdata == NULL || datalen == 0 || datalen > 16) {
1975         RLOGE("Invalid data passed to requestSimOpenChannel");
1976         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1977         return;
1978     }
1979 
1980     snprintf(cmd, sizeof(cmd), "AT+CCHO=%s", pdata);
1981 
1982     err = at_send_command_numeric(cmd, &p_response);
1983     if (err < 0 || p_response == NULL || p_response->success == 0) {
1984         RLOGE("Error %d opening logical channel: %d",
1985               err, p_response ? p_response->success : 0);
1986         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1987         at_response_free(p_response);
1988         return;
1989     }
1990 
1991     memset(session_id, 0, sizeof(session_id));
1992 
1993     // Ensure integer only by scanning for an extra char but expect one result
1994     line = p_response->p_intermediates->line;
1995     if (sscanf(line, "%" SCNd32 "%c", session_id, &dummy) != 1) {
1996         RLOGE("Invalid AT response, expected integer, was '%s'", line);
1997         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1998         return;
1999     }
2000 
2001     session_id[1] = 0x90;
2002     RIL_onRequestComplete(t, RIL_E_SUCCESS, session_id, sizeof(session_id));
2003     at_response_free(p_response);
2004 }
2005 
2006 static void requestSimCloseChannel(void *data, size_t datalen, RIL_Token t)
2007 {
2008     ATResponse *p_response = NULL;
2009     int32_t session_id;
2010     int err;
2011     char cmd[32];
2012 
2013     if (data == NULL || datalen != sizeof(session_id)) {
2014         ALOGE("Invalid data passed to requestSimCloseChannel");
2015         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2016         return;
2017     }
2018     session_id = ((int32_t *)data)[0];
2019     snprintf(cmd, sizeof(cmd), "AT+CCHC=%" PRId32, session_id);
2020     err = at_send_command_singleline(cmd, "+CCHC", &p_response);
2021 
2022     if (err < 0 || p_response == NULL || p_response->success == 0) {
2023         AT_CME_Error cme = p_response ? at_get_cme_error(p_response) :
2024                                         CME_ERROR_NON_CME;
2025         RIL_Errno ril_e = (cme == CME_INVALID_INDEX) ? RIL_E_INVALID_ARGUMENTS :
2026                                                        RIL_E_GENERIC_FAILURE;
2027 
2028         ALOGE("Error %d closing logical channel %d: %d",
2029               err, session_id, p_response ? p_response->success : 0);
2030         RIL_onRequestComplete(t, ril_e, NULL, 0);
2031         at_response_free(p_response);
2032         return;
2033     }
2034 
2035     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2036 
2037     at_response_free(p_response);
2038 }
2039 
2040 static void requestSimTransmitApduChannel(void *data,
2041                                           size_t datalen,
2042                                           RIL_Token t)
2043 {
2044     ATResponse *p_response = NULL;
2045     int err;
2046     char *cmd;
2047     char *line;
2048     size_t cmd_size;
2049     RIL_SIM_IO_Response sim_response;
2050     memset(&sim_response, 0, sizeof(sim_response));
2051     RIL_SIM_APDU *apdu = (RIL_SIM_APDU *)data;
2052 
2053     if (apdu == NULL || datalen != sizeof(RIL_SIM_APDU)) {
2054         RLOGE("Error input invalid %p %d %d", apdu, (int)datalen, (int)(sizeof(RIL_SIM_APDU)));
2055         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2056         return;
2057     }
2058 
2059     cmd_size = 10 + (apdu->data ? strlen(apdu->data) : 0);
2060     asprintf(&cmd, "AT+CGLA=%d,%zu,%02x%02x%02x%02x%02x%s",
2061              apdu->sessionid, cmd_size, apdu->cla, apdu->instruction,
2062              apdu->p1, apdu->p2, apdu->p3, apdu->data ? apdu->data : "");
2063 
2064     err = at_send_command_singleline(cmd, "+CGLA", &p_response);
2065     free(cmd);
2066     if (err < 0 || p_response == NULL || p_response->success == 0) {
2067         RLOGE("Error %d transmitting APDU: %d",
2068               err, p_response ? p_response->success : 0);
2069         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2070         at_response_free(p_response);
2071         return;
2072     }
2073 
2074     line = p_response->p_intermediates->line;
2075     err = parseSimResponseLine(line, &sim_response);
2076 
2077     if (err == 0) {
2078         RIL_onRequestComplete(t, RIL_E_SUCCESS,
2079                               &sim_response, sizeof(sim_response));
2080     } else {
2081         RLOGE("Error %d parsing SIM response line: %s", err, line);
2082         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2083     }
2084     at_response_free(p_response);
2085 }
2086 
2087 static void requestSetupDataCall(void *data, size_t datalen, RIL_Token t)
2088 {
2089     const char *apn;
2090     char *cmd;
2091     int err;
2092     ATResponse *p_response = NULL;
2093 
2094     apn = ((const char **)data)[2];
2095 
2096 #ifdef USE_TI_COMMANDS
2097     // Config for multislot class 10 (probably default anyway eh?)
2098     err = at_send_command("AT%CPRIM=\"GMM\",\"CONFIG MULTISLOT_CLASS=<10>\"",
2099                         NULL);
2100 
2101     err = at_send_command("AT%DATA=2,\"UART\",1,,\"SER\",\"UART\",0", NULL);
2102 #endif /* USE_TI_COMMANDS */
2103 
2104     int fd, qmistatus;
2105     size_t cur = 0;
2106     size_t len;
2107     ssize_t written, rlen;
2108     char status[32] = {0};
2109     int retry = 10;
2110     const char *pdp_type;
2111 
2112     RLOGD("requesting data connection to APN '%s'", apn);
2113 
2114     fd = open ("/dev/qmi", O_RDWR);
2115     if (fd >= 0) { /* the device doesn't exist on the emulator */
2116 
2117         RLOGD("opened the qmi device\n");
2118         asprintf(&cmd, "up:%s", apn);
2119         len = strlen(cmd);
2120 
2121         while (cur < len) {
2122             do {
2123                 written = write (fd, cmd + cur, len - cur);
2124             } while (written < 0 && errno == EINTR);
2125 
2126             if (written < 0) {
2127                 RLOGE("### ERROR writing to /dev/qmi");
2128                 close(fd);
2129                 goto error;
2130             }
2131 
2132             cur += written;
2133         }
2134 
2135         // wait for interface to come online
2136 
2137         do {
2138             sleep(1);
2139             do {
2140                 rlen = read(fd, status, 31);
2141             } while (rlen < 0 && errno == EINTR);
2142 
2143             if (rlen < 0) {
2144                 RLOGE("### ERROR reading from /dev/qmi");
2145                 close(fd);
2146                 goto error;
2147             } else {
2148                 status[rlen] = '\0';
2149                 RLOGD("### status: %s", status);
2150             }
2151         } while (strncmp(status, "STATE=up", 8) && strcmp(status, "online") && --retry);
2152 
2153         close(fd);
2154 
2155         if (retry == 0) {
2156             RLOGE("### Failed to get data connection up\n");
2157             goto error;
2158         }
2159 
2160         qmistatus = system("netcfg rmnet0 dhcp");
2161 
2162         RLOGD("netcfg rmnet0 dhcp: status %d\n", qmistatus);
2163 
2164         if (qmistatus < 0) goto error;
2165 
2166     } else {
2167         bool hasWifi = hasWifiCapability();
2168         const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
2169         if (setInterfaceState(radioInterfaceName, kInterfaceUp) != RIL_E_SUCCESS) {
2170             goto error;
2171         }
2172 
2173         if (datalen > 6 * sizeof(char *)) {
2174             pdp_type = ((const char **)data)[6];
2175         } else {
2176             pdp_type = "IP";
2177         }
2178 
2179         asprintf(&cmd, "AT+CGDCONT=1,\"%s\",\"%s\",,0,0", pdp_type, apn);
2180         //FIXME check for error here
2181         err = at_send_command(cmd, NULL);
2182         free(cmd);
2183 
2184         // Set required QoS params to default
2185         err = at_send_command("AT+CGQREQ=1", NULL);
2186 
2187         // Set minimum QoS params to default
2188         err = at_send_command("AT+CGQMIN=1", NULL);
2189 
2190         // packet-domain event reporting
2191         err = at_send_command("AT+CGEREP=1,0", NULL);
2192 
2193         // Hangup anything that's happening there now
2194         err = at_send_command("AT+CGACT=1,0", NULL);
2195 
2196         // Start data on PDP context 1
2197         err = at_send_command("ATD*99***1#", &p_response);
2198 
2199         if (err < 0 || p_response->success == 0) {
2200             goto error;
2201         }
2202     }
2203 
2204     requestOrSendDataCallList(&t);
2205 
2206     at_response_free(p_response);
2207 
2208     return;
2209 error:
2210     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2211     at_response_free(p_response);
2212 
2213 }
2214 
2215 static void requestDeactivateDataCall(RIL_Token t)
2216 {
2217     bool hasWifi = hasWifiCapability();
2218     const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
2219     RIL_Errno rilErrno = setInterfaceState(radioInterfaceName, kInterfaceDown);
2220     RIL_onRequestComplete(t, rilErrno, NULL, 0);
2221 }
2222 
2223 static void requestSMSAcknowledge(void *data, size_t datalen __unused, RIL_Token t)
2224 {
2225     int ackSuccess;
2226     int err;
2227 
2228     if (getSIMStatus() == SIM_ABSENT) {
2229         RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2230         return;
2231     }
2232 
2233     ackSuccess = ((int *)data)[0];
2234 
2235     if (ackSuccess == 1) {
2236         err = at_send_command("AT+CNMA=1", NULL);
2237     } else if (ackSuccess == 0)  {
2238         err = at_send_command("AT+CNMA=2", NULL);
2239     } else {
2240         RLOGE("unsupported arg to RIL_REQUEST_SMS_ACKNOWLEDGE\n");
2241         goto error;
2242     }
2243 
2244     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2245 error:
2246     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2247 
2248 }
2249 
2250 static void  requestSIM_IO(void *data, size_t datalen __unused, RIL_Token t)
2251 {
2252     ATResponse *p_response = NULL;
2253     RIL_SIM_IO_Response sr;
2254     int err;
2255     char *cmd = NULL;
2256     RIL_SIM_IO_v6 *p_args;
2257     char *line;
2258 
2259     memset(&sr, 0, sizeof(sr));
2260 
2261     p_args = (RIL_SIM_IO_v6 *)data;
2262 
2263     /* FIXME handle pin2 */
2264 
2265     if (p_args->data == NULL) {
2266         asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d",
2267                     p_args->command, p_args->fileid,
2268                     p_args->p1, p_args->p2, p_args->p3);
2269     } else {
2270         asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d,%s",
2271                     p_args->command, p_args->fileid,
2272                     p_args->p1, p_args->p2, p_args->p3, p_args->data);
2273     }
2274 
2275     if (p_args->command == 0xdc) {
2276         s_sim_update_started = 1;
2277     }
2278 
2279     err = at_send_command_singleline(cmd, "+CRSM:", &p_response);
2280 
2281     if (err < 0 || p_response->success == 0) {
2282         goto error;
2283     }
2284 
2285     line = p_response->p_intermediates->line;
2286 
2287     err = parseSimResponseLine(line, &sr);
2288     if (err < 0) {
2289         goto error;
2290     }
2291 
2292     RIL_onRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
2293     at_response_free(p_response);
2294     free(cmd);
2295 
2296     return;
2297 error:
2298     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2299     at_response_free(p_response);
2300     free(cmd);
2301 
2302 }
2303 
2304 static void  requestEnterSimPin(void*  data, size_t  datalen, RIL_Token  t)
2305 {
2306     ATResponse   *p_response = NULL;
2307     int           err;
2308     char*         cmd = NULL;
2309     const char**  strings = (const char**)data;;
2310 
2311     if ( datalen == sizeof(char*) ) {
2312         asprintf(&cmd, "AT+CPIN=%s", strings[0]);
2313     } else if ( datalen == 2*sizeof(char*) ) {
2314         asprintf(&cmd, "AT+CPIN=%s,%s", strings[0], strings[1]);
2315     } else
2316         goto error;
2317 
2318     err = at_send_command_singleline(cmd, "+CPIN:", &p_response);
2319     free(cmd);
2320 
2321     if (err < 0 || p_response->success == 0) {
2322 error:
2323         RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, NULL, 0);
2324     } else {
2325         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2326     }
2327     at_response_free(p_response);
2328 }
2329 
2330 
2331 static void  requestSendUSSD(void *data, size_t datalen __unused, RIL_Token t)
2332 {
2333     const char *ussdRequest;
2334 
2335     ussdRequest = (char *)(data);
2336 
2337 
2338     RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
2339 
2340 // @@@ TODO
2341 
2342 }
2343 
2344 static void requestExitEmergencyMode(void *data __unused, size_t datalen __unused, RIL_Token t)
2345 {
2346     int err;
2347     ATResponse *p_response = NULL;
2348 
2349     err = at_send_command("AT+WSOS=0", &p_response);
2350 
2351     if (err < 0 || p_response->success == 0) {
2352         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2353         return;
2354     }
2355 
2356     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2357 }
2358 
2359 // TODO: Use all radio types
2360 static int techFromModemType(int mdmtype)
2361 {
2362     int ret = -1;
2363     switch (1 << mdmtype) {
2364         case MDM_CDMA:
2365             ret = RADIO_TECH_1xRTT;
2366             break;
2367         case MDM_EVDO:
2368             ret = RADIO_TECH_EVDO_A;
2369             break;
2370         case MDM_GSM:
2371             ret = RADIO_TECH_GPRS;
2372             break;
2373         case MDM_WCDMA:
2374             ret = RADIO_TECH_HSPA;
2375             break;
2376         case MDM_LTE:
2377             ret = RADIO_TECH_LTE;
2378             break;
2379     }
2380     return ret;
2381 }
2382 
2383 static void requestGetCellInfoList(void *data __unused, size_t datalen __unused, RIL_Token t)
2384 {
2385     uint64_t curTime = ril_nano_time();
2386     RIL_CellInfo_v12 ci[1] =
2387     {
2388         { // ci[0]
2389             1, // cellInfoType
2390             1, // registered
2391             RIL_TIMESTAMP_TYPE_MODEM,
2392             curTime - 1000, // Fake some time in the past
2393             { // union CellInfo
2394                 {  // RIL_CellInfoGsm gsm
2395                     {  // gsm.cellIdneityGsm
2396                         s_mcc, // mcc
2397                         s_mnc, // mnc
2398                         s_lac, // lac
2399                         s_cid, // cid
2400                         0, //arfcn unknown
2401                         0xFF, // bsic unknown
2402                     },
2403                     {  // gsm.signalStrengthGsm
2404                         10, // signalStrength
2405                         0  // bitErrorRate
2406                         , INT_MAX // timingAdvance invalid value
2407                     }
2408                 }
2409             }
2410         }
2411     };
2412 
2413     RIL_onRequestComplete(t, RIL_E_SUCCESS, ci, sizeof(ci));
2414 }
2415 
2416 
2417 static void requestSetCellInfoListRate(void *data, size_t datalen __unused, RIL_Token t)
2418 {
2419     // For now we'll save the rate but no RIL_UNSOL_CELL_INFO_LIST messages
2420     // will be sent.
2421     assert (datalen == sizeof(int));
2422     s_cell_info_rate_ms = ((int *)data)[0];
2423 
2424     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2425 }
2426 
2427 static void requestGetHardwareConfig(void *data, size_t datalen, RIL_Token t)
2428 {
2429    // TODO - hook this up with real query/info from radio.
2430 
2431    RIL_HardwareConfig hwCfg;
2432    memset(&hwCfg, 0, sizeof(hwCfg));
2433 
2434    RIL_UNUSED_PARM(data);
2435    RIL_UNUSED_PARM(datalen);
2436 
2437    hwCfg.type = -1;
2438 
2439    RIL_onRequestComplete(t, RIL_E_SUCCESS, &hwCfg, sizeof(hwCfg));
2440 }
2441 
2442 static void requestGetTtyMode(void *data, size_t datalen, RIL_Token t)
2443 {
2444    int  ttyModeResponse;
2445 
2446    RIL_UNUSED_PARM(data);
2447    RIL_UNUSED_PARM(datalen);
2448 
2449    ttyModeResponse = (getSIMStatus() == SIM_READY) ? 1  // TTY Full
2450                                                    : 0; // TTY Off
2451 
2452    RIL_onRequestComplete(t, RIL_E_SUCCESS, &ttyModeResponse, sizeof(ttyModeResponse));
2453 }
2454 
2455 static void requestGetRadioCapability(void *data, size_t datalen, RIL_Token t)
2456 {
2457    RIL_RadioCapability radioCapability;
2458 
2459    RIL_UNUSED_PARM(data);
2460    RIL_UNUSED_PARM(datalen);
2461 
2462    radioCapability.version = RIL_RADIO_CAPABILITY_VERSION;
2463    radioCapability.session = 0;
2464    radioCapability.phase   = 0;
2465    radioCapability.rat     = RAF_NR | RAF_LTE | RAF_UMTS | RAF_GSM;
2466    radioCapability.logicalModemUuid[0] = '\0';
2467    radioCapability.status  = RC_STATUS_SUCCESS;
2468 
2469    RIL_onRequestComplete(t, RIL_E_SUCCESS, &radioCapability, sizeof(radioCapability));
2470 }
2471 
2472 static void requestGetMute(void *data, size_t datalen, RIL_Token t)
2473 {
2474    int  muteResponse;
2475 
2476    RIL_UNUSED_PARM(data);
2477    RIL_UNUSED_PARM(datalen);
2478 
2479    muteResponse = 0; // Mute disabled
2480 
2481    RIL_onRequestComplete(t, RIL_E_SUCCESS, &muteResponse, sizeof(muteResponse));
2482 }
2483 
2484 static void requestGetSimAuthentication(void *data, size_t datalen __unused, RIL_Token t)
2485 {
2486     // TODO - hook this up with real query/info from radio.
2487     RIL_SimAuthentication* auth = (RIL_SimAuthentication*)data;
2488 
2489     RIL_SIM_IO_Response auth_response = {
2490         0x90,
2491         0x00,
2492         ""
2493     };
2494 
2495     // special case: empty authData, should return empty response
2496     if (auth->authData == NULL || strlen(auth->authData) == 0) {
2497         char reply[] = "";
2498         RIL_onRequestComplete(t, RIL_E_SUCCESS, &auth_response, sizeof(auth_response));
2499         RLOGD("%s empty data in", __func__);
2500         return;
2501     }
2502 
2503     //talk to modem
2504     ATResponse *p_response = NULL;
2505     memset(&auth_response, 0, sizeof(auth_response));
2506     int err;
2507     char *cmd = NULL;
2508     int auth_len = strlen(auth->authData);
2509     int total_len = auth_len + 12;
2510     asprintf(&cmd, "AT+CSIM=%d, \"008800%02x%02x%s00\"", total_len, auth->authContext,
2511             auth_len, auth->authData);
2512 
2513     err = at_send_command_singleline(cmd, "+CSIM:", &p_response);
2514     if (err < 0 || p_response == NULL || p_response->success == 0) {
2515         ALOGE("%s Error %d transmitting CSIM: %d", __func__,
2516               err, p_response ? p_response->success : 0);
2517         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2518         at_response_free(p_response);
2519         return;
2520     }
2521 
2522     char* line = p_response->p_intermediates->line;
2523 
2524     parseAuthResponse(line, &auth_response);
2525     RIL_onRequestComplete(t, auth_response.sw2, &auth_response, sizeof(auth_response));
2526     free(auth_response.simResponse);
2527     free(p_response);
2528 }
2529 
2530 static void requestModemActivityInfo(RIL_Token t)
2531 {
2532     int err;
2533     char *line;
2534     ATResponse *p_response = NULL;
2535     RIL_ActivityStatsInfo info;
2536 
2537     err = at_send_command_singleline("AT+MAI", "+MAI:", &p_response);
2538     if (err < 0 || p_response == NULL || p_response->success == 0) {
2539         ALOGE("Error transmitting AT+MAI, err=%d, success=%d",
2540             err, (p_response ? p_response->success : 0));
2541         goto error;
2542     }
2543 
2544     memset(&info, 0, sizeof(info));
2545     if (sscanf(p_response->p_intermediates->line,
2546                "+MAI: sleep=%u idle=%u rx=%u tx0=%u tx1=%u tx2=%u tx3=%u tx4=%u",
2547                &info.sleep_mode_time_ms,
2548                &info.idle_mode_time_ms,
2549                &info.rx_mode_time_ms,
2550                &info.tx_mode_time_ms[0],
2551                &info.tx_mode_time_ms[1],
2552                &info.tx_mode_time_ms[2],
2553                &info.tx_mode_time_ms[3],
2554                &info.tx_mode_time_ms[4]) == 8) {
2555         RIL_onRequestComplete(t, RIL_E_SUCCESS, &info, sizeof(info));
2556         at_response_free(p_response);
2557         return;
2558     } else {
2559         ALOGE("Unexpected response for AT+MAI: '%s'",
2560             p_response->p_intermediates->line);
2561     }
2562 
2563 error:
2564     at_response_free(p_response);
2565     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2566 }
2567 
2568 static void requestSetCarrierRestrictions(const RIL_CarrierRestrictions *restrictions __unused, RIL_Token t)
2569 {
2570     ATResponse *p_response = NULL;
2571     int success;
2572     int err;
2573     char cmd[32];
2574 
2575     snprintf(cmd, sizeof(cmd), "AT+CRRSTR=%d,%d",
2576         restrictions->len_allowed_carriers,
2577         restrictions->len_excluded_carriers);
2578 
2579     err = at_send_command_singleline(cmd, "+CRRSTR:", &p_response);
2580     success = p_response ? p_response->success : 0;
2581     at_response_free(p_response);
2582 
2583     if (err == 0 && success) {
2584         RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2585     } else {
2586         ALOGE("'%s' failed with err=%d success=%d", cmd, err, success);
2587         RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2588     }
2589 }
2590 
2591 /*** Callback methods from the RIL library to us ***/
2592 
2593 /**
2594  * Call from RIL to us to make a RIL_REQUEST
2595  *
2596  * Must be completed with a call to RIL_onRequestComplete()
2597  *
2598  * RIL_onRequestComplete() may be called from any thread, before or after
2599  * this function returns.
2600  *
2601  * Because onRequest function could be called from multiple different thread,
2602  * we must ensure that the underlying at_send_command_* function
2603  * is atomic.
2604  */
2605 static void
2606 onRequest (int request, void *data, size_t datalen, RIL_Token t)
2607 {
2608     ATResponse *p_response;
2609     int err;
2610 
2611     RLOGD("onRequest: %s", requestToString(request));
2612 
2613     /* Ignore all requests except RIL_REQUEST_GET_SIM_STATUS
2614      * when RADIO_STATE_UNAVAILABLE.
2615      */
2616     if (sState == RADIO_STATE_UNAVAILABLE
2617         && request != RIL_REQUEST_GET_SIM_STATUS
2618     ) {
2619         RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2620         return;
2621     }
2622 
2623     /* Ignore all non-power requests when RADIO_STATE_OFF
2624      * (except RIL_REQUEST_GET_SIM_STATUS)
2625      */
2626     if (sState == RADIO_STATE_OFF) {
2627         switch(request) {
2628             case RIL_REQUEST_BASEBAND_VERSION:
2629             case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
2630             case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
2631             case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
2632             case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
2633             case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
2634             case RIL_REQUEST_CDMA_SUBSCRIPTION:
2635             case RIL_REQUEST_DEVICE_IDENTITY:
2636             case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
2637             case RIL_REQUEST_GET_ACTIVITY_INFO:
2638             case RIL_REQUEST_GET_CARRIER_RESTRICTIONS:
2639             case RIL_REQUEST_GET_CURRENT_CALLS:
2640             case RIL_REQUEST_GET_IMEI:
2641             case RIL_REQUEST_GET_MUTE:
2642             case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
2643             case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
2644             case RIL_REQUEST_GET_RADIO_CAPABILITY:
2645             case RIL_REQUEST_GET_SIM_STATUS:
2646             case RIL_REQUEST_NV_RESET_CONFIG:
2647             case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
2648             case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
2649             case RIL_REQUEST_QUERY_TTY_MODE:
2650             case RIL_REQUEST_RADIO_POWER:
2651             case RIL_REQUEST_SET_BAND_MODE:
2652             case RIL_REQUEST_SET_CARRIER_RESTRICTIONS:
2653             case RIL_REQUEST_SET_LOCATION_UPDATES:
2654             case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
2655             case RIL_REQUEST_SET_TTY_MODE:
2656             case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
2657             case RIL_REQUEST_STOP_LCE:
2658             case RIL_REQUEST_VOICE_RADIO_TECH:
2659                 // Process all the above, even though the radio is off
2660                 break;
2661 
2662             default:
2663                 // For all others, say NOT_AVAILABLE because the radio is off
2664                 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2665                 return;
2666         }
2667     }
2668 
2669     switch (request) {
2670         case RIL_REQUEST_GET_SIM_STATUS: {
2671             RIL_CardStatus_v6 *p_card_status;
2672             char *p_buffer;
2673             int buffer_size;
2674 
2675             int result = getCardStatus(&p_card_status);
2676             if (result == RIL_E_SUCCESS) {
2677                 p_buffer = (char *)p_card_status;
2678                 buffer_size = sizeof(*p_card_status);
2679             } else {
2680                 p_buffer = NULL;
2681                 buffer_size = 0;
2682             }
2683             RIL_onRequestComplete(t, result, p_buffer, buffer_size);
2684             freeCardStatus(p_card_status);
2685             break;
2686         }
2687         case RIL_REQUEST_GET_CURRENT_CALLS:
2688             requestGetCurrentCalls(data, datalen, t);
2689             break;
2690         case RIL_REQUEST_DIAL:
2691             requestDial(data, datalen, t);
2692             break;
2693         case RIL_REQUEST_HANGUP:
2694             requestHangup(data, datalen, t);
2695             break;
2696         case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
2697         case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
2698         case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
2699         case RIL_REQUEST_CONFERENCE:
2700         case RIL_REQUEST_UDUB:
2701              requestCallSelection(data, datalen, t, request);
2702              break;
2703         case RIL_REQUEST_ANSWER:
2704             at_send_command("ATA", NULL);
2705 
2706 #ifdef WORKAROUND_ERRONEOUS_ANSWER
2707             s_expectAnswer = 1;
2708 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
2709 
2710             if (getSIMStatus() != SIM_READY) {
2711                 RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
2712             } else {
2713                 // Success or failure is ignored by the upper layer here.
2714                 // It will call GET_CURRENT_CALLS and determine success that way.
2715                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2716             }
2717             break;
2718 
2719         case RIL_REQUEST_SEPARATE_CONNECTION:
2720             {
2721                 char  cmd[12];
2722                 int   party = ((int*)data)[0];
2723 
2724                 if (getSIMStatus() == SIM_ABSENT) {
2725                     RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2726                     return;
2727                 }
2728                 // Make sure that party is in a valid range.
2729                 // (Note: The Telephony middle layer imposes a range of 1 to 7.
2730                 // It's sufficient for us to just make sure it's single digit.)
2731                 if (party > 0 && party < 10) {
2732                     sprintf(cmd, "AT+CHLD=2%d", party);
2733                     at_send_command(cmd, NULL);
2734                     RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2735                 } else {
2736                     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2737                 }
2738             }
2739             break;
2740 
2741         case RIL_REQUEST_SIGNAL_STRENGTH:
2742             requestSignalStrength(data, datalen, t);
2743             break;
2744         case RIL_REQUEST_VOICE_REGISTRATION_STATE:
2745         case RIL_REQUEST_DATA_REGISTRATION_STATE:
2746             requestRegistrationState(request, data, datalen, t);
2747             break;
2748         case RIL_REQUEST_OPERATOR:
2749             requestOperator(data, datalen, t);
2750             break;
2751         case RIL_REQUEST_RADIO_POWER:
2752             requestRadioPower(data, datalen, t);
2753             break;
2754         case RIL_REQUEST_DTMF: {
2755             char c = ((char *)data)[0];
2756             char *cmd;
2757             asprintf(&cmd, "AT+VTS=%c", (int)c);
2758             at_send_command(cmd, NULL);
2759             free(cmd);
2760             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2761             break;
2762         }
2763         case RIL_REQUEST_SEND_SMS:
2764         case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
2765             requestSendSMS(data, datalen, t);
2766             break;
2767         case RIL_REQUEST_CDMA_SEND_SMS:
2768             requestCdmaSendSMS(data, datalen, t);
2769             break;
2770         case RIL_REQUEST_IMS_SEND_SMS:
2771             requestImsSendSMS(data, datalen, t);
2772             break;
2773         case RIL_REQUEST_SIM_OPEN_CHANNEL:
2774             requestSimOpenChannel(data, datalen, t);
2775             break;
2776         case RIL_REQUEST_SIM_CLOSE_CHANNEL:
2777             requestSimCloseChannel(data, datalen, t);
2778             break;
2779         case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
2780             requestSimTransmitApduChannel(data, datalen, t);
2781             break;
2782         case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC:
2783             requestSimTransmitApduChannel(data, datalen, t);
2784             break;
2785         case RIL_REQUEST_SETUP_DATA_CALL:
2786             requestSetupDataCall(data, datalen, t);
2787             break;
2788         case RIL_REQUEST_DEACTIVATE_DATA_CALL:
2789             requestDeactivateDataCall(t);
2790             break;
2791         case RIL_REQUEST_SMS_ACKNOWLEDGE:
2792             requestSMSAcknowledge(data, datalen, t);
2793             break;
2794 
2795         case RIL_REQUEST_GET_IMSI:
2796             p_response = NULL;
2797             err = at_send_command_numeric("AT+CIMI", &p_response);
2798 
2799             if (err < 0 || p_response->success == 0) {
2800                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2801             } else {
2802                 RIL_onRequestComplete(t, RIL_E_SUCCESS,
2803                     p_response->p_intermediates->line, sizeof(char *));
2804             }
2805             at_response_free(p_response);
2806             break;
2807 
2808         case RIL_REQUEST_GET_IMEI:
2809             p_response = NULL;
2810             err = at_send_command_numeric("AT+CGSN", &p_response);
2811 
2812             if (err < 0 || p_response->success == 0) {
2813                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2814             } else {
2815                 RIL_onRequestComplete(t, RIL_E_SUCCESS,
2816                     p_response->p_intermediates->line, sizeof(char *));
2817             }
2818             at_response_free(p_response);
2819             break;
2820 
2821         case RIL_REQUEST_SIM_IO:
2822             requestSIM_IO(data,datalen,t);
2823             break;
2824 
2825         case RIL_REQUEST_SEND_USSD:
2826             requestSendUSSD(data, datalen, t);
2827             break;
2828 
2829         case RIL_REQUEST_CANCEL_USSD:
2830             if (getSIMStatus() == SIM_ABSENT) {
2831                 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2832                 return;
2833             }
2834             p_response = NULL;
2835             err = at_send_command_numeric("AT+CUSD=2", &p_response);
2836 
2837             if (err < 0 || p_response->success == 0) {
2838                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2839             } else {
2840                 RIL_onRequestComplete(t, RIL_E_SUCCESS,
2841                     p_response->p_intermediates->line, sizeof(char *));
2842             }
2843             at_response_free(p_response);
2844             break;
2845 
2846         case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
2847             setNetworkSelectionAutomatic(t);
2848             break;
2849 
2850         case RIL_REQUEST_DATA_CALL_LIST:
2851             requestDataCallList(data, datalen, t);
2852             break;
2853 
2854         case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
2855             requestQueryNetworkSelectionMode(data, datalen, t);
2856             break;
2857 
2858         case RIL_REQUEST_OEM_HOOK_RAW:
2859             // echo back data
2860             RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
2861             break;
2862 
2863 
2864         case RIL_REQUEST_OEM_HOOK_STRINGS: {
2865             int i;
2866             const char ** cur;
2867 
2868             RLOGD("got OEM_HOOK_STRINGS: 0x%8p %lu", data, (long)datalen);
2869 
2870 
2871             for (i = (datalen / sizeof (char *)), cur = (const char **)data ;
2872                     i > 0 ; cur++, i --) {
2873                 RLOGD("> '%s'", *cur);
2874             }
2875 
2876             // echo back strings
2877             RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
2878             break;
2879         }
2880 
2881         case RIL_REQUEST_WRITE_SMS_TO_SIM:
2882             requestWriteSmsToSim(data, datalen, t);
2883             break;
2884 
2885         case RIL_REQUEST_DELETE_SMS_ON_SIM: {
2886             char * cmd;
2887             p_response = NULL;
2888             asprintf(&cmd, "AT+CMGD=%d", ((int *)data)[0]);
2889             err = at_send_command(cmd, &p_response);
2890             free(cmd);
2891             if (err < 0 || p_response->success == 0) {
2892                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2893             } else {
2894                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2895             }
2896             at_response_free(p_response);
2897             break;
2898         }
2899 
2900         case RIL_REQUEST_ENTER_SIM_PIN:
2901         case RIL_REQUEST_ENTER_SIM_PUK:
2902         case RIL_REQUEST_ENTER_SIM_PIN2:
2903         case RIL_REQUEST_ENTER_SIM_PUK2:
2904         case RIL_REQUEST_CHANGE_SIM_PIN:
2905         case RIL_REQUEST_CHANGE_SIM_PIN2:
2906             requestEnterSimPin(data, datalen, t);
2907             break;
2908 
2909         case RIL_REQUEST_IMS_REGISTRATION_STATE: {
2910             int reply[2];
2911             //0==unregistered, 1==registered
2912             reply[0] = s_ims_registered;
2913 
2914             //to be used when changed to include service supporated info
2915             //reply[1] = s_ims_services;
2916 
2917             // FORMAT_3GPP(1) vs FORMAT_3GPP2(2);
2918             reply[1] = s_ims_format;
2919 
2920             RLOGD("IMS_REGISTRATION=%d, format=%d ",
2921                     reply[0], reply[1]);
2922             if (reply[1] != -1) {
2923                 RIL_onRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply));
2924             } else {
2925                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2926             }
2927             break;
2928         }
2929 
2930         case RIL_REQUEST_VOICE_RADIO_TECH:
2931             {
2932                 int tech = techFromModemType(TECH(sMdmInfo));
2933                 if (tech < 0 )
2934                     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2935                 else
2936                     RIL_onRequestComplete(t, RIL_E_SUCCESS, &tech, sizeof(tech));
2937             }
2938             break;
2939         case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
2940             requestSetPreferredNetworkType(request, data, datalen, t);
2941             break;
2942 
2943         case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
2944             requestGetPreferredNetworkType(request, data, datalen, t);
2945             break;
2946 
2947         case RIL_REQUEST_GET_CELL_INFO_LIST:
2948             requestGetCellInfoList(data, datalen, t);
2949             break;
2950 
2951         case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
2952             requestSetCellInfoListRate(data, datalen, t);
2953             break;
2954 
2955         case RIL_REQUEST_GET_HARDWARE_CONFIG:
2956             requestGetHardwareConfig(data, datalen, t);
2957             break;
2958 
2959         case RIL_REQUEST_SHUTDOWN:
2960             requestShutdown(t);
2961             break;
2962 
2963         case RIL_REQUEST_QUERY_TTY_MODE:
2964             requestGetTtyMode(data, datalen, t);
2965             break;
2966 
2967         case RIL_REQUEST_GET_RADIO_CAPABILITY:
2968             requestGetRadioCapability(data, datalen, t);
2969             break;
2970 
2971         case RIL_REQUEST_GET_MUTE:
2972             requestGetMute(data, datalen, t);
2973             break;
2974 
2975         case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
2976         case RIL_REQUEST_ALLOW_DATA:
2977         case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
2978         case RIL_REQUEST_SET_CLIR:
2979         case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
2980         case RIL_REQUEST_SET_BAND_MODE:
2981         case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
2982         case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
2983         case RIL_REQUEST_SET_LOCATION_UPDATES:
2984         case RIL_REQUEST_SET_TTY_MODE:
2985         case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
2986             RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2987             break;
2988 
2989         case RIL_REQUEST_SIM_AUTHENTICATION:
2990             requestGetSimAuthentication(data, datalen, t);
2991             break;
2992 
2993         case RIL_REQUEST_BASEBAND_VERSION:
2994             requestCdmaBaseBandVersion(request, data, datalen, t);
2995             break;
2996 
2997         case RIL_REQUEST_DEVICE_IDENTITY:
2998             requestDeviceIdentity(request, data, datalen, t);
2999             break;
3000 
3001         case RIL_REQUEST_CDMA_SUBSCRIPTION:
3002             requestCdmaSubscription(request, data, datalen, t);
3003             break;
3004 
3005         case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
3006             requestCdmaGetSubscriptionSource(request, data, datalen, t);
3007             break;
3008 
3009         case RIL_REQUEST_START_LCE:
3010         case RIL_REQUEST_STOP_LCE:
3011         case RIL_REQUEST_PULL_LCEDATA:
3012             if (getSIMStatus() == SIM_ABSENT) {
3013                 RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
3014             } else {
3015                 RIL_onRequestComplete(t, RIL_E_LCE_NOT_SUPPORTED, NULL, 0);
3016             }
3017             break;
3018 
3019         case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
3020             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
3021                 requestCdmaGetRoamingPreference(request, data, datalen, t);
3022             } else {
3023                 RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
3024             }
3025             break;
3026 
3027         case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
3028             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
3029                 requestCdmaSetSubscriptionSource(request, data, datalen, t);
3030             } else {
3031                 // VTS tests expect us to silently do nothing
3032                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3033             }
3034             break;
3035 
3036         case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
3037             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
3038                 requestCdmaSetRoamingPreference(request, data, datalen, t);
3039             } else {
3040                 // VTS tests expect us to silently do nothing
3041                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3042             }
3043             break;
3044 
3045         case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
3046             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
3047                 requestExitEmergencyMode(data, datalen, t);
3048             } else {
3049                 // VTS tests expect us to silently do nothing
3050                 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3051             }
3052             break;
3053 
3054         case RIL_REQUEST_GET_ACTIVITY_INFO:
3055             requestModemActivityInfo(t);
3056             break;
3057 
3058         case RIL_REQUEST_SET_CARRIER_RESTRICTIONS:
3059             if (datalen == sizeof(RIL_CarrierRestrictions)) {
3060                 requestSetCarrierRestrictions((const RIL_CarrierRestrictions *)data, t);
3061             } else {
3062                 /* unexpected sizeof */
3063                 RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
3064             }
3065             break;
3066 
3067         default:
3068             RLOGD("Request not supported. Tech: %d",TECH(sMdmInfo));
3069             RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
3070             break;
3071     }
3072 }
3073 
3074 /**
3075  * Synchronous call from the RIL to us to return current radio state.
3076  * RADIO_STATE_UNAVAILABLE should be the initial state.
3077  */
3078 static RIL_RadioState
3079 currentState()
3080 {
3081     return sState;
3082 }
3083 /**
3084  * Call from RIL to us to find out whether a specific request code
3085  * is supported by this implementation.
3086  *
3087  * Return 1 for "supported" and 0 for "unsupported"
3088  */
3089 
3090 static int
3091 onSupports (int requestCode __unused)
3092 {
3093     //@@@ todo
3094 
3095     return 1;
3096 }
3097 
3098 static void onCancel (RIL_Token t __unused)
3099 {
3100     //@@@todo
3101 
3102 }
3103 
3104 static const char * getVersion(void)
3105 {
3106     return "android reference-ril 1.0";
3107 }
3108 
3109 static void
3110 setRadioTechnology(ModemInfo *mdm, int newtech)
3111 {
3112     RLOGD("setRadioTechnology(%d)", newtech);
3113 
3114     int oldtech = TECH(mdm);
3115 
3116     if (newtech != oldtech) {
3117         RLOGD("Tech change (%d => %d)", oldtech, newtech);
3118         TECH(mdm) = newtech;
3119         if (techFromModemType(newtech) != techFromModemType(oldtech)) {
3120             int tech = techFromModemType(TECH(sMdmInfo));
3121             if (tech > 0 ) {
3122                 RIL_onUnsolicitedResponse(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
3123                                           &tech, sizeof(tech));
3124             }
3125         }
3126     }
3127 }
3128 
3129 static void
3130 setRadioState(RIL_RadioState newState)
3131 {
3132     RLOGD("setRadioState(%d)", newState);
3133     RIL_RadioState oldState;
3134 
3135     pthread_mutex_lock(&s_state_mutex);
3136 
3137     oldState = sState;
3138 
3139     if (s_closed > 0) {
3140         // If we're closed, the only reasonable state is
3141         // RADIO_STATE_UNAVAILABLE
3142         // This is here because things on the main thread
3143         // may attempt to change the radio state after the closed
3144         // event happened in another thread
3145         newState = RADIO_STATE_UNAVAILABLE;
3146     }
3147 
3148     if (sState != newState || s_closed > 0) {
3149         sState = newState;
3150 
3151         pthread_cond_broadcast (&s_state_cond);
3152     }
3153 
3154     pthread_mutex_unlock(&s_state_mutex);
3155 
3156 
3157     /* do these outside of the mutex */
3158     if (sState != oldState) {
3159         RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
3160                                     NULL, 0);
3161         // Sim state can change as result of radio state change
3162         RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
3163                                     NULL, 0);
3164 
3165         /* FIXME onSimReady() and onRadioPowerOn() cannot be called
3166          * from the AT reader thread
3167          * Currently, this doesn't happen, but if that changes then these
3168          * will need to be dispatched on the request thread
3169          */
3170         if (sState == RADIO_STATE_ON) {
3171             onRadioPowerOn();
3172         }
3173     }
3174 }
3175 
3176 /** Returns RUIM_NOT_READY on error */
3177 static SIM_Status
3178 getRUIMStatus()
3179 {
3180     ATResponse *p_response = NULL;
3181     int err;
3182     int ret;
3183     char *cpinLine;
3184     char *cpinResult;
3185 
3186     if (sState == RADIO_STATE_OFF || sState == RADIO_STATE_UNAVAILABLE) {
3187         ret = SIM_NOT_READY;
3188         goto done;
3189     }
3190 
3191     err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
3192 
3193     if (err != 0) {
3194         ret = SIM_NOT_READY;
3195         goto done;
3196     }
3197 
3198     switch (at_get_cme_error(p_response)) {
3199         case CME_SUCCESS:
3200             break;
3201 
3202         case CME_SIM_NOT_INSERTED:
3203             ret = SIM_ABSENT;
3204             goto done;
3205 
3206         default:
3207             ret = SIM_NOT_READY;
3208             goto done;
3209     }
3210 
3211     /* CPIN? has succeeded, now look at the result */
3212 
3213     cpinLine = p_response->p_intermediates->line;
3214     err = at_tok_start (&cpinLine);
3215 
3216     if (err < 0) {
3217         ret = SIM_NOT_READY;
3218         goto done;
3219     }
3220 
3221     err = at_tok_nextstr(&cpinLine, &cpinResult);
3222 
3223     if (err < 0) {
3224         ret = SIM_NOT_READY;
3225         goto done;
3226     }
3227 
3228     if (0 == strcmp (cpinResult, "SIM PIN")) {
3229         ret = SIM_PIN;
3230         goto done;
3231     } else if (0 == strcmp (cpinResult, "SIM PUK")) {
3232         ret = SIM_PUK;
3233         goto done;
3234     } else if (0 == strcmp (cpinResult, "PH-NET PIN")) {
3235         return SIM_NETWORK_PERSONALIZATION;
3236     } else if (0 != strcmp (cpinResult, "READY"))  {
3237         /* we're treating unsupported lock types as "sim absent" */
3238         ret = SIM_ABSENT;
3239         goto done;
3240     }
3241 
3242     at_response_free(p_response);
3243     p_response = NULL;
3244     cpinResult = NULL;
3245 
3246     ret = SIM_READY;
3247 
3248 done:
3249     at_response_free(p_response);
3250     return ret;
3251 }
3252 
3253 /** Returns SIM_NOT_READY on error */
3254 static SIM_Status
3255 getSIMStatus()
3256 {
3257     ATResponse *p_response = NULL;
3258     int err;
3259     SIM_Status ret;
3260     char *cpinLine;
3261     char *cpinResult;
3262 
3263     RLOGD("getSIMStatus(). sState: %d",sState);
3264     err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
3265 
3266     if (err != 0) {
3267         ret = SIM_NOT_READY;
3268         goto done;
3269     }
3270 
3271     switch (at_get_cme_error(p_response)) {
3272         case CME_SUCCESS:
3273             break;
3274 
3275         case CME_SIM_NOT_INSERTED:
3276             ret = SIM_ABSENT;
3277             goto done;
3278 
3279         default:
3280             ret = SIM_NOT_READY;
3281             goto done;
3282     }
3283 
3284     /* CPIN? has succeeded, now look at the result */
3285 
3286     cpinLine = p_response->p_intermediates->line;
3287     err = at_tok_start (&cpinLine);
3288 
3289     if (err < 0) {
3290         ret = SIM_NOT_READY;
3291         goto done;
3292     }
3293 
3294     err = at_tok_nextstr(&cpinLine, &cpinResult);
3295 
3296     if (err < 0) {
3297         ret = SIM_NOT_READY;
3298         goto done;
3299     }
3300 
3301     if (0 == strcmp (cpinResult, "SIM PIN")) {
3302         ret = SIM_PIN;
3303     } else if (0 == strcmp (cpinResult, "SIM PUK")) {
3304         ret = SIM_PUK;
3305     } else if (0 == strcmp (cpinResult, "PH-NET PIN")) {
3306         ret = SIM_NETWORK_PERSONALIZATION;
3307     } else if (0 == strcmp (cpinResult, "RESTRICTED"))  {
3308         ret = SIM_RESTRICTED;
3309     } else if (0 == strcmp (cpinResult, "READY"))  {
3310         ret = (sState == RADIO_STATE_ON) ? SIM_READY : SIM_NOT_READY;
3311     } else {
3312         /* we're treating unsupported lock types as "sim absent" */
3313         ret = SIM_ABSENT;
3314     }
3315 
3316 done:
3317     at_response_free(p_response);
3318     return ret;
3319 }
3320 
3321 
3322 /**
3323  * Get the current card status.
3324  *
3325  * This must be freed using freeCardStatus.
3326  * @return: On success returns RIL_E_SUCCESS
3327  */
3328 static int getCardStatus(RIL_CardStatus_v6 **pp_card_status) {
3329     static const RIL_AppStatus app_status_array[] = {
3330         // SIM_ABSENT = 0
3331         { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
3332           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3333         // SIM_NOT_READY = 1
3334         { RIL_APPTYPE_USIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
3335           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3336         // SIM_READY = 2
3337         { RIL_APPTYPE_USIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
3338           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3339         // SIM_PIN = 3
3340         { RIL_APPTYPE_USIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
3341           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
3342         // SIM_PUK = 4
3343         { RIL_APPTYPE_USIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
3344           NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
3345         // SIM_NETWORK_PERSONALIZATION = 5
3346         { RIL_APPTYPE_USIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
3347           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
3348         // SIM_RESTRICTED = 6
3349         { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
3350           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3351 
3352         // RUIM_ABSENT = 7
3353         { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
3354           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3355         // RUIM_NOT_READY = 8
3356         { RIL_APPTYPE_RUIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
3357           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3358         // RUIM_READY = 9
3359         { RIL_APPTYPE_RUIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
3360           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3361         // RUIM_PIN = 10
3362         { RIL_APPTYPE_RUIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
3363           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
3364         // RUIM_PUK = 11
3365         { RIL_APPTYPE_RUIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
3366           NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
3367         // RUIM_NETWORK_PERSONALIZATION = 12
3368         { RIL_APPTYPE_RUIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
3369            NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
3370         // RUIM_RESTRICTED = 13
3371         { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
3372           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3373 
3374         // ISIM_ABSENT = 14
3375         { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
3376           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3377         // ISIM_NOT_READY = 15
3378         { RIL_APPTYPE_ISIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
3379           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3380         // ISIM_READY = 16
3381         { RIL_APPTYPE_ISIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
3382           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3383         // ISIM_PIN = 17
3384         { RIL_APPTYPE_ISIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
3385           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
3386         // ISIM_PUK = 18
3387         { RIL_APPTYPE_ISIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
3388           NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
3389         // ISIM_NETWORK_PERSONALIZATION = 19
3390         { RIL_APPTYPE_ISIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
3391           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
3392         // ISIM_RESTRICTED = 20
3393         { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
3394           NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
3395     };
3396 
3397     RIL_CardState card_state;
3398     int num_apps;
3399 
3400     SIM_Status sim_status = getSIMStatus();
3401     switch (sim_status) {
3402         case SIM_ABSENT:
3403             card_state = RIL_CARDSTATE_ABSENT;
3404             num_apps = 0;
3405             break;
3406 
3407         case SIM_RESTRICTED:
3408             card_state = RIL_CARDSTATE_RESTRICTED;
3409             num_apps = 0;
3410             break;
3411 
3412         default:
3413             card_state = RIL_CARDSTATE_PRESENT;
3414             num_apps = 3;
3415             break;
3416     }
3417 
3418     // Allocate and initialize base card status.
3419     RIL_CardStatus_v6 *p_card_status = malloc(sizeof(RIL_CardStatus_v6));
3420     p_card_status->card_state = card_state;
3421     p_card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
3422     p_card_status->gsm_umts_subscription_app_index = -1;
3423     p_card_status->cdma_subscription_app_index = -1;
3424     p_card_status->ims_subscription_app_index = -1;
3425     p_card_status->num_applications = num_apps;
3426 
3427     // Initialize application status
3428     int i;
3429     for (i = 0; i < RIL_CARD_MAX_APPS; i++) {
3430         p_card_status->applications[i] = app_status_array[SIM_ABSENT];
3431     }
3432 
3433     // Pickup the appropriate application status
3434     // that reflects sim_status for gsm.
3435     if (num_apps != 0) {
3436         p_card_status->num_applications = 3;
3437         p_card_status->gsm_umts_subscription_app_index = 0;
3438         p_card_status->cdma_subscription_app_index = 1;
3439         p_card_status->ims_subscription_app_index = 2;
3440 
3441         // Get the correct app status
3442         p_card_status->applications[0] = app_status_array[sim_status];
3443         p_card_status->applications[1] = app_status_array[sim_status + RUIM_ABSENT];
3444         p_card_status->applications[2] = app_status_array[sim_status + ISIM_ABSENT];
3445     }
3446 
3447     *pp_card_status = p_card_status;
3448     return RIL_E_SUCCESS;
3449 }
3450 
3451 /**
3452  * Free the card status returned by getCardStatus
3453  */
3454 static void freeCardStatus(RIL_CardStatus_v6 *p_card_status) {
3455     free(p_card_status);
3456 }
3457 
3458 /**
3459  * SIM ready means any commands that access the SIM will work, including:
3460  *  AT+CPIN, AT+CSMS, AT+CNMI, AT+CRSM
3461  *  (all SMS-related commands)
3462  */
3463 
3464 static void pollSIMState (void *param __unused)
3465 {
3466     ATResponse *p_response;
3467     int ret;
3468 
3469     if (sState != RADIO_STATE_UNAVAILABLE) {
3470         // no longer valid to poll
3471         return;
3472     }
3473 
3474     switch(getSIMStatus()) {
3475         case SIM_ABSENT:
3476         case SIM_PIN:
3477         case SIM_PUK:
3478         case SIM_NETWORK_PERSONALIZATION:
3479         default:
3480             RLOGI("SIM ABSENT or LOCKED");
3481             RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
3482         return;
3483 
3484         case SIM_NOT_READY:
3485             RIL_requestTimedCallback (pollSIMState, NULL, &TIMEVAL_SIMPOLL);
3486         return;
3487 
3488         case SIM_READY:
3489             RLOGI("SIM_READY");
3490             onSIMReady();
3491             RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
3492         return;
3493     }
3494 }
3495 
3496 /** returns 1 if on, 0 if off, and -1 on error */
3497 static int isRadioOn()
3498 {
3499     ATResponse *p_response = NULL;
3500     int err;
3501     char *line;
3502     char ret;
3503 
3504     err = at_send_command_singleline("AT+CFUN?", "+CFUN:", &p_response);
3505 
3506     if (err < 0 || p_response->success == 0) {
3507         // assume radio is off
3508         goto error;
3509     }
3510 
3511     line = p_response->p_intermediates->line;
3512 
3513     err = at_tok_start(&line);
3514     if (err < 0) goto error;
3515 
3516     err = at_tok_nextbool(&line, &ret);
3517     if (err < 0) goto error;
3518 
3519     at_response_free(p_response);
3520 
3521     return (int)ret;
3522 
3523 error:
3524 
3525     at_response_free(p_response);
3526     return -1;
3527 }
3528 
3529 /**
3530  * Parse the response generated by a +CTEC AT command
3531  * The values read from the response are stored in current and preferred.
3532  * Both current and preferred may be null. The corresponding value is ignored in that case.
3533  *
3534  * @return: -1 if some error occurs (or if the modem doesn't understand the +CTEC command)
3535  *          1 if the response includes the current technology only
3536  *          0 if the response includes both current technology and preferred mode
3537  */
3538 int parse_technology_response( const char *response, int *current, int32_t *preferred )
3539 {
3540     int err;
3541     char *line, *p;
3542     int ct;
3543     int32_t pt = 0;
3544     char *str_pt;
3545 
3546     line = p = strdup(response);
3547     RLOGD("Response: %s", line);
3548     err = at_tok_start(&p);
3549     if (err || !at_tok_hasmore(&p)) {
3550         RLOGD("err: %d. p: %s", err, p);
3551         free(line);
3552         return -1;
3553     }
3554 
3555     err = at_tok_nextint(&p, &ct);
3556     if (err) {
3557         free(line);
3558         return -1;
3559     }
3560     if (current) *current = ct;
3561 
3562     RLOGD("line remaining after int: %s", p);
3563 
3564     err = at_tok_nexthexint(&p, &pt);
3565     if (err) {
3566         free(line);
3567         return 1;
3568     }
3569     if (preferred) {
3570         *preferred = pt;
3571     }
3572     free(line);
3573 
3574     return 0;
3575 }
3576 
3577 int query_supported_techs( ModemInfo *mdm __unused, int *supported )
3578 {
3579     ATResponse *p_response;
3580     int err, val, techs = 0;
3581     char *tok;
3582     char *line;
3583 
3584     RLOGD("query_supported_techs");
3585     err = at_send_command_singleline("AT+CTEC=?", "+CTEC:", &p_response);
3586     if (err || !p_response->success)
3587         goto error;
3588     line = p_response->p_intermediates->line;
3589     err = at_tok_start(&line);
3590     if (err || !at_tok_hasmore(&line))
3591         goto error;
3592     while (!at_tok_nextint(&line, &val)) {
3593         techs |= ( 1 << val );
3594     }
3595     if (supported) *supported = techs;
3596     return 0;
3597 error:
3598     at_response_free(p_response);
3599     return -1;
3600 }
3601 
3602 /**
3603  * query_ctec. Send the +CTEC AT command to the modem to query the current
3604  * and preferred modes. It leaves values in the addresses pointed to by
3605  * current and preferred. If any of those pointers are NULL, the corresponding value
3606  * is ignored, but the return value will still reflect if retreiving and parsing of the
3607  * values suceeded.
3608  *
3609  * @mdm Currently unused
3610  * @current A pointer to store the current mode returned by the modem. May be null.
3611  * @preferred A pointer to store the preferred mode returned by the modem. May be null.
3612  * @return -1 on error (or failure to parse)
3613  *         1 if only the current mode was returned by modem (or failed to parse preferred)
3614  *         0 if both current and preferred were returned correctly
3615  */
3616 int query_ctec(ModemInfo *mdm __unused, int *current, int32_t *preferred)
3617 {
3618     ATResponse *response = NULL;
3619     int err;
3620     int res;
3621 
3622     RLOGD("query_ctec. current: %p, preferred: %p", current, preferred);
3623     err = at_send_command_singleline("AT+CTEC?", "+CTEC:", &response);
3624     if (!err && response->success) {
3625         res = parse_technology_response(response->p_intermediates->line, current, preferred);
3626         at_response_free(response);
3627         return res;
3628     }
3629     RLOGE("Error executing command: %d. response: %p. status: %d", err, response, response? response->success : -1);
3630     at_response_free(response);
3631     return -1;
3632 }
3633 
3634 int is_multimode_modem(ModemInfo *mdm)
3635 {
3636     ATResponse *response;
3637     int err;
3638     char *line;
3639     int tech;
3640     int32_t preferred;
3641 
3642     if (query_ctec(mdm, &tech, &preferred) == 0) {
3643         mdm->currentTech = tech;
3644         mdm->preferredNetworkMode = preferred;
3645         if (query_supported_techs(mdm, &mdm->supportedTechs)) {
3646             return 0;
3647         }
3648         return 1;
3649     }
3650     return 0;
3651 }
3652 
3653 /**
3654  * Find out if our modem is GSM, CDMA or both (Multimode)
3655  */
3656 static void probeForModemMode(ModemInfo *info)
3657 {
3658     ATResponse *response;
3659     int err;
3660     assert (info);
3661     // Currently, our only known multimode modem is qemu's android modem,
3662     // which implements the AT+CTEC command to query and set mode.
3663     // Try that first
3664 
3665     if (is_multimode_modem(info)) {
3666         RLOGI("Found Multimode Modem. Supported techs mask: %8.8x. Current tech: %d",
3667             info->supportedTechs, info->currentTech);
3668         return;
3669     }
3670 
3671     /* Being here means that our modem is not multimode */
3672     info->isMultimode = 0;
3673 
3674     /* CDMA Modems implement the AT+WNAM command */
3675     err = at_send_command_singleline("AT+WNAM","+WNAM:", &response);
3676     if (!err && response->success) {
3677         at_response_free(response);
3678         // TODO: find out if we really support EvDo
3679         info->supportedTechs = MDM_CDMA | MDM_EVDO;
3680         info->currentTech = MDM_CDMA;
3681         RLOGI("Found CDMA Modem");
3682         return;
3683     }
3684     if (!err) at_response_free(response);
3685     // TODO: find out if modem really supports WCDMA/LTE
3686     info->supportedTechs = MDM_GSM | MDM_WCDMA | MDM_LTE;
3687     info->currentTech = MDM_GSM;
3688     RLOGI("Found GSM Modem");
3689 }
3690 
3691 /**
3692  * Initialize everything that can be configured while we're still in
3693  * AT+CFUN=0
3694  */
3695 static void initializeCallback(void *param __unused)
3696 {
3697     ATResponse *p_response = NULL;
3698     int err;
3699 
3700     setRadioState (RADIO_STATE_OFF);
3701 
3702     at_handshake();
3703 
3704     probeForModemMode(sMdmInfo);
3705     /* note: we don't check errors here. Everything important will
3706        be handled in onATTimeout and onATReaderClosed */
3707 
3708     /*  atchannel is tolerant of echo but it must */
3709     /*  have verbose result codes */
3710     at_send_command("ATE0Q0V1", NULL);
3711 
3712     /*  No auto-answer */
3713     at_send_command("ATS0=0", NULL);
3714 
3715     /*  Extended errors */
3716     at_send_command("AT+CMEE=1", NULL);
3717 
3718     /*  Network registration events */
3719     err = at_send_command("AT+CREG=2", &p_response);
3720 
3721     /* some handsets -- in tethered mode -- don't support CREG=2 */
3722     if (err < 0 || p_response->success == 0) {
3723         at_send_command("AT+CREG=1", NULL);
3724     }
3725 
3726     at_response_free(p_response);
3727 
3728     /*  GPRS registration events */
3729     at_send_command("AT+CGREG=1", NULL);
3730 
3731     /*  Call Waiting notifications */
3732     at_send_command("AT+CCWA=1", NULL);
3733 
3734     /*  Alternating voice/data off */
3735     at_send_command("AT+CMOD=0", NULL);
3736 
3737     /*  Not muted */
3738     at_send_command("AT+CMUT=0", NULL);
3739 
3740     /*  +CSSU unsolicited supp service notifications */
3741     at_send_command("AT+CSSN=0,1", NULL);
3742 
3743     /*  no connected line identification */
3744     at_send_command("AT+COLP=0", NULL);
3745 
3746     /*  HEX character set */
3747     at_send_command("AT+CSCS=\"HEX\"", NULL);
3748 
3749     /*  USSD unsolicited */
3750     at_send_command("AT+CUSD=1", NULL);
3751 
3752     /*  Enable +CGEV GPRS event notifications, but don't buffer */
3753     at_send_command("AT+CGEREP=1,0", NULL);
3754 
3755     /*  SMS PDU mode */
3756     at_send_command("AT+CMGF=0", NULL);
3757 
3758 #ifdef USE_TI_COMMANDS
3759 
3760     at_send_command("AT%CPI=3", NULL);
3761 
3762     /*  TI specific -- notifications when SMS is ready (currently ignored) */
3763     at_send_command("AT%CSTAT=1", NULL);
3764 
3765 #endif /* USE_TI_COMMANDS */
3766 
3767 
3768     /* assume radio is off on error */
3769     if (isRadioOn() > 0) {
3770         setRadioState (RADIO_STATE_ON);
3771     }
3772 }
3773 
3774 static void waitForClose()
3775 {
3776     pthread_mutex_lock(&s_state_mutex);
3777 
3778     while (s_closed == 0) {
3779         pthread_cond_wait(&s_state_cond, &s_state_mutex);
3780     }
3781 
3782     pthread_mutex_unlock(&s_state_mutex);
3783 }
3784 
3785 static void sendUnsolImsNetworkStateChanged()
3786 {
3787 #if 0 // to be used when unsol is changed to return data.
3788     int reply[2];
3789     reply[0] = s_ims_registered;
3790     reply[1] = s_ims_services;
3791     reply[1] = s_ims_format;
3792 #endif
3793     RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED,
3794             NULL, 0);
3795 }
3796 
3797 /**
3798  * Called by atchannel when an unsolicited line appears
3799  * This is called on atchannel's reader thread. AT commands may
3800  * not be issued here
3801  */
3802 static void onUnsolicited (const char *s, const char *sms_pdu)
3803 {
3804     char *line = NULL, *p;
3805     int err;
3806 
3807     /* Ignore unsolicited responses until we're initialized.
3808      * This is OK because the RIL library will poll for initial state
3809      */
3810     if (sState == RADIO_STATE_UNAVAILABLE) {
3811         return;
3812     }
3813 
3814 #define  CGFPCCFG "%CGFPCCFG:"
3815     if (strStartsWith(s, CGFPCCFG)) {
3816         /* goldfish specific TODO: send phys channel cfg unsol
3817         */
3818         char *response;
3819         line = p = strdup(s);
3820         RLOGD("got CGFPCCFG line %s and %s\n", s, p);
3821         err = at_tok_start(&line);
3822         if(err) {
3823             RLOGE("invalid CGFPCCFG line %s and %s\n", s, p);
3824         }
3825 #define kSize 5
3826         int configs[kSize];
3827         for (int i=0; i < kSize && !err; ++i) {
3828             err = at_tok_nextint(&line, &(configs[i]));
3829             RLOGD("got i %d, val = %d", i, configs[i]);
3830         }
3831         if(err) {
3832             RLOGE("invalid CGFPCCFG line %s and %s\n", s, p);
3833         } else {
3834             RIL_onUnsolicitedResponse (
3835                 RIL_UNSOL_PHYSICAL_CHANNEL_CONFIGS,
3836                 configs, kSize);
3837         }
3838         free(p);
3839     } else if (strStartsWith(s, "%CTZV:")) {
3840         /* TI specific -- NITZ time */
3841         char *response;
3842 
3843         line = p = strdup(s);
3844         at_tok_start(&p);
3845 
3846         err = at_tok_nextstr(&p, &response);
3847 
3848         if (err != 0) {
3849             RLOGE("invalid NITZ line %s\n", s);
3850         } else {
3851             RIL_onUnsolicitedResponse (
3852                 RIL_UNSOL_NITZ_TIME_RECEIVED,
3853                 response, strlen(response) + 1);
3854         }
3855         free(line);
3856     } else if (strStartsWith(s,"+CRING:")
3857                 || strStartsWith(s,"RING")
3858                 || strStartsWith(s,"NO CARRIER")
3859                 || strStartsWith(s,"+CCWA")
3860     ) {
3861         RIL_onUnsolicitedResponse (
3862             RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
3863             NULL, 0);
3864 #ifdef WORKAROUND_FAKE_CGEV
3865         RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL); //TODO use new function
3866 #endif /* WORKAROUND_FAKE_CGEV */
3867     } else if (strStartsWith(s,"+CREG:")
3868                 || strStartsWith(s,"+CGREG:")
3869     ) {
3870         RIL_onUnsolicitedResponse (
3871             RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
3872             NULL, 0);
3873 #ifdef WORKAROUND_FAKE_CGEV
3874         RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
3875 #endif /* WORKAROUND_FAKE_CGEV */
3876     } else if (strStartsWith(s, "+CMT:")) {
3877         RIL_onUnsolicitedResponse (
3878             RIL_UNSOL_RESPONSE_NEW_SMS,
3879             sms_pdu, strlen(sms_pdu));
3880     } else if (strStartsWith(s, "+CDS:")) {
3881         RIL_onUnsolicitedResponse (
3882             RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
3883             sms_pdu, strlen(sms_pdu));
3884     } else if (strStartsWith(s, "+CGEV:")) {
3885         /* Really, we can ignore NW CLASS and ME CLASS events here,
3886          * but right now we don't since extranous
3887          * RIL_UNSOL_DATA_CALL_LIST_CHANGED calls are tolerated
3888          */
3889         /* can't issue AT commands here -- call on main thread */
3890         RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
3891 #ifdef WORKAROUND_FAKE_CGEV
3892     } else if (strStartsWith(s, "+CME ERROR: 150")) {
3893         RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
3894 #endif /* WORKAROUND_FAKE_CGEV */
3895     } else if (strStartsWith(s, "+CTEC: ")) {
3896         int tech, mask;
3897         switch (parse_technology_response(s, &tech, NULL))
3898         {
3899             case -1: // no argument could be parsed.
3900                 RLOGE("invalid CTEC line %s\n", s);
3901                 break;
3902             case 1: // current mode correctly parsed
3903             case 0: // preferred mode correctly parsed
3904                 mask = 1 << tech;
3905                 if (mask != MDM_GSM && mask != MDM_CDMA &&
3906                      mask != MDM_WCDMA && mask != MDM_LTE) {
3907                     RLOGE("Unknown technology %d\n", tech);
3908                 } else {
3909                     setRadioTechnology(sMdmInfo, tech);
3910                 }
3911                 break;
3912         }
3913     } else if (strStartsWith(s, "+CCSS: ")) {
3914         int source = 0;
3915         line = p = strdup(s);
3916         if (!line) {
3917             RLOGE("+CCSS: Unable to allocate memory");
3918             return;
3919         }
3920         if (at_tok_start(&p) < 0) {
3921             free(line);
3922             return;
3923         }
3924         if (at_tok_nextint(&p, &source) < 0) {
3925             RLOGE("invalid +CCSS response: %s", line);
3926             free(line);
3927             return;
3928         }
3929         SSOURCE(sMdmInfo) = source;
3930         RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
3931                                   &source, sizeof(source));
3932     } else if (strStartsWith(s, "+WSOS: ")) {
3933         char state = 0;
3934         int unsol;
3935         line = p = strdup(s);
3936         if (!line) {
3937             RLOGE("+WSOS: Unable to allocate memory");
3938             return;
3939         }
3940         if (at_tok_start(&p) < 0) {
3941             free(line);
3942             return;
3943         }
3944         if (at_tok_nextbool(&p, &state) < 0) {
3945             RLOGE("invalid +WSOS response: %s", line);
3946             free(line);
3947             return;
3948         }
3949         free(line);
3950 
3951         unsol = state ?
3952                 RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE : RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE;
3953 
3954         RIL_onUnsolicitedResponse(unsol, NULL, 0);
3955 
3956     } else if (strStartsWith(s, "+WPRL: ")) {
3957         int version = -1;
3958         line = p = strdup(s);
3959         if (!line) {
3960             RLOGE("+WPRL: Unable to allocate memory");
3961             return;
3962         }
3963         if (at_tok_start(&p) < 0) {
3964             RLOGE("invalid +WPRL response: %s", s);
3965             free(line);
3966             return;
3967         }
3968         if (at_tok_nextint(&p, &version) < 0) {
3969             RLOGE("invalid +WPRL response: %s", s);
3970             free(line);
3971             return;
3972         }
3973         free(line);
3974         RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_PRL_CHANGED, &version, sizeof(version));
3975     } else if (strStartsWith(s, "+CFUN: 0")) {
3976         setRadioState(RADIO_STATE_OFF);
3977     }
3978 }
3979 
3980 /* Called on command or reader thread */
3981 static void onATReaderClosed()
3982 {
3983     RLOGI("AT channel closed\n");
3984     at_close();
3985     s_closed = 1;
3986 
3987     setRadioState (RADIO_STATE_UNAVAILABLE);
3988 }
3989 
3990 /* Called on command thread */
3991 static void onATTimeout()
3992 {
3993     RLOGI("AT channel timeout; closing\n");
3994     at_close();
3995 
3996     s_closed = 1;
3997 
3998     /* FIXME cause a radio reset here */
3999 
4000     setRadioState (RADIO_STATE_UNAVAILABLE);
4001 }
4002 
4003 /* Called to pass hardware configuration information to telephony
4004  * framework.
4005  */
4006 static void setHardwareConfiguration(int num, RIL_HardwareConfig *cfg)
4007 {
4008    RIL_onUnsolicitedResponse(RIL_UNSOL_HARDWARE_CONFIG_CHANGED, cfg, num*sizeof(*cfg));
4009 }
4010 
4011 static void usage(char *s __unused)
4012 {
4013 #ifdef RIL_SHLIB
4014     fprintf(stderr, "reference-ril requires: -p <tcp port> or -d /dev/tty_device\n");
4015 #else
4016     fprintf(stderr, "usage: %s [-p <tcp port>] [-d /dev/tty_device]\n", s);
4017     exit(-1);
4018 #endif
4019 }
4020 
4021 static void onInterfaceAddressChange(unsigned int ifIndex,
4022                                      const struct ifAddress* addresses,
4023                                      size_t numAddresses) {
4024     char ifName[IF_NAMESIZE];
4025     size_t i;
4026     bool hasWifi = hasWifiCapability();
4027     const char* radioIfName = getRadioInterfaceName(hasWifi);
4028     char* currentLoc;
4029     size_t remaining;
4030 
4031     if (if_indextoname(ifIndex, ifName) == NULL) {
4032         RLOGE("Unable to get interface name for interface %u", ifIndex);
4033         return;
4034     }
4035     if (strcmp(radioIfName, ifName) != 0) {
4036         // This is not for the radio interface, ignore it
4037         return;
4038     }
4039 
4040     pthread_mutex_lock(&s_addresses_mutex);
4041     // Clear out any existing addresses, we receive a full set of addresses
4042     // that are going to replace the existing ones.
4043     s_if_addresses[0] = '\0';
4044     currentLoc = s_if_addresses;
4045     remaining = sizeof(s_if_addresses);
4046     for (i = 0; i < numAddresses; ++i) {
4047         char address[INET6_ADDRSTRLEN];
4048         if (inet_ntop(addresses[i].family, &addresses[i].addr,
4049                       address, sizeof(address))) {
4050             int printed = 0;
4051             if (s_if_addresses[0]) {
4052                 // We've already printed something, separate them
4053                 if (remaining < 1) {
4054                     continue;
4055                 }
4056                 *currentLoc++ = ' ';
4057                 --remaining;
4058             }
4059             printed = snprintf(currentLoc, remaining, "%s/%d",
4060                                address, addresses[i].prefix);
4061             if (printed > 0) {
4062                 remaining -= (size_t)printed;
4063                 currentLoc += printed;
4064             }
4065         } else {
4066             RLOGE("Unable to convert address to string for if %s", ifName);
4067         }
4068     }
4069     pthread_mutex_unlock(&s_addresses_mutex);
4070 
4071     // Send unsolicited call list change to notify upper layers about the new
4072     // addresses
4073     requestOrSendDataCallList(NULL);
4074 }
4075 
4076 static void onIpv6Change(const struct in6_addr* gateway,
4077                          const struct in6_addr* dnsServers,
4078                          size_t numDnsServers) {
4079     char* dnsLoc = s_ipv6_dns;
4080     size_t remaining = sizeof(s_ipv6_dns);
4081     char address[INET6_ADDRSTRLEN];
4082 
4083     pthread_mutex_lock(&s_addresses_mutex);
4084 
4085     inet_ntop(AF_INET6, gateway, s_ipv6_gateway, sizeof(s_ipv6_gateway));
4086 
4087     s_ipv6_dns[0] = '\0';
4088     for (size_t i = 0; i < numDnsServers; ++i) {
4089         if (inet_ntop(AF_INET6, &dnsServers[i], address, sizeof(address))) {
4090             size_t len = strlcat(s_ipv6_dns, address, sizeof(s_ipv6_dns));
4091             if (i + 1 < numDnsServers && len + 1 < sizeof(s_ipv6_dns)) {
4092                 // There's more to come and there's room for more, separate
4093                 // multiple DNS servers by a space.
4094                 s_ipv6_dns[len] = ' ';
4095                 s_ipv6_dns[len + 1] = '\0';
4096             }
4097         }
4098     }
4099 
4100     pthread_mutex_unlock(&s_addresses_mutex);
4101 
4102     // Send unsolicited call list change to notify upper layers about the new
4103     // addresses
4104     requestOrSendDataCallList(NULL);
4105 }
4106 
4107 static void *
4108 mainLoop(void *param __unused)
4109 {
4110     int fd;
4111     int ret;
4112     bool hasWifi = hasWifiCapability();
4113     const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
4114     struct ifMonitor* ifMonitor = ifMonitorCreate();
4115     struct ipv6Monitor* ipv6Monitor = ipv6MonitorCreate(radioInterfaceName);
4116 
4117     AT_DUMP("== ", "entering mainLoop()", -1 );
4118     at_set_on_reader_closed(onATReaderClosed);
4119     at_set_on_timeout(onATTimeout);
4120 
4121     ifMonitorSetCallback(ifMonitor, &onInterfaceAddressChange);
4122     ifMonitorRunAsync(ifMonitor);
4123 
4124     ipv6MonitorSetCallback(ipv6Monitor, &onIpv6Change);
4125     ipv6MonitorRunAsync(ipv6Monitor);
4126 
4127     for (;;) {
4128         fd = -1;
4129         while  (fd < 0) {
4130             if (isInEmulator()) {
4131                 fd = qemud_channel_open("gsm");
4132             } else if (s_port > 0) {
4133                 fd = socket_network_client("localhost", s_port, SOCK_STREAM);
4134             } else if (s_device_socket) {
4135                 fd = socket_local_client(s_device_path,
4136                                          ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
4137                                          SOCK_STREAM);
4138             } else if (s_device_path != NULL) {
4139                 fd = open (s_device_path, O_RDWR);
4140                 if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
4141                     /* disable echo on serial ports */
4142                     struct termios  ios;
4143                     tcgetattr( fd, &ios );
4144                     ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
4145                     tcsetattr( fd, TCSANOW, &ios );
4146                 }
4147             }
4148 
4149             if (fd < 0) {
4150                 RLOGE("Error opening AT interface, retrying...");
4151                 sleep(10);
4152                 /* never returns */
4153             }
4154         }
4155 
4156         s_closed = 0;
4157 
4158         ret = at_open(fd, onUnsolicited);
4159         if (ret < 0) {
4160             RLOGE ("AT error %d on at_open\n", ret);
4161             break;
4162         }
4163 
4164 
4165         RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);
4166 
4167         // Give initializeCallback a chance to dispatched, since
4168         // we don't presently have a cancellation mechanism
4169         sleep(1);
4170 
4171         waitForClose();
4172         RLOGI("Re-opening after close");
4173     }
4174 
4175     ifMonitorStop(ifMonitor);
4176     ifMonitorFree(ifMonitor);
4177 
4178     ipv6MonitorStop(ipv6Monitor);
4179     ipv6MonitorFree(ipv6Monitor);
4180 
4181     return NULL;
4182 }
4183 
4184 #ifdef RIL_SHLIB
4185 
4186 pthread_t s_tid_mainloop;
4187 
4188 const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
4189 {
4190     int ret;
4191     int fd = -1;
4192     int opt;
4193     pthread_attr_t attr;
4194 
4195     s_rilenv = env;
4196 
4197     while ( -1 != (opt = getopt(argc, argv, "p:d:s:c:"))) {
4198         switch (opt) {
4199             case 'p':
4200                 s_port = atoi(optarg);
4201                 if (s_port == 0) {
4202                     usage(argv[0]);
4203                     return NULL;
4204                 }
4205                 RLOGI("Opening loopback port %d\n", s_port);
4206             break;
4207 
4208             case 'd':
4209                 s_device_path = optarg;
4210                 RLOGI("Opening tty device %s\n", s_device_path);
4211             break;
4212 
4213             case 's':
4214                 s_device_path   = optarg;
4215                 s_device_socket = 1;
4216                 RLOGI("Opening socket %s\n", s_device_path);
4217             break;
4218 
4219             case 'c':
4220                 RLOGI("Client id received %s\n", optarg);
4221             break;
4222 
4223             default:
4224                 usage(argv[0]);
4225                 return NULL;
4226         }
4227     }
4228 
4229     if (s_port < 0 && s_device_path == NULL && !isInEmulator()) {
4230         usage(argv[0]);
4231         return NULL;
4232     }
4233 
4234     sMdmInfo = calloc(1, sizeof(ModemInfo));
4235     if (!sMdmInfo) {
4236         RLOGE("Unable to alloc memory for ModemInfo");
4237         return NULL;
4238     }
4239     pthread_attr_init (&attr);
4240     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
4241     ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);
4242 
4243     return &s_callbacks;
4244 }
4245 #else /* RIL_SHLIB */
4246 int main (int argc, char **argv)
4247 {
4248     int ret;
4249     int fd = -1;
4250     int opt;
4251 
4252     while ( -1 != (opt = getopt(argc, argv, "p:d:"))) {
4253         switch (opt) {
4254             case 'p':
4255                 s_port = atoi(optarg);
4256                 if (s_port == 0) {
4257                     usage(argv[0]);
4258                 }
4259                 RLOGI("Opening loopback port %d\n", s_port);
4260             break;
4261 
4262             case 'd':
4263                 s_device_path = optarg;
4264                 RLOGI("Opening tty device %s\n", s_device_path);
4265             break;
4266 
4267             case 's':
4268                 s_device_path   = optarg;
4269                 s_device_socket = 1;
4270                 RLOGI("Opening socket %s\n", s_device_path);
4271             break;
4272 
4273             default:
4274                 usage(argv[0]);
4275         }
4276     }
4277 
4278     if (s_port < 0 && s_device_path == NULL && !isInEmulator()) {
4279         usage(argv[0]);
4280     }
4281 
4282     RIL_register(&s_callbacks);
4283 
4284     mainLoop(NULL);
4285 
4286     return 0;
4287 }
4288 
4289 #endif /* RIL_SHLIB */
4290