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