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