100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/* //device/system/reference-ril/reference-ril.c
200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**
300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** Copyright 2006, The Android Open Source Project
400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**
500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** you may not use this file except in compliance with the License.
700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** You may obtain a copy of the License at
800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**
900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
1000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project**
1100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
1200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
1300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** See the License for the specific language governing permissions and
1500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project** limitations under the License.
1600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project*/
1700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <telephony/ril.h>
1900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <stdio.h>
2000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <assert.h>
2100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <string.h>
2200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <errno.h>
2300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <unistd.h>
2400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <sys/types.h>
2500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <sys/stat.h>
2600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <fcntl.h>
2700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <pthread.h>
2800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <alloca.h>
2900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include "atchannel.h"
3000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include "at_tok.h"
3100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include "misc.h"
3200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <getopt.h>
3300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <sys/socket.h>
3400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <cutils/sockets.h>
3500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <termios.h>
3600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
3700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define LOG_TAG "RIL"
3800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <utils/Log.h>
3900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
4000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define MAX_AT_RESPONSE 0x1000
4100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
42f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville/* pathname returned from RIL_REQUEST_SETUP_DATA_CALL / RIL_REQUEST_SETUP_DEFAULT_PDP */
4300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define PPP_TTY_PATH "/dev/omap_csmi_tty1"
4400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
4500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef USE_TI_COMMANDS
4600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
4700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Enable a workaround
4800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// 1) Make incoming call, do not answer
4900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// 2) Hangup remote end
5000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Expected: call should disappear from CLCC line
5100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Actual: Call shows as "ACTIVE" before disappearing
5200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define WORKAROUND_ERRONEOUS_ANSWER 1
5300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Some varients of the TI stack do not support the +CGEV unsolicited
5500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// response. However, they seem to send an unsolicited +CME ERROR: 150
5600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define WORKAROUND_FAKE_CGEV 1
5700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
5800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
59309ac294bd529ff5a71f1c1e62cd493df1010271John Wangtypedef enum {
60309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_ABSENT = 0,
61309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_NOT_READY = 1,
62309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_READY = 2, /* SIM_READY means the radio state is RADIO_STATE_SIM_READY */
63309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_PIN = 3,
64309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_PUK = 4,
65309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_NETWORK_PERSONALIZATION = 5
66309ac294bd529ff5a71f1c1e62cd493df1010271John Wang} SIM_Status;
67309ac294bd529ff5a71f1c1e62cd493df1010271John Wang
6800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onRequest (int request, void *data, size_t datalen, RIL_Token t);
6900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic RIL_RadioState currentState();
7000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int onSupports (int requestCode);
7100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onCancel (RIL_Token t);
7200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const char *getVersion();
7300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int isRadioOn();
74309ac294bd529ff5a71f1c1e62cd493df1010271John Wangstatic SIM_Status getSIMStatus();
75f6aa7c1c8a9531a254970f85860d74cdd033821cWink Savillestatic int getCardStatus(RIL_CardStatus **pp_card_status);
76f6aa7c1c8a9531a254970f85860d74cdd033821cWink Savillestatic void freeCardStatus(RIL_CardStatus *p_card_status);
77f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void onDataCallListChanged(void *param);
7800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
7900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectextern const char * requestToString(int request);
8000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
8100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/*** Static Variables ***/
8200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const RIL_RadioFunctions s_callbacks = {
8300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_VERSION,
8400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    onRequest,
8500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    currentState,
8600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    onSupports,
8700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    onCancel,
8800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    getVersion
8900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project};
9000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
9100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef RIL_SHLIB
9200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const struct RIL_Env *s_rilenv;
9300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
9400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define RIL_onRequestComplete(t, e, response, responselen) s_rilenv->OnRequestComplete(t,e, response, responselen)
9500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define RIL_onUnsolicitedResponse(a,b,c) s_rilenv->OnUnsolicitedResponse(a,b,c)
9600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define RIL_requestTimedCallback(a,b,c) s_rilenv->RequestTimedCallback(a,b,c)
9700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
9800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
9900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic RIL_RadioState sState = RADIO_STATE_UNAVAILABLE;
10000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
10100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic pthread_mutex_t s_state_mutex = PTHREAD_MUTEX_INITIALIZER;
10200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic pthread_cond_t s_state_cond = PTHREAD_COND_INITIALIZER;
10300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
10400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_port = -1;
10500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const char * s_device_path = NULL;
10600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int          s_device_socket = 0;
10700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
10800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/* trigger change to this with s_state_cond */
10900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_closed = 0;
11000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
11100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int sFD;     /* file desc of AT channel */
11200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic char sATBuffer[MAX_AT_RESPONSE+1];
11300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic char *sATBufferCur = NULL;
11400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
11500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const struct timeval TIMEVAL_SIMPOLL = {1,0};
11600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const struct timeval TIMEVAL_CALLSTATEPOLL = {0,500000};
11700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const struct timeval TIMEVAL_0 = {0,0};
11800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
11900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
12000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Max number of times we'll try to repoll when we think
12100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// we have a AT+CLCC race condition
12200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define REPOLL_CALLS_COUNT_MAX 4
12300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
12400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Line index that was incoming or waiting at last poll, or -1 for none
12500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_incomingOrWaitingLine = -1;
12600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Number of times we've asked for a repoll of AT+CLCC
12700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_repollCallsCount = 0;
12800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Should we expect a call to be answered in the next CLCC?
12900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_expectAnswer = 0;
13000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_ERRONEOUS_ANSWER */
13100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
13200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void pollSIMState (void *param);
13300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void setRadioState(RIL_RadioState newState);
13400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
13500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int clccStateToRILState(int state, RIL_CallState *p_state)
13600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
13700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
13800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch(state) {
13900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 0: *p_state = RIL_CALL_ACTIVE;   return 0;
14000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 1: *p_state = RIL_CALL_HOLDING;  return 0;
14100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 2: *p_state = RIL_CALL_DIALING;  return 0;
14200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 3: *p_state = RIL_CALL_ALERTING; return 0;
14300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 4: *p_state = RIL_CALL_INCOMING; return 0;
14400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 5: *p_state = RIL_CALL_WAITING;  return 0;
14500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default: return -1;
14600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
14700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
14800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
14900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
15000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Note: directly modified line and has *p_call point directly into
15100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * modified line
15200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
1533d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Savillestatic int callFromCLCCLine(char *line, RIL_Call *p_call)
15400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
15500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        //+CLCC: 1,0,2,0,0,\"+18005551212\",145
15600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        //     index,isMT,state,mode,isMpty(,number,TOA)?
15700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
15800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
15900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int state;
16000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int mode;
16100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
16300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
16400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &(p_call->index));
16600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
16700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextbool(&line, &(p_call->isMT));
16900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
17000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &state);
17200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
17300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = clccStateToRILState(state, &(p_call->state));
17500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
17600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &mode);
17800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
17900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
18000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_call->isVoice = (mode == 0);
18100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
18200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextbool(&line, &(p_call->isMpty));
18300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
18400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
18500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (at_tok_hasmore(&line)) {
18600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &(p_call->number));
18700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
18800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* tolerate null here */
18900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) return 0;
19000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
19100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // Some lame implementations return strings
19200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // like "NOT AVAILABLE" in the CLCC line
19300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (p_call->number != NULL
19400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            && 0 == strspn(p_call->number, "+0123456789")
19500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        ) {
19600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_call->number = NULL;
19700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
19800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
19900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &p_call->toa);
20000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
20100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
20200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
20374fa38884320698c1623764850e3131b9769dff0Wink Saville    p_call->uusInfo = NULL;
20474fa38884320698c1623764850e3131b9769dff0Wink Saville
20500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return 0;
20600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
20700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
20800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    LOGE("invalid CLCC line\n");
20900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return -1;
21000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
21100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
21200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
21300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/** do post-AT+CFUN=1 initialization */
21400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onRadioPowerOn()
21500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
21600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef USE_TI_COMMANDS
21700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Must be after CFUN=1 */
21800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  TI specific -- notifications for CPHS things such */
21900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  as CPHS message waiting indicator */
22000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
22100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT%CPHS=1", NULL);
22200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
22300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  TI specific -- enable NITZ unsol notifs */
22400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT%CTZV=1", NULL);
22500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
22600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
22700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pollSIMState(NULL);
22800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
22900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
23000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/** do post- SIM ready initialization */
23100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onSIMReady()
23200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
23300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command_singleline("AT+CSMS=1", "+CSMS:", NULL);
23400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*
23500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * Always send SMS messages directly to the TE
23600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
23700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * mode = 1 // discard when link is reserved (link should never be
23800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *             reserved)
23900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * mt = 2   // most messages routed to TE
24000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * bm = 2   // new cell BM's routed to TE
24100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * ds = 1   // Status reports routed to TE
24200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * bfr = 1  // flush buffer
24300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
24400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CNMI=1,2,2,1,1", NULL);
24500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
24600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
24700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestRadioPower(void *data, size_t datalen, RIL_Token t)
24800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
24900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int onOff;
25000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
25100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
25200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
25300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
25400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    assert (datalen >= sizeof(int *));
25500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    onOff = ((int *)data)[0];
25600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
25700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (onOff == 0 && sState != RADIO_STATE_OFF) {
25800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_send_command("AT+CFUN=0", &p_response);
25900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project       if (err < 0 || p_response->success == 0) goto error;
26000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        setRadioState(RADIO_STATE_OFF);
26100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (onOff > 0 && sState == RADIO_STATE_OFF) {
26200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_send_command("AT+CFUN=1", &p_response);
26300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0|| p_response->success == 0) {
26400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // Some stacks return an error when there is no SIM,
26500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // but they really turn the RF portion on
26600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // So, if we get an error, let's check to see if it
26700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // turned on anyway
26800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
26900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (isRadioOn() != 1) {
27000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                goto error;
27100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
27200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
27300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        setRadioState(RADIO_STATE_SIM_NOT_READY);
27400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
27500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
27600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
27700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
27800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
27900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
28000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
28100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
28200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
28300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
284f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void requestOrSendDataCallList(RIL_Token *t);
28500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
286f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void onDataCallListChanged(void *param)
28700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
288f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville    requestOrSendDataCallList(NULL);
28900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
29000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
291f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void requestDataCallList(void *data, size_t datalen, RIL_Token t)
29200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
293f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville    requestOrSendDataCallList(&t);
29400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
29500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
296f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void requestOrSendDataCallList(RIL_Token *t)
29700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
29800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response;
29900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATLine *p_cur;
30000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
30100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int n = 0;
30200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *out;
30300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
30400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_multiline ("AT+CGACT?", "+CGACT:", &p_response);
30500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) {
30600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (t != NULL)
30700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
30800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        else
309f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville            RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
31000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                      NULL, 0);
31100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
31200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
31300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
31400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (p_cur = p_response->p_intermediates; p_cur != NULL;
31500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         p_cur = p_cur->p_next)
31600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        n++;
31700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
318f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville    RIL_Data_Call_Response *responses =
319f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        alloca(n * sizeof(RIL_Data_Call_Response));
32000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
32100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int i;
32200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (i = 0; i < n; i++) {
32300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].cid = -1;
32400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].active = -1;
32500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].type = "";
32600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].apn = "";
32700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].address = "";
32800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
32900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
330f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville    RIL_Data_Call_Response *response = responses;
33100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (p_cur = p_response->p_intermediates; p_cur != NULL;
33200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         p_cur = p_cur->p_next) {
33300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *line = p_cur->line;
33400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
33500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_start(&line);
33600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
33700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
33800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
33900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &response->cid);
34000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
34100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
34200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
34300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &response->active);
34400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
34500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
34600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
34700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        response++;
34800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
34900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
35000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
35100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
35200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_multiline ("AT+CGDCONT?", "+CGDCONT:", &p_response);
35300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) {
35400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (t != NULL)
35500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
35600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        else
357f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville            RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
35800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                      NULL, 0);
35900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
36000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
36100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
36200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (p_cur = p_response->p_intermediates; p_cur != NULL;
36300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         p_cur = p_cur->p_next) {
36400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *line = p_cur->line;
36500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        int cid;
36600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *type;
36700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *apn;
36800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *address;
36900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
37000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
37100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_start(&line);
37200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
37300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
37400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
37500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &cid);
37600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
37700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
37800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
37900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        for (i = 0; i < n; i++) {
38000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (responses[i].cid == cid)
38100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                break;
38200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
38300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
38400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (i >= n) {
38500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* details for a context we didn't hear about in the last request */
38600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            continue;
38700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
38800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
38900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &out);
39000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
39100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
39200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
39300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].type = alloca(strlen(out) + 1);
39400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        strcpy(responses[i].type, out);
39500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
39600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &out);
39700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
39800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
39900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
40000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].apn = alloca(strlen(out) + 1);
40100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        strcpy(responses[i].apn, out);
40200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
40300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &out);
40400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
40500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
40600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
40700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].address = alloca(strlen(out) + 1);
40800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        strcpy(responses[i].address, out);
40900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
41000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
41100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
41200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
41300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (t != NULL)
41400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(*t, RIL_E_SUCCESS, responses,
415f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville                              n * sizeof(RIL_Data_Call_Response));
41600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    else
417f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
41800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                  responses,
419f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville                                  n * sizeof(RIL_Data_Call_Response));
42000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
42100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
42200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
42300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
42400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (t != NULL)
42500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
42600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    else
427f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
42800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                  NULL, 0);
42900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
43000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
43100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
43200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
43300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestQueryNetworkSelectionMode(
43400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                void *data, size_t datalen, RIL_Token t)
43500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
43600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
43700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
43800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int response = 0;
43900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line;
44000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
44100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline("AT+COPS?", "+COPS:", &p_response);
44200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
44300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
44400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
44500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
44600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
44700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
44800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
44900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
45000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
45100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) {
45200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
45300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
45400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
45500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &response);
45600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
45700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) {
45800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
45900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
46000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
46100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(int));
46200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
46300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
46400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
46500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
46600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    LOGE("requestQueryNetworkSelectionMode must never return error when radio is on");
46700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
46800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
46900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
47000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void sendCallStateChanged(void *param)
47100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
47200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onUnsolicitedResponse (
47300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
47400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        NULL, 0);
47500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
47600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
47700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestGetCurrentCalls(void *data, size_t datalen, RIL_Token t)
47800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
47900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
48000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response;
48100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATLine *p_cur;
48200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int countCalls;
48300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int countValidCalls;
4843d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    RIL_Call *p_calls;
4853d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    RIL_Call **pp_calls;
48600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int i;
48700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int needRepoll = 0;
48800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
48900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
49000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int prevIncomingOrWaitingLine;
49100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
49200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    prevIncomingOrWaitingLine = s_incomingOrWaitingLine;
49300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_incomingOrWaitingLine = -1;
49400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /*WORKAROUND_ERRONEOUS_ANSWER*/
49500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
49600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_multiline ("AT+CLCC", "+CLCC:", &p_response);
49700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
49800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) {
49900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
50000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
50100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
50200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
50300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* count the calls */
50400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (countCalls = 0, p_cur = p_response->p_intermediates
50500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur != NULL
50600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur = p_cur->p_next
50700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
50800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        countCalls++;
50900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
51000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
51100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* yes, there's an array of pointers and then an array of structures */
51200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5133d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    pp_calls = (RIL_Call **)alloca(countCalls * sizeof(RIL_Call *));
5143d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    p_calls = (RIL_Call *)alloca(countCalls * sizeof(RIL_Call));
5153d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    memset (p_calls, 0, countCalls * sizeof(RIL_Call));
51600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
51700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* init the pointer array */
51800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for(i = 0; i < countCalls ; i++) {
51900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        pp_calls[i] = &(p_calls[i]);
52000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
52100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
52200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (countValidCalls = 0, p_cur = p_response->p_intermediates
52300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur != NULL
52400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur = p_cur->p_next
52500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
52600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = callFromCLCCLine(p_cur->line, p_calls + countValidCalls);
52700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
52800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err != 0) {
52900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            continue;
53000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
53100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
53200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
53300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (p_calls[countValidCalls].state == RIL_CALL_INCOMING
53400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            || p_calls[countValidCalls].state == RIL_CALL_WAITING
53500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        ) {
53600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            s_incomingOrWaitingLine = p_calls[countValidCalls].index;
53700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
53800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /*WORKAROUND_ERRONEOUS_ANSWER*/
53900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
54000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (p_calls[countValidCalls].state != RIL_CALL_ACTIVE
54100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            && p_calls[countValidCalls].state != RIL_CALL_HOLDING
54200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        ) {
54300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            needRepoll = 1;
54400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
54500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
54600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        countValidCalls++;
54700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
54800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
54900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
55000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // Basically:
55100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // A call was incoming or waiting
55200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // Now it's marked as active
55300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // But we never answered it
55400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    //
55500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // This is probably a bug, and the call will probably
55600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // disappear from the call list in the next poll
55700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (prevIncomingOrWaitingLine >= 0
55800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            && s_incomingOrWaitingLine < 0
55900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            && s_expectAnswer == 0
56000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
56100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        for (i = 0; i < countValidCalls ; i++) {
56200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
56300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (p_calls[i].index == prevIncomingOrWaitingLine
56400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    && p_calls[i].state == RIL_CALL_ACTIVE
56500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    && s_repollCallsCount < REPOLL_CALLS_COUNT_MAX
56600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ) {
56700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGI(
56800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    "Hit WORKAROUND_ERRONOUS_ANSWER case."
56900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    " Repoll count: %d\n", s_repollCallsCount);
57000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_repollCallsCount++;
57100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                goto error;
57200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
57300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
57400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
57500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
57600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_expectAnswer = 0;
57700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_repollCallsCount = 0;
57800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /*WORKAROUND_ERRONEOUS_ANSWER*/
57900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5803d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    RIL_onRequestComplete(t, RIL_E_SUCCESS, pp_calls,
5813d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville            countValidCalls * sizeof (RIL_Call *));
58200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
58300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
58400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
58500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef POLL_CALL_STATE
58600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (countValidCalls) {  // We don't seem to get a "NO CARRIER" message from
58700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                            // smd, so we're forced to poll until the call ends.
58800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#else
58900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (needRepoll) {
59000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
59100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_requestTimedCallback (sendCallStateChanged, NULL, &TIMEVAL_CALLSTATEPOLL);
59200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
59300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
59400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
59500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
59600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
59700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
59800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
59900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
60000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestDial(void *data, size_t datalen, RIL_Token t)
60100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
60200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_Dial *p_dial;
60300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd;
60400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *clir;
60500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
60600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
60700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_dial = (RIL_Dial *)data;
60800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
60900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch (p_dial->clir) {
61000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 1: clir = "I"; break;  /*invocation*/
61100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 2: clir = "i"; break;  /*suppression*/
61200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
61300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 0: clir = ""; break;   /*subscription default*/
61400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
61500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
61600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd, "ATD%s%s;", p_dial->address, clir);
61700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
61800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ret = at_send_command(cmd, NULL);
61900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
62000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
62100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
62200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* success or failure is ignored by the upper layer here.
62300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project       it will call GET_CURRENT_CALLS and determine success that way */
62400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
62500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
62600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
62700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestWriteSmsToSim(void *data, size_t datalen, RIL_Token t)
62800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
62900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_SMS_WriteArgs *p_args;
63000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd;
63100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int length;
63200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
63300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
63400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
63500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_args = (RIL_SMS_WriteArgs *)data;
63600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
63700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    length = strlen(p_args->pdu)/2;
63800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd, "AT+CMGW=%d,%d", length, p_args->status);
63900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
64000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_sms(cmd, p_args->pdu, "+CMGW:", &p_response);
64100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
64200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) goto error;
64300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
64400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
64500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
64600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
64700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
64800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
64900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
65000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
65100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
65200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
65300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestHangup(void *data, size_t datalen, RIL_Token t)
65400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
65500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int *p_line;
65600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
65700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
65800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd;
65900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
66000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_line = (int *)data;
66100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
66200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // 3GPP 22.030 6.5.5
66300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // "Releases a specific active call X"
66400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd, "AT+CHLD=1%d", p_line[0]);
66500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
66600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ret = at_send_command(cmd, NULL);
66700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
66800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
66900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
67000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* success or failure is ignored by the upper layer here.
67100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project       it will call GET_CURRENT_CALLS and determine success that way */
67200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
67300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
67400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
67500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestSignalStrength(void *data, size_t datalen, RIL_Token t)
67600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
67700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
67800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
67900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int response[2];
68000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line;
68100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
68200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response);
68300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
68400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
68500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
68600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
68700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
68800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
68900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
69000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
69100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
69200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
69300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
69400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &(response[0]));
69500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
69600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
69700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &(response[1]));
69800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
69900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
70000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
70100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
70200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
70300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
70400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
70500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
70600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    LOGE("requestSignalStrength must never return an error when radio is on");
70700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
70800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
70900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
71000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
71100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestRegistrationState(int request, void *data,
71200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                        size_t datalen, RIL_Token t)
71300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
71400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
71500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int response[4];
71600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char * responseStr[4];
71700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
71800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *cmd;
71900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *prefix;
72000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line, *p;
72100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int commas;
72200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int skip;
72300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int count = 3;
72400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
72500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
72600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (request == RIL_REQUEST_REGISTRATION_STATE) {
72700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        cmd = "AT+CREG?";
72800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        prefix = "+CREG:";
72900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (request == RIL_REQUEST_GPRS_REGISTRATION_STATE) {
73000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        cmd = "AT+CGREG?";
73100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        prefix = "+CGREG:";
73200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else {
73300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        assert(0);
73400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
73500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
73600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
73700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline(cmd, prefix, &p_response);
73800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
73900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0) goto error;
74000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
74100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
74200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
74300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
74400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
74500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
74600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* Ok you have to be careful here
74700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * The solicited version of the CREG response is
74800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +CREG: n, stat, [lac, cid]
74900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * and the unsolicited version is
75000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +CREG: stat, [lac, cid]
75100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * The <n> parameter is basically "is unsolicited creg on?"
75200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * which it should always be
75300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
75400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * Now we should normally get the solicited version here,
75500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * but the unsolicited version could have snuck in
75600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * so we have to handle both
75700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
75800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * Also since the LAC and CID are only reported when registered,
75900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * we can have 1, 2, 3, or 4 arguments here
76000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
76100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * finally, a +CGREG: answer may have a fifth value that corresponds
76200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * to the network type, as in;
76300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
76400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *   +CGREG: n, stat [,lac, cid [,networkType]]
76500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
76600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
76700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* count number of commas */
76800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    commas = 0;
76900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (p = line ; *p != '\0' ;p++) {
77000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (*p == ',') commas++;
77100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
77200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
77300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch (commas) {
77400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 0: /* +CREG: <stat> */
77500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &response[0]);
77600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
77700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            response[1] = -1;
77800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            response[2] = -1;
77900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
78000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
78100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 1: /* +CREG: <n>, <stat> */
78200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &skip);
78300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
78400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &response[0]);
78500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
78600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            response[1] = -1;
78700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            response[2] = -1;
78800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
78900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
79000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
79100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 2: /* +CREG: <stat>, <lac>, <cid> */
79200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &response[0]);
79300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
79400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nexthexint(&line, &response[1]);
79500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
79600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nexthexint(&line, &response[2]);
79700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
79800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
79900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 3: /* +CREG: <n>, <stat>, <lac>, <cid> */
80000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &skip);
80100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
80200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &response[0]);
80300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
80400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nexthexint(&line, &response[1]);
80500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
80600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nexthexint(&line, &response[2]);
80700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
80800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
80900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* special case for CGREG, there is a fourth parameter
81000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * that is the network type (unknown/gprs/edge/umts)
81100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         */
81200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 4: /* +CGREG: <n>, <stat>, <lac>, <cid>, <networkType> */
81300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &skip);
81400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
81500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &response[0]);
81600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
81700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nexthexint(&line, &response[1]);
81800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
81900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nexthexint(&line, &response[2]);
82000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
82100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nexthexint(&line, &response[3]);
82200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
82300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            count = 4;
82400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
82500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
82600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
82700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
82800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
82900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&responseStr[0], "%d", response[0]);
8306f189a6a1b53adfa9570cf5911c3f81ef1b1fcf8John Wang    asprintf(&responseStr[1], "%x", response[1]);
8316f189a6a1b53adfa9570cf5911c3f81ef1b1fcf8John Wang    asprintf(&responseStr[2], "%x", response[2]);
83200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
83300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (count > 3)
83400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&responseStr[3], "%d", response[3]);
83500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
83600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
83700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
83800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
83900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
84000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
84100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    LOGE("requestRegistrationState must never return an error when radio is on");
84200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
84300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
84400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
84500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
84600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestOperator(void *data, size_t datalen, RIL_Token t)
84700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
84800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
84900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int i;
85000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int skip;
85100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATLine *p_cur;
85200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *response[3];
85300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
85400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    memset(response, 0, sizeof(response));
85500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
85600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
85700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
85800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_multiline(
85900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
86000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        "+COPS:", &p_response);
86100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
86200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* we expect 3 lines here:
86300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +COPS: 0,0,"T - Mobile"
86400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +COPS: 0,1,"TMO"
86500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +COPS: 0,2,"310170"
86600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
86700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
86800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0) goto error;
86900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
87000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (i = 0, p_cur = p_response->p_intermediates
87100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur != NULL
87200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur = p_cur->p_next, i++
87300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
87400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *line = p_cur->line;
87500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
87600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_start(&line);
87700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
87800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
87900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &skip);
88000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
88100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
88200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // If we're unregistered, we may just get
88300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // a "+COPS: 0" response
88400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (!at_tok_hasmore(&line)) {
88500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            response[i] = NULL;
88600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            continue;
88700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
88800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
88900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &skip);
89000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
89100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
89200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // a "+COPS: 0, n" response is also possible
89300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (!at_tok_hasmore(&line)) {
89400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            response[i] = NULL;
89500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            continue;
89600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
89700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
89800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &(response[i]));
89900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
90000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
90100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
90200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (i != 3) {
90300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* expect 3 lines exactly */
90400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
90500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
90600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
90700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
90800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
90900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
91000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
91100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
91200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    LOGE("requestOperator must not return error when radio is on");
91300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
91400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
91500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
91600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
91700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestSendSMS(void *data, size_t datalen, RIL_Token t)
91800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
91900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
92000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *smsc;
92100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *pdu;
92200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int tpLayerLength;
92300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd1, *cmd2;
92400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_SMS_Response response;
92500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
92600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
92700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    smsc = ((const char **)data)[0];
92800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pdu = ((const char **)data)[1];
92900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
93000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    tpLayerLength = strlen(pdu)/2;
93100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
93200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // "NULL for default SMSC"
93300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (smsc == NULL) {
93400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        smsc= "00";
93500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
93600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
93700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd1, "AT+CMGS=%d", tpLayerLength);
93800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd2, "%s%s", smsc, pdu);
93900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
94000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_sms(cmd1, cmd2, "+CMGS:", &p_response);
94100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
94200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) goto error;
94300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
94400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    memset(&response, 0, sizeof(response));
94500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
94600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* FIXME fill in messageRef and ackPDU */
94700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
94800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
94900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
95000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
95100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
95200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
95300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
95400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
95500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
95600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
957f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void requestSetupDataCall(void *data, size_t datalen, RIL_Token t)
95800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
95900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *apn;
96000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd;
96100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
96200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
96300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *response[2] = { "1", PPP_TTY_PATH };
96400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
965f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville    apn = ((const char **)data)[2];
96600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
96700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef USE_TI_COMMANDS
96800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // Config for multislot class 10 (probably default anyway eh?)
96900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command("AT%CPRIM=\"GMM\",\"CONFIG MULTISLOT_CLASS=<10>\"",
97000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                        NULL);
97100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
97200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command("AT%DATA=2,\"UART\",1,,\"SER\",\"UART\",0", NULL);
97300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* USE_TI_COMMANDS */
97400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
97500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int fd, qmistatus;
97600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    size_t cur = 0;
97700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    size_t len;
97800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ssize_t written, rlen;
97900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char status[32] = {0};
98000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int retry = 10;
98100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
98200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    LOGD("requesting data connection to APN '%s'", apn);
98300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
98400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    fd = open ("/dev/qmi", O_RDWR);
98500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (fd >= 0) { /* the device doesn't exist on the emulator */
98600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
98700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    LOGD("opened the qmi device\n");
98800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    asprintf(&cmd, "up:%s", apn);
98900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    len = strlen(cmd);
99000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
99100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    while (cur < len) {
99200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project		    do {
99300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	            written = write (fd, cmd + cur, len - cur);
99400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	        } while (written < 0 && errno == EINTR);
99500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
99600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	        if (written < 0) {
99700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGE("### ERROR writing to /dev/qmi");
99800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                close(fd);
99900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                goto error;
100000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
100100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
100200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            cur += written;
100300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
100400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
100500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // wait for interface to come online
100600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
100700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        do {
100800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            sleep(1);
100900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            do {
101000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                rlen = read(fd, status, 31);
101100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } while (rlen < 0 && errno == EINTR);
101200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
101300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (rlen < 0) {
101400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGE("### ERROR reading from /dev/qmi");
101500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                close(fd);
101600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                goto error;
101700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
101800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                status[rlen] = '\0';
101900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGD("### status: %s", status);
102000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
102100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        } while (strncmp(status, "STATE=up", 8) && strcmp(status, "online") && --retry);
102200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
102300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        close(fd);
102400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
102500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (retry == 0) {
102600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            LOGE("### Failed to get data connection up\n");
102700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	        goto error;
102800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project		}
102900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
103000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        qmistatus = system("netcfg rmnet0 dhcp");
103100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
103200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        LOGD("netcfg rmnet0 dhcp: status %d\n", qmistatus);
103300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
103400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    if (qmistatus < 0) goto error;
103500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
103600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	} else {
103700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
103800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&cmd, "AT+CGDCONT=1,\"IP\",\"%s\",,0,0", apn);
103900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    //FIXME check for error here
104000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    err = at_send_command(cmd, NULL);
104100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    free(cmd);
104200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
104300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    // Set required QoS params to default
104400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    err = at_send_command("AT+CGQREQ=1", NULL);
104500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
104600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    // Set minimum QoS params to default
104700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    err = at_send_command("AT+CGQMIN=1", NULL);
104800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
104900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    // packet-domain event reporting
105000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    err = at_send_command("AT+CGEREP=1,0", NULL);
105100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
105200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    // Hangup anything that's happening there now
105300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    err = at_send_command("AT+CGACT=1,0", NULL);
105400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
105500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    // Start data on PDP context 1
105600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    err = at_send_command("ATD*99***1#", &p_response);
105700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
105800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    if (err < 0 || p_response->success == 0) {
105900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	        goto error;
106000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project	    }
106100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
106200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
106300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
106400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
106500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
106600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
106700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
106800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
106900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
107000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
107100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
107200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
107300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestSMSAcknowledge(void *data, size_t datalen, RIL_Token t)
107400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
107500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ackSuccess;
107600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
107700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
107800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ackSuccess = ((int *)data)[0];
107900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
108000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (ackSuccess == 1) {
108100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_send_command("AT+CNMA=1", NULL);
108200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (ackSuccess == 0)  {
108300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_send_command("AT+CNMA=2", NULL);
108400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else {
108500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        LOGE("unsupported arg to RIL_REQUEST_SMS_ACKNOWLEDGE\n");
108600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
108700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
108800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
108900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
109000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
109100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
109200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
109300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
109400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
109500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void  requestSIM_IO(void *data, size_t datalen, RIL_Token t)
109600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
109700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
109800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_SIM_IO_Response sr;
109900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
110000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd = NULL;
110100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_SIM_IO *p_args;
110200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line;
110300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
110400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    memset(&sr, 0, sizeof(sr));
110500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
110600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_args = (RIL_SIM_IO *)data;
110700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
110800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* FIXME handle pin2 */
110900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
111000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (p_args->data == NULL) {
111100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d",
111200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_args->command, p_args->fileid,
111300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_args->p1, p_args->p2, p_args->p3);
111400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else {
111500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d,%s",
111600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_args->command, p_args->fileid,
111700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_args->p1, p_args->p2, p_args->p3, p_args->data);
111800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
111900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
112000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline(cmd, "+CRSM:", &p_response);
112100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
112200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
112300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
112400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
112500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
112600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
112700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
112800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
112900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
113000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
113100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &(sr.sw1));
113200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
113300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
113400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &(sr.sw2));
113500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
113600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
113700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (at_tok_hasmore(&line)) {
113800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &(sr.simResponse));
113900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
114000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
114100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
114200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
114300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
114400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
114500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
114600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
114700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
114800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
114900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
115000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
115100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
115200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
115300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
115400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void  requestEnterSimPin(void*  data, size_t  datalen, RIL_Token  t)
115500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
115600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse   *p_response = NULL;
115700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int           err;
115800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char*         cmd = NULL;
115900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char**  strings = (const char**)data;;
116000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
116100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if ( datalen == sizeof(char*) ) {
116200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&cmd, "AT+CPIN=%s", strings[0]);
116300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if ( datalen == 2*sizeof(char*) ) {
116400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&cmd, "AT+CPIN=%s,%s", strings[0], strings[1]);
116500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else
116600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
116700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
116800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline(cmd, "+CPIN:", &p_response);
116900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
117000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
117100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
117200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
117300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, NULL, 0);
117400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else {
117500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
117600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
117700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
117800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
117900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
118000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
118100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void  requestSendUSSD(void *data, size_t datalen, RIL_Token t)
118200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
118300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *ussdRequest;
118400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
118500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ussdRequest = (char *)(data);
118600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
118700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
118800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
118900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
119000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// @@@ TODO
119100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
119200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
119300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
119400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
119500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/*** Callback methods from the RIL library to us ***/
119600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
119700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
119800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Call from RIL to us to make a RIL_REQUEST
119900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *
120000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Must be completed with a call to RIL_onRequestComplete()
120100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *
120200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * RIL_onRequestComplete() may be called from any thread, before or after
120300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * this function returns.
120400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *
120500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Will always be called from the same thread, so returning here implies
120600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * that the radio is ready to process another command (whether or not
120700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * the previous command has completed).
120800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
120900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void
121000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectonRequest (int request, void *data, size_t datalen, RIL_Token t)
121100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
121200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response;
121300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
121400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
121500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    LOGD("onRequest: %s", requestToString(request));
121600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
121700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* Ignore all requests except RIL_REQUEST_GET_SIM_STATUS
121800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * when RADIO_STATE_UNAVAILABLE.
121900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
122000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState == RADIO_STATE_UNAVAILABLE
122100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        && request != RIL_REQUEST_GET_SIM_STATUS
122200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
122300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
122400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
122500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
122600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
122700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* Ignore all non-power requests when RADIO_STATE_OFF
122800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * (except RIL_REQUEST_GET_SIM_STATUS)
122900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
123000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState == RADIO_STATE_OFF
123100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        && !(request == RIL_REQUEST_RADIO_POWER
123200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            || request == RIL_REQUEST_GET_SIM_STATUS)
123300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
123400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
123500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
123600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
123700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
123800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch (request) {
123900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_GET_SIM_STATUS: {
1240f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            RIL_CardStatus *p_card_status;
1241f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            char *p_buffer;
1242f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            int buffer_size;
1243f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1244f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            int result = getCardStatus(&p_card_status);
1245f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            if (result == RIL_E_SUCCESS) {
1246f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville                p_buffer = (char *)p_card_status;
1247f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville                buffer_size = sizeof(*p_card_status);
1248f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            } else {
1249f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville                p_buffer = NULL;
1250f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville                buffer_size = 0;
1251f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            }
1252f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            RIL_onRequestComplete(t, result, p_buffer, buffer_size);
1253f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            freeCardStatus(p_card_status);
125400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
125500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
125600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_GET_CURRENT_CALLS:
125700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestGetCurrentCalls(data, datalen, t);
125800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
125900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_DIAL:
126000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestDial(data, datalen, t);
126100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
126200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_HANGUP:
126300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestHangup(data, datalen, t);
126400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
126500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
126600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // 3GPP 22.030 6.5.5
126700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // "Releases all held calls or sets User Determined User Busy
126800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            //  (UDUB) for a waiting call."
126900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+CHLD=0", NULL);
127000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
127100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
127200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
127300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
127400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
127500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
127600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // 3GPP 22.030 6.5.5
127700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // "Releases all active calls (if any exist) and accepts
127800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            //  the other (held or waiting) call."
127900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+CHLD=1", NULL);
128000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
128100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
128200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
128300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
128400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
128500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
128600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // 3GPP 22.030 6.5.5
128700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // "Places all active calls (if any exist) on hold and accepts
128800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            //  the other (held or waiting) call."
128900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+CHLD=2", NULL);
129000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
129100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
129200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            s_expectAnswer = 1;
129300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_ERRONEOUS_ANSWER */
129400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
129500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
129600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
129700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
129800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
129900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ANSWER:
130000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("ATA", NULL);
130100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
130200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
130300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            s_expectAnswer = 1;
130400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_ERRONEOUS_ANSWER */
130500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
130600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
130700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
130800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
130900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
131000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_CONFERENCE:
131100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // 3GPP 22.030 6.5.5
131200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // "Adds a held call to the conversation"
131300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+CHLD=3", NULL);
131400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
131500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
131600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
131700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
131800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
131900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_UDUB:
132000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* user determined user busy */
132100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* sometimes used: ATH */
132200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("ATH", NULL);
132300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
132400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
132500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
132600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
132700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
132800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
132900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SEPARATE_CONNECTION:
133000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            {
133100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                char  cmd[12];
133200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                int   party = ((int*)data)[0];
133300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
133400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                // Make sure that party is in a valid range.
133500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                // (Note: The Telephony middle layer imposes a range of 1 to 7.
133600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                // It's sufficient for us to just make sure it's single digit.)
133700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if (party > 0 && party < 10) {
133800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    sprintf(cmd, "AT+CHLD=2%d", party);
133900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    at_send_command(cmd, NULL);
134000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
134100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                } else {
134200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
134300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                }
134400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
134500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
134600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
134700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SIGNAL_STRENGTH:
134800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSignalStrength(data, datalen, t);
134900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
135000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_REGISTRATION_STATE:
135100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_GPRS_REGISTRATION_STATE:
135200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestRegistrationState(request, data, datalen, t);
135300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
135400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_OPERATOR:
135500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestOperator(data, datalen, t);
135600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
135700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_RADIO_POWER:
135800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestRadioPower(data, datalen, t);
135900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
136000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_DTMF: {
136100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            char c = ((char *)data)[0];
136200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            char *cmd;
136300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            asprintf(&cmd, "AT+VTS=%c", (int)c);
136400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command(cmd, NULL);
136500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            free(cmd);
136600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
136700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
136800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
136900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SEND_SMS:
137000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSendSMS(data, datalen, t);
137100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
1372f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        case RIL_REQUEST_SETUP_DATA_CALL:
1373f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville            requestSetupDataCall(data, datalen, t);
137400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
137500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SMS_ACKNOWLEDGE:
137600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSMSAcknowledge(data, datalen, t);
137700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
137800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
137900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_GET_IMSI:
138000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_response = NULL;
138100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_send_command_numeric("AT+CIMI", &p_response);
138200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
138300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0 || p_response->success == 0) {
138400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
138500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
138600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_SUCCESS,
138700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_response->p_intermediates->line, sizeof(char *));
138800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
138900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_response_free(p_response);
139000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
139100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
139200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_GET_IMEI:
139300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_response = NULL;
139400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_send_command_numeric("AT+CGSN", &p_response);
139500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
139600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0 || p_response->success == 0) {
139700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
139800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
139900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_SUCCESS,
140000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_response->p_intermediates->line, sizeof(char *));
140100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
140200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_response_free(p_response);
140300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
140400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
140500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SIM_IO:
140600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSIM_IO(data,datalen,t);
140700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
140800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
140900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SEND_USSD:
141000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSendUSSD(data, datalen, t);
141100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
141200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
141300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_CANCEL_USSD:
141400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_response = NULL;
141500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_send_command_numeric("AT+CUSD=2", &p_response);
141600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
141700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0 || p_response->success == 0) {
141800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
141900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
142000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_SUCCESS,
142100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_response->p_intermediates->line, sizeof(char *));
142200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
142300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_response_free(p_response);
142400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
142500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
142600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
142700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+COPS=0", NULL);
142800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
142900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1430f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        case RIL_REQUEST_DATA_CALL_LIST:
1431f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville            requestDataCallList(data, datalen, t);
143200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
143300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
143400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
143500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestQueryNetworkSelectionMode(data, datalen, t);
143600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
143700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
143800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_OEM_HOOK_RAW:
143900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // echo back data
144000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
144100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
144200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
144300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
144400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_OEM_HOOK_STRINGS: {
144500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            int i;
144600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            const char ** cur;
144700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
144800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            LOGD("got OEM_HOOK_STRINGS: 0x%8p %lu", data, (long)datalen);
144900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
145000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
145100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            for (i = (datalen / sizeof (char *)), cur = (const char **)data ;
145200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    i > 0 ; cur++, i --) {
145300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGD("> '%s'", *cur);
145400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
145500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
145600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // echo back strings
145700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
145800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
145900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
146000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
146100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_WRITE_SMS_TO_SIM:
146200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestWriteSmsToSim(data, datalen, t);
146300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
146400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
146500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_DELETE_SMS_ON_SIM: {
146600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            char * cmd;
146700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_response = NULL;
146800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            asprintf(&cmd, "AT+CMGD=%d", ((int *)data)[0]);
146900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_send_command(cmd, &p_response);
147000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            free(cmd);
147100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0 || p_response->success == 0) {
147200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
147300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
147400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
147500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
147600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_response_free(p_response);
147700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
147800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
147900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
148000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ENTER_SIM_PIN:
148100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ENTER_SIM_PUK:
148200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ENTER_SIM_PIN2:
148300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ENTER_SIM_PUK2:
148400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_CHANGE_SIM_PIN:
148500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_CHANGE_SIM_PIN2:
148600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestEnterSimPin(data, datalen, t);
148700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
148800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
148900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
149000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
149100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
149200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
149300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
149400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
149500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
149600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Synchronous call from the RIL to us to return current radio state.
149700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * RADIO_STATE_UNAVAILABLE should be the initial state.
149800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
149900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic RIL_RadioState
150000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectcurrentState()
150100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
150200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return sState;
150300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
150400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
150500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Call from RIL to us to find out whether a specific request code
150600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * is supported by this implementation.
150700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *
150800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Return 1 for "supported" and 0 for "unsupported"
150900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
151000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
151100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int
151200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectonSupports (int requestCode)
151300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
151400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    //@@@ todo
151500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
151600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return 1;
151700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
151800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
151900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onCancel (RIL_Token t)
152000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
152100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    //@@@todo
152200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
152300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
152400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
152500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const char * getVersion(void)
152600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
152700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return "android reference-ril 1.0";
152800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
152900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
153000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void
153100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectsetRadioState(RIL_RadioState newState)
153200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
153300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_RadioState oldState;
153400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
153500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_mutex_lock(&s_state_mutex);
153600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
153700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    oldState = sState;
153800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
153900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (s_closed > 0) {
154000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // If we're closed, the only reasonable state is
154100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // RADIO_STATE_UNAVAILABLE
154200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // This is here because things on the main thread
154300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // may attempt to change the radio state after the closed
154400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // event happened in another thread
154500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        newState = RADIO_STATE_UNAVAILABLE;
154600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
154700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
154800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState != newState || s_closed > 0) {
154900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        sState = newState;
155000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
155100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        pthread_cond_broadcast (&s_state_cond);
155200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
155300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
155400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_mutex_unlock(&s_state_mutex);
155500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
155600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
155700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* do these outside of the mutex */
155800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState != oldState) {
155900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
156000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                    NULL, 0);
156100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
156200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* FIXME onSimReady() and onRadioPowerOn() cannot be called
156300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * from the AT reader thread
156400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * Currently, this doesn't happen, but if that changes then these
156500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * will need to be dispatched on the request thread
156600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         */
156700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (sState == RADIO_STATE_SIM_READY) {
156800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            onSIMReady();
156900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        } else if (sState == RADIO_STATE_SIM_NOT_READY) {
157000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            onRadioPowerOn();
157100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
157200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
157300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
157400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1575309ac294bd529ff5a71f1c1e62cd493df1010271John Wang/** Returns SIM_NOT_READY on error */
1576309ac294bd529ff5a71f1c1e62cd493df1010271John Wangstatic SIM_Status
157700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectgetSIMStatus()
157800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
157900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
158000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
158100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
158200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cpinLine;
158300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cpinResult;
158400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
158500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState == RADIO_STATE_OFF || sState == RADIO_STATE_UNAVAILABLE) {
1586309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_NOT_READY;
158700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
158800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
158900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
159000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
159100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
159200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0) {
1593309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_NOT_READY;
159400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
159500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
159600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
159700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch (at_get_cme_error(p_response)) {
159800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case CME_SUCCESS:
159900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
160000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
160100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case CME_SIM_NOT_INSERTED:
1602309ac294bd529ff5a71f1c1e62cd493df1010271John Wang            ret = SIM_ABSENT;
160300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto done;
160400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
160500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
1606309ac294bd529ff5a71f1c1e62cd493df1010271John Wang            ret = SIM_NOT_READY;
160700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto done;
160800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
160900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
161000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* CPIN? has succeeded, now look at the result */
161100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
161200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    cpinLine = p_response->p_intermediates->line;
161300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start (&cpinLine);
161400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
161500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) {
1616309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_NOT_READY;
161700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
161800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
161900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
162000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextstr(&cpinLine, &cpinResult);
162100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
162200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) {
1623309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_NOT_READY;
162400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
162500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
162600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
162700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (0 == strcmp (cpinResult, "SIM PIN")) {
1628309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_PIN;
162900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
163000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (0 == strcmp (cpinResult, "SIM PUK")) {
1631309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_PUK;
163200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
163300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (0 == strcmp (cpinResult, "PH-NET PIN")) {
1634309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        return SIM_NETWORK_PERSONALIZATION;
163500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (0 != strcmp (cpinResult, "READY"))  {
163600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* we're treating unsupported lock types as "sim absent" */
1637309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_ABSENT;
163800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
163900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
164000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
164100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
164200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_response = NULL;
164300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    cpinResult = NULL;
164400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1645309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    ret = SIM_READY;
164600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
164700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectdone:
164800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
164900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return ret;
165000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
165100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
165200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
165300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
1654f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville * Get the current card status.
1655f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville *
1656f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville * This must be freed using freeCardStatus.
1657f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville * @return: On success returns RIL_E_SUCCESS
1658f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville */
1659f6aa7c1c8a9531a254970f85860d74cdd033821cWink Savillestatic int getCardStatus(RIL_CardStatus **pp_card_status) {
1660f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    static RIL_AppStatus app_status_array[] = {
1661309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_ABSENT = 0
1662f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
1663f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
1664309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_NOT_READY = 1
1665f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
1666f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
1667309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_READY = 2
1668f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
1669f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
1670309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_PIN = 3
1671f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
1672f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
1673309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_PUK = 4
1674f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
1675f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
1676309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_NETWORK_PERSONALIZATION = 5
1677f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
1678f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN }
1679f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    };
1680f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    RIL_CardState card_state;
1681f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    int num_apps;
1682f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1683f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    int sim_status = getSIMStatus();
1684309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    if (sim_status == SIM_ABSENT) {
1685f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        card_state = RIL_CARDSTATE_ABSENT;
1686f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        num_apps = 0;
1687f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    } else {
1688f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        card_state = RIL_CARDSTATE_PRESENT;
1689f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        num_apps = 1;
1690f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    }
1691f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1692f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    // Allocate and initialize base card status.
1693f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    RIL_CardStatus *p_card_status = malloc(sizeof(RIL_CardStatus));
1694f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->card_state = card_state;
1695f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
1696f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->gsm_umts_subscription_app_index = RIL_CARD_MAX_APPS;
1697f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->cdma_subscription_app_index = RIL_CARD_MAX_APPS;
1698f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->num_applications = num_apps;
1699f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1700f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    // Initialize application status
1701f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    int i;
1702f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    for (i = 0; i < RIL_CARD_MAX_APPS; i++) {
1703309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        p_card_status->applications[i] = app_status_array[SIM_ABSENT];
1704f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    }
1705f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1706f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    // Pickup the appropriate application status
1707f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    // that reflects sim_status for gsm.
1708f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    if (num_apps != 0) {
1709f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        // Only support one app, gsm
1710f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        p_card_status->num_applications = 1;
1711f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        p_card_status->gsm_umts_subscription_app_index = 0;
1712f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1713f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        // Get the correct app status
1714f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        p_card_status->applications[0] = app_status_array[sim_status];
1715f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    }
1716f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1717f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    *pp_card_status = p_card_status;
1718f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    return RIL_E_SUCCESS;
1719f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville}
1720f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1721f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville/**
1722f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville * Free the card status returned by getCardStatus
1723f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville */
1724f6aa7c1c8a9531a254970f85860d74cdd033821cWink Savillestatic void freeCardStatus(RIL_CardStatus *p_card_status) {
1725f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    free(p_card_status);
1726f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville}
1727f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1728f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville/**
172900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * SIM ready means any commands that access the SIM will work, including:
173000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *  AT+CPIN, AT+CSMS, AT+CNMI, AT+CRSM
173100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *  (all SMS-related commands)
173200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
173300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
173400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void pollSIMState (void *param)
173500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
173600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response;
173700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
173800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
173900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState != RADIO_STATE_SIM_NOT_READY) {
174000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // no longer valid to poll
174100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
174200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
174300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
174400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch(getSIMStatus()) {
1745309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_ABSENT:
1746309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_PIN:
1747309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_PUK:
1748309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_NETWORK_PERSONALIZATION:
174900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
175000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            setRadioState(RADIO_STATE_SIM_LOCKED_OR_ABSENT);
175100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
175200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1753309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_NOT_READY:
175400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_requestTimedCallback (pollSIMState, NULL, &TIMEVAL_SIMPOLL);
175500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
175600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1757309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_READY:
175800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            setRadioState(RADIO_STATE_SIM_READY);
175900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
176000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
176100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
176200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
176300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/** returns 1 if on, 0 if off, and -1 on error */
176400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int isRadioOn()
176500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
176600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
176700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
176800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line;
176900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char ret;
177000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
177100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline("AT+CFUN?", "+CFUN:", &p_response);
177200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
177300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
177400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // assume radio is off
177500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
177600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
177700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
177800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
177900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
178000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
178100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
178200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
178300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextbool(&line, &ret);
178400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
178500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
178600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
178700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
178800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return (int)ret;
178900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
179000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
179100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
179200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
179300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return -1;
179400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
179500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
179600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
179700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Initialize everything that can be configured while we're still in
179800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * AT+CFUN=0
179900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
180000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void initializeCallback(void *param)
180100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
180200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
180300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
180400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
180500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    setRadioState (RADIO_STATE_OFF);
180600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
180700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_handshake();
180800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
180900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* note: we don't check errors here. Everything important will
181000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project       be handled in onATTimeout and onATReaderClosed */
181100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
181200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  atchannel is tolerant of echo but it must */
181300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  have verbose result codes */
181400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("ATE0Q0V1", NULL);
181500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
181600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  No auto-answer */
181700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("ATS0=0", NULL);
181800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
181900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Extended errors */
182000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CMEE=1", NULL);
182100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
182200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Network registration events */
182300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command("AT+CREG=2", &p_response);
182400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
182500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* some handsets -- in tethered mode -- don't support CREG=2 */
182600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
182700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        at_send_command("AT+CREG=1", NULL);
182800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
182900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
183000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
183100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
183200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  GPRS registration events */
183300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CGREG=1", NULL);
183400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
183500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Call Waiting notifications */
183600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CCWA=1", NULL);
183700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
183800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Alternating voice/data off */
183900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CMOD=0", NULL);
184000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
184100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Not muted */
184200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CMUT=0", NULL);
184300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
184400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  +CSSU unsolicited supp service notifications */
184500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CSSN=0,1", NULL);
184600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
184700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  no connected line identification */
184800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+COLP=0", NULL);
184900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
185000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  HEX character set */
185100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CSCS=\"HEX\"", NULL);
185200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
185300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  USSD unsolicited */
185400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CUSD=1", NULL);
185500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
185600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Enable +CGEV GPRS event notifications, but don't buffer */
185700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CGEREP=1,0", NULL);
185800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
185900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  SMS PDU mode */
186000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CMGF=0", NULL);
186100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
186200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef USE_TI_COMMANDS
186300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
186400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT%CPI=3", NULL);
186500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
186600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  TI specific -- notifications when SMS is ready (currently ignored) */
186700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT%CSTAT=1", NULL);
186800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
186900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* USE_TI_COMMANDS */
187000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
187100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
187200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* assume radio is off on error */
187300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (isRadioOn() > 0) {
187400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        setRadioState (RADIO_STATE_SIM_NOT_READY);
187500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
187600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
187700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
187800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void waitForClose()
187900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
188000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_mutex_lock(&s_state_mutex);
188100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
188200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    while (s_closed == 0) {
188300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        pthread_cond_wait(&s_state_cond, &s_state_mutex);
188400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
188500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
188600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_mutex_unlock(&s_state_mutex);
188700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
188800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
188900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
189000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Called by atchannel when an unsolicited line appears
189100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * This is called on atchannel's reader thread. AT commands may
189200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * not be issued here
189300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
189400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onUnsolicited (const char *s, const char *sms_pdu)
189500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
189600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line = NULL;
189700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
189800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
189900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* Ignore unsolicited responses until we're initialized.
190000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * This is OK because the RIL library will poll for initial state
190100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
190200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState == RADIO_STATE_UNAVAILABLE) {
190300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
190400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
190500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
190600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (strStartsWith(s, "%CTZV:")) {
190700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* TI specific -- NITZ time */
190800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *response;
190900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
191000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        line = strdup(s);
191100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        at_tok_start(&line);
191200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
191300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &response);
191400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
191500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err != 0) {
191600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            LOGE("invalid NITZ line %s\n", s);
191700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        } else {
191800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onUnsolicitedResponse (
191900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_UNSOL_NITZ_TIME_RECEIVED,
192000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                response, strlen(response));
192100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
192200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s,"+CRING:")
192300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                || strStartsWith(s,"RING")
192400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                || strStartsWith(s,"NO CARRIER")
192500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                || strStartsWith(s,"+CCWA")
192600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
192700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (
192800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
192900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            NULL, 0);
193000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_FAKE_CGEV
1931f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL); //TODO use new function
193200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_FAKE_CGEV */
193300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s,"+CREG:")
193400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                || strStartsWith(s,"+CGREG:")
193500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
193600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (
193700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED,
193800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            NULL, 0);
193900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_FAKE_CGEV
19407f8568086f2ea14885b0091c793e14c2656f0da2Wink Saville        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
194100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_FAKE_CGEV */
194200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s, "+CMT:")) {
194300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (
194400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_UNSOL_RESPONSE_NEW_SMS,
194500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            sms_pdu, strlen(sms_pdu));
194600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s, "+CDS:")) {
194700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (
194800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
194900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            sms_pdu, strlen(sms_pdu));
195000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s, "+CGEV:")) {
195100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* Really, we can ignore NW CLASS and ME CLASS events here,
195200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * but right now we don't since extranous
1953f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville         * RIL_UNSOL_DATA_CALL_LIST_CHANGED calls are tolerated
195400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         */
195500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* can't issue AT commands here -- call on main thread */
1956f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
195700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_FAKE_CGEV
195800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s, "+CME ERROR: 150")) {
1959f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
196000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_FAKE_CGEV */
196100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
196200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
196300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
196400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/* Called on command or reader thread */
196500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onATReaderClosed()
196600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
196700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    LOGI("AT channel closed\n");
196800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_close();
196900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_closed = 1;
197000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
197100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    setRadioState (RADIO_STATE_UNAVAILABLE);
197200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
197300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
197400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/* Called on command thread */
197500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onATTimeout()
197600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
197700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    LOGI("AT channel timeout; closing\n");
197800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_close();
197900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
198000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_closed = 1;
198100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
198200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* FIXME cause a radio reset here */
198300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
198400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    setRadioState (RADIO_STATE_UNAVAILABLE);
198500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
198600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
198700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void usage(char *s)
198800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
198900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef RIL_SHLIB
199000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    fprintf(stderr, "reference-ril requires: -p <tcp port> or -d /dev/tty_device\n");
199100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#else
199200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    fprintf(stderr, "usage: %s [-p <tcp port>] [-d /dev/tty_device]\n", s);
199300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    exit(-1);
199400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
199500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
199600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
199700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void *
199800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectmainLoop(void *param)
199900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
200000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int fd;
200100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
200200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
200300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    AT_DUMP("== ", "entering mainLoop()", -1 );
200400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_set_on_reader_closed(onATReaderClosed);
200500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_set_on_timeout(onATTimeout);
200600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
200700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (;;) {
200800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        fd = -1;
200900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        while  (fd < 0) {
201000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (s_port > 0) {
201100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                fd = socket_loopback_client(s_port, SOCK_STREAM);
201200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else if (s_device_socket) {
2013e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                if (!strcmp(s_device_path, "/dev/socket/qemud")) {
2014e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                    /* Qemu-specific control socket */
2015e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                    fd = socket_local_client( "qemud",
2016e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                                              ANDROID_SOCKET_NAMESPACE_RESERVED,
2017e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                                              SOCK_STREAM );
2018e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                    if (fd >= 0 ) {
2019e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                        char  answer[2];
2020e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project
2021e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                        if ( write(fd, "gsm", 3) != 3 ||
2022e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                             read(fd, answer, 2) != 2 ||
2023e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                             memcmp(answer, "OK", 2) != 0)
2024e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                        {
2025e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                            close(fd);
2026e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                            fd = -1;
2027e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                        }
2028e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                   }
2029e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                }
2030e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                else
2031e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                    fd = socket_local_client( s_device_path,
2032e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                                            ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
2033e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                                            SOCK_STREAM );
203400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else if (s_device_path != NULL) {
203500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                fd = open (s_device_path, O_RDWR);
203600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
203700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    /* disable echo on serial ports */
203800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    struct termios  ios;
203900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    tcgetattr( fd, &ios );
204000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
204100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    tcsetattr( fd, TCSANOW, &ios );
204200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                }
204300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
204400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
204500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (fd < 0) {
204600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                perror ("opening AT interface. retrying...");
204700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                sleep(10);
204800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                /* never returns */
204900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
205000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
205100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
205200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        s_closed = 0;
205300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        ret = at_open(fd, onUnsolicited);
205400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
205500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (ret < 0) {
205600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            LOGE ("AT error %d on at_open\n", ret);
205700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            return 0;
205800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
205900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
206000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);
206100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
206200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // Give initializeCallback a chance to dispatched, since
206300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // we don't presently have a cancellation mechanism
206400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        sleep(1);
206500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
206600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        waitForClose();
206700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        LOGI("Re-opening after close");
206800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
206900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
207000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
207100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef RIL_SHLIB
207200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
207300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectpthread_t s_tid_mainloop;
207400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
207500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectconst RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
207600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
207700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
207800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int fd = -1;
207900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int opt;
208000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_attr_t attr;
208100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
208200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_rilenv = env;
208300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
208400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    while ( -1 != (opt = getopt(argc, argv, "p:d:s:"))) {
208500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        switch (opt) {
208600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 'p':
208700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_port = atoi(optarg);
208800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if (s_port == 0) {
208900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    usage(argv[0]);
209000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    return NULL;
209100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                }
209200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGI("Opening loopback port %d\n", s_port);
209300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
209400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
209500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 'd':
209600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_path = optarg;
209700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGI("Opening tty device %s\n", s_device_path);
209800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
209900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
210000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 's':
210100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_path   = optarg;
210200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_socket = 1;
210300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGI("Opening socket %s\n", s_device_path);
210400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
210500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
210600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            default:
210700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                usage(argv[0]);
210800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                return NULL;
210900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
211000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
211100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
211200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (s_port < 0 && s_device_path == NULL) {
211300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        usage(argv[0]);
211400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return NULL;
211500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
211600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
211700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_attr_init (&attr);
211800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
211900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);
212000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
212100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return &s_callbacks;
212200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
212300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#else /* RIL_SHLIB */
212400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectint main (int argc, char **argv)
212500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
212600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
212700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int fd = -1;
212800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int opt;
212900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
213000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    while ( -1 != (opt = getopt(argc, argv, "p:d:"))) {
213100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        switch (opt) {
213200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 'p':
213300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_port = atoi(optarg);
213400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if (s_port == 0) {
213500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    usage(argv[0]);
213600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                }
213700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGI("Opening loopback port %d\n", s_port);
213800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
213900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
214000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 'd':
214100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_path = optarg;
214200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGI("Opening tty device %s\n", s_device_path);
214300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
214400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
214500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 's':
214600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_path   = optarg;
214700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_socket = 1;
214800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                LOGI("Opening socket %s\n", s_device_path);
214900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
215000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
215100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            default:
215200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                usage(argv[0]);
215300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
215400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
215500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
215600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (s_port < 0 && s_device_path == NULL) {
215700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        usage(argv[0]);
215800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
215900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
216000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_register(&s_callbacks);
216100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
216200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    mainLoop(NULL);
216300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
216400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return 0;
216500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
216600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
216700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* RIL_SHLIB */
2168