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
18e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#include <telephony/ril_cdma_sms.h>
198a9e02161271505de274db0c3a88087056dd5dfcWink Saville#include <telephony/librilutils.h>
2000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <stdio.h>
2100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <assert.h>
2200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <string.h>
2300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <errno.h>
2400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <unistd.h>
2500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <sys/types.h>
2600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <sys/stat.h>
2700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <fcntl.h>
2800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <pthread.h>
2900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <alloca.h>
3000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include "atchannel.h"
3100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include "at_tok.h"
3200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include "misc.h"
3300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <getopt.h>
3400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <sys/socket.h>
3500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <cutils/sockets.h>
3600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <termios.h>
37af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner#include <sys/system_properties.h>
3800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
399a9fbd294bf8a7465cf10480935edea8304ef661Wink Saville#include "ril.h"
40385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine#include "hardware/qemu_pipe.h"
419a9fbd294bf8a7465cf10480935edea8304ef661Wink Saville
4200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define LOG_TAG "RIL"
4300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#include <utils/Log.h>
4400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
4500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define MAX_AT_RESPONSE 0x1000
4600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
47f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville/* pathname returned from RIL_REQUEST_SETUP_DATA_CALL / RIL_REQUEST_SETUP_DEFAULT_PDP */
48f838ede4a7c8b5994a84b92de8c2bcb346379be4Robert Greenwalt#define PPP_TTY_PATH "eth0"
4900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef USE_TI_COMMANDS
5100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Enable a workaround
5300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// 1) Make incoming call, do not answer
5400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// 2) Hangup remote end
5500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Expected: call should disappear from CLCC line
5600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Actual: Call shows as "ACTIVE" before disappearing
5700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define WORKAROUND_ERRONEOUS_ANSWER 1
5800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Some varients of the TI stack do not support the +CGEV unsolicited
6000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// response. However, they seem to send an unsolicited +CME ERROR: 150
6100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define WORKAROUND_FAKE_CGEV 1
6200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
6300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
64e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano/* Modem Technology bits */
65e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define MDM_GSM         0x01
66e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define MDM_WCDMA       0x02
67e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define MDM_CDMA        0x04
68e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define MDM_EVDO        0x08
69e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define MDM_LTE         0x10
70e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
71e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanotypedef struct {
72e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int supportedTechs; // Bitmask of supported Modem Technology bits
73e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int currentTech;    // Technology the modem is currently using (in the format used by modem)
74e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int isMultimode;
75e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
76e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // Preferred mode bitmask. This is actually 4 byte-sized bitmasks with different priority values,
77e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // in which the byte number from LSB to MSB give the priority.
78e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    //
79e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    //          |MSB|   |   |LSB
80e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // value:   |00 |00 |00 |00
81e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // byte #:  |3  |2  |1  |0
82e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    //
83e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // Higher byte order give higher priority. Thus, a value of 0x0000000f represents
84e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // a preferred mode of GSM, WCDMA, CDMA, and EvDo in which all are equally preferrable, whereas
85e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // 0x00000201 represents a mode with GSM and WCDMA, in which WCDMA is preferred over GSM
86e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int32_t preferredNetworkMode;
87e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int subscription_source;
88e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
89e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano} ModemInfo;
90e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
91e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic ModemInfo *sMdmInfo;
92e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano// TECH returns the current technology in the format used by the modem.
93e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano// It can be used as an l-value
94e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define TECH(mdminfo)                 ((mdminfo)->currentTech)
95e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano// TECH_BIT returns the bitmask equivalent of the current tech
96e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define TECH_BIT(mdminfo)            (1 << ((mdminfo)->currentTech))
97e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define IS_MULTIMODE(mdminfo)         ((mdminfo)->isMultimode)
98e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define TECH_SUPPORTED(mdminfo, tech) ((mdminfo)->supportedTechs & (tech))
99e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define PREFERRED_NETWORK(mdminfo)    ((mdminfo)->preferredNetworkMode)
100e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano// CDMA Subscription Source
101e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define SSOURCE(mdminfo)              ((mdminfo)->subscription_source)
102e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
103e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic int net2modem[] = {
104e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_GSM | MDM_WCDMA,                                 // 0  - GSM / WCDMA Pref
105e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_GSM,                                             // 1  - GSM only
106e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_WCDMA,                                           // 2  - WCDMA only
107e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_GSM | MDM_WCDMA,                                 // 3  - GSM / WCDMA Auto
108e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_CDMA | MDM_EVDO,                                 // 4  - CDMA / EvDo Auto
109e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_CDMA,                                            // 5  - CDMA only
110e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_EVDO,                                            // 6  - EvDo only
111e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO,           // 7  - GSM/WCDMA, CDMA, EvDo
112e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_LTE | MDM_CDMA | MDM_EVDO,                       // 8  - LTE, CDMA and EvDo
113e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_LTE | MDM_GSM | MDM_WCDMA,                       // 9  - LTE, GSM/WCDMA
114e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
115e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_LTE,                                             // 11 - LTE only
116e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano};
117e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
118e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic int32_t net2pmask[] = {
119e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_GSM | (MDM_WCDMA << 8),                          // 0  - GSM / WCDMA Pref
120e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_GSM,                                             // 1  - GSM only
121e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_WCDMA,                                           // 2  - WCDMA only
122e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_GSM | MDM_WCDMA,                                 // 3  - GSM / WCDMA Auto
123e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_CDMA | MDM_EVDO,                                 // 4  - CDMA / EvDo Auto
124e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_CDMA,                                            // 5  - CDMA only
125e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_EVDO,                                            // 6  - EvDo only
126e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO,           // 7  - GSM/WCDMA, CDMA, EvDo
127e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_LTE | MDM_CDMA | MDM_EVDO,                       // 8  - LTE, CDMA and EvDo
128e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_LTE | MDM_GSM | MDM_WCDMA,                       // 9  - LTE, GSM/WCDMA
129e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
130e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    MDM_LTE,                                             // 11 - LTE only
131e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano};
132e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
133e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic int is3gpp2(int radioTech) {
134e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    switch (radioTech) {
135e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RADIO_TECH_IS95A:
136e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RADIO_TECH_IS95B:
137e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RADIO_TECH_1xRTT:
138e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RADIO_TECH_EVDO_0:
139e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RADIO_TECH_EVDO_A:
140e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RADIO_TECH_EVDO_B:
141e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RADIO_TECH_EHRPD:
142e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return 1;
143e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        default:
144e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return 0;
145e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
146e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
147e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
148309ac294bd529ff5a71f1c1e62cd493df1010271John Wangtypedef enum {
149309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_ABSENT = 0,
150309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_NOT_READY = 1,
151309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_READY = 2, /* SIM_READY means the radio state is RADIO_STATE_SIM_READY */
152309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_PIN = 3,
153309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    SIM_PUK = 4,
154e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    SIM_NETWORK_PERSONALIZATION = 5,
155e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RUIM_ABSENT = 6,
156e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RUIM_NOT_READY = 7,
157e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RUIM_READY = 8,
158e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RUIM_PIN = 9,
159e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RUIM_PUK = 10,
160e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RUIM_NETWORK_PERSONALIZATION = 11
161af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner} SIM_Status;
162309ac294bd529ff5a71f1c1e62cd493df1010271John Wang
16300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onRequest (int request, void *data, size_t datalen, RIL_Token t);
16400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic RIL_RadioState currentState();
16500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int onSupports (int requestCode);
16600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onCancel (RIL_Token t);
16700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const char *getVersion();
16800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int isRadioOn();
169309ac294bd529ff5a71f1c1e62cd493df1010271John Wangstatic SIM_Status getSIMStatus();
1702c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Savillestatic int getCardStatus(RIL_CardStatus_v6 **pp_card_status);
1712c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Savillestatic void freeCardStatus(RIL_CardStatus_v6 *p_card_status);
172f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void onDataCallListChanged(void *param);
17300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectextern const char * requestToString(int request);
17500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/*** Static Variables ***/
17700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const RIL_RadioFunctions s_callbacks = {
17800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_VERSION,
17900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    onRequest,
18000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    currentState,
18100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    onSupports,
18200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    onCancel,
18300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    getVersion
18400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project};
18500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
18600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef RIL_SHLIB
18700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const struct RIL_Env *s_rilenv;
18800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
18900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define RIL_onRequestComplete(t, e, response, responselen) s_rilenv->OnRequestComplete(t,e, response, responselen)
19000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define RIL_onUnsolicitedResponse(a,b,c) s_rilenv->OnUnsolicitedResponse(a,b,c)
19100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define RIL_requestTimedCallback(a,b,c) s_rilenv->RequestTimedCallback(a,b,c)
19200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
19300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
19400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic RIL_RadioState sState = RADIO_STATE_UNAVAILABLE;
19500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
19600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic pthread_mutex_t s_state_mutex = PTHREAD_MUTEX_INITIALIZER;
19700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic pthread_cond_t s_state_cond = PTHREAD_COND_INITIALIZER;
19800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
19900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_port = -1;
20000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const char * s_device_path = NULL;
20100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int          s_device_socket = 0;
20200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
20300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/* trigger change to this with s_state_cond */
20400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_closed = 0;
20500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
20600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int sFD;     /* file desc of AT channel */
20700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic char sATBuffer[MAX_AT_RESPONSE+1];
20800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic char *sATBufferCur = NULL;
20900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
21000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const struct timeval TIMEVAL_SIMPOLL = {1,0};
21100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const struct timeval TIMEVAL_CALLSTATEPOLL = {0,500000};
21200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const struct timeval TIMEVAL_0 = {0,0};
21300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
214a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowastatic int s_ims_registered  = 0;        // 0==unregistered
215a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowastatic int s_ims_services    = 1;        // & 0x1 == sms over ims supported
216a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowastatic int s_ims_format    = 1;          // FORMAT_3GPP(1) vs FORMAT_3GPP2(2);
217a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowastatic int s_ims_cause_retry = 0;        // 1==causes sms over ims to temp fail
218a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowastatic int s_ims_cause_perm_failure = 0; // 1==causes sms over ims to permanent fail
219a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowastatic int s_ims_gsm_retry   = 0;        // 1==causes sms over gsm to temp fail
220a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowastatic int s_ims_gsm_fail    = 0;        // 1==causes sms over gsm to permanent fail
221a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
22200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
22300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Max number of times we'll try to repoll when we think
22400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// we have a AT+CLCC race condition
22500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#define REPOLL_CALLS_COUNT_MAX 4
22600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
22700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Line index that was incoming or waiting at last poll, or -1 for none
22800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_incomingOrWaitingLine = -1;
22900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Number of times we've asked for a repoll of AT+CLCC
23000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_repollCallsCount = 0;
23100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// Should we expect a call to be answered in the next CLCC?
23200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int s_expectAnswer = 0;
23300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_ERRONEOUS_ANSWER */
23400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2358a9e02161271505de274db0c3a88087056dd5dfcWink Savillestatic int s_cell_info_rate_ms = INT_MAX;
2368a9e02161271505de274db0c3a88087056dd5dfcWink Savillestatic int s_mcc = 0;
2378a9e02161271505de274db0c3a88087056dd5dfcWink Savillestatic int s_mnc = 0;
2388a9e02161271505de274db0c3a88087056dd5dfcWink Savillestatic int s_lac = 0;
2398a9e02161271505de274db0c3a88087056dd5dfcWink Savillestatic int s_cid = 0;
2408a9e02161271505de274db0c3a88087056dd5dfcWink Saville
24100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void pollSIMState (void *param);
24200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void setRadioState(RIL_RadioState newState);
243e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void setRadioTechnology(ModemInfo *mdm, int newtech);
244e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic int query_ctec(ModemInfo *mdm, int *current, int32_t *preferred);
245e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic int parse_technology_response(const char *response, int *current, int32_t *preferred);
246e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic int techFromModemType(int mdmtype);
24700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
24800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int clccStateToRILState(int state, RIL_CallState *p_state)
24900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
25000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
25100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch(state) {
25200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 0: *p_state = RIL_CALL_ACTIVE;   return 0;
25300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 1: *p_state = RIL_CALL_HOLDING;  return 0;
25400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 2: *p_state = RIL_CALL_DIALING;  return 0;
25500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 3: *p_state = RIL_CALL_ALERTING; return 0;
25600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 4: *p_state = RIL_CALL_INCOMING; return 0;
25700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 5: *p_state = RIL_CALL_WAITING;  return 0;
25800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default: return -1;
25900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
26000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
26100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
26200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
26300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Note: directly modified line and has *p_call point directly into
26400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * modified line
26500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
2663d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Savillestatic int callFromCLCCLine(char *line, RIL_Call *p_call)
26700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
26800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        //+CLCC: 1,0,2,0,0,\"+18005551212\",145
26900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        //     index,isMT,state,mode,isMpty(,number,TOA)?
27000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
27100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
27200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int state;
27300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int mode;
27400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
27500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
27600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
27700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
27800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &(p_call->index));
27900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
28000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
28100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextbool(&line, &(p_call->isMT));
28200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
28300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
28400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &state);
28500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
28600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
28700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = clccStateToRILState(state, &(p_call->state));
28800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
28900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
29000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &mode);
29100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
29200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
29300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_call->isVoice = (mode == 0);
29400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
29500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextbool(&line, &(p_call->isMpty));
29600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
29700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
29800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (at_tok_hasmore(&line)) {
29900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &(p_call->number));
30000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
30100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* tolerate null here */
30200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) return 0;
30300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
30400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // Some lame implementations return strings
30500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // like "NOT AVAILABLE" in the CLCC line
30600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (p_call->number != NULL
30700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            && 0 == strspn(p_call->number, "+0123456789")
30800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        ) {
30900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_call->number = NULL;
31000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
31100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
31200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &p_call->toa);
31300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
31400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
31500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
31674fa38884320698c1623764850e3131b9769dff0Wink Saville    p_call->uusInfo = NULL;
31774fa38884320698c1623764850e3131b9769dff0Wink Saville
31800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return 0;
31900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
32000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
3214dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGE("invalid CLCC line\n");
32200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return -1;
32300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
32400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
32500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
32600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/** do post-AT+CFUN=1 initialization */
32700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onRadioPowerOn()
32800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
32900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef USE_TI_COMMANDS
33000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Must be after CFUN=1 */
33100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  TI specific -- notifications for CPHS things such */
33200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  as CPHS message waiting indicator */
33300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
33400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT%CPHS=1", NULL);
33500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
33600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  TI specific -- enable NITZ unsol notifs */
33700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT%CTZV=1", NULL);
33800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
33900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
34000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pollSIMState(NULL);
34100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
34200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
34300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/** do post- SIM ready initialization */
34400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onSIMReady()
34500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
34600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command_singleline("AT+CSMS=1", "+CSMS:", NULL);
34700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*
34800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * Always send SMS messages directly to the TE
34900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
35000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * mode = 1 // discard when link is reserved (link should never be
35100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *             reserved)
35200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * mt = 2   // most messages routed to TE
35300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * bm = 2   // new cell BM's routed to TE
35400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * ds = 1   // Status reports routed to TE
35500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * bfr = 1  // flush buffer
35600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
35700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CNMI=1,2,2,1,1", NULL);
35800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
35900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
36000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestRadioPower(void *data, size_t datalen, RIL_Token t)
36100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
36200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int onOff;
36300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
36400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
36500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
36600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
36700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    assert (datalen >= sizeof(int *));
36800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    onOff = ((int *)data)[0];
36900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
37000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (onOff == 0 && sState != RADIO_STATE_OFF) {
37100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_send_command("AT+CFUN=0", &p_response);
37200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project       if (err < 0 || p_response->success == 0) goto error;
37300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        setRadioState(RADIO_STATE_OFF);
37400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (onOff > 0 && sState == RADIO_STATE_OFF) {
37500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_send_command("AT+CFUN=1", &p_response);
37600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0|| p_response->success == 0) {
37700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // Some stacks return an error when there is no SIM,
37800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // but they really turn the RF portion on
37900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // So, if we get an error, let's check to see if it
38000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // turned on anyway
38100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
38200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (isRadioOn() != 1) {
38300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                goto error;
38400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
38500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
386e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        setRadioState(RADIO_STATE_ON);
38700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
38800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
38900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
39000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
39100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
39200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
39300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
39400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
39500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
39600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
397f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void requestOrSendDataCallList(RIL_Token *t);
39800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
399f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void onDataCallListChanged(void *param)
40000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
401f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville    requestOrSendDataCallList(NULL);
40200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
40300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
404f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void requestDataCallList(void *data, size_t datalen, RIL_Token t)
40500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
406f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville    requestOrSendDataCallList(&t);
40700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
40800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
409f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void requestOrSendDataCallList(RIL_Token *t)
41000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
41100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response;
41200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATLine *p_cur;
41300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
41400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int n = 0;
41500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *out;
41600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
41700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_multiline ("AT+CGACT?", "+CGACT:", &p_response);
41800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) {
41900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (t != NULL)
42000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
42100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        else
422f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville            RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
42300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                      NULL, 0);
42400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
42500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
42600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
42700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (p_cur = p_response->p_intermediates; p_cur != NULL;
42800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         p_cur = p_cur->p_next)
42900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        n++;
43000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
4312c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    RIL_Data_Call_Response_v6 *responses =
4322c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        alloca(n * sizeof(RIL_Data_Call_Response_v6));
43300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
43400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int i;
43500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (i = 0; i < n; i++) {
4364380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        responses[i].status = -1;
437250eb3c8c3adbbbaf49c30ee09a061268d9a491aWink Saville        responses[i].suggestedRetryTime = -1;
43800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].cid = -1;
43900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].active = -1;
44000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].type = "";
4414380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        responses[i].ifname = "";
4424380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        responses[i].addresses = "";
4434380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        responses[i].dnses = "";
4442c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        responses[i].gateways = "";
44500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
44600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
4472c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    RIL_Data_Call_Response_v6 *response = responses;
44800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (p_cur = p_response->p_intermediates; p_cur != NULL;
44900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         p_cur = p_cur->p_next) {
45000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *line = p_cur->line;
45100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
45200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_start(&line);
45300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
45400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
45500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
45600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &response->cid);
45700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
45800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
45900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
46000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &response->active);
46100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
46200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
46300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
46400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        response++;
46500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
46600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
46700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
46800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
46900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_multiline ("AT+CGDCONT?", "+CGDCONT:", &p_response);
47000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) {
47100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (t != NULL)
47200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
47300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        else
474f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville            RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
47500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                      NULL, 0);
47600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
47700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
47800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
47900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (p_cur = p_response->p_intermediates; p_cur != NULL;
48000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         p_cur = p_cur->p_next) {
48100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *line = p_cur->line;
48200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        int cid;
48300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
48400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_start(&line);
48500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
48600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
48700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
48800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &cid);
48900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
49000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
49100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
49200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        for (i = 0; i < n; i++) {
49300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (responses[i].cid == cid)
49400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                break;
49500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
49600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
49700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (i >= n) {
49800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* details for a context we didn't hear about in the last request */
49900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            continue;
50000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
50100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5024380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        // Assume no error
5034380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        responses[i].status = 0;
5044380897c6cdc99486a061b819943e3b290ebcf09Wink Saville
5054380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        // type
50600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &out);
50700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
50800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
50900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        responses[i].type = alloca(strlen(out) + 1);
51000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        strcpy(responses[i].type, out);
51100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5124380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        // APN ignored for v5
51300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &out);
51400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
51500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
51600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5174380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        responses[i].ifname = alloca(strlen(PPP_TTY_PATH) + 1);
5184380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        strcpy(responses[i].ifname, PPP_TTY_PATH);
51900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
52000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &out);
52100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0)
52200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
52300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
5244380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        responses[i].addresses = alloca(strlen(out) + 1);
5254380897c6cdc99486a061b819943e3b290ebcf09Wink Saville        strcpy(responses[i].addresses, out);
5264380897c6cdc99486a061b819943e3b290ebcf09Wink Saville
527af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner        {
528af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner            char  propValue[PROP_VALUE_MAX];
529af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner
530af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner            if (__system_property_get("ro.kernel.qemu", propValue) != 0) {
531af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                /* We are in the emulator - the dns servers are listed
532af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                 * by the following system properties, setup in
533af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                 * /system/etc/init.goldfish.sh:
534af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                 *  - net.eth0.dns1
535af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                 *  - net.eth0.dns2
536af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                 *  - net.eth0.dns3
537af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                 *  - net.eth0.dns4
538af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                 */
539af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                const int   dnslist_sz = 128;
540af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                char*       dnslist = alloca(dnslist_sz);
541af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                const char* separator = "";
542af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                int         nn;
543af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner
544af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                dnslist[0] = 0;
545af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                for (nn = 1; nn <= 4; nn++) {
546af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    /* Probe net.eth0.dns<n> */
547af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    char  propName[PROP_NAME_MAX];
548af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    snprintf(propName, sizeof propName, "net.eth0.dns%d", nn);
549af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner
550af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    /* Ignore if undefined */
551af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    if (__system_property_get(propName, propValue) == 0) {
552af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                        continue;
553af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    }
554af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner
555af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    /* Append the DNS IP address */
556af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    strlcat(dnslist, separator, dnslist_sz);
557af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    strlcat(dnslist, propValue, dnslist_sz);
558af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                    separator = " ";
559af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                }
560af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                responses[i].dnses = dnslist;
5612c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville
5622c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                /* There is only on gateway in the emulator */
5632c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                responses[i].gateways = "10.0.2.2";
564af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner            }
565af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner            else {
566af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                /* I don't know where we are, so use the public Google DNS
5672c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                 * servers by default and no gateway.
568af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                 */
569af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner                responses[i].dnses = "8.8.8.8 8.8.4.4";
5702c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                responses[i].gateways = "";
571af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner            }
572af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner        }
57300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
57400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
57500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
57600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
57700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (t != NULL)
57800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(*t, RIL_E_SUCCESS, responses,
5792c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                              n * sizeof(RIL_Data_Call_Response_v6));
58000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    else
581f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
58200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                  responses,
5832c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville                                  n * sizeof(RIL_Data_Call_Response_v6));
58400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
58500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
58600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
58700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
58800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (t != NULL)
58900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
59000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    else
591f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
59200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                  NULL, 0);
59300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
59400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
59500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
59600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
59700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestQueryNetworkSelectionMode(
59800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                void *data, size_t datalen, RIL_Token t)
59900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
60000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
60100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
60200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int response = 0;
60300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line;
60400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
60500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline("AT+COPS?", "+COPS:", &p_response);
60600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
60700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
60800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
60900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
61000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
61100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
61200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
61300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
61400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
61500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) {
61600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
61700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
61800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
61900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &response);
62000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
62100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) {
62200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
62300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
62400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
62500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(int));
62600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
62700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
62800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
62900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
6304dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGE("requestQueryNetworkSelectionMode must never return error when radio is on");
63100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
63200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
63300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
63400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void sendCallStateChanged(void *param)
63500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
63600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onUnsolicitedResponse (
63700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
63800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        NULL, 0);
63900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
64000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
64100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestGetCurrentCalls(void *data, size_t datalen, RIL_Token t)
64200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
64300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
64400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response;
64500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATLine *p_cur;
64600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int countCalls;
64700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int countValidCalls;
6483d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    RIL_Call *p_calls;
6493d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    RIL_Call **pp_calls;
65000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int i;
65100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int needRepoll = 0;
65200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
65300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
65400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int prevIncomingOrWaitingLine;
65500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
65600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    prevIncomingOrWaitingLine = s_incomingOrWaitingLine;
65700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_incomingOrWaitingLine = -1;
65800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /*WORKAROUND_ERRONEOUS_ANSWER*/
65900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
66000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_multiline ("AT+CLCC", "+CLCC:", &p_response);
66100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
66200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) {
66300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
66400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
66500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
66600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
66700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* count the calls */
66800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (countCalls = 0, p_cur = p_response->p_intermediates
66900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur != NULL
67000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur = p_cur->p_next
67100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
67200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        countCalls++;
67300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
67400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
67500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* yes, there's an array of pointers and then an array of structures */
67600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
6773d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    pp_calls = (RIL_Call **)alloca(countCalls * sizeof(RIL_Call *));
6783d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    p_calls = (RIL_Call *)alloca(countCalls * sizeof(RIL_Call));
6793d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    memset (p_calls, 0, countCalls * sizeof(RIL_Call));
68000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
68100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* init the pointer array */
68200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for(i = 0; i < countCalls ; i++) {
68300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        pp_calls[i] = &(p_calls[i]);
68400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
68500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
68600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (countValidCalls = 0, p_cur = p_response->p_intermediates
68700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur != NULL
68800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur = p_cur->p_next
68900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
69000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = callFromCLCCLine(p_cur->line, p_calls + countValidCalls);
69100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
69200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err != 0) {
69300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            continue;
69400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
69500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
69600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
69700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (p_calls[countValidCalls].state == RIL_CALL_INCOMING
69800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            || p_calls[countValidCalls].state == RIL_CALL_WAITING
69900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        ) {
70000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            s_incomingOrWaitingLine = p_calls[countValidCalls].index;
70100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
70200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /*WORKAROUND_ERRONEOUS_ANSWER*/
70300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
70400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (p_calls[countValidCalls].state != RIL_CALL_ACTIVE
70500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            && p_calls[countValidCalls].state != RIL_CALL_HOLDING
70600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        ) {
70700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            needRepoll = 1;
70800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
70900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
71000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        countValidCalls++;
71100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
71200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
71300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
71400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // Basically:
71500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // A call was incoming or waiting
71600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // Now it's marked as active
71700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // But we never answered it
71800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    //
71900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // This is probably a bug, and the call will probably
72000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // disappear from the call list in the next poll
72100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (prevIncomingOrWaitingLine >= 0
72200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            && s_incomingOrWaitingLine < 0
72300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            && s_expectAnswer == 0
72400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
72500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        for (i = 0; i < countValidCalls ; i++) {
72600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
72700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (p_calls[i].index == prevIncomingOrWaitingLine
72800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    && p_calls[i].state == RIL_CALL_ACTIVE
72900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    && s_repollCallsCount < REPOLL_CALLS_COUNT_MAX
73000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ) {
7314dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGI(
73200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    "Hit WORKAROUND_ERRONOUS_ANSWER case."
73300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    " Repoll count: %d\n", s_repollCallsCount);
73400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_repollCallsCount++;
73500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                goto error;
73600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
73700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
73800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
73900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
74000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_expectAnswer = 0;
74100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_repollCallsCount = 0;
74200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /*WORKAROUND_ERRONEOUS_ANSWER*/
74300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
7443d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville    RIL_onRequestComplete(t, RIL_E_SUCCESS, pp_calls,
7453d54e74bc450bb40977e3ae6fab6185fe687bdaeWink Saville            countValidCalls * sizeof (RIL_Call *));
74600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
74700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
74800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
74900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef POLL_CALL_STATE
75000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (countValidCalls) {  // We don't seem to get a "NO CARRIER" message from
75100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                            // smd, so we're forced to poll until the call ends.
75200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#else
75300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (needRepoll) {
75400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
75500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_requestTimedCallback (sendCallStateChanged, NULL, &TIMEVAL_CALLSTATEPOLL);
75600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
75700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
75800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
75900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
76000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
76100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
76200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
76300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
76400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestDial(void *data, size_t datalen, RIL_Token t)
76500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
76600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_Dial *p_dial;
76700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd;
76800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *clir;
76900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
77000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
77100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_dial = (RIL_Dial *)data;
77200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
77300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch (p_dial->clir) {
77400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 1: clir = "I"; break;  /*invocation*/
77500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 2: clir = "i"; break;  /*suppression*/
77600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
77700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 0: clir = ""; break;   /*subscription default*/
77800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
77900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
78000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd, "ATD%s%s;", p_dial->address, clir);
78100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
78200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ret = at_send_command(cmd, NULL);
78300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
78400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
78500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
78600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* success or failure is ignored by the upper layer here.
78700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project       it will call GET_CURRENT_CALLS and determine success that way */
78800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
78900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
79000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
79100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestWriteSmsToSim(void *data, size_t datalen, RIL_Token t)
79200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
79300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_SMS_WriteArgs *p_args;
79400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd;
79500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int length;
79600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
79700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
79800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
79900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_args = (RIL_SMS_WriteArgs *)data;
80000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
80100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    length = strlen(p_args->pdu)/2;
80200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd, "AT+CMGW=%d,%d", length, p_args->status);
80300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
80400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_sms(cmd, p_args->pdu, "+CMGW:", &p_response);
80500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
80600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) goto error;
80700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
80800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
80900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
81000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
81100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
81200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
81300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
81400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
81500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
81600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
81700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestHangup(void *data, size_t datalen, RIL_Token t)
81800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
81900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int *p_line;
82000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
82100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
82200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd;
82300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
82400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_line = (int *)data;
82500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
82600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // 3GPP 22.030 6.5.5
82700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // "Releases a specific active call X"
82800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd, "AT+CHLD=1%d", p_line[0]);
82900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
83000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ret = at_send_command(cmd, NULL);
83100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
83200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
83300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
83400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* success or failure is ignored by the upper layer here.
83500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project       it will call GET_CURRENT_CALLS and determine success that way */
83600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
83700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
83800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
83900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestSignalStrength(void *data, size_t datalen, RIL_Token t)
84000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
84100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
84200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
84300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line;
8449efcac5782b93564d47c1687e67e85849c72afedUma Maheswari Ramalingam    int count =0;
8459efcac5782b93564d47c1687e67e85849c72afedUma Maheswari Ramalingam    int numofElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
8469efcac5782b93564d47c1687e67e85849c72afedUma Maheswari Ramalingam    int response[numofElements];
84700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
84800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response);
84900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
85000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
85100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
85200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
85300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
85400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
85500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
85600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
85700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
85800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
85900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
8609efcac5782b93564d47c1687e67e85849c72afedUma Maheswari Ramalingam    for (count =0; count < numofElements; count ++) {
8619efcac5782b93564d47c1687e67e85849c72afedUma Maheswari Ramalingam        err = at_tok_nextint(&line, &(response[count]));
8629efcac5782b93564d47c1687e67e85849c72afedUma Maheswari Ramalingam        if (err < 0) goto error;
8639efcac5782b93564d47c1687e67e85849c72afedUma Maheswari Ramalingam    }
86400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
8659efcac5782b93564d47c1687e67e85849c72afedUma Maheswari Ramalingam    RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
86600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
86700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
86800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
86900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
87000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
8714dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGE("requestSignalStrength must never return an error when radio is on");
87200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
87300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
87400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
87500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
876e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano/**
877e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * networkModePossible. Decides whether the network mode is appropriate for the
878e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * specified modem
879e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano */
880e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic int networkModePossible(ModemInfo *mdm, int nm)
881e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
882e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if ((net2modem[nm] & mdm->supportedTechs) == net2modem[nm]) {
883e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano       return 1;
884e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
885e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return 0;
886e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
887e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestSetPreferredNetworkType( int request, void *data,
888e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                            size_t datalen, RIL_Token t )
889e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
890e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
891e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *cmd = NULL;
892e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int value = *(int *)data;
893e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int current, old;
894e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
895e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int32_t preferred = net2pmask[value];
896e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
8974dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("requestSetPreferredNetworkType: current: %x. New: %x", PREFERRED_NETWORK(sMdmInfo), preferred);
898e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!networkModePossible(sMdmInfo, value)) {
899e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        RIL_onRequestComplete(t, RIL_E_MODE_NOT_SUPPORTED, NULL, 0);
900e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return;
901e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
902e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (query_ctec(sMdmInfo, &current, NULL) < 0) {
903e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
904e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return;
905e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
906e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    old = PREFERRED_NETWORK(sMdmInfo);
9074dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("old != preferred: %d", old != preferred);
908e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (old != preferred) {
909e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        asprintf(&cmd, "AT+CTEC=%d,\"%x\"", current, preferred);
9104dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGD("Sending command: <%s>", cmd);
911e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        err = at_send_command_singleline(cmd, "+CTEC:", &p_response);
912e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        free(cmd);
913e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (err || !p_response->success) {
914e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
915e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
916e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
917e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        PREFERRED_NETWORK(sMdmInfo) = value;
918e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (!strstr( p_response->p_intermediates->line, "DONE") ) {
919e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            int current;
920e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            int res = parse_technology_response(p_response->p_intermediates->line, &current, NULL);
921e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            switch (res) {
922e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                case -1: // Error or unable to parse
923e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                    break;
924e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                case 1: // Only able to parse current
925e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                case 0: // Both current and preferred were parsed
926e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                    setRadioTechnology(sMdmInfo, current);
927e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                    break;
928e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            }
929e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
930e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
931e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
932e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
933e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
934e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestGetPreferredNetworkType(int request, void *data,
935e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                   size_t datalen, RIL_Token t)
936e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
937e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int preferred;
938e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    unsigned i;
939e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
940e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    switch ( query_ctec(sMdmInfo, NULL, &preferred) ) {
941e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case -1: // Error or unable to parse
942e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case 1: // Only able to parse current
943e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
944e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
945e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case 0: // Both current and preferred were parsed
946e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            for ( i = 0 ; i < sizeof(net2pmask) / sizeof(int32_t) ; i++ ) {
947e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                if (preferred == net2pmask[i]) {
948e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                    RIL_onRequestComplete(t, RIL_E_SUCCESS, &i, sizeof(int));
949e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                    return;
950e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                }
951e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            }
9524dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("Unknown preferred mode received from modem: %d", preferred);
953e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
954e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
955e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
956e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
957e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
958e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
959e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestCdmaPrlVersion(int request, void *data,
960e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                   size_t datalen, RIL_Token t)
961e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
962e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
963e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char * responseStr;
964e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
965e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    const char *cmd;
966e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line;
967e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
968e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command_singleline("AT+WPRL?", "+WPRL:", &p_response);
969e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0 || !p_response->success) goto error;
970e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    line = p_response->p_intermediates->line;
971e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_start(&line);
972e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0) goto error;
973e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_nextstr(&line, &responseStr);
974e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0 || !responseStr) goto error;
975e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, strlen(responseStr));
976e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    at_response_free(p_response);
977e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return;
978e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
979e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    at_response_free(p_response);
980e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
981e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
982e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
983e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestCdmaBaseBandVersion(int request, void *data,
984e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                   size_t datalen, RIL_Token t)
985e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
986e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
987e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char * responseStr;
988e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
989e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    const char *cmd;
990e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    const char *prefix;
991e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line, *p;
992e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int commas;
993e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int skip;
994e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int count = 4;
995e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
996e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // Fixed values. TODO: query modem
997e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr = strdup("1.0.0.0");
998e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, sizeof(responseStr));
999e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(responseStr);
1000e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
1001e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1002e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestCdmaDeviceIdentity(int request, void *data,
100300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                        size_t datalen, RIL_Token t)
100400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
100500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
100600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int response[4];
100700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char * responseStr[4];
100800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
100900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *cmd;
101000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *prefix;
101100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line, *p;
101200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int commas;
101300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int skip;
1014e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int count = 4;
101500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1016e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // Fixed values. TODO: Query modem
1017e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr[0] = "----";
1018e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr[1] = "----";
1019e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr[2] = "77777777";
102000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1021e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command_numeric("AT+CGSN", &p_response);
1022e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0 || p_response->success == 0) {
1023e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1024e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return;
102500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else {
1026e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        responseStr[3] = p_response->p_intermediates->line;
1027e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
1028e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1029e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
1030e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    at_response_free(p_response);
1031e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1032e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return;
1033e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
10344dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGE("requestCdmaDeviceIdentity must never return an error when radio is on");
1035e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    at_response_free(p_response);
1036e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1037e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
1038e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1039e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestCdmaGetSubscriptionSource(int request, void *data,
1040e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                        size_t datalen, RIL_Token t)
1041e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1042e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
1043e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int *ss = (int *)data;
1044e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
1045e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *cmd = NULL;
1046e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line = NULL;
1047e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int response;
1048e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1049e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    asprintf(&cmd, "AT+CCSS?");
1050e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!cmd) goto error;
1051e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1052e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command_singleline(cmd, "+CCSS:", &p_response);
1053e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0 || !p_response->success)
105400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
1055e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1056e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    line = p_response->p_intermediates->line;
1057e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_start(&line);
1058e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0) goto error;
1059e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1060e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_nextint(&line, &response);
1061e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(cmd);
1062e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    cmd = NULL;
1063e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1064e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1065e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1066e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return;
1067e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
1068e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(cmd);
1069e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1070e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
1071e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1072e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestCdmaSetSubscriptionSource(int request, void *data,
1073e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                        size_t datalen, RIL_Token t)
1074e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1075e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
1076e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int *ss = (int *)data;
1077e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
1078e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *cmd = NULL;
1079e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1080e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!ss || !datalen) {
10814dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGE("RIL_REQUEST_CDMA_SET_SUBSCRIPTION without data!");
1082e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1083e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return;
108400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
1085e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    asprintf(&cmd, "AT+CCSS=%d", ss[0]);
1086e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!cmd) goto error;
108700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1088e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command(cmd, &p_response);
1089e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0 || !p_response->success)
1090e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto error;
1091e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(cmd);
1092e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    cmd = NULL;
109300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1094e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
109500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1096e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, ss, sizeof(ss[0]));
1097e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1098e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return;
1099e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
1100e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(cmd);
1101e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1102e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
1103e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1104e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestCdmaSubscription(int request, void *data,
1105e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                        size_t datalen, RIL_Token t)
1106e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1107e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
1108e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int response[5];
1109e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char * responseStr[5];
1110e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
1111e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    const char *cmd;
1112e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    const char *prefix;
1113e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line, *p;
1114e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int commas;
1115e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int skip;
1116e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int count = 5;
1117e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1118e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // Fixed values. TODO: Query modem
1119e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr[0] = "8587777777"; // MDN
1120e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr[1] = "1"; // SID
1121e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr[2] = "1"; // NID
1122e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr[3] = "8587777777"; // MIN
1123e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr[4] = "1"; // PRL Version
1124e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
1125e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1126e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return;
1127e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
11284dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGE("requestRegistrationState must never return an error when radio is on");
1129e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1130e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
1131e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1132e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestCdmaGetRoamingPreference(int request, void *data,
1133e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                                 size_t datalen, RIL_Token t)
1134e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1135e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int roaming_pref = -1;
1136e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
1137e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line;
1138e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int res;
1139e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1140e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    res = at_send_command_singleline("AT+WRMP?", "+WRMP:", &p_response);
1141e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (res < 0 || !p_response->success) {
1142e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto error;
1143e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
114400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
114500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1146e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    res = at_tok_start(&line);
1147e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (res < 0) goto error;
1148e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1149e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    res = at_tok_nextint(&line, &roaming_pref);
1150e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (res < 0) goto error;
1151e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1152e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano     RIL_onRequestComplete(t, RIL_E_SUCCESS, &roaming_pref, sizeof(roaming_pref));
1153e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return;
1154e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
1155e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1156e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
1157e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1158e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestCdmaSetRoamingPreference(int request, void *data,
1159e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                                 size_t datalen, RIL_Token t)
1160e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1161e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int *pref = (int *)data;
1162e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
1163e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line;
1164e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int res;
1165e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *cmd = NULL;
1166e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1167e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    asprintf(&cmd, "AT+WRMP=%d", *pref);
1168e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (cmd == NULL) goto error;
1169e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1170e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    res = at_send_command(cmd, &p_response);
1171e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (res < 0 || !p_response->success)
1172e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto error;
1173e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1174e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1175e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(cmd);
1176e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return;
1177e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
1178e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(cmd);
1179e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1180e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
1181e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1182e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic int parseRegistrationState(char *str, int *type, int *items, int **response)
1183e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1184e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
1185e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line = str, *p;
1186e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int *resp = NULL;
1187e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int skip;
1188e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int count = 3;
1189e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int commas;
1190e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
11914dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("parseRegistrationState. Parsing: %s",str);
119200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
119300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
119400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
119500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* Ok you have to be careful here
119600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * The solicited version of the CREG response is
119700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +CREG: n, stat, [lac, cid]
119800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * and the unsolicited version is
119900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +CREG: stat, [lac, cid]
120000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * The <n> parameter is basically "is unsolicited creg on?"
120100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * which it should always be
120200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
120300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * Now we should normally get the solicited version here,
120400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * but the unsolicited version could have snuck in
120500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * so we have to handle both
120600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
120700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * Also since the LAC and CID are only reported when registered,
120800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * we can have 1, 2, 3, or 4 arguments here
120900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
121000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * finally, a +CGREG: answer may have a fifth value that corresponds
121100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * to the network type, as in;
121200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *
121300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     *   +CGREG: n, stat [,lac, cid [,networkType]]
121400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
121500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
121600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* count number of commas */
121700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    commas = 0;
121800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (p = line ; *p != '\0' ;p++) {
121900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (*p == ',') commas++;
122000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
122100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1222e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    resp = (int *)calloc(commas + 1, sizeof(int));
1223e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!resp) goto error;
122400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch (commas) {
122500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 0: /* +CREG: <stat> */
1226e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nextint(&line, &resp[0]);
122700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1228e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            resp[1] = -1;
1229e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            resp[2] = -1;
123000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
123100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
123200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 1: /* +CREG: <n>, <stat> */
123300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &skip);
123400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1235e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nextint(&line, &resp[0]);
123600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1237e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            resp[1] = -1;
1238e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            resp[2] = -1;
123900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
124000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
124100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
124200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 2: /* +CREG: <stat>, <lac>, <cid> */
1243e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nextint(&line, &resp[0]);
124400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1245e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nexthexint(&line, &resp[1]);
124600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1247e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nexthexint(&line, &resp[2]);
124800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
124900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
125000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 3: /* +CREG: <n>, <stat>, <lac>, <cid> */
125100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &skip);
125200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1253e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nextint(&line, &resp[0]);
125400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1255e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nexthexint(&line, &resp[1]);
125600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1257e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nexthexint(&line, &resp[2]);
125800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
125900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
126000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* special case for CGREG, there is a fourth parameter
126100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * that is the network type (unknown/gprs/edge/umts)
126200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         */
126300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case 4: /* +CGREG: <n>, <stat>, <lac>, <cid>, <networkType> */
126400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_tok_nextint(&line, &skip);
126500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1266e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nextint(&line, &resp[0]);
126700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1268e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nexthexint(&line, &resp[1]);
126900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1270e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nexthexint(&line, &resp[2]);
127100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
1272e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            err = at_tok_nexthexint(&line, &resp[3]);
127300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0) goto error;
127400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            count = 4;
127500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        break;
127600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
127700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto error;
127800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
12798a9e02161271505de274db0c3a88087056dd5dfcWink Saville    s_lac = resp[1];
12808a9e02161271505de274db0c3a88087056dd5dfcWink Saville    s_cid = resp[2];
1281e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (response)
1282e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        *response = resp;
1283e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (items)
1284e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        *items = commas + 1;
1285e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (type)
1286e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        *type = techFromModemType(TECH(sMdmInfo));
1287e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return 0;
1288e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
1289e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(resp);
1290e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return -1;
1291e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
129200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1293e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define REG_STATE_LEN 15
1294e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano#define REG_DATA_STATE_LEN 6
1295e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestRegistrationState(int request, void *data,
1296e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                        size_t datalen, RIL_Token t)
1297e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1298e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
1299e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int *registration;
1300e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char **responseStr = NULL;
1301e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
1302e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    const char *cmd;
1303e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    const char *prefix;
1304e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line;
1305e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int i = 0, j, numElements = 0;
1306e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int count = 3;
1307e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int type, startfrom;
130800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
13094dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("requestRegistrationState");
1310e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1311e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        cmd = "AT+CREG?";
1312e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        prefix = "+CREG:";
1313e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        numElements = REG_STATE_LEN;
1314e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1315e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        cmd = "AT+CGREG?";
1316e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        prefix = "+CGREG:";
1317e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        numElements = REG_DATA_STATE_LEN;
1318e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else {
1319e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        assert(0);
1320e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto error;
1321e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
132200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1323e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command_singleline(cmd, prefix, &p_response);
1324e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1325e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err != 0) goto error;
1326e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1327e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    line = p_response->p_intermediates->line;
1328e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1329e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (parseRegistrationState(line, &type, &count, &registration)) goto error;
1330e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1331e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr = malloc(numElements * sizeof(char *));
1332e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!responseStr) goto error;
1333e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    memset(responseStr, 0, numElements * sizeof(char *));
1334e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    /**
1335e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano     * The first '4' bytes for both registration states remain the same.
1336e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano     * But if the request is 'DATA_REGISTRATION_STATE',
1337e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano     * the 5th and 6th byte(s) are optional.
1338e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano     */
1339e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (is3gpp2(type) == 1) {
13404dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGD("registration state type: 3GPP2");
1341e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // TODO: Query modem
1342e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        startfrom = 3;
1343e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1344e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[3], "8");     // EvDo revA
1345e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[4], "1");     // BSID
1346e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[5], "123");   // Latitude
1347e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[6], "222");   // Longitude
1348e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[7], "0");     // CSS Indicator
1349e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[8], "4");     // SID
1350e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[9], "65535"); // NID
1351e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[10], "0");    // Roaming indicator
1352e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[11], "1");    // System is in PRL
1353e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[12], "0");    // Default Roaming indicator
1354e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[13], "0");    // Reason for denial
1355e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[14], "0");    // Primary Scrambling Code of Current cell
1356e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano      } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1357e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[3], "8");   // Available data radio technology
1358e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano      }
1359e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else { // type == RADIO_TECH_3GPP
13604dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGD("registration state type: 3GPP");
1361e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        startfrom = 0;
1362e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        asprintf(&responseStr[1], "%x", registration[1]);
1363e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        asprintf(&responseStr[2], "%x", registration[2]);
1364e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (count > 3)
1365e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            asprintf(&responseStr[3], "%d", registration[3]);
1366e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
1367e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    asprintf(&responseStr[0], "%d", registration[0]);
1368e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1369e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    /**
1370e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano     * Optional bytes for DATA_REGISTRATION_STATE request
1371e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano     * 4th byte : Registration denial code
1372e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano     * 5th byte : The max. number of simultaneous Data Calls
1373e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano     */
1374e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if(request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1375e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // asprintf(&responseStr[4], "3");
1376e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // asprintf(&responseStr[5], "1");
1377e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
1378e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1379e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    for (j = startfrom; j < numElements; j++) {
1380e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (!responseStr[i]) goto error;
1381e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
1382e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(registration);
1383e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    registration = NULL;
1384e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1385e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, numElements*sizeof(responseStr));
1386e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    for (j = 0; j < numElements; j++ ) {
1387e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        free(responseStr[j]);
1388e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        responseStr[j] = NULL;
1389e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
1390e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(responseStr);
1391e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    responseStr = NULL;
139200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
139300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
139400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
139500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
1396e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (responseStr) {
1397e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        for (j = 0; j < numElements; j++) {
1398e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            free(responseStr[j]);
1399e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            responseStr[j] = NULL;
1400e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
1401e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        free(responseStr);
1402e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        responseStr = NULL;
1403e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
14044dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGE("requestRegistrationState must never return an error when radio is on");
140500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
140600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
140700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
140800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
140900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestOperator(void *data, size_t datalen, RIL_Token t)
141000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
141100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
141200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int i;
141300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int skip;
141400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATLine *p_cur;
141500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *response[3];
141600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
141700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    memset(response, 0, sizeof(response));
141800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
141900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
142000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
142100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_multiline(
142200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
142300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        "+COPS:", &p_response);
142400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
142500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* we expect 3 lines here:
142600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +COPS: 0,0,"T - Mobile"
142700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +COPS: 0,1,"TMO"
142800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * +COPS: 0,2,"310170"
142900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
143000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
143100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0) goto error;
143200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
143300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (i = 0, p_cur = p_response->p_intermediates
143400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur != NULL
143500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            ; p_cur = p_cur->p_next, i++
143600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
143700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *line = p_cur->line;
143800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
143900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_start(&line);
144000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
144100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
144200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &skip);
144300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
144400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
144500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // If we're unregistered, we may just get
144600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // a "+COPS: 0" response
144700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (!at_tok_hasmore(&line)) {
144800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            response[i] = NULL;
144900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            continue;
145000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
145100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
145200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextint(&line, &skip);
145300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
145400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
145500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // a "+COPS: 0, n" response is also possible
145600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (!at_tok_hasmore(&line)) {
145700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            response[i] = NULL;
145800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            continue;
145900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
146000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
146100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &(response[i]));
146200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
14638a9e02161271505de274db0c3a88087056dd5dfcWink Saville        // Simple assumption that mcc and mnc are 3 digits each
14648a9e02161271505de274db0c3a88087056dd5dfcWink Saville        if (strlen(response[i]) == 6) {
14658a9e02161271505de274db0c3a88087056dd5dfcWink Saville            if (sscanf(response[i], "%3d%3d", &s_mcc, &s_mnc) != 2) {
14668a9e02161271505de274db0c3a88087056dd5dfcWink Saville                RLOGE("requestOperator expected mccmnc to be 6 decimal digits");
14678a9e02161271505de274db0c3a88087056dd5dfcWink Saville            }
14688a9e02161271505de274db0c3a88087056dd5dfcWink Saville        }
146900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
147000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
147100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (i != 3) {
147200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* expect 3 lines exactly */
147300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
147400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
147500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
147600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
147700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
147800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
147900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
148000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
14814dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGE("requestOperator must not return error when radio is on");
148200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
148300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
148400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
148500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1486e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestCdmaSendSMS(void *data, size_t datalen, RIL_Token t)
1487e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1488e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err = 1; // Set to go to error:
1489e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_SMS_Response response;
1490e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_CDMA_SMS_Message* rcsm;
1491e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
14924dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("requestCdmaSendSMS datalen=%d, sizeof(RIL_CDMA_SMS_Message)=%d",
1493e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            datalen, sizeof(RIL_CDMA_SMS_Message));
1494e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1495e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // verify data content to test marshalling/unmarshalling:
1496e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    rcsm = (RIL_CDMA_SMS_Message*)data;
14974dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("TeleserviceID=%d, bIsServicePresent=%d, \
1498e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            uServicecategory=%d, sAddress.digit_mode=%d, \
1499e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            sAddress.Number_mode=%d, sAddress.number_type=%d, ",
1500e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            rcsm->uTeleserviceID,  rcsm->bIsServicePresent,
1501e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            rcsm->uServicecategory,rcsm->sAddress.digit_mode,
1502e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            rcsm->sAddress.number_mode,rcsm->sAddress.number_type);
1503e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1504e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err != 0) goto error;
1505e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1506e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // Cdma Send SMS implementation will go here:
1507e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // But it is not implemented yet.
1508e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1509e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    memset(&response, 0, sizeof(response));
1510a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    response.messageRef = 1;
1511e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1512e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return;
1513e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1514e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
1515e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // Cdma Send SMS will always cause send retry error.
1516a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    response.messageRef = -1;
1517a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
1518e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
1519e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
152000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestSendSMS(void *data, size_t datalen, RIL_Token t)
152100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
152200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
152300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *smsc;
152400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *pdu;
152500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int tpLayerLength;
152600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd1, *cmd2;
152700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_SMS_Response response;
152800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
152900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1530a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    memset(&response, 0, sizeof(response));
1531a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RLOGD("requestSendSMS datalen =%d", datalen);
1532a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1533a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    if (s_ims_gsm_fail != 0) goto error;
1534a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    if (s_ims_gsm_retry != 0) goto error2;
1535a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
153600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    smsc = ((const char **)data)[0];
153700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pdu = ((const char **)data)[1];
153800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
153900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    tpLayerLength = strlen(pdu)/2;
154000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
154100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // "NULL for default SMSC"
154200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (smsc == NULL) {
154300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        smsc= "00";
154400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
154500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
154600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd1, "AT+CMGS=%d", tpLayerLength);
154700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    asprintf(&cmd2, "%s%s", smsc, pdu);
154800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
154900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_sms(cmd1, cmd2, "+CMGS:", &p_response);
155000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
155100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0 || p_response->success == 0) goto error;
155200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
155300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* FIXME fill in messageRef and ackPDU */
1554a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    response.messageRef = 1;
155500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
155600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
155700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
155800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
155900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
1560a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    response.messageRef = -2;
1561a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response));
1562a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    at_response_free(p_response);
1563a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    return;
1564a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowaerror2:
1565a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    // send retry error.
1566a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    response.messageRef = -1;
1567a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
156800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
1569a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    return;
1570a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    }
1571a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1572a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowastatic void requestImsSendSMS(void *data, size_t datalen, RIL_Token t)
1573a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa{
1574a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RIL_IMS_SMS_Message *p_args;
1575a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RIL_SMS_Response response;
1576a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1577a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    memset(&response, 0, sizeof(response));
1578a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1579a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RLOGD("requestImsSendSMS: datalen=%d, "
1580a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        "registered=%d, service=%d, format=%d, ims_perm_fail=%d, "
1581a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        "ims_retry=%d, gsm_fail=%d, gsm_retry=%d",
1582a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        datalen, s_ims_registered, s_ims_services, s_ims_format,
1583a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        s_ims_cause_perm_failure, s_ims_cause_retry, s_ims_gsm_fail,
1584a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        s_ims_gsm_retry);
1585a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1586a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    // figure out if this is gsm/cdma format
1587a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    // then route it to requestSendSMS vs requestCdmaSendSMS respectively
1588a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    p_args = (RIL_IMS_SMS_Message *)data;
1589a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1590a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    if (0 != s_ims_cause_perm_failure ) goto error;
1591a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1592a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    // want to fail over ims and this is first request over ims
1593a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    if (0 != s_ims_cause_retry && 0 == p_args->retry) goto error2;
1594a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1595a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    if (RADIO_TECH_3GPP == p_args->tech) {
1596a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        return requestSendSMS(p_args->message.gsmMessage,
1597a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa                datalen - sizeof(RIL_RadioTechnologyFamily),
1598a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa                t);
1599a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    } else if (RADIO_TECH_3GPP2 == p_args->tech) {
1600a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        return requestCdmaSendSMS(p_args->message.cdmaMessage,
1601a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa                datalen - sizeof(RIL_RadioTechnologyFamily),
1602a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa                t);
1603a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    } else {
1604a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        RLOGE("requestImsSendSMS invalid format value =%d", p_args->tech);
1605a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    }
1606a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1607a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowaerror:
1608a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    response.messageRef = -2;
1609a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response));
1610a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    return;
1611a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
1612a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowaerror2:
1613a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    response.messageRef = -1;
1614a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
161500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
161600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1617f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Savillestatic void requestSetupDataCall(void *data, size_t datalen, RIL_Token t)
161800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
161900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *apn;
162000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd;
162100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
162200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
162300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1624f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville    apn = ((const char **)data)[2];
162500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
162600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef USE_TI_COMMANDS
162700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    // Config for multislot class 10 (probably default anyway eh?)
162800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command("AT%CPRIM=\"GMM\",\"CONFIG MULTISLOT_CLASS=<10>\"",
162900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                        NULL);
163000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
163100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command("AT%DATA=2,\"UART\",1,,\"SER\",\"UART\",0", NULL);
163200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* USE_TI_COMMANDS */
163300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
163400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int fd, qmistatus;
163500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    size_t cur = 0;
163600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    size_t len;
163700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ssize_t written, rlen;
163800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char status[32] = {0};
163900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int retry = 10;
16404f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti    const char *pdp_type;
164100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16424dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("requesting data connection to APN '%s'", apn);
164300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
164400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    fd = open ("/dev/qmi", O_RDWR);
164500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (fd >= 0) { /* the device doesn't exist on the emulator */
164600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16474dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGD("opened the qmi device\n");
16484f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        asprintf(&cmd, "up:%s", apn);
16494f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        len = strlen(cmd);
165000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16514f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        while (cur < len) {
16524f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti            do {
16534f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti                written = write (fd, cmd + cur, len - cur);
16544f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti            } while (written < 0 && errno == EINTR);
165500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16564f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti            if (written < 0) {
16574dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGE("### ERROR writing to /dev/qmi");
165800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                close(fd);
165900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                goto error;
166000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
166100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
166200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            cur += written;
166300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
166400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
166500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // wait for interface to come online
166600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
166700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        do {
166800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            sleep(1);
166900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            do {
167000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                rlen = read(fd, status, 31);
167100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } while (rlen < 0 && errno == EINTR);
167200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
167300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (rlen < 0) {
16744dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGE("### ERROR reading from /dev/qmi");
167500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                close(fd);
167600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                goto error;
167700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
167800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                status[rlen] = '\0';
16794dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGD("### status: %s", status);
168000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
168100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        } while (strncmp(status, "STATE=up", 8) && strcmp(status, "online") && --retry);
168200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
168300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        close(fd);
168400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
168500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (retry == 0) {
16864dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("### Failed to get data connection up\n");
16874f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti            goto error;
16884f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        }
168900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
169000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        qmistatus = system("netcfg rmnet0 dhcp");
169100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16924dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGD("netcfg rmnet0 dhcp: status %d\n", qmistatus);
169300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16944f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        if (qmistatus < 0) goto error;
16954f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti
16964f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti    } else {
169700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
16984f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        if (datalen > 6 * sizeof(char *)) {
16994f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti            pdp_type = ((const char **)data)[6];
17004f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        } else {
17014f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti            pdp_type = "IP";
17024f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        }
170300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1704af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turner        asprintf(&cmd, "AT+CGDCONT=1,\"%s\",\"%s\",,0,0", pdp_type, apn);
17054f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        //FIXME check for error here
17064f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        err = at_send_command(cmd, NULL);
17074f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        free(cmd);
170800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17094f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        // Set required QoS params to default
17104f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        err = at_send_command("AT+CGQREQ=1", NULL);
171100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17124f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        // Set minimum QoS params to default
17134f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        err = at_send_command("AT+CGQMIN=1", NULL);
171400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17154f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        // packet-domain event reporting
17164f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        err = at_send_command("AT+CGEREP=1,0", NULL);
171700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17184f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        // Hangup anything that's happening there now
17194f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        err = at_send_command("AT+CGACT=1,0", NULL);
172000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17214f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        // Start data on PDP context 1
17224f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        err = at_send_command("ATD*99***1#", &p_response);
172300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17244f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        if (err < 0 || p_response->success == 0) {
17254f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti            goto error;
17264f81dcf2a9bc84cbfbb6d3d658c452c22e9b6e83Lorenzo Colitti        }
172700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
172800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17294380897c6cdc99486a061b819943e3b290ebcf09Wink Saville    requestOrSendDataCallList(&t);
17304380897c6cdc99486a061b819943e3b290ebcf09Wink Saville
173100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
173200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
173300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
173400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
173500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
173600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
173700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
173800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
173900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
174000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void requestSMSAcknowledge(void *data, size_t datalen, RIL_Token t)
174100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
174200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ackSuccess;
174300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
174400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
174500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ackSuccess = ((int *)data)[0];
174600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
174700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (ackSuccess == 1) {
174800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_send_command("AT+CNMA=1", NULL);
174900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (ackSuccess == 0)  {
175000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_send_command("AT+CNMA=2", NULL);
175100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else {
17524dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGE("unsupported arg to RIL_REQUEST_SMS_ACKNOWLEDGE\n");
175300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
175400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
175500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
175600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
175700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
175800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
175900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
176000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
176100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
176200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void  requestSIM_IO(void *data, size_t datalen, RIL_Token t)
176300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
176400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
176500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_SIM_IO_Response sr;
176600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
176700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cmd = NULL;
17682c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    RIL_SIM_IO_v6 *p_args;
176900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line;
177000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
177100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    memset(&sr, 0, sizeof(sr));
177200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
17732c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    p_args = (RIL_SIM_IO_v6 *)data;
177400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
177500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* FIXME handle pin2 */
177600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
177700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (p_args->data == NULL) {
177800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d",
177900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_args->command, p_args->fileid,
178000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_args->p1, p_args->p2, p_args->p3);
178100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else {
178200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d,%s",
178300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_args->command, p_args->fileid,
178400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_args->p1, p_args->p2, p_args->p3, p_args->data);
178500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
178600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
178700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline(cmd, "+CRSM:", &p_response);
178800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
178900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
179000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
179100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
179200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
179300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
179400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
179500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
179600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
179700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
179800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &(sr.sw1));
179900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
180000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
180100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextint(&line, &(sr.sw2));
180200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
180300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
180400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (at_tok_hasmore(&line)) {
180500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        err = at_tok_nextstr(&line, &(sr.simResponse));
180600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err < 0) goto error;
180700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
180800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
180900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
181000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
181100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
181200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
181300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return;
181400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
181500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
181600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
181700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
181800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
181900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
182000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
182100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void  requestEnterSimPin(void*  data, size_t  datalen, RIL_Token  t)
182200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
182300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse   *p_response = NULL;
182400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int           err;
182500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char*         cmd = NULL;
182600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char**  strings = (const char**)data;;
182700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
182800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if ( datalen == sizeof(char*) ) {
182900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&cmd, "AT+CPIN=%s", strings[0]);
183000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if ( datalen == 2*sizeof(char*) ) {
183100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        asprintf(&cmd, "AT+CPIN=%s,%s", strings[0], strings[1]);
183200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else
183300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
183400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
183500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline(cmd, "+CPIN:", &p_response);
183600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    free(cmd);
183700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
183800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
183900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
184000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, NULL, 0);
184100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else {
184200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
184300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
184400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
184500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
184600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
184700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
184800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void  requestSendUSSD(void *data, size_t datalen, RIL_Token t)
184900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
185000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    const char *ussdRequest;
185100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
185200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ussdRequest = (char *)(data);
185300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
185400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
185500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
185600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
185700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project// @@@ TODO
185800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
185900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
186000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
1861e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void requestExitEmergencyMode(void *data, size_t datalen, RIL_Token t)
1862e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1863e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
1864e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
1865e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1866e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command("AT+WSOS=0", &p_response);
1867e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1868e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0 || p_response->success == 0) {
1869e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1870e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return;
1871e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
1872e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1873e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1874e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
1875e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
1876e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano// TODO: Use all radio types
1877e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic int techFromModemType(int mdmtype)
1878e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
1879e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int ret = -1;
1880e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    switch (1 << mdmtype) {
1881e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case MDM_CDMA:
1882e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            ret = RADIO_TECH_1xRTT;
1883e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
1884e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case MDM_EVDO:
1885e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            ret = RADIO_TECH_EVDO_A;
1886e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
1887e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case MDM_GSM:
1888e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            ret = RADIO_TECH_GPRS;
1889e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
1890e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case MDM_WCDMA:
1891e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            ret = RADIO_TECH_HSPA;
1892e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
1893e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case MDM_LTE:
1894e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            ret = RADIO_TECH_LTE;
1895e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
1896e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
1897e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return ret;
1898e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
189900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
19008a9e02161271505de274db0c3a88087056dd5dfcWink Savillestatic void requestGetCellInfoList(void *data, size_t datalen, RIL_Token t)
19018a9e02161271505de274db0c3a88087056dd5dfcWink Saville{
19028a9e02161271505de274db0c3a88087056dd5dfcWink Saville    uint64_t curTime = ril_nano_time();
19038a9e02161271505de274db0c3a88087056dd5dfcWink Saville    RIL_CellInfo ci[1] =
19048a9e02161271505de274db0c3a88087056dd5dfcWink Saville    {
19058a9e02161271505de274db0c3a88087056dd5dfcWink Saville        { // ci[0]
19068a9e02161271505de274db0c3a88087056dd5dfcWink Saville            1, // cellInfoType
19078a9e02161271505de274db0c3a88087056dd5dfcWink Saville            1, // registered
19088a9e02161271505de274db0c3a88087056dd5dfcWink Saville            curTime - 1000, // Fake some time in the past
19098a9e02161271505de274db0c3a88087056dd5dfcWink Saville            { // union CellInfo
19108a9e02161271505de274db0c3a88087056dd5dfcWink Saville                {  // RIL_CellInfoGsm gsm
19118a9e02161271505de274db0c3a88087056dd5dfcWink Saville                    {  // gsm.cellIdneityGsm
19128a9e02161271505de274db0c3a88087056dd5dfcWink Saville                        s_mcc, // mcc
19138a9e02161271505de274db0c3a88087056dd5dfcWink Saville                        s_mnc, // mnc
19148a9e02161271505de274db0c3a88087056dd5dfcWink Saville                        s_lac, // lac
19158a9e02161271505de274db0c3a88087056dd5dfcWink Saville                        s_cid, // cid
19168a9e02161271505de274db0c3a88087056dd5dfcWink Saville                        0  // psc
19178a9e02161271505de274db0c3a88087056dd5dfcWink Saville                    },
19188a9e02161271505de274db0c3a88087056dd5dfcWink Saville                    {  // gsm.signalStrengthGsm
19198a9e02161271505de274db0c3a88087056dd5dfcWink Saville                        10, // signalStrength
19208a9e02161271505de274db0c3a88087056dd5dfcWink Saville                        0  // bitErrorRate
19218a9e02161271505de274db0c3a88087056dd5dfcWink Saville                    }
19228a9e02161271505de274db0c3a88087056dd5dfcWink Saville                }
19238a9e02161271505de274db0c3a88087056dd5dfcWink Saville            }
19248a9e02161271505de274db0c3a88087056dd5dfcWink Saville        }
19258a9e02161271505de274db0c3a88087056dd5dfcWink Saville    };
19268a9e02161271505de274db0c3a88087056dd5dfcWink Saville
19278a9e02161271505de274db0c3a88087056dd5dfcWink Saville    RIL_onRequestComplete(t, RIL_E_SUCCESS, ci, sizeof(ci));
19288a9e02161271505de274db0c3a88087056dd5dfcWink Saville}
19298a9e02161271505de274db0c3a88087056dd5dfcWink Saville
19308a9e02161271505de274db0c3a88087056dd5dfcWink Saville
19318a9e02161271505de274db0c3a88087056dd5dfcWink Savillestatic void requestSetCellInfoListRate(void *data, size_t datalen, RIL_Token t)
19328a9e02161271505de274db0c3a88087056dd5dfcWink Saville{
19338a9e02161271505de274db0c3a88087056dd5dfcWink Saville    // For now we'll save the rate but no RIL_UNSOL_CELL_INFO_LIST messages
19348a9e02161271505de274db0c3a88087056dd5dfcWink Saville    // will be sent.
19358a9e02161271505de274db0c3a88087056dd5dfcWink Saville    assert (datalen == sizeof(int));
19368a9e02161271505de274db0c3a88087056dd5dfcWink Saville    s_cell_info_rate_ms = ((int *)data)[0];
19378a9e02161271505de274db0c3a88087056dd5dfcWink Saville
19388a9e02161271505de274db0c3a88087056dd5dfcWink Saville    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
19398a9e02161271505de274db0c3a88087056dd5dfcWink Saville}
19408a9e02161271505de274db0c3a88087056dd5dfcWink Saville
194100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/*** Callback methods from the RIL library to us ***/
194200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
194300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
194400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Call from RIL to us to make a RIL_REQUEST
194500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *
194600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Must be completed with a call to RIL_onRequestComplete()
194700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *
194800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * RIL_onRequestComplete() may be called from any thread, before or after
194900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * this function returns.
195000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *
195100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Will always be called from the same thread, so returning here implies
195200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * that the radio is ready to process another command (whether or not
195300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * the previous command has completed).
195400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
195500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void
195600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectonRequest (int request, void *data, size_t datalen, RIL_Token t)
195700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
195800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response;
195900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
196000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
19614dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("onRequest: %s", requestToString(request));
196200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
196300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* Ignore all requests except RIL_REQUEST_GET_SIM_STATUS
196400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * when RADIO_STATE_UNAVAILABLE.
196500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
196600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState == RADIO_STATE_UNAVAILABLE
196700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        && request != RIL_REQUEST_GET_SIM_STATUS
196800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
196900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
197000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
197100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
197200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
197300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* Ignore all non-power requests when RADIO_STATE_OFF
197400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * (except RIL_REQUEST_GET_SIM_STATUS)
197500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
197600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState == RADIO_STATE_OFF
197700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        && !(request == RIL_REQUEST_RADIO_POWER
197800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            || request == RIL_REQUEST_GET_SIM_STATUS)
197900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
198000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
198100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
198200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
198300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
198400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch (request) {
198500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_GET_SIM_STATUS: {
19862c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville            RIL_CardStatus_v6 *p_card_status;
1987f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            char *p_buffer;
1988f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            int buffer_size;
1989f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
1990f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            int result = getCardStatus(&p_card_status);
1991f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            if (result == RIL_E_SUCCESS) {
1992f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville                p_buffer = (char *)p_card_status;
1993f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville                buffer_size = sizeof(*p_card_status);
1994f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            } else {
1995f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville                p_buffer = NULL;
1996f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville                buffer_size = 0;
1997f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            }
1998f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            RIL_onRequestComplete(t, result, p_buffer, buffer_size);
1999f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville            freeCardStatus(p_card_status);
200000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
200100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
200200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_GET_CURRENT_CALLS:
200300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestGetCurrentCalls(data, datalen, t);
200400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
200500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_DIAL:
200600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestDial(data, datalen, t);
200700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
200800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_HANGUP:
200900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestHangup(data, datalen, t);
201000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
201100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
201200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // 3GPP 22.030 6.5.5
201300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // "Releases all held calls or sets User Determined User Busy
201400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            //  (UDUB) for a waiting call."
201500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+CHLD=0", NULL);
201600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
201700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
201800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
201900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
202000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
202100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
202200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // 3GPP 22.030 6.5.5
202300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // "Releases all active calls (if any exist) and accepts
202400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            //  the other (held or waiting) call."
202500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+CHLD=1", NULL);
202600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
202700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
202800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
202900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
203000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
203100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
203200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // 3GPP 22.030 6.5.5
203300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // "Places all active calls (if any exist) on hold and accepts
203400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            //  the other (held or waiting) call."
203500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+CHLD=2", NULL);
203600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
203700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
203800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            s_expectAnswer = 1;
203900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_ERRONEOUS_ANSWER */
204000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
204100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
204200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
204300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
204400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
204500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ANSWER:
204600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("ATA", NULL);
204700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
204800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_ERRONEOUS_ANSWER
204900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            s_expectAnswer = 1;
205000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_ERRONEOUS_ANSWER */
205100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
205200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
205300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
205400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
205500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
205600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_CONFERENCE:
205700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // 3GPP 22.030 6.5.5
205800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // "Adds a held call to the conversation"
205900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+CHLD=3", NULL);
206000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
206100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
206200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
206300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
206400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
206500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_UDUB:
206600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* user determined user busy */
206700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* sometimes used: ATH */
206800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("ATH", NULL);
206900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
207000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            /* success or failure is ignored by the upper layer here.
207100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project               it will call GET_CURRENT_CALLS and determine success that way */
207200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
207300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
207400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
207500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SEPARATE_CONNECTION:
207600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            {
207700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                char  cmd[12];
207800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                int   party = ((int*)data)[0];
207900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
208000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                // Make sure that party is in a valid range.
208100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                // (Note: The Telephony middle layer imposes a range of 1 to 7.
208200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                // It's sufficient for us to just make sure it's single digit.)
208300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if (party > 0 && party < 10) {
208400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    sprintf(cmd, "AT+CHLD=2%d", party);
208500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    at_send_command(cmd, NULL);
208600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
208700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                } else {
208800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
208900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                }
209000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
209100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
209200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
209300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SIGNAL_STRENGTH:
209400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSignalStrength(data, datalen, t);
209500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
20962c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        case RIL_REQUEST_VOICE_REGISTRATION_STATE:
20972c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville        case RIL_REQUEST_DATA_REGISTRATION_STATE:
209800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestRegistrationState(request, data, datalen, t);
209900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
210000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_OPERATOR:
210100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestOperator(data, datalen, t);
210200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
210300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_RADIO_POWER:
210400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestRadioPower(data, datalen, t);
210500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
210600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_DTMF: {
210700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            char c = ((char *)data)[0];
210800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            char *cmd;
210900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            asprintf(&cmd, "AT+VTS=%c", (int)c);
211000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command(cmd, NULL);
211100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            free(cmd);
211200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
211300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
211400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
211500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SEND_SMS:
211600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSendSMS(data, datalen, t);
211700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
2118e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_CDMA_SEND_SMS:
2119e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            requestCdmaSendSMS(data, datalen, t);
2120e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
2121a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        case RIL_REQUEST_IMS_SEND_SMS:
2122a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            requestImsSendSMS(data, datalen, t);
2123a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            break;
2124f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        case RIL_REQUEST_SETUP_DATA_CALL:
2125f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville            requestSetupDataCall(data, datalen, t);
212600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
212700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SMS_ACKNOWLEDGE:
212800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSMSAcknowledge(data, datalen, t);
212900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
213000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
213100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_GET_IMSI:
213200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_response = NULL;
213300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_send_command_numeric("AT+CIMI", &p_response);
213400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
213500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0 || p_response->success == 0) {
213600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
213700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
213800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_SUCCESS,
213900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_response->p_intermediates->line, sizeof(char *));
214000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
214100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_response_free(p_response);
214200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
214300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
214400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_GET_IMEI:
214500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_response = NULL;
214600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_send_command_numeric("AT+CGSN", &p_response);
214700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
214800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0 || p_response->success == 0) {
214900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
215000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
215100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_SUCCESS,
215200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_response->p_intermediates->line, sizeof(char *));
215300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
215400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_response_free(p_response);
215500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
215600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
215700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SIM_IO:
215800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSIM_IO(data,datalen,t);
215900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
216000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
216100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SEND_USSD:
216200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestSendUSSD(data, datalen, t);
216300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
216400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
216500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_CANCEL_USSD:
216600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_response = NULL;
216700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_send_command_numeric("AT+CUSD=2", &p_response);
216800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
216900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0 || p_response->success == 0) {
217000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
217100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
217200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_SUCCESS,
217300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    p_response->p_intermediates->line, sizeof(char *));
217400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
217500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_response_free(p_response);
217600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
217700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
217800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
217900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_send_command("AT+COPS=0", NULL);
218000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
218100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2182f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        case RIL_REQUEST_DATA_CALL_LIST:
2183f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville            requestDataCallList(data, datalen, t);
218400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
218500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
218600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
218700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestQueryNetworkSelectionMode(data, datalen, t);
218800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
218900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
219000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_OEM_HOOK_RAW:
219100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // echo back data
219200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
219300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
219400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
219500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
219600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_OEM_HOOK_STRINGS: {
219700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            int i;
219800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            const char ** cur;
219900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
22004dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGD("got OEM_HOOK_STRINGS: 0x%8p %lu", data, (long)datalen);
220100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
220200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
220300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            for (i = (datalen / sizeof (char *)), cur = (const char **)data ;
220400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    i > 0 ; cur++, i --) {
22054dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGD("> '%s'", *cur);
220600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
220700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
220800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            // echo back strings
220900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
221000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
221100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
221200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
221300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_WRITE_SMS_TO_SIM:
221400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestWriteSmsToSim(data, datalen, t);
221500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
221600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
221700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_DELETE_SMS_ON_SIM: {
221800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            char * cmd;
221900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            p_response = NULL;
222000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            asprintf(&cmd, "AT+CMGD=%d", ((int *)data)[0]);
222100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            err = at_send_command(cmd, &p_response);
222200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            free(cmd);
222300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (err < 0 || p_response->success == 0) {
222400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
222500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else {
222600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
222700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
222800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            at_response_free(p_response);
222900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
223000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
223100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
223200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ENTER_SIM_PIN:
223300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ENTER_SIM_PUK:
223400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ENTER_SIM_PIN2:
223500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_ENTER_SIM_PUK2:
223600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_CHANGE_SIM_PIN:
223700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case RIL_REQUEST_CHANGE_SIM_PIN2:
223800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            requestEnterSimPin(data, datalen, t);
223900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
224000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2241a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        case RIL_REQUEST_IMS_REGISTRATION_STATE: {
2242a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            int reply[2];
2243a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            //0==unregistered, 1==registered
2244a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            reply[0] = s_ims_registered;
2245a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
2246a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            //to be used when changed to include service supporated info
2247a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            //reply[1] = s_ims_services;
2248a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
2249a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            // FORMAT_3GPP(1) vs FORMAT_3GPP2(2);
2250a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            reply[1] = s_ims_format;
2251a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
2252a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            RLOGD("IMS_REGISTRATION=%d, format=%d ",
2253a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa                    reply[0], reply[1]);
2254a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            if (reply[1] != -1) {
2255a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa                RIL_onRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply));
2256a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            } else {
2257a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa                RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2258a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            }
2259a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            break;
2260a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa        }
2261a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
2262e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_VOICE_RADIO_TECH:
2263e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            {
2264e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                int tech = techFromModemType(TECH(sMdmInfo));
2265e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                if (tech < 0 )
2266e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2267e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                else
2268e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                    RIL_onRequestComplete(t, RIL_E_SUCCESS, &tech, sizeof(tech));
2269e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            }
2270e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
2271e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
2272e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            requestSetPreferredNetworkType(request, data, datalen, t);
2273e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
2274e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2275e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
2276e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            requestGetPreferredNetworkType(request, data, datalen, t);
2277e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
2278e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
22795802701949894c743dc95731091af94307c54bd0Jun Tian        case RIL_REQUEST_GET_CELL_INFO_LIST:
22805802701949894c743dc95731091af94307c54bd0Jun Tian            requestGetCellInfoList(data, datalen, t);
22815802701949894c743dc95731091af94307c54bd0Jun Tian            break;
22825802701949894c743dc95731091af94307c54bd0Jun Tian
22835802701949894c743dc95731091af94307c54bd0Jun Tian        case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
22845802701949894c743dc95731091af94307c54bd0Jun Tian            requestSetCellInfoListRate(data, datalen, t);
22855802701949894c743dc95731091af94307c54bd0Jun Tian            break;
22865802701949894c743dc95731091af94307c54bd0Jun Tian
2287e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        /* CDMA Specific Requests */
2288e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_BASEBAND_VERSION:
2289e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
2290e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                requestCdmaBaseBandVersion(request, data, datalen, t);
2291e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
2292e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            } // Fall-through if tech is not cdma
2293e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2294e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_DEVICE_IDENTITY:
2295e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
2296e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                requestCdmaDeviceIdentity(request, data, datalen, t);
2297e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
2298e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            } // Fall-through if tech is not cdma
2299e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2300e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_CDMA_SUBSCRIPTION:
2301e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
2302e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                requestCdmaSubscription(request, data, datalen, t);
2303e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
2304e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            } // Fall-through if tech is not cdma
2305e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2306e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
2307e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
2308e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                requestCdmaSetSubscriptionSource(request, data, datalen, t);
2309e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
2310e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            } // Fall-through if tech is not cdma
2311e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2312e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
2313e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
2314e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                requestCdmaGetSubscriptionSource(request, data, datalen, t);
2315e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
2316e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            } // Fall-through if tech is not cdma
2317e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2318e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
2319e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
2320e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                requestCdmaGetRoamingPreference(request, data, datalen, t);
2321e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
2322e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            } // Fall-through if tech is not cdma
2323e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2324e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
2325e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
2326e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                requestCdmaSetRoamingPreference(request, data, datalen, t);
2327e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
2328e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            } // Fall-through if tech is not cdma
2329e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2330e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
2331e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
2332e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                requestExitEmergencyMode(data, datalen, t);
2333e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
2334e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            } // Fall-through if tech is not cdma
2335e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
233600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
23374dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGD("Request not supported. Tech: %d",TECH(sMdmInfo));
233800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
233900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
234000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
234100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
234200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
234300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
234400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Synchronous call from the RIL to us to return current radio state.
234500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * RADIO_STATE_UNAVAILABLE should be the initial state.
234600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
234700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic RIL_RadioState
234800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectcurrentState()
234900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
235000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return sState;
235100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
235200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
235300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Call from RIL to us to find out whether a specific request code
235400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * is supported by this implementation.
235500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *
235600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Return 1 for "supported" and 0 for "unsupported"
235700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
235800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
235900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int
236000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectonSupports (int requestCode)
236100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
236200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    //@@@ todo
236300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
236400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return 1;
236500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
236600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
236700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onCancel (RIL_Token t)
236800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
236900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    //@@@todo
237000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
237100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
237200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
237300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic const char * getVersion(void)
237400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
237500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return "android reference-ril 1.0";
237600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
237700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
237800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void
2379e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-SollanosetRadioTechnology(ModemInfo *mdm, int newtech)
2380e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
23814dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("setRadioTechnology(%d)", newtech);
2382e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2383e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int oldtech = TECH(mdm);
2384e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2385e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (newtech != oldtech) {
23864dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGD("Tech change (%d => %d)", oldtech, newtech);
2387e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        TECH(mdm) = newtech;
2388e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (techFromModemType(newtech) != techFromModemType(oldtech)) {
2389e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            int tech = techFromModemType(TECH(sMdmInfo));
2390e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            if (tech > 0 ) {
2391e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                RIL_onUnsolicitedResponse(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
2392e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                          &tech, sizeof(tech));
2393e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            }
2394e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
2395e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2396e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
2397e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2398e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void
239900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectsetRadioState(RIL_RadioState newState)
240000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
24014dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("setRadioState(%d)", newState);
240200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_RadioState oldState;
240300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
240400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_mutex_lock(&s_state_mutex);
240500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
240600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    oldState = sState;
240700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
240800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (s_closed > 0) {
240900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // If we're closed, the only reasonable state is
241000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // RADIO_STATE_UNAVAILABLE
241100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // This is here because things on the main thread
241200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // may attempt to change the radio state after the closed
241300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // event happened in another thread
241400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        newState = RADIO_STATE_UNAVAILABLE;
241500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
241600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
241700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState != newState || s_closed > 0) {
241800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        sState = newState;
241900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
242000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        pthread_cond_broadcast (&s_state_cond);
242100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
242200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
242300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_mutex_unlock(&s_state_mutex);
242400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
242500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
242600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* do these outside of the mutex */
242700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState != oldState) {
242800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
242900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                                    NULL, 0);
243000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
243100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* FIXME onSimReady() and onRadioPowerOn() cannot be called
243200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * from the AT reader thread
243300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * Currently, this doesn't happen, but if that changes then these
243400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * will need to be dispatched on the request thread
243500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         */
2436e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (sState == RADIO_STATE_ON) {
243700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            onRadioPowerOn();
243800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
243900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
244000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
244100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2442e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano/** Returns RUIM_NOT_READY on error */
2443e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic SIM_Status
2444e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-SollanogetRUIMStatus()
2445e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
2446e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response = NULL;
2447e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
2448e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int ret;
2449e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *cpinLine;
2450e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *cpinResult;
2451e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2452e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (sState == RADIO_STATE_OFF || sState == RADIO_STATE_UNAVAILABLE) {
2453e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        ret = SIM_NOT_READY;
2454e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto done;
2455e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2456e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2457e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
2458e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2459e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err != 0) {
2460e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        ret = SIM_NOT_READY;
2461e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto done;
2462e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2463e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2464e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    switch (at_get_cme_error(p_response)) {
2465e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case CME_SUCCESS:
2466e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            break;
2467e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2468e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        case CME_SIM_NOT_INSERTED:
2469e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            ret = SIM_ABSENT;
2470e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            goto done;
2471e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2472e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        default:
2473e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            ret = SIM_NOT_READY;
2474e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            goto done;
2475e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2476e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2477e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    /* CPIN? has succeeded, now look at the result */
2478e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2479e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    cpinLine = p_response->p_intermediates->line;
2480e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_start (&cpinLine);
2481e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2482e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0) {
2483e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        ret = SIM_NOT_READY;
2484e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto done;
2485e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2486e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2487e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_nextstr(&cpinLine, &cpinResult);
2488e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2489e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err < 0) {
2490e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        ret = SIM_NOT_READY;
2491e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto done;
2492e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2493e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2494e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (0 == strcmp (cpinResult, "SIM PIN")) {
2495e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        ret = SIM_PIN;
2496e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto done;
2497e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else if (0 == strcmp (cpinResult, "SIM PUK")) {
2498e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        ret = SIM_PUK;
2499e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto done;
2500e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else if (0 == strcmp (cpinResult, "PH-NET PIN")) {
2501e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return SIM_NETWORK_PERSONALIZATION;
2502e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else if (0 != strcmp (cpinResult, "READY"))  {
2503e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        /* we're treating unsupported lock types as "sim absent" */
2504e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        ret = SIM_ABSENT;
2505e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto done;
2506e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2507e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2508e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    at_response_free(p_response);
2509e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    p_response = NULL;
2510e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    cpinResult = NULL;
2511e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2512e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ret = SIM_READY;
2513e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2514e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanodone:
2515e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    at_response_free(p_response);
2516e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return ret;
2517e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
2518e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2519309ac294bd529ff5a71f1c1e62cd493df1010271John Wang/** Returns SIM_NOT_READY on error */
2520af1298d72fd6a8b2d5bed7db15f6d181240fce83David 'Digit' Turnerstatic SIM_Status
252100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectgetSIMStatus()
252200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
252300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
252400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
252500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
252600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cpinLine;
252700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *cpinResult;
252800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
25294dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("getSIMStatus(). sState: %d",sState);
253000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState == RADIO_STATE_OFF || sState == RADIO_STATE_UNAVAILABLE) {
2531309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_NOT_READY;
253200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
253300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
253400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
253500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
253600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
253700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err != 0) {
2538309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_NOT_READY;
253900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
254000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
254100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
254200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch (at_get_cme_error(p_response)) {
254300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case CME_SUCCESS:
254400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
254500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
254600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        case CME_SIM_NOT_INSERTED:
2547309ac294bd529ff5a71f1c1e62cd493df1010271John Wang            ret = SIM_ABSENT;
254800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto done;
254900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
255000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
2551309ac294bd529ff5a71f1c1e62cd493df1010271John Wang            ret = SIM_NOT_READY;
255200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            goto done;
255300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
255400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
255500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* CPIN? has succeeded, now look at the result */
255600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
255700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    cpinLine = p_response->p_intermediates->line;
255800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start (&cpinLine);
255900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
256000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) {
2561309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_NOT_READY;
256200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
256300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
256400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
256500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextstr(&cpinLine, &cpinResult);
256600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
256700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) {
2568309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_NOT_READY;
256900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
257000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
257100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
257200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (0 == strcmp (cpinResult, "SIM PIN")) {
2573309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_PIN;
257400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
257500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (0 == strcmp (cpinResult, "SIM PUK")) {
2576309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_PUK;
257700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
257800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (0 == strcmp (cpinResult, "PH-NET PIN")) {
2579309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        return SIM_NETWORK_PERSONALIZATION;
258000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (0 != strcmp (cpinResult, "READY"))  {
258100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* we're treating unsupported lock types as "sim absent" */
2582309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        ret = SIM_ABSENT;
258300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto done;
258400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
258500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
258600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
258700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    p_response = NULL;
258800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    cpinResult = NULL;
258900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2590309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    ret = SIM_READY;
259100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
259200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectdone:
259300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
259400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return ret;
259500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
259600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
259700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
259800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
2599f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville * Get the current card status.
2600f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville *
2601f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville * This must be freed using freeCardStatus.
2602f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville * @return: On success returns RIL_E_SUCCESS
2603f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville */
26042c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Savillestatic int getCardStatus(RIL_CardStatus_v6 **pp_card_status) {
2605f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    static RIL_AppStatus app_status_array[] = {
2606309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_ABSENT = 0
2607f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
2608f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
2609309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_NOT_READY = 1
2610f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
2611f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
2612309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_READY = 2
2613f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
2614f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
2615309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_PIN = 3
2616f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
2617f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
2618309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_PUK = 4
2619f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
2620f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville          NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
2621309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        // SIM_NETWORK_PERSONALIZATION = 5
2622f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        { RIL_APPTYPE_SIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
2623e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano          NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
2624e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // RUIM_ABSENT = 6
2625e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
2626e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
2627e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // RUIM_NOT_READY = 7
2628e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        { RIL_APPTYPE_RUIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
2629e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
2630e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // RUIM_READY = 8
2631e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        { RIL_APPTYPE_RUIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
2632e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
2633e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // RUIM_PIN = 9
2634e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        { RIL_APPTYPE_RUIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
2635e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano          NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
2636e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // RUIM_PUK = 10
2637e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        { RIL_APPTYPE_RUIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
2638e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano          NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
2639e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // RUIM_NETWORK_PERSONALIZATION = 11
2640e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        { RIL_APPTYPE_RUIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
2641e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN }
2642f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    };
2643f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    RIL_CardState card_state;
2644f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    int num_apps;
2645f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
2646f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    int sim_status = getSIMStatus();
2647309ac294bd529ff5a71f1c1e62cd493df1010271John Wang    if (sim_status == SIM_ABSENT) {
2648f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        card_state = RIL_CARDSTATE_ABSENT;
2649f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        num_apps = 0;
2650f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    } else {
2651f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        card_state = RIL_CARDSTATE_PRESENT;
2652e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        num_apps = 2;
2653f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    }
2654f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
2655f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    // Allocate and initialize base card status.
26562c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    RIL_CardStatus_v6 *p_card_status = malloc(sizeof(RIL_CardStatus_v6));
2657f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->card_state = card_state;
2658f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->universal_pin_state = RIL_PINSTATE_UNKNOWN;
2659f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->gsm_umts_subscription_app_index = RIL_CARD_MAX_APPS;
2660f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->cdma_subscription_app_index = RIL_CARD_MAX_APPS;
26612c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville    p_card_status->ims_subscription_app_index = RIL_CARD_MAX_APPS;
2662f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    p_card_status->num_applications = num_apps;
2663f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
2664f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    // Initialize application status
2665f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    int i;
2666f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    for (i = 0; i < RIL_CARD_MAX_APPS; i++) {
2667309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        p_card_status->applications[i] = app_status_array[SIM_ABSENT];
2668f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    }
2669f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
2670f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    // Pickup the appropriate application status
2671f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    // that reflects sim_status for gsm.
2672f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    if (num_apps != 0) {
2673f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        // Only support one app, gsm
2674e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        p_card_status->num_applications = 2;
2675f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        p_card_status->gsm_umts_subscription_app_index = 0;
2676e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        p_card_status->cdma_subscription_app_index = 1;
2677f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
2678f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        // Get the correct app status
2679f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville        p_card_status->applications[0] = app_status_array[sim_status];
2680e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        p_card_status->applications[1] = app_status_array[sim_status + RUIM_ABSENT];
2681f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    }
2682f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
2683f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    *pp_card_status = p_card_status;
2684f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    return RIL_E_SUCCESS;
2685f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville}
2686f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
2687f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville/**
2688f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville * Free the card status returned by getCardStatus
2689f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville */
26902c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Savillestatic void freeCardStatus(RIL_CardStatus_v6 *p_card_status) {
2691f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville    free(p_card_status);
2692f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville}
2693f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville
2694f6aa7c1c8a9531a254970f85860d74cdd033821cWink Saville/**
269500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * SIM ready means any commands that access the SIM will work, including:
269600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *  AT+CPIN, AT+CSMS, AT+CNMI, AT+CRSM
269700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project *  (all SMS-related commands)
269800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
269900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
270000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void pollSIMState (void *param)
270100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
270200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response;
270300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
270400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
270500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState != RADIO_STATE_SIM_NOT_READY) {
270600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // no longer valid to poll
270700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
270800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
270900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
271000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    switch(getSIMStatus()) {
2711309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_ABSENT:
2712309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_PIN:
2713309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_PUK:
2714309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_NETWORK_PERSONALIZATION:
271500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        default:
27164dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGI("SIM ABSENT or LOCKED");
2717e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
271800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
271900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2720309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_NOT_READY:
272100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_requestTimedCallback (pollSIMState, NULL, &TIMEVAL_SIMPOLL);
272200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
272300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2724309ac294bd529ff5a71f1c1e62cd493df1010271John Wang        case SIM_READY:
27254dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGI("SIM_READY");
2726e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            onSIMReady();
2727e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
272800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
272900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
273000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
273100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
273200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/** returns 1 if on, 0 if off, and -1 on error */
273300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic int isRadioOn()
273400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
273500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
273600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
273700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char *line;
273800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    char ret;
273900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
274000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command_singleline("AT+CFUN?", "+CFUN:", &p_response);
274100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
274200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
274300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // assume radio is off
274400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        goto error;
274500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
274600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
274700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    line = p_response->p_intermediates->line;
274800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
274900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_start(&line);
275000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
275100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
275200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_tok_nextbool(&line, &ret);
275300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0) goto error;
275400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
275500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
275600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
275700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return (int)ret;
275800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
275900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projecterror:
276000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
276100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
276200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return -1;
276300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
276400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
276500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
2766e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * Parse the response generated by a +CTEC AT command
2767e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * The values read from the response are stored in current and preferred.
2768e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * Both current and preferred may be null. The corresponding value is ignored in that case.
2769e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano *
2770e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * @return: -1 if some error occurs (or if the modem doesn't understand the +CTEC command)
2771e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano *          1 if the response includes the current technology only
2772e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano *          0 if the response includes both current technology and preferred mode
2773e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano */
2774e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoint parse_technology_response( const char *response, int *current, int32_t *preferred )
2775e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
2776e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
2777e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line, *p;
2778e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int ct;
2779e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int32_t pt = 0;
2780e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *str_pt;
2781e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2782e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    line = p = strdup(response);
27834dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("Response: %s", line);
2784e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_start(&p);
2785e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err || !at_tok_hasmore(&p)) {
27864dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGD("err: %d. p: %s", err, p);
2787e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        free(line);
2788e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return -1;
2789e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2790e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2791e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_nextint(&p, &ct);
2792e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err) {
2793e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        free(line);
2794e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return -1;
2795e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2796e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (current) *current = ct;
2797e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
27984dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("line remaining after int: %s", p);
2799e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2800e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_nexthexint(&p, &pt);
2801e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err) {
2802e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        free(line);
2803e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return 1;
2804e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2805e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (preferred) {
2806e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        *preferred = pt;
2807e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2808e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    free(line);
2809e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2810e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return 0;
2811e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
2812e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2813e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoint query_supported_techs( ModemInfo *mdm, int *supported )
2814e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
2815e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *p_response;
2816e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err, val, techs = 0;
2817e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *tok;
2818e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line;
2819e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
28204dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("query_supported_techs");
2821e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command_singleline("AT+CTEC=?", "+CTEC:", &p_response);
2822e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err || !p_response->success)
2823e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto error;
2824e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    line = p_response->p_intermediates->line;
2825e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_tok_start(&line);
2826e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (err || !at_tok_hasmore(&line))
2827e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        goto error;
2828e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    while (!at_tok_nextint(&line, &val)) {
2829e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        techs |= ( 1 << val );
2830e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2831e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (supported) *supported = techs;
2832e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return 0;
2833e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoerror:
2834e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    at_response_free(p_response);
2835e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return -1;
2836e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
2837e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2838e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano/**
2839e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * query_ctec. Send the +CTEC AT command to the modem to query the current
2840e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * and preferred modes. It leaves values in the addresses pointed to by
2841e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * current and preferred. If any of those pointers are NULL, the corresponding value
2842e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * is ignored, but the return value will still reflect if retreiving and parsing of the
2843e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * values suceeded.
2844e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano *
2845e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * @mdm Currently unused
2846e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * @current A pointer to store the current mode returned by the modem. May be null.
2847e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * @preferred A pointer to store the preferred mode returned by the modem. May be null.
2848e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * @return -1 on error (or failure to parse)
2849e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano *         1 if only the current mode was returned by modem (or failed to parse preferred)
2850e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano *         0 if both current and preferred were returned correctly
2851e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano */
2852e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoint query_ctec(ModemInfo *mdm, int *current, int32_t *preferred)
2853e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
2854e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *response = NULL;
2855e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
2856e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int res;
2857e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
28584dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGD("query_ctec. current: %d, preferred: %d", (int)current, (int) preferred);
2859e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command_singleline("AT+CTEC?", "+CTEC:", &response);
2860e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!err && response->success) {
2861e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        res = parse_technology_response(response->p_intermediates->line, current, preferred);
2862e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        at_response_free(response);
2863e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return res;
2864e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
28654dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGE("Error executing command: %d. response: %x. status: %d", err, (int)response, response? response->success : -1);
2866e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    at_response_free(response);
2867e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return -1;
2868e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
2869e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2870e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanoint is_multimode_modem(ModemInfo *mdm)
2871e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
2872e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *response;
2873e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
2874e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line;
2875e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int tech;
2876e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int32_t preferred;
2877e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2878e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (query_ctec(mdm, &tech, &preferred) == 0) {
2879e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        mdm->currentTech = tech;
2880e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        mdm->preferredNetworkMode = preferred;
2881e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (query_supported_techs(mdm, &mdm->supportedTechs)) {
2882e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return 0;
2883e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
2884e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return 1;
2885e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2886e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    return 0;
2887e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
2888e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2889e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano/**
2890e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano * Find out if our modem is GSM, CDMA or both (Multimode)
2891e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano */
2892e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollanostatic void probeForModemMode(ModemInfo *info)
2893e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano{
2894e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    ATResponse *response;
2895e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    int err;
2896e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    assert (info);
2897e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // Currently, our only known multimode modem is qemu's android modem,
2898e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // which implements the AT+CTEC command to query and set mode.
2899e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // Try that first
2900e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2901e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (is_multimode_modem(info)) {
29024dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGI("Found Multimode Modem. Supported techs mask: %8.8x. Current tech: %d",
2903e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            info->supportedTechs, info->currentTech);
2904e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return;
2905e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2906e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2907e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    /* Being here means that our modem is not multimode */
2908e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    info->isMultimode = 0;
2909e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2910e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    /* CDMA Modems implement the AT+WNAM command */
2911e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    err = at_send_command_singleline("AT+WNAM","+WNAM:", &response);
2912e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!err && response->success) {
2913e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        at_response_free(response);
2914e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        // TODO: find out if we really support EvDo
2915e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        info->supportedTechs = MDM_CDMA | MDM_EVDO;
2916e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        info->currentTech = MDM_CDMA;
29174dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGI("Found CDMA Modem");
2918e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return;
2919e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
2920e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!err) at_response_free(response);
2921e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    // TODO: find out if modem really supports WCDMA/LTE
2922e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    info->supportedTechs = MDM_GSM | MDM_WCDMA | MDM_LTE;
2923e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    info->currentTech = MDM_GSM;
29244dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGI("Found GSM Modem");
2925e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano}
2926e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
2927e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano/**
292800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Initialize everything that can be configured while we're still in
292900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * AT+CFUN=0
293000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
293100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void initializeCallback(void *param)
293200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
293300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ATResponse *p_response = NULL;
293400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
293500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
293600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    setRadioState (RADIO_STATE_OFF);
293700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
293800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_handshake();
293900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
2940e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    probeForModemMode(sMdmInfo);
294100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* note: we don't check errors here. Everything important will
294200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project       be handled in onATTimeout and onATReaderClosed */
294300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
294400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  atchannel is tolerant of echo but it must */
294500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  have verbose result codes */
294600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("ATE0Q0V1", NULL);
294700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
294800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  No auto-answer */
294900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("ATS0=0", NULL);
295000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
295100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Extended errors */
295200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CMEE=1", NULL);
295300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
295400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Network registration events */
295500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    err = at_send_command("AT+CREG=2", &p_response);
295600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
295700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* some handsets -- in tethered mode -- don't support CREG=2 */
295800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (err < 0 || p_response->success == 0) {
295900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        at_send_command("AT+CREG=1", NULL);
296000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
296100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
296200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_response_free(p_response);
296300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
296400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  GPRS registration events */
296500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CGREG=1", NULL);
296600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
296700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Call Waiting notifications */
296800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CCWA=1", NULL);
296900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
297000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Alternating voice/data off */
297100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CMOD=0", NULL);
297200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
297300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Not muted */
297400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CMUT=0", NULL);
297500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
297600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  +CSSU unsolicited supp service notifications */
297700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CSSN=0,1", NULL);
297800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
297900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  no connected line identification */
298000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+COLP=0", NULL);
298100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
298200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  HEX character set */
298300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CSCS=\"HEX\"", NULL);
298400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
298500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  USSD unsolicited */
298600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CUSD=1", NULL);
298700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
298800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  Enable +CGEV GPRS event notifications, but don't buffer */
298900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CGEREP=1,0", NULL);
299000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
299100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  SMS PDU mode */
299200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT+CMGF=0", NULL);
299300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
299400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef USE_TI_COMMANDS
299500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
299600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT%CPI=3", NULL);
299700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
299800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /*  TI specific -- notifications when SMS is ready (currently ignored) */
299900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_send_command("AT%CSTAT=1", NULL);
300000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
300100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* USE_TI_COMMANDS */
300200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
300300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
300400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* assume radio is off on error */
300500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (isRadioOn() > 0) {
3006e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        setRadioState (RADIO_STATE_ON);
300700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
300800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
300900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
301000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void waitForClose()
301100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
301200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_mutex_lock(&s_state_mutex);
301300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
301400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    while (s_closed == 0) {
301500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        pthread_cond_wait(&s_state_cond, &s_state_mutex);
301600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
301700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
301800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_mutex_unlock(&s_state_mutex);
301900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
302000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
3021a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowastatic void sendUnsolImsNetworkStateChanged()
3022a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa{
3023a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa#if 0 // to be used when unsol is changed to return data.
3024a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    int reply[2];
3025a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    reply[0] = s_ims_registered;
3026a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    reply[1] = s_ims_services;
3027a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    reply[1] = s_ims_format;
3028a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa#endif
3029a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa    RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED,
3030a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa            NULL, 0);
3031a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa}
3032a18b9d1e1a014290691d63a7f335085dadc83e46Sukanya Rajkhowa
303300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/**
303400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * Called by atchannel when an unsolicited line appears
303500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * This is called on atchannel's reader thread. AT commands may
303600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project * not be issued here
303700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project */
303800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onUnsolicited (const char *s, const char *sms_pdu)
303900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
3040e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    char *line = NULL, *p;
304100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int err;
304200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
304300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* Ignore unsolicited responses until we're initialized.
304400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     * This is OK because the RIL library will poll for initial state
304500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project     */
304600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (sState == RADIO_STATE_UNAVAILABLE) {
304700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return;
304800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
304900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
305000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (strStartsWith(s, "%CTZV:")) {
305100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* TI specific -- NITZ time */
305200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        char *response;
305300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
3054e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        line = p = strdup(s);
3055e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        at_tok_start(&p);
305600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
3057e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        err = at_tok_nextstr(&p, &response);
305800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
3059e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        free(line);
306000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (err != 0) {
30614dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("invalid NITZ line %s\n", s);
306200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        } else {
306300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_onUnsolicitedResponse (
306400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                RIL_UNSOL_NITZ_TIME_RECEIVED,
306500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                response, strlen(response));
306600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
306700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s,"+CRING:")
306800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                || strStartsWith(s,"RING")
306900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                || strStartsWith(s,"NO CARRIER")
307000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                || strStartsWith(s,"+CCWA")
307100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
307200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (
307300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
307400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            NULL, 0);
307500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_FAKE_CGEV
3076f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL); //TODO use new function
307700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_FAKE_CGEV */
307800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s,"+CREG:")
307900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                || strStartsWith(s,"+CGREG:")
308000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ) {
308100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (
30822c1fb3a4e7aa8039bdefacceec98aa43cfe5784cWink Saville            RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
308300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            NULL, 0);
308400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_FAKE_CGEV
30857f8568086f2ea14885b0091c793e14c2656f0da2Wink Saville        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
308600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_FAKE_CGEV */
308700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s, "+CMT:")) {
308800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (
308900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_UNSOL_RESPONSE_NEW_SMS,
309000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            sms_pdu, strlen(sms_pdu));
309100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s, "+CDS:")) {
309200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_onUnsolicitedResponse (
309300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
309400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            sms_pdu, strlen(sms_pdu));
309500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s, "+CGEV:")) {
309600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* Really, we can ignore NW CLASS and ME CLASS events here,
309700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         * but right now we don't since extranous
3098f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville         * RIL_UNSOL_DATA_CALL_LIST_CHANGED calls are tolerated
309900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project         */
310000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        /* can't issue AT commands here -- call on main thread */
3101f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
310200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef WORKAROUND_FAKE_CGEV
310300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    } else if (strStartsWith(s, "+CME ERROR: 150")) {
3104f4c4d36c410a3501d282dd7de1c7c3350734f27eWink Saville        RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
310500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* WORKAROUND_FAKE_CGEV */
3106e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else if (strStartsWith(s, "+CTEC: ")) {
3107e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        int tech, mask;
3108e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        switch (parse_technology_response(s, &tech, NULL))
3109e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        {
3110e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            case -1: // no argument could be parsed.
31114dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGE("invalid CTEC line %s\n", s);
3112e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
3113e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            case 1: // current mode correctly parsed
3114e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            case 0: // preferred mode correctly parsed
3115e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                mask = 1 << tech;
3116e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                if (mask != MDM_GSM && mask != MDM_CDMA &&
3117e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                     mask != MDM_WCDMA && mask != MDM_LTE) {
31184dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                    RLOGE("Unknown technology %d\n", tech);
3119e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                } else {
3120e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                    setRadioTechnology(sMdmInfo, tech);
3121e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                }
3122e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                break;
3123e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3124e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else if (strStartsWith(s, "+CCSS: ")) {
3125e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        int source = 0;
3126e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        line = p = strdup(s);
3127e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (!line) {
31284dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("+CCSS: Unable to allocate memory");
3129e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
3130e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3131e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (at_tok_start(&p) < 0) {
3132e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            free(line);
3133e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
3134e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3135e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (at_tok_nextint(&p, &source) < 0) {
31364dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("invalid +CCSS response: %s", line);
3137e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            free(line);
3138e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
3139e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3140e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        SSOURCE(sMdmInfo) = source;
3141e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
3142e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                                  &source, sizeof(source));
3143e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else if (strStartsWith(s, "+WSOS: ")) {
3144e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        char state = 0;
3145e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        int unsol;
3146e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        line = p = strdup(s);
3147e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (!line) {
31484dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("+WSOS: Unable to allocate memory");
3149e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
3150e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3151e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (at_tok_start(&p) < 0) {
3152e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            free(line);
3153e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
3154e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3155e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (at_tok_nextbool(&p, &state) < 0) {
31564dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("invalid +WSOS response: %s", line);
3157e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            free(line);
3158e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
3159e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3160e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        free(line);
3161e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
3162e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        unsol = state ?
3163e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano                RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE : RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE;
3164e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
3165e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        RIL_onUnsolicitedResponse(unsol, NULL, 0);
3166e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano
3167e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else if (strStartsWith(s, "+WPRL: ")) {
3168e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        int version = -1;
3169e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        line = p = strdup(s);
3170e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (!line) {
31714dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("+WPRL: Unable to allocate memory");
3172e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
3173e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3174e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (at_tok_start(&p) < 0) {
31754dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("invalid +WPRL response: %s", s);
3176e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            free(line);
3177e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
3178e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3179e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        if (at_tok_nextint(&p, &version) < 0) {
31804dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE("invalid +WPRL response: %s", s);
3181e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            free(line);
3182e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano            return;
3183e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        }
3184e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        free(line);
3185e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_PRL_CHANGED, &version, sizeof(version));
3186e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    } else if (strStartsWith(s, "+CFUN: 0")) {
3187e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        setRadioState(RADIO_STATE_OFF);
318800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
318900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
319000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
319100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/* Called on command or reader thread */
319200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onATReaderClosed()
319300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
31944dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGI("AT channel closed\n");
319500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_close();
319600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_closed = 1;
319700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
319800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    setRadioState (RADIO_STATE_UNAVAILABLE);
319900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
320000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
320100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project/* Called on command thread */
320200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void onATTimeout()
320300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
32044dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville    RLOGI("AT channel timeout; closing\n");
320500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_close();
320600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
320700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_closed = 1;
320800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
320900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    /* FIXME cause a radio reset here */
321000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
321100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    setRadioState (RADIO_STATE_UNAVAILABLE);
321200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
321300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
321400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void usage(char *s)
321500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
321600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef RIL_SHLIB
321700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    fprintf(stderr, "reference-ril requires: -p <tcp port> or -d /dev/tty_device\n");
321800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#else
321900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    fprintf(stderr, "usage: %s [-p <tcp port>] [-d /dev/tty_device]\n", s);
322000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    exit(-1);
322100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif
322200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
322300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
322400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectstatic void *
322500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source ProjectmainLoop(void *param)
322600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
322700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int fd;
322800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
322900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
323000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    AT_DUMP("== ", "entering mainLoop()", -1 );
323100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_set_on_reader_closed(onATReaderClosed);
323200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    at_set_on_timeout(onATTimeout);
323300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
323400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    for (;;) {
323500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        fd = -1;
323600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        while  (fd < 0) {
323700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (s_port > 0) {
323800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                fd = socket_loopback_client(s_port, SOCK_STREAM);
323900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else if (s_device_socket) {
3240e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                if (!strcmp(s_device_path, "/dev/socket/qemud")) {
3241385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                    /* Before trying to connect to /dev/socket/qemud (which is
3242385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                     * now another "legacy" way of communicating with the
3243385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                     * emulator), we will try to connecto to gsm service via
3244385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                     * qemu pipe. */
3245385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                    fd = qemu_pipe_open("qemud:gsm");
3246385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                    if (fd < 0) {
3247385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                        /* Qemu-specific control socket */
3248385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                        fd = socket_local_client( "qemud",
3249385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                                                  ANDROID_SOCKET_NAMESPACE_RESERVED,
3250385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                                                  SOCK_STREAM );
3251385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                        if (fd >= 0 ) {
3252385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                            char  answer[2];
3253385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine
3254385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                            if ( write(fd, "gsm", 3) != 3 ||
3255385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                                 read(fd, answer, 2) != 2 ||
3256385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                                 memcmp(answer, "OK", 2) != 0)
3257385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                            {
3258385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                                close(fd);
3259385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                                fd = -1;
3260385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                            }
3261385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                       }
3262385a73934b05fd28915e0ae17020dbfe3b20afd4Vladimir Chtchetkine                    }
3263e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                }
3264e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                else
3265e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                    fd = socket_local_client( s_device_path,
3266e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                                            ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
3267e6e6fb2ebbaae681ab45b866bb9bba57aff1c33cThe Android Open Source Project                                            SOCK_STREAM );
326800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            } else if (s_device_path != NULL) {
326900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                fd = open (s_device_path, O_RDWR);
327000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
327100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    /* disable echo on serial ports */
327200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    struct termios  ios;
327300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    tcgetattr( fd, &ios );
327400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    ios.c_lflag = 0;  /* disable ECHO, ICANON, etc... */
327500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    tcsetattr( fd, TCSANOW, &ios );
327600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                }
327700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
327800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
327900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            if (fd < 0) {
328000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                perror ("opening AT interface. retrying...");
328100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                sleep(10);
328200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                /* never returns */
328300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            }
328400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
328500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
328600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        s_closed = 0;
328700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        ret = at_open(fd, onUnsolicited);
328800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
328900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        if (ret < 0) {
32904dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville            RLOGE ("AT error %d on at_open\n", ret);
329100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            return 0;
329200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
329300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
329400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);
329500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
329600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // Give initializeCallback a chance to dispatched, since
329700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        // we don't presently have a cancellation mechanism
329800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        sleep(1);
329900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
330000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        waitForClose();
33014dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGI("Re-opening after close");
330200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
330300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
330400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
330500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#ifdef RIL_SHLIB
330600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
330700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectpthread_t s_tid_mainloop;
330800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
330900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectconst RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
331000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
331100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
331200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int fd = -1;
331300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int opt;
331400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_attr_t attr;
331500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
331600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    s_rilenv = env;
331700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
331800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    while ( -1 != (opt = getopt(argc, argv, "p:d:s:"))) {
331900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        switch (opt) {
332000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 'p':
332100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_port = atoi(optarg);
332200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if (s_port == 0) {
332300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    usage(argv[0]);
332400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    return NULL;
332500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                }
33264dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGI("Opening loopback port %d\n", s_port);
332700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
332800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
332900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 'd':
333000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_path = optarg;
33314dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGI("Opening tty device %s\n", s_device_path);
333200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
333300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
333400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 's':
333500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_path   = optarg;
333600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_socket = 1;
33374dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGI("Opening socket %s\n", s_device_path);
333800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
333900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
334000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            default:
334100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                usage(argv[0]);
334200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                return NULL;
334300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
334400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
334500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
334600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (s_port < 0 && s_device_path == NULL) {
334700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        usage(argv[0]);
334800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        return NULL;
334900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
335000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
3351e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    sMdmInfo = calloc(1, sizeof(ModemInfo));
3352e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    if (!sMdmInfo) {
33534dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville        RLOGE("Unable to alloc memory for ModemInfo");
3354e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano        return NULL;
3355e9645049ba5ec9081b208f92400669613c2a8aa7Jaime A Lopez-Sollano    }
335600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_attr_init (&attr);
335700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
335800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);
335900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
336000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return &s_callbacks;
336100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
336200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#else /* RIL_SHLIB */
336300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Projectint main (int argc, char **argv)
336400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project{
336500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int ret;
336600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int fd = -1;
336700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    int opt;
336800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
336900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    while ( -1 != (opt = getopt(argc, argv, "p:d:"))) {
337000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        switch (opt) {
337100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 'p':
337200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_port = atoi(optarg);
337300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                if (s_port == 0) {
337400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                    usage(argv[0]);
337500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                }
33764dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGI("Opening loopback port %d\n", s_port);
337700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
337800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
337900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 'd':
338000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_path = optarg;
33814dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGI("Opening tty device %s\n", s_device_path);
338200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
338300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
338400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            case 's':
338500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_path   = optarg;
338600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                s_device_socket = 1;
33874dcab4f90d2d49e40100e4888b1411dfbd1c9783Wink Saville                RLOGI("Opening socket %s\n", s_device_path);
338800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            break;
338900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
339000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project            default:
339100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project                usage(argv[0]);
339200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        }
339300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
339400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
339500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    if (s_port < 0 && s_device_path == NULL) {
339600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project        usage(argv[0]);
339700f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    }
339800f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
339900f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    RIL_register(&s_callbacks);
340000f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
340100f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    mainLoop(NULL);
340200f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
340300f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project    return 0;
340400f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project}
340500f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project
340600f06fc3fdb05d4276e76091cacb42b6f6862222The Android Open Source Project#endif /* RIL_SHLIB */
3407