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