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