1 /* //device/system/reference-ril/reference-ril.c
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include <telephony/ril_cdma_sms.h>
19 #include <telephony/librilutils.h>
20 #include <stdio.h>
21 #include <assert.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <unistd.h>
25 #include <sys/cdefs.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <inttypes.h>
29 #include <fcntl.h>
30 #include <pthread.h>
31 #include <alloca.h>
32 #include "atchannel.h"
33 #include "at_tok.h"
34 #include "misc.h"
35 #include <getopt.h>
36 #include <sys/socket.h>
37 #include <cutils/properties.h>
38 #include <cutils/sockets.h>
39 #include <termios.h>
40 #include <qemu_pipe.h>
41 #include <sys/wait.h>
42 #include <stdbool.h>
43 #include <net/if.h>
44 #include <netinet/in.h>
45 #include <linux/vm_sockets.h>
46 #include <arpa/inet.h>
47
48 #include "guest/hals/ril/reference-libril/ril.h"
49 #define LOG_TAG "RIL"
50 #include <utils/Log.h>
51
noopRemoveWarning(void * a)52 static void *noopRemoveWarning( void *a ) { return a; }
53 #define RIL_UNUSED_PARM(a) noopRemoveWarning((void *)&(a));
54
55 #define MAX_AT_RESPONSE 0x1000
56
57 #define MAX_PDP 3
58
59 /* pathname returned from RIL_REQUEST_SETUP_DATA_CALL / RIL_REQUEST_SETUP_DEFAULT_PDP */
60 // This is used if Wifi is not supported, plain old eth0
61 #define PPP_TTY_PATH_ETH0 "eth0"
62 // This is used if Wifi is supported to separate radio and wifi interface
63 #define PPP_TTY_PATH_RADIO0 "radio0"
64
65 // Default MTU value
66 #define DEFAULT_MTU 1500
67
68 #ifdef USE_TI_COMMANDS
69
70 // Enable a workaround
71 // 1) Make incoming call, do not answer
72 // 2) Hangup remote end
73 // Expected: call should disappear from CLCC line
74 // Actual: Call shows as "ACTIVE" before disappearing
75 #define WORKAROUND_ERRONEOUS_ANSWER 1
76
77 // Some variants of the TI stack do not support the +CGEV unsolicited
78 // response. However, they seem to send an unsolicited +CME ERROR: 150
79 #define WORKAROUND_FAKE_CGEV 1
80 #endif
81
82 /* Modem Technology bits */
83 #define MDM_GSM 0x01
84 #define MDM_WCDMA 0x02
85 #define MDM_CDMA 0x04
86 #define MDM_EVDO 0x08
87 #define MDM_TDSCDMA 0x10
88 #define MDM_LTE 0x20
89 #define MDM_NR 0x40
90
91 typedef struct {
92 int supportedTechs; // Bitmask of supported Modem Technology bits
93 int currentTech; // Technology the modem is currently using (in the format used by modem)
94 int isMultimode;
95
96 // Preferred mode bitmask. This is actually 4 byte-sized bitmasks with different priority values,
97 // in which the byte number from LSB to MSB give the priority.
98 //
99 // |MSB| | |LSB
100 // value: |00 |00 |00 |00
101 // byte #: |3 |2 |1 |0
102 //
103 // Higher byte order give higher priority. Thus, a value of 0x0000000f represents
104 // a preferred mode of GSM, WCDMA, CDMA, and EvDo in which all are equally preferrable, whereas
105 // 0x00000201 represents a mode with GSM and WCDMA, in which WCDMA is preferred over GSM
106 int32_t preferredNetworkMode;
107 int subscription_source;
108
109 } ModemInfo;
110
111 static ModemInfo *sMdmInfo;
112 // TECH returns the current technology in the format used by the modem.
113 // It can be used as an l-value
114 #define TECH(mdminfo) ((mdminfo)->currentTech)
115 // TECH_BIT returns the bitmask equivalent of the current tech
116 #define TECH_BIT(mdminfo) (1 << ((mdminfo)->currentTech))
117 #define IS_MULTIMODE(mdminfo) ((mdminfo)->isMultimode)
118 #define TECH_SUPPORTED(mdminfo, tech) ((mdminfo)->supportedTechs & (tech))
119 #define PREFERRED_NETWORK(mdminfo) ((mdminfo)->preferredNetworkMode)
120 // CDMA Subscription Source
121 #define SSOURCE(mdminfo) ((mdminfo)->subscription_source)
122
123 static int net2modem[] = {
124 MDM_GSM | MDM_WCDMA, // 0 - GSM / WCDMA Pref
125 MDM_GSM, // 1 - GSM only
126 MDM_WCDMA, // 2 - WCDMA only
127 MDM_GSM | MDM_WCDMA, // 3 - GSM / WCDMA Auto
128 MDM_CDMA | MDM_EVDO, // 4 - CDMA / EvDo Auto
129 MDM_CDMA, // 5 - CDMA only
130 MDM_EVDO, // 6 - EvDo only
131 MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO, // 7 - GSM/WCDMA, CDMA, EvDo
132 MDM_LTE | MDM_CDMA | MDM_EVDO, // 8 - LTE, CDMA and EvDo
133 MDM_LTE | MDM_GSM | MDM_WCDMA, // 9 - LTE, GSM/WCDMA
134 MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
135 MDM_LTE, // 11 - LTE only
136 MDM_LTE | MDM_WCDMA, // 12 - LTE and WCDMA
137 MDM_TDSCDMA, // 13 - TD-SCDMA only
138 MDM_WCDMA | MDM_TDSCDMA, // 14 - TD-SCDMA and WCDMA
139 MDM_LTE | MDM_TDSCDMA, // 15 - LTE and TD-SCDMA
140 MDM_TDSCDMA | MDM_GSM, // 16 - TD-SCDMA and GSM
141 MDM_LTE | MDM_TDSCDMA | MDM_GSM, // 17 - TD-SCDMA, GSM and LTE
142 MDM_WCDMA | MDM_TDSCDMA | MDM_GSM, // 18 - TD-SCDMA, GSM and WCDMA
143 MDM_LTE | MDM_WCDMA | MDM_TDSCDMA, // 19 - LTE, TD-SCDMA and WCDMA
144 MDM_LTE | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM, // 20 - LTE, TD-SCDMA, GSM, and WCDMA
145 MDM_EVDO | MDM_CDMA | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM, // 21 - TD-SCDMA, CDMA, EVDO, GSM and WCDMA
146 MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM, // 22 - LTE, TDCSDMA, CDMA, EVDO, GSM and WCDMA
147 MDM_NR, // 23 - NR 5G only mode
148 MDM_NR | MDM_LTE, // 24 - NR 5G, LTE
149 MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO, // 25 - NR 5G, LTE, CDMA and EvDo
150 MDM_NR | MDM_LTE | MDM_WCDMA | MDM_GSM, // 26 - NR 5G, LTE, GSM and WCDMA
151 MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM, // 27 - NR 5G, LTE, CDMA, EvDo, GSM and WCDMA
152 MDM_NR | MDM_LTE | MDM_WCDMA, // 28 - NR 5G, LTE and WCDMA
153 MDM_NR | MDM_LTE | MDM_TDSCDMA, // 29 - NR 5G, LTE and TDSCDMA
154 MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_GSM, // 30 - NR 5G, LTE, TD-SCDMA and GSM
155 MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA, // 31 - NR 5G, LTE, TD-SCDMA, WCDMA
156 MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA | MDM_GSM, // 32 - NR 5G, LTE, TD-SCDMA, GSM and WCDMA
157 MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM, // 33 - NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA
158 };
159
160 static int32_t net2pmask[] = {
161 MDM_GSM | (MDM_WCDMA << 8), // 0 - GSM / WCDMA Pref
162 MDM_GSM, // 1 - GSM only
163 MDM_WCDMA, // 2 - WCDMA only
164 MDM_GSM | MDM_WCDMA, // 3 - GSM / WCDMA Auto
165 MDM_CDMA | MDM_EVDO, // 4 - CDMA / EvDo Auto
166 MDM_CDMA, // 5 - CDMA only
167 MDM_EVDO, // 6 - EvDo only
168 MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO, // 7 - GSM/WCDMA, CDMA, EvDo
169 MDM_LTE | MDM_CDMA | MDM_EVDO, // 8 - LTE, CDMA and EvDo
170 MDM_LTE | MDM_GSM | MDM_WCDMA, // 9 - LTE, GSM/WCDMA
171 MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
172 MDM_LTE, // 11 - LTE only
173 MDM_LTE | MDM_WCDMA, // 12 - LTE and WCDMA
174 MDM_TDSCDMA, // 13 - TD-SCDMA only
175 MDM_WCDMA | MDM_TDSCDMA, // 14 - TD-SCDMA and WCDMA
176 MDM_LTE | MDM_TDSCDMA, // 15 - LTE and TD-SCDMA
177 MDM_TDSCDMA | MDM_GSM, // 16 - TD-SCDMA and GSM
178 MDM_LTE | MDM_TDSCDMA | MDM_GSM, // 17 - TD-SCDMA, GSM and LTE
179 MDM_WCDMA | MDM_TDSCDMA | MDM_GSM, // 18 - TD-SCDMA, GSM and WCDMA
180 MDM_LTE | MDM_WCDMA | MDM_TDSCDMA, // 19 - LTE, TD-SCDMA and WCDMA
181 MDM_LTE | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM, // 20 - LTE, TD-SCDMA, GSM, and WCDMA
182 MDM_EVDO | MDM_CDMA | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM, // 21 - TD-SCDMA, CDMA, EVDO, GSM and WCDMA
183 MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM, // 22 - LTE, TDCSDMA, CDMA, EVDO, GSM and WCDMA
184 MDM_NR, // 23 - NR 5G only mode
185 MDM_NR | MDM_LTE, // 24 - NR 5G, LTE
186 MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO, // 25 - NR 5G, LTE, CDMA and EvDo
187 MDM_NR | MDM_LTE | MDM_WCDMA | MDM_GSM, // 26 - NR 5G, LTE, GSM and WCDMA
188 MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM, // 27 - NR 5G, LTE, CDMA, EvDo, GSM and WCDMA
189 MDM_NR | MDM_LTE | MDM_WCDMA, // 28 - NR 5G, LTE and WCDMA
190 MDM_NR | MDM_LTE | MDM_TDSCDMA, // 29 - NR 5G, LTE and TDSCDMA
191 MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_GSM, // 30 - NR 5G, LTE, TD-SCDMA and GSM
192 MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA, // 31 - NR 5G, LTE, TD-SCDMA, WCDMA
193 MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA | MDM_GSM, // 32 - NR 5G, LTE, TD-SCDMA, GSM and WCDMA
194 MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM, // 33 - NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA
195 };
196
197 #define GSM (RAF_GSM | RAF_GPRS | RAF_EDGE)
198 #define CDMA (RAF_IS95A | RAF_IS95B | RAF_1xRTT)
199 #define EVDO (RAF_EVDO_0 | RAF_EVDO_A | RAF_EVDO_B | RAF_EHRPD)
200 #define WCDMA (RAF_HSUPA | RAF_HSDPA | RAF_HSPA | RAF_HSPAP | RAF_UMTS)
201 #define LTE (RAF_LTE | RAF_LTE_CA)
202 #define NR (RAF_NR)
203
204 typedef struct {
205 int bitmap;
206 int type;
207 } NetworkTypeBitmap;
208
209 static NetworkTypeBitmap s_networkMask[] = {
210 {WCDMA | GSM, MDM_GSM | (MDM_WCDMA << 8)}, // 0 - GSM / WCDMA Pref
211 {GSM, MDM_GSM}, // 1 - GSM only
212 {WCDMA, MDM_WCDMA}, // 2 - WCDMA only
213 {WCDMA | GSM, MDM_GSM | MDM_WCDMA}, // 3 - GSM / WCDMA Auto
214 {CDMA | EVDO, MDM_CDMA | MDM_EVDO}, // 4 - CDMA / EvDo Auto
215 {CDMA, MDM_CDMA}, // 5 - CDMA only
216 {EVDO, MDM_EVDO}, // 6 - EvDo only
217 {GSM | WCDMA | CDMA | EVDO, MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO}, // 7 - GSM/WCDMA, CDMA, EvDo
218 {LTE | CDMA | EVDO, MDM_LTE | MDM_CDMA | MDM_EVDO}, // 8 - LTE, CDMA and EvDo
219 {LTE | GSM | WCDMA, MDM_LTE | MDM_GSM | MDM_WCDMA}, // 9 - LTE, GSM/WCDMA
220 {LTE | CDMA | EVDO | GSM | WCDMA, MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA}, // 10 - LTE, CDMA, EvDo, GSM/WCDMA
221 {LTE, MDM_LTE}, // 11 - LTE only
222 {LTE | WCDMA, MDM_LTE | MDM_WCDMA}, // 12 - LTE and WCDMA
223 {RAF_TD_SCDMA, MDM_TDSCDMA}, // 13 - TD-SCDMA only
224 {RAF_TD_SCDMA | WCDMA, MDM_WCDMA | MDM_TDSCDMA}, // 14 - TD-SCDMA and WCDMA
225 {LTE | RAF_TD_SCDMA, MDM_LTE | MDM_TDSCDMA}, // 15 - LTE and TD-SCDMA
226 {RAF_TD_SCDMA | GSM, MDM_TDSCDMA | MDM_GSM}, // 16 - TD-SCDMA and GSM
227 {LTE | RAF_TD_SCDMA | GSM, MDM_LTE | MDM_TDSCDMA | MDM_GSM}, // 17 - TD-SCDMA, GSM and LTE
228 {RAF_TD_SCDMA | GSM | WCDMA, MDM_WCDMA | MDM_TDSCDMA | MDM_GSM}, // 18 - TD-SCDMA, GSM and WCDMA
229 {LTE | RAF_TD_SCDMA | WCDMA, MDM_LTE | MDM_WCDMA | MDM_TDSCDMA}, // 19 - LTE, TD-SCDMA and WCDMA
230 {LTE | RAF_TD_SCDMA | GSM | WCDMA,MDM_LTE | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM}, // 20 - LTE, TD-SCDMA, GSM, and WCDMA
231 {RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA, MDM_EVDO | MDM_CDMA | MDM_WCDMA | MDM_TDSCDMA | MDM_GSM}, // 21 - TD-SCDMA, CDMA, EVDO, GSM and WCDMA
232 {LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA, MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM}, // 22 - LTE, TDCSDMA, CDMA, EVDO, GSM and WCDMA
233 {NR, MDM_NR}, // 23 - NR 5G only mode
234 {NR | LTE, MDM_NR | MDM_LTE}, // 24 - NR 5G, LTE
235 {NR | LTE | CDMA | EVDO, MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO}, // 25 - NR 5G, LTE, CDMA and EvDo
236 {NR | LTE | GSM | WCDMA, MDM_NR | MDM_LTE | MDM_WCDMA | MDM_GSM}, // 26 - NR 5G, LTE, GSM and WCDMA
237 {NR | LTE | CDMA | EVDO | GSM | WCDMA, MDM_NR | MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM}, // 27 - NR 5G, LTE, CDMA, EvDo, GSM and WCDMA
238 {NR | LTE | WCDMA, MDM_NR | MDM_LTE | MDM_WCDMA}, // 28 - NR 5G, LTE and WCDMA
239 {NR | LTE | RAF_TD_SCDMA, MDM_NR | MDM_LTE | MDM_TDSCDMA}, // 29 - NR 5G, LTE and TDSCDMA
240 {NR | LTE | RAF_TD_SCDMA | GSM, MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_GSM}, // 30 - NR 5G, LTE, TD-SCDMA and GSM
241 {NR | LTE | RAF_TD_SCDMA | WCDMA, MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA}, // 31 - NR 5G, LTE, TD-SCDMA, WCDMA
242 {NR | LTE | RAF_TD_SCDMA | GSM | WCDMA, MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_WCDMA | MDM_GSM}, // 32 - NR 5G, LTE, TD-SCDMA, GSM and WCDMA
243 {NR | LTE | RAF_TD_SCDMA | CDMA | EVDO | GSM | WCDMA, MDM_NR | MDM_LTE | MDM_TDSCDMA | MDM_CDMA | MDM_EVDO | MDM_WCDMA | MDM_GSM}, // 33 - NR 5G, LTE, TD-SCDMA, CDMA, EVDO, GSM and WCDMA
244 };
245
is3gpp2(int radioTech)246 static int is3gpp2(int radioTech) {
247 switch (radioTech) {
248 case RADIO_TECH_IS95A:
249 case RADIO_TECH_IS95B:
250 case RADIO_TECH_1xRTT:
251 case RADIO_TECH_EVDO_0:
252 case RADIO_TECH_EVDO_A:
253 case RADIO_TECH_EVDO_B:
254 case RADIO_TECH_EHRPD:
255 return 1;
256 default:
257 return 0;
258 }
259 }
260
261 typedef enum {
262 SIM_ABSENT = 0,
263 SIM_NOT_READY = 1,
264 SIM_READY = 2,
265 SIM_PIN = 3,
266 SIM_PUK = 4,
267 SIM_NETWORK_PERSONALIZATION = 5,
268 RUIM_ABSENT = 6,
269 RUIM_NOT_READY = 7,
270 RUIM_READY = 8,
271 RUIM_PIN = 9,
272 RUIM_PUK = 10,
273 RUIM_NETWORK_PERSONALIZATION = 11,
274 ISIM_ABSENT = 12,
275 ISIM_NOT_READY = 13,
276 ISIM_READY = 14,
277 ISIM_PIN = 15,
278 ISIM_PUK = 16,
279 ISIM_NETWORK_PERSONALIZATION = 17,
280 } SIM_Status;
281
282 static void onRequest (int request, void *data, size_t datalen, RIL_Token t);
283 static RIL_RadioState currentState();
284 static int onSupports (int requestCode);
285 static void onCancel (RIL_Token t);
286 static const char *getVersion();
287 static int isRadioOn();
288 static SIM_Status getSIMStatus();
289 static int getCardStatus(RIL_CardStatus_v1_4 **pp_card_status);
290 static void freeCardStatus(RIL_CardStatus_v1_4 *p_card_status);
291 static void onDataCallListChanged(void *param);
292
293 extern const char * requestToString(int request);
294 extern uint8_t hexCharToInt(uint8_t c);
295 extern uint8_t * convertHexStringToBytes(void *response, size_t responseLen);
296
297 /*** Static Variables ***/
298 static const RIL_RadioFunctions s_callbacks = {
299 RIL_VERSION,
300 onRequest,
301 currentState,
302 onSupports,
303 onCancel,
304 getVersion
305 };
306
307 #ifdef RIL_SHLIB
308 static const struct RIL_Env *s_rilenv;
309
310 #define RIL_onRequestComplete(t, e, response, responselen) s_rilenv->OnRequestComplete(t,e, response, responselen)
311 #define RIL_onUnsolicitedResponse(a,b,c) s_rilenv->OnUnsolicitedResponse(a,b,c)
312 #define RIL_requestTimedCallback(a,b,c) s_rilenv->RequestTimedCallback(a,b,c)
313 #endif
314
315 static RIL_RadioState sState = RADIO_STATE_UNAVAILABLE;
316
317 static pthread_mutex_t s_state_mutex = PTHREAD_MUTEX_INITIALIZER;
318 static pthread_cond_t s_state_cond = PTHREAD_COND_INITIALIZER;
319
320 static int s_port = -1;
321 static const char * s_device_path = NULL;
322 static int s_device_socket = 0;
323 static uint32_t s_modem_simulator_port = -1;
324
325 /* trigger change to this with s_state_cond */
326 static int s_closed = 0;
327
328 static int sFD; /* file desc of AT channel */
329 static char sATBuffer[MAX_AT_RESPONSE+1];
330 static char *sATBufferCur = NULL;
331
332 static const struct timeval TIMEVAL_SIMPOLL = {1,0};
333 static const struct timeval TIMEVAL_CALLSTATEPOLL = {0,500000};
334 static const struct timeval TIMEVAL_0 = {0,0};
335
336 static int s_ims_registered = 0; // 0==unregistered
337 static int s_ims_services = 1; // & 0x1 == sms over ims supported
338 static int s_ims_format = 1; // FORMAT_3GPP(1) vs FORMAT_3GPP2(2);
339 static int s_ims_cause_retry = 0; // 1==causes sms over ims to temp fail
340 static int s_ims_cause_perm_failure = 0; // 1==causes sms over ims to permanent fail
341 static int s_ims_gsm_retry = 0; // 1==causes sms over gsm to temp fail
342 static int s_ims_gsm_fail = 0; // 1==causes sms over gsm to permanent fail
343
344 #ifdef WORKAROUND_ERRONEOUS_ANSWER
345 // Max number of times we'll try to repoll when we think
346 // we have a AT+CLCC race condition
347 #define REPOLL_CALLS_COUNT_MAX 4
348
349 // Line index that was incoming or waiting at last poll, or -1 for none
350 static int s_incomingOrWaitingLine = -1;
351 // Number of times we've asked for a repoll of AT+CLCC
352 static int s_repollCallsCount = 0;
353 // Should we expect a call to be answered in the next CLCC?
354 static int s_expectAnswer = 0;
355 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
356
357
358 static int s_cell_info_rate_ms = INT_MAX;
359 static int s_mcc = 0;
360 static int s_mnc = 0;
361 static int s_lac = 0;
362 static int s_cid = 0;
363
364 // STK
365 static bool s_stkServiceRunning = false;
366 static char *s_stkUnsolResponse = NULL;
367
368 typedef enum {
369 STK_UNSOL_EVENT_UNKNOWN,
370 STK_UNSOL_EVENT_NOTIFY,
371 STK_UNSOL_PROACTIVE_CMD,
372 } StkUnsolEvent;
373
374 typedef enum {
375 STK_RUN_AT = 0x34,
376 STK_SEND_DTMF = 0x14,
377 STK_SEND_SMS = 0x13,
378 STK_SEND_SS = 0x11,
379 STK_SEND_USSD = 0x12,
380 STK_PLAY_TONE = 0x20,
381 STK_OPEN_CHANNEL = 0x40,
382 STK_CLOSE_CHANNEL = 0x41,
383 STK_RECEIVE_DATA = 0x42,
384 STK_SEND_DATA = 0x43,
385 STK_GET_CHANNEL_STATUS = 0x44,
386 STK_REFRESH = 0x01,
387 } StkCmdType;
388
389 enum PDPState {
390 PDP_IDLE,
391 PDP_BUSY,
392 };
393
394 struct PDPInfo {
395 int cid;
396 enum PDPState state;
397 };
398
399 struct PDPInfo s_PDP[] = {
400 {1, PDP_IDLE},
401 {2, PDP_IDLE},
402 {3, PDP_IDLE},
403 };
404
405 static void pollSIMState (void *param);
406 static void setRadioState(RIL_RadioState newState);
407 static void setRadioTechnology(ModemInfo *mdm, int newtech);
408 static int query_ctec(ModemInfo *mdm, int *current, int32_t *preferred);
409 static int parse_technology_response(const char *response, int *current, int32_t *preferred);
410 static int techFromModemType(int mdmtype);
411 static void getIccId(char *iccid, int size);
412
clccStateToRILState(int state,RIL_CallState * p_state)413 static int clccStateToRILState(int state, RIL_CallState *p_state)
414 {
415 switch(state) {
416 case 0: *p_state = RIL_CALL_ACTIVE; return 0;
417 case 1: *p_state = RIL_CALL_HOLDING; return 0;
418 case 2: *p_state = RIL_CALL_DIALING; return 0;
419 case 3: *p_state = RIL_CALL_ALERTING; return 0;
420 case 4: *p_state = RIL_CALL_INCOMING; return 0;
421 case 5: *p_state = RIL_CALL_WAITING; return 0;
422 default: return -1;
423 }
424 }
425
426 /**
427 * Note: directly modified line and has *p_call point directly into
428 * modified line
429 */
callFromCLCCLine(char * line,RIL_Call * p_call)430 static int callFromCLCCLine(char *line, RIL_Call *p_call)
431 {
432 //+CLCC: 1,0,2,0,0,\"+18005551212\",145
433 // index,isMT,state,mode,isMpty(,number,TOA)?
434
435 int err;
436 int state;
437 int mode;
438
439 err = at_tok_start(&line);
440 if (err < 0) goto error;
441
442 err = at_tok_nextint(&line, &(p_call->index));
443 if (err < 0) goto error;
444
445 err = at_tok_nextbool(&line, &(p_call->isMT));
446 if (err < 0) goto error;
447
448 err = at_tok_nextint(&line, &state);
449 if (err < 0) goto error;
450
451 err = clccStateToRILState(state, &(p_call->state));
452 if (err < 0) goto error;
453
454 err = at_tok_nextint(&line, &mode);
455 if (err < 0) goto error;
456
457 p_call->isVoice = (mode == 0);
458
459 err = at_tok_nextbool(&line, &(p_call->isMpty));
460 if (err < 0) goto error;
461
462 if (at_tok_hasmore(&line)) {
463 err = at_tok_nextstr(&line, &(p_call->number));
464
465 /* tolerate null here */
466 if (err < 0) return 0;
467
468 // Some lame implementations return strings
469 // like "NOT AVAILABLE" in the CLCC line
470 if (p_call->number != NULL
471 && 0 == strspn(p_call->number, "+0123456789")
472 ) {
473 p_call->number = NULL;
474 }
475
476 err = at_tok_nextint(&line, &p_call->toa);
477 if (err < 0) goto error;
478 }
479
480 p_call->uusInfo = NULL;
481
482 return 0;
483
484 error:
485 RLOGE("invalid CLCC line\n");
486 return -1;
487 }
488
parseSimResponseLine(char * line,RIL_SIM_IO_Response * response)489 static int parseSimResponseLine(char* line, RIL_SIM_IO_Response* response) {
490 int err;
491
492 err = at_tok_start(&line);
493 if (err < 0) return err;
494 err = at_tok_nextint(&line, &response->sw1);
495 if (err < 0) return err;
496 err = at_tok_nextint(&line, &response->sw2);
497 if (err < 0) return err;
498
499 if (at_tok_hasmore(&line)) {
500 err = at_tok_nextstr(&line, &response->simResponse);
501 if (err < 0) return err;
502 }
503 return 0;
504 }
505
506 enum InterfaceState {
507 kInterfaceUp,
508 kInterfaceDown,
509 };
510
setInterfaceState(const char * interfaceName,enum InterfaceState state)511 static RIL_Errno setInterfaceState(const char* interfaceName,
512 enum InterfaceState state) {
513 struct ifreq request;
514 int status = 0;
515 int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
516 if (sock == -1) {
517 RLOGE("Failed to open interface socket: %s (%d)",
518 strerror(errno), errno);
519 return RIL_E_GENERIC_FAILURE;
520 }
521
522 memset(&request, 0, sizeof(request));
523 strncpy(request.ifr_name, interfaceName, sizeof(request.ifr_name));
524 request.ifr_name[sizeof(request.ifr_name) - 1] = '\0';
525 status = ioctl(sock, SIOCGIFFLAGS, &request);
526 if (status != 0) {
527 RLOGE("Failed to get interface flags for %s: %s (%d)",
528 interfaceName, strerror(errno), errno);
529 close(sock);
530 return RIL_E_RADIO_NOT_AVAILABLE;
531 }
532
533 bool isUp = (request.ifr_flags & IFF_UP);
534 if ((state == kInterfaceUp && isUp) || (state == kInterfaceDown && !isUp)) {
535 // Interface already in desired state
536 close(sock);
537 return RIL_E_SUCCESS;
538 }
539
540 // Simply toggle the flag since we know it's the opposite of what we want
541 request.ifr_flags ^= IFF_UP;
542
543 status = ioctl(sock, SIOCSIFFLAGS, &request);
544 if (status != 0) {
545 RLOGE("Failed to set interface flags for %s: %s (%d)",
546 interfaceName, strerror(errno), errno);
547 close(sock);
548 return RIL_E_GENERIC_FAILURE;
549 }
550
551 close(sock);
552 return RIL_E_SUCCESS;
553 }
554
555 /** do post-AT+CFUN=1 initialization */
onRadioPowerOn()556 static void onRadioPowerOn()
557 {
558 #ifdef USE_TI_COMMANDS
559 /* Must be after CFUN=1 */
560 /* TI specific -- notifications for CPHS things such */
561 /* as CPHS message waiting indicator */
562
563 at_send_command("AT%CPHS=1", NULL);
564
565 /* TI specific -- enable NITZ unsol notifs */
566 at_send_command("AT%CTZV=1", NULL);
567 #endif
568
569 pollSIMState(NULL);
570 }
571
572 /** do post- SIM ready initialization */
onSIMReady()573 static void onSIMReady()
574 {
575 at_send_command_singleline("AT+CSMS=1", "+CSMS:", NULL);
576 /*
577 * Always send SMS messages directly to the TE
578 *
579 * mode = 1 // discard when link is reserved (link should never be
580 * reserved)
581 * mt = 2 // most messages routed to TE
582 * bm = 2 // new cell BM's routed to TE
583 * ds = 1 // Status reports routed to TE
584 * bfr = 1 // flush buffer
585 */
586 at_send_command("AT+CNMI=1,2,2,1,1", NULL);
587 }
588
requestRadioPower(void * data,size_t datalen __unused,RIL_Token t)589 static void requestRadioPower(void *data, size_t datalen __unused, RIL_Token t)
590 {
591 int onOff;
592
593 int err;
594 ATResponse *p_response = NULL;
595
596 assert (datalen >= sizeof(int *));
597 onOff = ((int *)data)[0];
598
599 if (onOff == 0 && sState != RADIO_STATE_OFF) {
600 err = at_send_command("AT+CFUN=0", &p_response);
601 if (err < 0 || p_response->success == 0) goto error;
602 setRadioState(RADIO_STATE_OFF);
603 } else if (onOff > 0 && sState == RADIO_STATE_OFF) {
604 err = at_send_command("AT+CFUN=1", &p_response);
605 if (err < 0|| p_response->success == 0) {
606 // Some stacks return an error when there is no SIM,
607 // but they really turn the RF portion on
608 // So, if we get an error, let's check to see if it
609 // turned on anyway
610
611 if (isRadioOn() != 1) {
612 goto error;
613 }
614 }
615 setRadioState(RADIO_STATE_ON);
616 }
617
618 at_response_free(p_response);
619 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
620 return;
621 error:
622 at_response_free(p_response);
623 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
624 }
625
requestShutdown(RIL_Token t)626 static void requestShutdown(RIL_Token t)
627 {
628 int onOff;
629
630 int err;
631 ATResponse *p_response = NULL;
632
633 if (sState != RADIO_STATE_OFF) {
634 err = at_send_command("AT+CFUN=0", &p_response);
635 setRadioState(RADIO_STATE_UNAVAILABLE);
636 }
637
638 at_response_free(p_response);
639 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
640 return;
641 }
642
643 static void requestOrSendDataCallList(int cid, RIL_Token *t);
644
onDataCallListChanged(void * param __unused)645 static void onDataCallListChanged(void *param __unused)
646 {
647 requestOrSendDataCallList(-1, NULL);
648 }
649
requestDataCallList(void * data __unused,size_t datalen __unused,RIL_Token t)650 static void requestDataCallList(void *data __unused, size_t datalen __unused, RIL_Token t)
651 {
652 requestOrSendDataCallList(-1, &t);
653 }
654
655 // Hang up, reject, conference, call waiting
requestCallSelection(void * data __unused,size_t datalen __unused,RIL_Token t,int request)656 static void requestCallSelection(
657 void *data __unused, size_t datalen __unused, RIL_Token t, int request)
658 {
659 // 3GPP 22.030 6.5.5
660 static char hangupWaiting[] = "AT+CHLD=0";
661 static char hangupForeground[] = "AT+CHLD=1";
662 static char switchWaiting[] = "AT+CHLD=2";
663 static char conference[] = "AT+CHLD=3";
664 static char reject[] = "ATH";
665
666 char* atCommand;
667
668 if (getSIMStatus() == SIM_ABSENT) {
669 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
670 return;
671 }
672
673 switch(request) {
674 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
675 // "Releases all held calls or sets User Determined User Busy
676 // (UDUB) for a waiting call."
677 atCommand = hangupWaiting;
678 break;
679 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
680 // "Releases all active calls (if any exist) and accepts
681 // the other (held or waiting) call."
682 atCommand = hangupForeground;
683 break;
684 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
685 // "Places all active calls (if any exist) on hold and accepts
686 // the other (held or waiting) call."
687 atCommand = switchWaiting;
688 #ifdef WORKAROUND_ERRONEOUS_ANSWER
689 s_expectAnswer = 1;
690 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
691 break;
692 case RIL_REQUEST_CONFERENCE:
693 // "Adds a held call to the conversation"
694 atCommand = conference;
695 break;
696 case RIL_REQUEST_UDUB:
697 // User determined user busy (reject)
698 atCommand = reject;
699 break;
700 default:
701 assert(0);
702 }
703 at_send_command(atCommand, NULL);
704 // Success or failure is ignored by the upper layer here.
705 // It will call GET_CURRENT_CALLS and determine success that way.
706 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
707 }
708
hasWifiCapability()709 static bool hasWifiCapability()
710 {
711 char propValue[PROP_VALUE_MAX];
712 return property_get("ro.kernel.qemu.wifi", propValue, "") > 0 &&
713 strcmp("1", propValue) == 0;
714 }
715
getRadioInterfaceName(bool hasWifi)716 static const char* getRadioInterfaceName(bool hasWifi)
717 {
718 return hasWifi ? PPP_TTY_PATH_RADIO0 : PPP_TTY_PATH_ETH0;
719 }
720
requestOrSendDataCallList(int cid,RIL_Token * t)721 static void requestOrSendDataCallList(int cid, RIL_Token *t)
722 {
723 ATResponse *p_response = NULL;
724 ATLine *p_cur = NULL;
725 int err = -1;
726 int n = 0;
727 char *out = NULL;
728 char propValue[PROP_VALUE_MAX] = {0};
729 bool hasWifi = hasWifiCapability();
730 const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
731
732 err = at_send_command_multiline ("AT+CGACT?", "+CGACT:", &p_response);
733 if (err != 0 || p_response->success == 0) {
734 if (t != NULL)
735 RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
736 else
737 RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
738 NULL, 0);
739 return;
740 }
741
742 for (p_cur = p_response->p_intermediates; p_cur != NULL;
743 p_cur = p_cur->p_next)
744 n++;
745
746 RIL_Data_Call_Response_v11 *responses =
747 alloca(n * sizeof(RIL_Data_Call_Response_v11));
748
749 int i;
750 for (i = 0; i < n; i++) {
751 responses[i].status = -1;
752 responses[i].suggestedRetryTime = -1;
753 responses[i].cid = -1;
754 responses[i].active = -1;
755 responses[i].type = "";
756 responses[i].ifname = "";
757 responses[i].addresses = "";
758 responses[i].dnses = "";
759 responses[i].gateways = "";
760 responses[i].pcscf = "";
761 responses[i].mtu = 0;
762 }
763
764 RIL_Data_Call_Response_v11 *response = responses;
765 for (p_cur = p_response->p_intermediates; p_cur != NULL;
766 p_cur = p_cur->p_next) {
767 char *line = p_cur->line;
768
769 err = at_tok_start(&line);
770 if (err < 0)
771 goto error;
772
773 err = at_tok_nextint(&line, &response->cid);
774 if (err < 0)
775 goto error;
776
777 err = at_tok_nextint(&line, &response->active);
778 if (err < 0)
779 goto error;
780
781 response++;
782 }
783
784 at_response_free(p_response);
785
786 err = at_send_command_multiline ("AT+CGDCONT?", "+CGDCONT:", &p_response);
787 if (err != 0 || p_response->success == 0) {
788 if (t != NULL)
789 RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
790 else
791 RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
792 NULL, 0);
793 return;
794 }
795
796 for (p_cur = p_response->p_intermediates; p_cur != NULL;
797 p_cur = p_cur->p_next) {
798 char *line = p_cur->line;
799 int ncid;
800
801 err = at_tok_start(&line);
802 if (err < 0)
803 goto error;
804
805 err = at_tok_nextint(&line, &ncid);
806 if (err < 0)
807 goto error;
808
809 if (cid != ncid)
810 continue;
811
812 i = ncid - 1;
813 // Assume no error
814 responses[i].status = 0;
815
816 // type
817 err = at_tok_nextstr(&line, &out);
818 if (err < 0)
819 goto error;
820
821 int type_size = strlen(out) + 1;
822 responses[i].type = alloca(type_size);
823 strlcpy(responses[i].type, out, type_size);
824
825 // APN ignored for v5
826 err = at_tok_nextstr(&line, &out);
827 if (err < 0)
828 goto error;
829
830 int ifname_size = strlen(radioInterfaceName) + 1;
831 responses[i].ifname = alloca(ifname_size);
832 strlcpy(responses[i].ifname, radioInterfaceName, ifname_size);
833
834 err = at_tok_nextstr(&line, &out);
835 if (err < 0)
836 goto error;
837
838 int addresses_size = strlen(out) + 1;
839 responses[i].addresses = alloca(addresses_size);
840 strlcpy(responses[i].addresses, out, addresses_size);
841
842 if (isInEmulator()) {
843 /* We are in the emulator - the dns servers are listed
844 * by the following system properties, setup in
845 * /system/etc/init.goldfish.sh:
846 * - net.eth0.dns1
847 * - net.eth0.dns2
848 * - net.eth0.dns3
849 * - net.eth0.dns4
850 */
851 const int dnslist_sz = 128;
852 char* dnslist = alloca(dnslist_sz);
853 const char* separator = "";
854 int nn;
855
856 dnslist[0] = 0;
857 for (nn = 1; nn <= 4; nn++) {
858 /* Probe net.eth0.dns<n> */
859 char propName[PROP_NAME_MAX];
860 char propValue[PROP_VALUE_MAX];
861
862 snprintf(propName, sizeof propName, "net.eth0.dns%d", nn);
863
864 /* Ignore if undefined */
865 if (property_get(propName, propValue, "") <= 0) {
866 continue;
867 }
868
869 /* Append the DNS IP address */
870 strlcat(dnslist, separator, dnslist_sz);
871 strlcat(dnslist, propValue, dnslist_sz);
872 separator = " ";
873 }
874 responses[i].dnses = dnslist;
875
876 /* There is only one gateway in the emulator. If WiFi is
877 * configured the interface visible to RIL will be behind a NAT
878 * where the gateway is different. */
879 if (hasWifi) {
880 responses[i].gateways = "192.168.200.1";
881 } else if (property_get("net.eth0.gw", propValue, "") > 0) {
882 responses[i].gateways = propValue;
883 } else {
884 responses[i].gateways = "";
885 }
886 responses[i].mtu = DEFAULT_MTU;
887 } else {
888 /* I don't know where we are, so use the public Google DNS
889 * servers by default and no gateway.
890 */
891 responses[i].dnses = "8.8.8.8 8.8.4.4";
892 responses[i].gateways = "";
893 }
894 }
895
896 at_response_free(p_response);
897 p_response = NULL;
898
899 char cmd[64] = {0};
900 snprintf(cmd, sizeof(cmd), "AT+CGCONTRDP=%d", cid);
901 err = at_send_command_singleline(cmd, "+CGCONTRDP:", &p_response);
902 if (err < 0 || p_response->success == 0) {
903 goto error;
904 }
905
906 int skip = 0;
907 char *sskip = NULL;
908 char *input = p_response->p_intermediates->line;
909
910 int ncid = -1;
911 err = at_tok_start(&input);
912 if (err < 0) goto error;
913
914 err = at_tok_nextint(&input, &ncid); // cid
915 if (err < 0) goto error;
916
917 if (cid != ncid) goto error;
918
919 i = ncid - 1;
920
921 err = at_tok_nextint(&input, &skip); // bearer_id
922 if (err < 0) goto error;
923
924 err = at_tok_nextstr(&input, &sskip); // apn
925 if (err < 0) goto error;
926
927 err = at_tok_nextstr(&input, &sskip); // local_addr_and_subnet_mask
928 if (err < 0) goto error;
929
930 err = at_tok_nextstr(&input, &responses[i].gateways); // gw_addr
931 if (err < 0) goto error;
932
933 err = at_tok_nextstr(&input, &responses[i].dnses); // dns_prim_addr
934 if (err < 0) goto error;
935
936 if (t != NULL)
937 RIL_onRequestComplete(*t, RIL_E_SUCCESS, &responses[i],
938 sizeof(RIL_Data_Call_Response_v11));
939 else
940 RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
941 responses,
942 n * sizeof(RIL_Data_Call_Response_v11));
943
944 at_response_free(p_response);
945 return;
946
947 error:
948 if (t != NULL)
949 RIL_onRequestComplete(*t, RIL_E_GENERIC_FAILURE, NULL, 0);
950 else
951 RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
952 NULL, 0);
953 at_response_free(p_response);
954 }
955
requestQueryNetworkSelectionMode(void * data __unused,size_t datalen __unused,RIL_Token t)956 static void requestQueryNetworkSelectionMode(
957 void *data __unused, size_t datalen __unused, RIL_Token t)
958 {
959 int err;
960 ATResponse *p_response = NULL;
961 int response = 0;
962 char *line;
963
964 err = at_send_command_singleline("AT+COPS?", "+COPS:", &p_response);
965
966 if (err < 0 || p_response->success == 0) {
967 goto error;
968 }
969
970 line = p_response->p_intermediates->line;
971
972 err = at_tok_start(&line);
973
974 if (err < 0) {
975 goto error;
976 }
977
978 err = at_tok_nextint(&line, &response);
979
980 if (err < 0) {
981 goto error;
982 }
983
984 RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(int));
985 at_response_free(p_response);
986 return;
987 error:
988 at_response_free(p_response);
989 RLOGE("requestQueryNetworkSelectionMode must never return error when radio is on");
990 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
991 }
992
sendCallStateChanged(void * param __unused)993 static void sendCallStateChanged(void *param __unused)
994 {
995 RIL_onUnsolicitedResponse (
996 RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
997 NULL, 0);
998 }
999
requestGetCurrentCalls(void * data __unused,size_t datalen __unused,RIL_Token t)1000 static void requestGetCurrentCalls(void *data __unused, size_t datalen __unused, RIL_Token t)
1001 {
1002 int err;
1003 ATResponse *p_response;
1004 ATLine *p_cur;
1005 int countCalls;
1006 int countValidCalls;
1007 RIL_Call *p_calls;
1008 RIL_Call **pp_calls;
1009 int i;
1010 int needRepoll = 0;
1011
1012 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1013 int prevIncomingOrWaitingLine;
1014
1015 prevIncomingOrWaitingLine = s_incomingOrWaitingLine;
1016 s_incomingOrWaitingLine = -1;
1017 #endif /*WORKAROUND_ERRONEOUS_ANSWER*/
1018
1019 err = at_send_command_multiline ("AT+CLCC", "+CLCC:", &p_response);
1020
1021 if (err != 0 || p_response->success == 0) {
1022 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1023 return;
1024 }
1025
1026 /* count the calls */
1027 for (countCalls = 0, p_cur = p_response->p_intermediates
1028 ; p_cur != NULL
1029 ; p_cur = p_cur->p_next
1030 ) {
1031 countCalls++;
1032 }
1033
1034 /* yes, there's an array of pointers and then an array of structures */
1035
1036 pp_calls = (RIL_Call **)alloca(countCalls * sizeof(RIL_Call *));
1037 p_calls = (RIL_Call *)alloca(countCalls * sizeof(RIL_Call));
1038 memset (p_calls, 0, countCalls * sizeof(RIL_Call));
1039
1040 /* init the pointer array */
1041 for(i = 0; i < countCalls ; i++) {
1042 pp_calls[i] = &(p_calls[i]);
1043 }
1044
1045 for (countValidCalls = 0, p_cur = p_response->p_intermediates
1046 ; p_cur != NULL
1047 ; p_cur = p_cur->p_next
1048 ) {
1049 err = callFromCLCCLine(p_cur->line, p_calls + countValidCalls);
1050
1051 if (err != 0) {
1052 continue;
1053 }
1054
1055 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1056 if (p_calls[countValidCalls].state == RIL_CALL_INCOMING
1057 || p_calls[countValidCalls].state == RIL_CALL_WAITING
1058 ) {
1059 s_incomingOrWaitingLine = p_calls[countValidCalls].index;
1060 }
1061 #endif /*WORKAROUND_ERRONEOUS_ANSWER*/
1062
1063 if (p_calls[countValidCalls].state != RIL_CALL_ACTIVE
1064 && p_calls[countValidCalls].state != RIL_CALL_HOLDING
1065 ) {
1066 needRepoll = 1;
1067 }
1068
1069 countValidCalls++;
1070 }
1071
1072 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1073 // Basically:
1074 // A call was incoming or waiting
1075 // Now it's marked as active
1076 // But we never answered it
1077 //
1078 // This is probably a bug, and the call will probably
1079 // disappear from the call list in the next poll
1080 if (prevIncomingOrWaitingLine >= 0
1081 && s_incomingOrWaitingLine < 0
1082 && s_expectAnswer == 0
1083 ) {
1084 for (i = 0; i < countValidCalls ; i++) {
1085
1086 if (p_calls[i].index == prevIncomingOrWaitingLine
1087 && p_calls[i].state == RIL_CALL_ACTIVE
1088 && s_repollCallsCount < REPOLL_CALLS_COUNT_MAX
1089 ) {
1090 RLOGI(
1091 "Hit WORKAROUND_ERRONOUS_ANSWER case."
1092 " Repoll count: %d\n", s_repollCallsCount);
1093 s_repollCallsCount++;
1094 goto error;
1095 }
1096 }
1097 }
1098
1099 s_expectAnswer = 0;
1100 s_repollCallsCount = 0;
1101 #endif /*WORKAROUND_ERRONEOUS_ANSWER*/
1102
1103 RIL_onRequestComplete(t, RIL_E_SUCCESS, pp_calls,
1104 countValidCalls * sizeof (RIL_Call *));
1105
1106 at_response_free(p_response);
1107
1108 #ifdef POLL_CALL_STATE
1109 if (countValidCalls) { // We don't seem to get a "NO CARRIER" message from
1110 // smd, so we're forced to poll until the call ends.
1111 #else
1112 if (needRepoll) {
1113 #endif
1114 RIL_requestTimedCallback (sendCallStateChanged, NULL, &TIMEVAL_CALLSTATEPOLL);
1115 }
1116
1117 return;
1118 #ifdef WORKAROUND_ERRONEOUS_ANSWER
1119 error:
1120 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1121 at_response_free(p_response);
1122 #endif
1123 }
1124
1125 static void requestDial(void *data, size_t datalen __unused, RIL_Token t)
1126 {
1127 RIL_Dial *p_dial;
1128 char *cmd;
1129 const char *clir;
1130 int ret;
1131
1132 p_dial = (RIL_Dial *)data;
1133
1134 switch (p_dial->clir) {
1135 case 1: clir = "I"; break; /*invocation*/
1136 case 2: clir = "i"; break; /*suppression*/
1137 default:
1138 case 0: clir = ""; break; /*subscription default*/
1139 }
1140
1141 asprintf(&cmd, "ATD%s%s;", p_dial->address, clir);
1142
1143 ret = at_send_command(cmd, NULL);
1144
1145 free(cmd);
1146
1147 /* success or failure is ignored by the upper layer here.
1148 it will call GET_CURRENT_CALLS and determine success that way */
1149 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1150 }
1151
1152 static void requestWriteSmsToSim(void *data, size_t datalen __unused, RIL_Token t)
1153 {
1154 RIL_SMS_WriteArgs *p_args;
1155 char *cmd;
1156 int length;
1157 int err;
1158 ATResponse *p_response = NULL;
1159
1160 if (getSIMStatus() == SIM_ABSENT) {
1161 RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
1162 return;
1163 }
1164
1165 p_args = (RIL_SMS_WriteArgs *)data;
1166
1167 length = strlen(p_args->pdu)/2;
1168 asprintf(&cmd, "AT+CMGW=%d,%d", length, p_args->status);
1169
1170 err = at_send_command_sms(cmd, p_args->pdu, "+CMGW:", &p_response);
1171
1172 if (err != 0 || p_response->success == 0) goto error;
1173
1174 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1175 at_response_free(p_response);
1176
1177 return;
1178 error:
1179 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1180 at_response_free(p_response);
1181 }
1182
1183 static void requestHangup(void *data, size_t datalen __unused, RIL_Token t)
1184 {
1185 int *p_line;
1186
1187 int ret;
1188 char *cmd;
1189
1190 if (getSIMStatus() == SIM_ABSENT) {
1191 RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
1192 return;
1193 }
1194 p_line = (int *)data;
1195
1196 // 3GPP 22.030 6.5.5
1197 // "Releases a specific active call X"
1198 asprintf(&cmd, "AT+CHLD=1%d", p_line[0]);
1199
1200 ret = at_send_command(cmd, NULL);
1201
1202 free(cmd);
1203
1204 /* success or failure is ignored by the upper layer here.
1205 it will call GET_CURRENT_CALLS and determine success that way */
1206 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1207 }
1208
1209 static void requestSignalStrength(void *data __unused, size_t datalen __unused, RIL_Token t)
1210 {
1211 ATResponse *p_response = NULL;
1212 int err;
1213 char *line;
1214 int count = 0;
1215 // Accept a response that is at least v6, and up to v12
1216 int minNumOfElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
1217 int maxNumOfElements=sizeof(RIL_SignalStrength_v12)/sizeof(int);
1218 int response[maxNumOfElements];
1219
1220 memset(response, 0, sizeof(response));
1221
1222 err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response);
1223
1224 if (err < 0 || p_response->success == 0) {
1225 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1226 goto error;
1227 }
1228
1229 line = p_response->p_intermediates->line;
1230
1231 err = at_tok_start(&line);
1232 if (err < 0) goto error;
1233
1234 for (count = 0; count < maxNumOfElements; count++) {
1235 err = at_tok_nextint(&line, &(response[count]));
1236 if (err < 0 && count < minNumOfElements) goto error;
1237 }
1238
1239 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
1240
1241 at_response_free(p_response);
1242 return;
1243
1244 error:
1245 RLOGE("requestSignalStrength must never return an error when radio is on");
1246 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1247 at_response_free(p_response);
1248 }
1249
1250 /**
1251 * networkModePossible. Decides whether the network mode is appropriate for the
1252 * specified modem
1253 */
1254 static int networkModePossible(ModemInfo *mdm, int nm)
1255 {
1256 if ((net2modem[nm] & mdm->supportedTechs) == net2modem[nm]) {
1257 return 1;
1258 }
1259 return 0;
1260 }
1261
1262 int getPreferredFromBitmap(int value, int *index) {
1263 for (unsigned int i = 0; i < sizeof(s_networkMask) / sizeof(NetworkTypeBitmap); i++) {
1264 if (s_networkMask[i].bitmap == value) {
1265 if (index) *index = i;
1266 return s_networkMask[i].type;
1267 }
1268 }
1269 RLOGD("getPreferredFromBitmap %d not match", value);
1270 return MDM_LTE | MDM_GSM | MDM_WCDMA;
1271 }
1272
1273 unsigned getBitmapFromPreferred(int value) {
1274 for (unsigned int i = 0; i < sizeof(s_networkMask) / sizeof(NetworkTypeBitmap); i++) {
1275 if (s_networkMask[i].type == value) {
1276 return s_networkMask[i].bitmap;
1277 }
1278 }
1279 RLOGD("getBitmapFromPreferred %d not match", value);
1280 return LTE | GSM | WCDMA;
1281 }
1282
1283 static void requestSetPreferredNetworkType(int request, void *data,
1284 size_t datalen __unused, RIL_Token t )
1285 {
1286 ATResponse *p_response = NULL;
1287 char *cmd = NULL;
1288 int value = *(int *)data;
1289 int index = value;
1290 int current, old;
1291 int err;
1292 int32_t preferred;
1293
1294 if (request == RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE) {
1295 preferred = net2pmask[value];
1296 } else {
1297 preferred = getPreferredFromBitmap(value, &index);
1298 }
1299 RLOGD("requestSetPreferredNetworkType: current: %x. New: %x", PREFERRED_NETWORK(sMdmInfo), preferred);
1300
1301 if (!networkModePossible(sMdmInfo, index)) {
1302 RIL_onRequestComplete(t, RIL_E_MODE_NOT_SUPPORTED, NULL, 0);
1303 return;
1304 }
1305
1306 if (query_ctec(sMdmInfo, ¤t, NULL) < 0) {
1307 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1308 return;
1309 }
1310 old = PREFERRED_NETWORK(sMdmInfo);
1311 RLOGD("old != preferred: %d", old != preferred);
1312 if (old != preferred) {
1313 asprintf(&cmd, "AT+CTEC=%d,\"%x\"", current, preferred);
1314 RLOGD("Sending command: <%s>", cmd);
1315 err = at_send_command_singleline(cmd, "+CTEC:", &p_response);
1316 free(cmd);
1317 if (err || !p_response->success) {
1318 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1319 return;
1320 }
1321 PREFERRED_NETWORK(sMdmInfo) = value;
1322 if (!strstr( p_response->p_intermediates->line, "DONE") ) {
1323 int current;
1324 int res = parse_technology_response(p_response->p_intermediates->line, ¤t, NULL);
1325 switch (res) {
1326 case -1: // Error or unable to parse
1327 break;
1328 case 1: // Only able to parse current
1329 case 0: // Both current and preferred were parsed
1330 setRadioTechnology(sMdmInfo, current);
1331 break;
1332 }
1333 }
1334 }
1335 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1336 }
1337
1338 static void requestGetPreferredNetworkType(int request __unused, void *data __unused,
1339 size_t datalen __unused, RIL_Token t)
1340 {
1341 int preferred;
1342 unsigned i;
1343
1344 switch ( query_ctec(sMdmInfo, NULL, &preferred) ) {
1345 case -1: // Error or unable to parse
1346 case 1: // Only able to parse current
1347 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1348 break;
1349 case 0: // Both current and preferred were parsed
1350 for ( i = 0 ; i < sizeof(net2pmask) / sizeof(int32_t) ; i++ ) {
1351 if (preferred == net2pmask[i]) {
1352 goto done;
1353 }
1354 }
1355 RLOGE("Unknown preferred mode received from modem: %d", preferred);
1356 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1357 return;
1358 }
1359 done:
1360 if (request == RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP) {
1361 i = getBitmapFromPreferred(preferred);
1362 }
1363 RIL_onRequestComplete(t, RIL_E_SUCCESS, &i, sizeof(i));
1364 }
1365
1366 static void requestCdmaPrlVersion(int request __unused, void *data __unused,
1367 size_t datalen __unused, RIL_Token t)
1368 {
1369 int err;
1370 char * responseStr;
1371 ATResponse *p_response = NULL;
1372 const char *cmd;
1373 char *line;
1374
1375 err = at_send_command_singleline("AT+WPRL?", "+WPRL:", &p_response);
1376 if (err < 0 || !p_response->success) goto error;
1377 line = p_response->p_intermediates->line;
1378 err = at_tok_start(&line);
1379 if (err < 0) goto error;
1380 err = at_tok_nextstr(&line, &responseStr);
1381 if (err < 0 || !responseStr) goto error;
1382 RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, strlen(responseStr));
1383 at_response_free(p_response);
1384 return;
1385 error:
1386 at_response_free(p_response);
1387 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1388 }
1389
1390 static void requestCdmaBaseBandVersion(int request __unused, void *data __unused,
1391 size_t datalen __unused, RIL_Token t)
1392 {
1393 int err;
1394 char * responseStr;
1395 ATResponse *p_response = NULL;
1396 const char *cmd;
1397 const char *prefix;
1398 char *line, *p;
1399 int commas;
1400 int skip;
1401 int count = 4;
1402
1403 // Fixed values. TODO: query modem
1404 responseStr = strdup("1.0.0.0");
1405 RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, sizeof(responseStr));
1406 free(responseStr);
1407 }
1408
1409 static void requestDeviceIdentity(int request __unused, void *data __unused,
1410 size_t datalen __unused, RIL_Token t)
1411 {
1412 int err;
1413 int response[4];
1414 char * responseStr[4];
1415 ATResponse *p_response = NULL;
1416 const char *cmd;
1417 const char *prefix;
1418 char *line, *p;
1419 int commas;
1420 int skip;
1421 int count = 4;
1422
1423 // Fixed values. TODO: Query modem
1424 responseStr[0] = "----";
1425 responseStr[1] = "----";
1426 responseStr[2] = "77777777";
1427 responseStr[3] = ""; // default empty for non-CDMA
1428
1429 err = at_send_command_numeric("AT+CGSN", &p_response);
1430 if (err < 0 || p_response->success == 0) {
1431 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1432 return;
1433 } else {
1434 if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
1435 responseStr[3] = p_response->p_intermediates->line;
1436 } else {
1437 responseStr[0] = p_response->p_intermediates->line;
1438 }
1439 }
1440
1441 RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
1442 at_response_free(p_response);
1443 }
1444
1445 static void requestCdmaGetSubscriptionSource(int request __unused, void *data,
1446 size_t datalen __unused, RIL_Token t)
1447 {
1448 int err;
1449 int *ss = (int *)data;
1450 ATResponse *p_response = NULL;
1451 char *cmd = NULL;
1452 char *line = NULL;
1453 int response;
1454
1455 asprintf(&cmd, "AT+CCSS?");
1456 if (!cmd) goto error;
1457
1458 err = at_send_command_singleline(cmd, "+CCSS:", &p_response);
1459 if (err < 0 || !p_response->success)
1460 goto error;
1461
1462 line = p_response->p_intermediates->line;
1463 err = at_tok_start(&line);
1464 if (err < 0) goto error;
1465
1466 err = at_tok_nextint(&line, &response);
1467 free(cmd);
1468 cmd = NULL;
1469
1470 RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1471
1472 return;
1473 error:
1474 free(cmd);
1475 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1476 }
1477
1478 static void requestCdmaSetSubscriptionSource(int request __unused, void *data,
1479 size_t datalen, RIL_Token t)
1480 {
1481 int err;
1482 int *ss = (int *)data;
1483 ATResponse *p_response = NULL;
1484 char *cmd = NULL;
1485
1486 if (!ss || !datalen) {
1487 RLOGE("RIL_REQUEST_CDMA_SET_SUBSCRIPTION without data!");
1488 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1489 return;
1490 }
1491 asprintf(&cmd, "AT+CCSS=%d", ss[0]);
1492 if (!cmd) goto error;
1493
1494 err = at_send_command(cmd, &p_response);
1495 if (err < 0 || !p_response->success)
1496 goto error;
1497 free(cmd);
1498 cmd = NULL;
1499
1500 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1501
1502 RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, ss, sizeof(ss[0]));
1503
1504 return;
1505 error:
1506 free(cmd);
1507 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1508 }
1509
1510 static void requestCdmaSubscription(int request __unused, void *data __unused,
1511 size_t datalen __unused, RIL_Token t)
1512 {
1513 int err;
1514 int response[5];
1515 char * responseStr[5];
1516 ATResponse *p_response = NULL;
1517 const char *cmd;
1518 const char *prefix;
1519 char *line, *p;
1520 int commas;
1521 int skip;
1522 int count = 5;
1523
1524 // Fixed values. TODO: Query modem
1525 responseStr[0] = "8587777777"; // MDN
1526 responseStr[1] = "1"; // SID
1527 responseStr[2] = "1"; // NID
1528 responseStr[3] = "8587777777"; // MIN
1529 responseStr[4] = "1"; // PRL Version
1530 RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
1531 }
1532
1533 static void requestCdmaGetRoamingPreference(int request __unused, void *data __unused,
1534 size_t datalen __unused, RIL_Token t)
1535 {
1536 int roaming_pref = -1;
1537 ATResponse *p_response = NULL;
1538 char *line;
1539 int res;
1540
1541 res = at_send_command_singleline("AT+WRMP?", "+WRMP:", &p_response);
1542 if (res < 0 || !p_response->success) {
1543 goto error;
1544 }
1545 line = p_response->p_intermediates->line;
1546
1547 res = at_tok_start(&line);
1548 if (res < 0) goto error;
1549
1550 res = at_tok_nextint(&line, &roaming_pref);
1551 if (res < 0) goto error;
1552
1553 RIL_onRequestComplete(t, RIL_E_SUCCESS, &roaming_pref, sizeof(roaming_pref));
1554 return;
1555 error:
1556 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1557 }
1558
1559 static void requestCdmaSetRoamingPreference(int request __unused, void *data,
1560 size_t datalen __unused, RIL_Token t)
1561 {
1562 int *pref = (int *)data;
1563 ATResponse *p_response = NULL;
1564 char *line;
1565 int res;
1566 char *cmd = NULL;
1567
1568 asprintf(&cmd, "AT+WRMP=%d", *pref);
1569 if (cmd == NULL) goto error;
1570
1571 res = at_send_command(cmd, &p_response);
1572 if (res < 0 || !p_response->success)
1573 goto error;
1574
1575 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1576 free(cmd);
1577 return;
1578 error:
1579 free(cmd);
1580 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1581 }
1582
1583 static int parseRegistrationState(char *str, int *type, int *items, int **response)
1584 {
1585 int err;
1586 char *line = str, *p;
1587 int *resp = NULL;
1588 int skip;
1589 int count = 3;
1590 int commas;
1591
1592 RLOGD("parseRegistrationState. Parsing: %s",str);
1593 err = at_tok_start(&line);
1594 if (err < 0) goto error;
1595
1596 /* Ok you have to be careful here
1597 * The solicited version of the CREG response is
1598 * +CREG: n, stat, [lac, cid]
1599 * and the unsolicited version is
1600 * +CREG: stat, [lac, cid]
1601 * The <n> parameter is basically "is unsolicited creg on?"
1602 * which it should always be
1603 *
1604 * Now we should normally get the solicited version here,
1605 * but the unsolicited version could have snuck in
1606 * so we have to handle both
1607 *
1608 * Also since the LAC and CID are only reported when registered,
1609 * we can have 1, 2, 3, or 4 arguments here
1610 *
1611 * finally, a +CGREG: answer may have a fifth value that corresponds
1612 * to the network type, as in;
1613 *
1614 * +CGREG: n, stat [,lac, cid [,networkType]]
1615 */
1616
1617 /* count number of commas */
1618 commas = 0;
1619 for (p = line ; *p != '\0' ;p++) {
1620 if (*p == ',') commas++;
1621 }
1622
1623 resp = (int *)calloc(commas + 1, sizeof(int));
1624 if (!resp) goto error;
1625 switch (commas) {
1626 case 0: /* +CREG: <stat> */
1627 err = at_tok_nextint(&line, &resp[0]);
1628 if (err < 0) goto error;
1629 resp[1] = -1;
1630 resp[2] = -1;
1631 break;
1632
1633 case 1: /* +CREG: <n>, <stat> */
1634 err = at_tok_nextint(&line, &skip);
1635 if (err < 0) goto error;
1636 err = at_tok_nextint(&line, &resp[0]);
1637 if (err < 0) goto error;
1638 resp[1] = -1;
1639 resp[2] = -1;
1640 if (err < 0) goto error;
1641 break;
1642
1643 case 2: /* +CREG: <stat>, <lac>, <cid> */
1644 err = at_tok_nextint(&line, &resp[0]);
1645 if (err < 0) goto error;
1646 err = at_tok_nexthexint(&line, &resp[1]);
1647 if (err < 0) goto error;
1648 err = at_tok_nexthexint(&line, &resp[2]);
1649 if (err < 0) goto error;
1650 break;
1651 case 3: /* +CREG: <n>, <stat>, <lac>, <cid> */
1652 err = at_tok_nextint(&line, &skip);
1653 if (err < 0) goto error;
1654 err = at_tok_nextint(&line, &resp[0]);
1655 if (err < 0) goto error;
1656 err = at_tok_nexthexint(&line, &resp[1]);
1657 if (err < 0) goto error;
1658 err = at_tok_nexthexint(&line, &resp[2]);
1659 if (err < 0) goto error;
1660 break;
1661 /* special case for CGREG, there is a fourth parameter
1662 * that is the network type (unknown/gprs/edge/umts)
1663 */
1664 case 4: /* +CGREG: <n>, <stat>, <lac>, <cid>, <networkType> */
1665 err = at_tok_nextint(&line, &skip);
1666 if (err < 0) goto error;
1667 err = at_tok_nextint(&line, &resp[0]);
1668 if (err < 0) goto error;
1669 err = at_tok_nexthexint(&line, &resp[1]);
1670 if (err < 0) goto error;
1671 err = at_tok_nexthexint(&line, &resp[2]);
1672 if (err < 0) goto error;
1673 err = at_tok_nextint(&line, &resp[3]);
1674 if (err < 0) goto error;
1675 count = 4;
1676 break;
1677 default:
1678 goto error;
1679 }
1680 s_lac = resp[1];
1681 s_cid = resp[2];
1682 if (response)
1683 *response = resp;
1684 if (items)
1685 *items = commas + 1;
1686 if (type)
1687 *type = techFromModemType(TECH(sMdmInfo));
1688 return 0;
1689 error:
1690 free(resp);
1691 return -1;
1692 }
1693
1694 static int mapNetworkRegistrationResponse(int in_response) {
1695 int out_response = 0;
1696
1697 switch (in_response) {
1698 case 0:
1699 out_response = RADIO_TECH_GPRS; /* GPRS */
1700 break;
1701 case 3:
1702 out_response = RADIO_TECH_EDGE; /* EDGE */
1703 break;
1704 case 2:
1705 out_response = RADIO_TECH_UMTS; /* TD */
1706 break;
1707 case 4:
1708 out_response = RADIO_TECH_HSDPA; /* HSDPA */
1709 break;
1710 case 5:
1711 out_response = RADIO_TECH_HSUPA; /* HSUPA */
1712 break;
1713 case 6:
1714 out_response = RADIO_TECH_HSPA; /* HSPA */
1715 break;
1716 case 15:
1717 out_response = RADIO_TECH_HSPAP; /* HSPA+ */
1718 break;
1719 case 7:
1720 out_response = RADIO_TECH_LTE; /* LTE */
1721 break;
1722 case 16:
1723 out_response = RADIO_TECH_LTE_CA; /* LTE_CA */
1724 break;
1725 case 11: // NR connected to a 5GCN
1726 case 12: // NG-RAN
1727 case 13: // E-UTRA-NR dual connectivity
1728 out_response = RADIO_TECH_NR; /* NR */
1729 break;
1730 default:
1731 out_response = RADIO_TECH_UNKNOWN; /* UNKNOWN */
1732 break;
1733 }
1734 return out_response;
1735 }
1736
1737 #define REG_STATE_LEN 15
1738 #define REG_DATA_STATE_LEN 6
1739 static void requestRegistrationState(int request, void *data __unused,
1740 size_t datalen __unused, RIL_Token t)
1741 {
1742 int err;
1743 int *registration;
1744 char **responseStr = NULL;
1745 ATResponse *p_response = NULL;
1746 const char *cmd;
1747 const char *prefix;
1748 char *line;
1749 int i = 0, j, numElements = 0;
1750 int count = 3;
1751 int type, startfrom;
1752
1753 RLOGD("requestRegistrationState");
1754 if (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1755 cmd = "AT+CREG?";
1756 prefix = "+CREG:";
1757 numElements = REG_STATE_LEN;
1758 } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1759 cmd = "AT+CGREG?";
1760 prefix = "+CGREG:";
1761 numElements = REG_DATA_STATE_LEN;
1762 if (TECH_BIT(sMdmInfo) == MDM_LTE) {
1763 cmd = "AT+CEREG?";
1764 prefix = "+CEREG:";
1765 }
1766 } else {
1767 assert(0);
1768 goto error;
1769 }
1770
1771 err = at_send_command_singleline(cmd, prefix, &p_response);
1772
1773 if (err < 0 || !p_response->success) goto error;
1774
1775 line = p_response->p_intermediates->line;
1776
1777 if (parseRegistrationState(line, &type, &count, ®istration)) goto error;
1778
1779 responseStr = malloc(numElements * sizeof(char *));
1780 if (!responseStr) goto error;
1781 memset(responseStr, 0, numElements * sizeof(char *));
1782 /**
1783 * The first '4' bytes for both registration states remain the same.
1784 * But if the request is 'DATA_REGISTRATION_STATE',
1785 * the 5th and 6th byte(s) are optional.
1786 */
1787 if (is3gpp2(type) == 1) {
1788 RLOGD("registration state type: 3GPP2");
1789 // TODO: Query modem
1790 startfrom = 3;
1791 if(request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1792 asprintf(&responseStr[3], "8"); // EvDo revA
1793 asprintf(&responseStr[4], "1"); // BSID
1794 asprintf(&responseStr[5], "123"); // Latitude
1795 asprintf(&responseStr[6], "222"); // Longitude
1796 asprintf(&responseStr[7], "0"); // CSS Indicator
1797 asprintf(&responseStr[8], "4"); // SID
1798 asprintf(&responseStr[9], "65535"); // NID
1799 asprintf(&responseStr[10], "0"); // Roaming indicator
1800 asprintf(&responseStr[11], "1"); // System is in PRL
1801 asprintf(&responseStr[12], "0"); // Default Roaming indicator
1802 asprintf(&responseStr[13], "0"); // Reason for denial
1803 asprintf(&responseStr[14], "0"); // Primary Scrambling Code of Current cell
1804 } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1805 asprintf(&responseStr[3], "8"); // Available data radio technology
1806 }
1807 } else { // type == RADIO_TECH_3GPP
1808 RLOGD("registration state type: 3GPP");
1809 startfrom = 0;
1810 asprintf(&responseStr[1], "%x", registration[1]);
1811 asprintf(&responseStr[2], "%x", registration[2]);
1812 if (count > 3) {
1813 asprintf(&responseStr[3], "%d", mapNetworkRegistrationResponse(registration[3]));
1814 }
1815 }
1816 asprintf(&responseStr[0], "%d", registration[0]);
1817
1818 /**
1819 * Optional bytes for DATA_REGISTRATION_STATE request
1820 * 4th byte : Registration denial code
1821 * 5th byte : The max. number of simultaneous Data Calls
1822 */
1823 if(request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1824 // asprintf(&responseStr[4], "3");
1825 // asprintf(&responseStr[5], "1");
1826 }
1827
1828 for (j = startfrom; j < numElements; j++) {
1829 if (!responseStr[i]) goto error;
1830 }
1831 free(registration);
1832 registration = NULL;
1833
1834 RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, numElements*sizeof(responseStr));
1835 for (j = 0; j < numElements; j++ ) {
1836 free(responseStr[j]);
1837 responseStr[j] = NULL;
1838 }
1839 free(responseStr);
1840 responseStr = NULL;
1841 at_response_free(p_response);
1842
1843 return;
1844 error:
1845 if (responseStr) {
1846 for (j = 0; j < numElements; j++) {
1847 free(responseStr[j]);
1848 responseStr[j] = NULL;
1849 }
1850 free(responseStr);
1851 responseStr = NULL;
1852 }
1853 RLOGE("requestRegistrationState must never return an error when radio is on");
1854 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1855 at_response_free(p_response);
1856 }
1857
1858 static void requestOperator(void *data __unused, size_t datalen __unused, RIL_Token t)
1859 {
1860 int err;
1861 int i;
1862 int skip;
1863 ATLine *p_cur;
1864 char *response[3];
1865
1866 memset(response, 0, sizeof(response));
1867
1868 ATResponse *p_response = NULL;
1869
1870 err = at_send_command_multiline(
1871 "AT+COPS=3,0;+COPS?;+COPS=3,1;+COPS?;+COPS=3,2;+COPS?",
1872 "+COPS:", &p_response);
1873
1874 /* we expect 3 lines here:
1875 * +COPS: 0,0,"T - Mobile"
1876 * +COPS: 0,1,"TMO"
1877 * +COPS: 0,2,"310170"
1878 */
1879
1880 if (err != 0) goto error;
1881
1882 for (i = 0, p_cur = p_response->p_intermediates
1883 ; p_cur != NULL
1884 ; p_cur = p_cur->p_next, i++
1885 ) {
1886 char *line = p_cur->line;
1887
1888 err = at_tok_start(&line);
1889 if (err < 0) goto error;
1890
1891 err = at_tok_nextint(&line, &skip);
1892 if (err < 0) goto error;
1893
1894 // If we're unregistered, we may just get
1895 // a "+COPS: 0" response
1896 if (!at_tok_hasmore(&line)) {
1897 response[i] = NULL;
1898 continue;
1899 }
1900
1901 err = at_tok_nextint(&line, &skip);
1902 if (err < 0) goto error;
1903
1904 // a "+COPS: 0, n" response is also possible
1905 if (!at_tok_hasmore(&line)) {
1906 response[i] = NULL;
1907 continue;
1908 }
1909
1910 err = at_tok_nextstr(&line, &(response[i]));
1911 if (err < 0) goto error;
1912 // Simple assumption that mcc and mnc are 3 digits each
1913 int length = strlen(response[i]);
1914 if (length == 6) {
1915 if (sscanf(response[i], "%3d%3d", &s_mcc, &s_mnc) != 2) {
1916 RLOGE("requestOperator expected mccmnc to be 6 decimal digits");
1917 }
1918 } else if (length == 5) {
1919 if (sscanf(response[i], "%3d%2d", &s_mcc, &s_mnc) != 2) {
1920 RLOGE("requestOperator expected mccmnc to be 5 decimal digits");
1921 }
1922 }
1923 }
1924
1925 if (i != 3) {
1926 /* expect 3 lines exactly */
1927 goto error;
1928 }
1929
1930 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
1931 at_response_free(p_response);
1932
1933 return;
1934 error:
1935 RLOGE("requestOperator must not return error when radio is on");
1936 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1937 at_response_free(p_response);
1938 }
1939
1940 static void requestCdmaSendSMS(void *data, size_t datalen, RIL_Token t)
1941 {
1942 int err = 1; // Set to go to error:
1943 RIL_SMS_Response response;
1944 RIL_CDMA_SMS_Message* rcsm;
1945
1946 if (getSIMStatus() == SIM_ABSENT) {
1947 RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
1948 return;
1949 }
1950
1951 RLOGD("requestCdmaSendSMS datalen=%zu, sizeof(RIL_CDMA_SMS_Message)=%zu",
1952 datalen, sizeof(RIL_CDMA_SMS_Message));
1953
1954 // verify data content to test marshalling/unmarshalling:
1955 rcsm = (RIL_CDMA_SMS_Message*)data;
1956 RLOGD("TeleserviceID=%d, bIsServicePresent=%d, \
1957 uServicecategory=%d, sAddress.digit_mode=%d, \
1958 sAddress.Number_mode=%d, sAddress.number_type=%d, ",
1959 rcsm->uTeleserviceID, rcsm->bIsServicePresent,
1960 rcsm->uServicecategory,rcsm->sAddress.digit_mode,
1961 rcsm->sAddress.number_mode,rcsm->sAddress.number_type);
1962
1963 if (err != 0) goto error;
1964
1965 // Cdma Send SMS implementation will go here:
1966 // But it is not implemented yet.
1967
1968 memset(&response, 0, sizeof(response));
1969 response.messageRef = 1;
1970 RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1971 return;
1972
1973 error:
1974 // Cdma Send SMS will always cause send retry error.
1975 response.messageRef = -1;
1976 RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
1977 }
1978
1979 static void requestSendSMS(void *data, size_t datalen, RIL_Token t)
1980 {
1981 int err;
1982 const char *smsc;
1983 const char *pdu;
1984 int tpLayerLength;
1985 char *cmd1, *cmd2;
1986 RIL_SMS_Response response;
1987 ATResponse *p_response = NULL;
1988
1989 if (getSIMStatus() == SIM_ABSENT) {
1990 RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
1991 return;
1992 }
1993
1994 memset(&response, 0, sizeof(response));
1995 RLOGD("requestSendSMS datalen =%zu", datalen);
1996
1997 if (s_ims_gsm_fail != 0) goto error;
1998 if (s_ims_gsm_retry != 0) goto error2;
1999
2000 smsc = ((const char **)data)[0];
2001 pdu = ((const char **)data)[1];
2002
2003 tpLayerLength = strlen(pdu)/2;
2004
2005 // "NULL for default SMSC"
2006 if (smsc == NULL) {
2007 smsc= "00";
2008 }
2009
2010 asprintf(&cmd1, "AT+CMGS=%d", tpLayerLength);
2011 asprintf(&cmd2, "%s%s", smsc, pdu);
2012
2013 err = at_send_command_sms(cmd1, cmd2, "+CMGS:", &p_response);
2014
2015 free(cmd1);
2016 free(cmd2);
2017
2018 if (err != 0 || p_response->success == 0) goto error;
2019
2020 int messageRef = 1;
2021 char *line = p_response->p_intermediates->line;
2022
2023 err = at_tok_start(&line);
2024 if (err < 0) goto error;
2025
2026 err = at_tok_nextint(&line, &messageRef);
2027 if (err < 0) goto error;
2028
2029 /* FIXME fill in ackPDU */
2030 response.messageRef = messageRef;
2031 RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
2032 at_response_free(p_response);
2033
2034 return;
2035 error:
2036 response.messageRef = -2;
2037 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response));
2038 at_response_free(p_response);
2039 return;
2040 error2:
2041 // send retry error.
2042 response.messageRef = -1;
2043 RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
2044 at_response_free(p_response);
2045 return;
2046 }
2047
2048 static void requestImsSendSMS(void *data, size_t datalen, RIL_Token t)
2049 {
2050 RIL_IMS_SMS_Message *p_args;
2051 RIL_SMS_Response response;
2052
2053 memset(&response, 0, sizeof(response));
2054
2055 RLOGD("requestImsSendSMS: datalen=%zu, "
2056 "registered=%d, service=%d, format=%d, ims_perm_fail=%d, "
2057 "ims_retry=%d, gsm_fail=%d, gsm_retry=%d",
2058 datalen, s_ims_registered, s_ims_services, s_ims_format,
2059 s_ims_cause_perm_failure, s_ims_cause_retry, s_ims_gsm_fail,
2060 s_ims_gsm_retry);
2061
2062 // figure out if this is gsm/cdma format
2063 // then route it to requestSendSMS vs requestCdmaSendSMS respectively
2064 p_args = (RIL_IMS_SMS_Message *)data;
2065
2066 if (0 != s_ims_cause_perm_failure ) goto error;
2067
2068 // want to fail over ims and this is first request over ims
2069 if (0 != s_ims_cause_retry && 0 == p_args->retry) goto error2;
2070
2071 if (RADIO_TECH_3GPP == p_args->tech) {
2072 return requestSendSMS(p_args->message.gsmMessage,
2073 datalen - sizeof(RIL_RadioTechnologyFamily),
2074 t);
2075 } else if (RADIO_TECH_3GPP2 == p_args->tech) {
2076 return requestCdmaSendSMS(p_args->message.cdmaMessage,
2077 datalen - sizeof(RIL_RadioTechnologyFamily),
2078 t);
2079 } else {
2080 RLOGE("requestImsSendSMS invalid format value =%d", p_args->tech);
2081 }
2082
2083 error:
2084 response.messageRef = -2;
2085 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response));
2086 return;
2087
2088 error2:
2089 response.messageRef = -1;
2090 RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
2091 }
2092
2093 static void requestSimOpenChannel(void *data, size_t datalen, RIL_Token t)
2094 {
2095 ATResponse *p_response = NULL;
2096 int32_t session_id;
2097 int err;
2098 char cmd[64];
2099 char dummy;
2100 char *line;
2101
2102 // Max length is 16 bytes according to 3GPP spec 27.007 section 8.45
2103 if (data == NULL || datalen == 0 || datalen > 16) {
2104 ALOGE("Invalid data passed to requestSimOpenChannel");
2105 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2106 return;
2107 }
2108
2109 snprintf(cmd, sizeof(cmd), "AT+CCHO=%s", data);
2110
2111 err = at_send_command_numeric(cmd, &p_response);
2112 if (err < 0 || p_response == NULL || p_response->success == 0) {
2113 ALOGE("Error %d opening logical channel: %d",
2114 err, p_response ? p_response->success : 0);
2115 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2116 at_response_free(p_response);
2117 return;
2118 }
2119
2120 // Ensure integer only by scanning for an extra char but expect one result
2121 line = p_response->p_intermediates->line;
2122 if (sscanf(line, "%" SCNd32 "%c", &session_id, &dummy) != 1) {
2123 ALOGE("Invalid AT response, expected integer, was '%s'", line);
2124 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2125 return;
2126 }
2127
2128 RIL_onRequestComplete(t, RIL_E_SUCCESS, &session_id, sizeof(&session_id));
2129 at_response_free(p_response);
2130 }
2131
2132 static void requestSimCloseChannel(void *data, size_t datalen, RIL_Token t)
2133 {
2134 ATResponse *p_response = NULL;
2135 int32_t session_id;
2136 int err;
2137 char cmd[32];
2138
2139 if (data == NULL || datalen != sizeof(session_id)) {
2140 ALOGE("Invalid data passed to requestSimCloseChannel");
2141 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2142 return;
2143 }
2144 session_id = ((int32_t *)data)[0];
2145 if (session_id == 0) {
2146 RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
2147 return;
2148 }
2149
2150 snprintf(cmd, sizeof(cmd), "AT+CCHC=%" PRId32, session_id);
2151 err = at_send_command_singleline(cmd, "+CCHC", &p_response);
2152
2153 if (err < 0 || p_response == NULL || p_response->success == 0) {
2154 ALOGE("Error %d closing logical channel %d: %d",
2155 err, session_id, p_response ? p_response->success : 0);
2156 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2157 at_response_free(p_response);
2158 return;
2159 }
2160
2161
2162 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2163
2164 at_response_free(p_response);
2165 }
2166
2167 static void requestSimTransmitApduChannel(void *data,
2168 size_t datalen,
2169 RIL_Token t)
2170 {
2171 ATResponse *p_response = NULL;
2172 int err;
2173 char *cmd;
2174 char *line;
2175 size_t cmd_size;
2176 RIL_SIM_IO_Response sim_response;
2177 RIL_SIM_APDU *apdu = (RIL_SIM_APDU *)data;
2178
2179 if (apdu == NULL || datalen != sizeof(RIL_SIM_APDU)) {
2180 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2181 return;
2182 }
2183
2184 cmd_size = 10 + (apdu->data ? strlen(apdu->data) : 0);
2185 asprintf(&cmd, "AT+CGLA=%d,%zu,%02x%02x%02x%02x%02x%s",
2186 apdu->sessionid, cmd_size, apdu->cla, apdu->instruction,
2187 apdu->p1, apdu->p2, apdu->p3, apdu->data ? apdu->data : "");
2188
2189 err = at_send_command_singleline(cmd, "+CGLA", &p_response);
2190 free(cmd);
2191 if (err < 0 || p_response == NULL || p_response->success == 0) {
2192 ALOGE("Error %d transmitting APDU: %d",
2193 err, p_response ? p_response->success : 0);
2194 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2195 at_response_free(p_response);
2196 return;
2197 }
2198
2199 line = p_response->p_intermediates->line;
2200 err = parseSimResponseLine(line, &sim_response);
2201
2202 if (err == 0) {
2203 RIL_onRequestComplete(t, RIL_E_SUCCESS,
2204 &sim_response, sizeof(sim_response));
2205 } else {
2206 ALOGE("Error %d parsing SIM response line: %s", err, line);
2207 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2208 }
2209 at_response_free(p_response);
2210 }
2211
2212 static int getPDP() {
2213 int ret = -1;
2214
2215 for (int i = 0; i < MAX_PDP; i++) {
2216 if (s_PDP[i].state == PDP_IDLE) {
2217 s_PDP[i].state = PDP_BUSY;
2218 ret = s_PDP[i].cid;
2219 break;
2220 }
2221 }
2222 return ret;
2223 }
2224
2225 static void putPDP(int cid) {
2226 if (cid < 1 || cid > MAX_PDP ) {
2227 return;
2228 }
2229
2230 s_PDP[cid - 1].state = PDP_IDLE;
2231 }
2232
2233 static void requestSetupDataCall(void *data, size_t datalen, RIL_Token t)
2234 {
2235 const char *apn = NULL;
2236 char *cmd = NULL;
2237 int err = -1;
2238 int cid = -1;
2239 ATResponse *p_response = NULL;
2240
2241 apn = ((const char **)data)[2];
2242
2243 #ifdef USE_TI_COMMANDS
2244 // Config for multislot class 10 (probably default anyway eh?)
2245 err = at_send_command("AT%CPRIM=\"GMM\",\"CONFIG MULTISLOT_CLASS=<10>\"",
2246 NULL);
2247
2248 err = at_send_command("AT%DATA=2,\"UART\",1,,\"SER\",\"UART\",0", NULL);
2249 #endif /* USE_TI_COMMANDS */
2250
2251 int fd, qmistatus;
2252 size_t cur = 0;
2253 size_t len;
2254 ssize_t written, rlen;
2255 char status[32] = {0};
2256 int retry = 10;
2257 const char *pdp_type;
2258
2259 RLOGD("requesting data connection to APN '%s'", apn);
2260
2261 fd = open ("/dev/qmi", O_RDWR);
2262 if (fd >= 0) { /* the device doesn't exist on the emulator */
2263
2264 RLOGD("opened the qmi device\n");
2265 asprintf(&cmd, "up:%s", apn);
2266 len = strlen(cmd);
2267
2268 while (cur < len) {
2269 do {
2270 written = write (fd, cmd + cur, len - cur);
2271 } while (written < 0 && errno == EINTR);
2272
2273 if (written < 0) {
2274 RLOGE("### ERROR writing to /dev/qmi");
2275 close(fd);
2276 goto error;
2277 }
2278
2279 cur += written;
2280 }
2281
2282 // wait for interface to come online
2283
2284 do {
2285 sleep(1);
2286 do {
2287 rlen = read(fd, status, 31);
2288 } while (rlen < 0 && errno == EINTR);
2289
2290 if (rlen < 0) {
2291 RLOGE("### ERROR reading from /dev/qmi");
2292 close(fd);
2293 goto error;
2294 } else {
2295 status[rlen] = '\0';
2296 RLOGD("### status: %s", status);
2297 }
2298 } while (strncmp(status, "STATE=up", 8) && strcmp(status, "online") && --retry);
2299
2300 close(fd);
2301
2302 if (retry == 0) {
2303 RLOGE("### Failed to get data connection up\n");
2304 goto error;
2305 }
2306
2307 qmistatus = system("netcfg rmnet0 dhcp");
2308
2309 RLOGD("netcfg rmnet0 dhcp: status %d\n", qmistatus);
2310
2311 if (qmistatus < 0) goto error;
2312
2313 } else {
2314 bool hasWifi = hasWifiCapability();
2315 const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
2316 if (setInterfaceState(radioInterfaceName, kInterfaceUp) != RIL_E_SUCCESS) {
2317 goto error;
2318 }
2319
2320 if (datalen > 6 * sizeof(char *)) {
2321 pdp_type = ((const char **)data)[6];
2322 } else {
2323 pdp_type = "IP";
2324 }
2325
2326 cid = getPDP();
2327 if (cid < 1 ) goto error;
2328
2329 asprintf(&cmd, "AT+CGDCONT=%d,\"%s\",\"%s\",,0,0", cid, pdp_type, apn);
2330 //FIXME check for error here
2331 err = at_send_command(cmd, NULL);
2332 free(cmd);
2333
2334 // Set required QoS params to default
2335 err = at_send_command("AT+CGQREQ=1", NULL);
2336
2337 // Set minimum QoS params to default
2338 err = at_send_command("AT+CGQMIN=1", NULL);
2339
2340 // packet-domain event reporting
2341 err = at_send_command("AT+CGEREP=1,0", NULL);
2342
2343 // Hangup anything that's happening there now
2344 err = at_send_command("AT+CGACT=1,0", NULL);
2345
2346 // Start data on PDP context 1
2347 err = at_send_command("ATD*99***1#", &p_response);
2348
2349 if (err < 0 || p_response->success == 0) {
2350 goto error;
2351 }
2352 }
2353
2354 requestOrSendDataCallList(cid, &t);
2355
2356 at_response_free(p_response);
2357
2358 return;
2359 error:
2360 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2361 at_response_free(p_response);
2362 }
2363
2364 static void requestDeactivateDataCall(void *data, RIL_Token t)
2365 {
2366 const char *p_cid = ((const char **)data)[0];
2367 int cid = p_cid ? atoi(p_cid) : -1;
2368 RIL_Errno rilErrno = RIL_E_GENERIC_FAILURE;
2369 if (cid < 1 || cid > MAX_PDP) {
2370 RIL_onRequestComplete(t, rilErrno, NULL, 0);
2371 return;
2372 }
2373
2374 bool hasWifi = hasWifiCapability();
2375 const char* radioInterfaceName = getRadioInterfaceName(hasWifi);
2376 rilErrno = setInterfaceState(radioInterfaceName, kInterfaceDown);
2377 RIL_onRequestComplete(t, rilErrno, NULL, 0);
2378 putPDP(cid);
2379 }
2380
2381 static void requestSMSAcknowledge(void *data, size_t datalen __unused, RIL_Token t)
2382 {
2383 int ackSuccess;
2384 int err;
2385
2386 if (getSIMStatus() == SIM_ABSENT) {
2387 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2388 return;
2389 }
2390
2391 ackSuccess = ((int *)data)[0];
2392
2393 if (ackSuccess == 1) {
2394 err = at_send_command("AT+CNMA=1", NULL);
2395 } else if (ackSuccess == 0) {
2396 err = at_send_command("AT+CNMA=2", NULL);
2397 } else {
2398 RLOGE("unsupported arg to RIL_REQUEST_SMS_ACKNOWLEDGE\n");
2399 goto error;
2400 }
2401
2402 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2403 error:
2404 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2405 }
2406
2407 void convertBytesToHex(uint8_t *bytes, int length, uint8_t *hex_str) {
2408 int i;
2409 unsigned char tmp;
2410
2411 if (bytes == NULL || hex_str == NULL) {
2412 return;
2413 }
2414 for (i = 0; i < length; i++) {
2415 tmp = (unsigned char)((bytes[i] & 0xf0) >> 4);
2416 if (tmp <= 9) {
2417 *hex_str = (unsigned char)(tmp + '0');
2418 } else {
2419 *hex_str = (unsigned char)(tmp + 'A' - 10);
2420 }
2421 hex_str++;
2422 tmp = (unsigned char)(bytes[i] & 0x0f);
2423 if (tmp <= 9) {
2424 *hex_str = (unsigned char)(tmp + '0');
2425 } else {
2426 *hex_str = (unsigned char)(tmp + 'A' - 10);
2427 }
2428 hex_str++;
2429 }
2430 }
2431
2432 #define TYPE_EF 4
2433 #define RESPONSE_EF_SIZE 15
2434 #define TYPE_FILE_DES_LEN 5
2435 #define RESPONSE_DATA_FILE_DES_FLAG 2
2436 #define RESPONSE_DATA_FILE_DES_LEN_FLAG 3
2437 #define RESPONSE_DATA_FILE_TYPE 6
2438 #define RESPONSE_DATA_FILE_SIZE_1 2
2439 #define RESPONSE_DATA_FILE_SIZE_2 3
2440 #define RESPONSE_DATA_STRUCTURE 13
2441 #define RESPONSE_DATA_RECORD_LENGTH 14
2442 #define RESPONSE_DATA_FILE_RECORD_LEN_1 6
2443 #define RESPONSE_DATA_FILE_RECORD_LEN_2 7
2444 #define EF_TYPE_TRANSPARENT 0x01
2445 #define EF_TYPE_LINEAR_FIXED 0x02
2446 #define EF_TYPE_CYCLIC 0x06
2447 #define USIM_DATA_OFFSET_2 2
2448 #define USIM_DATA_OFFSET_3 3
2449 #define USIM_FILE_DES_TAG 0x82
2450 #define USIM_FILE_SIZE_TAG 0x80
2451
2452 bool convertUsimToSim(uint8_t *byteUSIM, int len, uint8_t *hexSIM) {
2453 int desIndex = 0;
2454 int sizeIndex = 0;
2455 int i = 0;
2456 uint8_t byteSIM[RESPONSE_EF_SIZE] = {0};
2457 for (i = 0; i < len; i++) {
2458 if (byteUSIM[i] == USIM_FILE_DES_TAG) {
2459 desIndex = i;
2460 break;
2461 }
2462 }
2463 for (i = desIndex; i < len;) {
2464 if (byteUSIM[i] == USIM_FILE_SIZE_TAG) {
2465 sizeIndex = i;
2466 break;
2467 } else {
2468 i += (byteUSIM[i + 1] + 2);
2469 }
2470 }
2471 byteSIM[RESPONSE_DATA_FILE_SIZE_1] =
2472 byteUSIM[sizeIndex + USIM_DATA_OFFSET_2];
2473 byteSIM[RESPONSE_DATA_FILE_SIZE_2] =
2474 byteUSIM[sizeIndex + USIM_DATA_OFFSET_3];
2475 byteSIM[RESPONSE_DATA_FILE_TYPE] = TYPE_EF;
2476 if ((byteUSIM[desIndex + RESPONSE_DATA_FILE_DES_FLAG] & 0x07) ==
2477 EF_TYPE_TRANSPARENT) {
2478 byteSIM[RESPONSE_DATA_STRUCTURE] = 0;
2479 } else if ((byteUSIM[desIndex + RESPONSE_DATA_FILE_DES_FLAG] & 0x07) ==
2480 EF_TYPE_LINEAR_FIXED) {
2481 if (USIM_FILE_DES_TAG != byteUSIM[RESPONSE_DATA_FILE_DES_FLAG]) {
2482 RLOGE("USIM_FILE_DES_TAG != ...");
2483 goto error;
2484 }
2485 if (TYPE_FILE_DES_LEN != byteUSIM[RESPONSE_DATA_FILE_DES_LEN_FLAG]) {
2486 goto error;
2487 }
2488 byteSIM[RESPONSE_DATA_STRUCTURE] = 1;
2489 byteSIM[RESPONSE_DATA_RECORD_LENGTH] =
2490 ((byteUSIM[RESPONSE_DATA_FILE_RECORD_LEN_1] & 0xff) << 8) +
2491 (byteUSIM[RESPONSE_DATA_FILE_RECORD_LEN_2] & 0xff);
2492 } else if ((byteUSIM[desIndex + RESPONSE_DATA_FILE_DES_FLAG] & 0x07) ==
2493 EF_TYPE_CYCLIC) {
2494 byteSIM[RESPONSE_DATA_STRUCTURE] = 3;
2495 byteSIM[RESPONSE_DATA_RECORD_LENGTH] =
2496 ((byteUSIM[RESPONSE_DATA_FILE_RECORD_LEN_1] & 0xff) << 8) +
2497 (byteUSIM[RESPONSE_DATA_FILE_RECORD_LEN_2] & 0xff);
2498 }
2499
2500 convertBytesToHex(byteSIM, RESPONSE_EF_SIZE, hexSIM);
2501 return true;
2502
2503 error:
2504 return false;
2505 }
2506
2507 static void requestSIM_IO(void *data, size_t datalen __unused, RIL_Token t)
2508 {
2509 ATResponse *p_response = NULL;
2510 RIL_SIM_IO_Response sr;
2511 int err;
2512 char *cmd = NULL;
2513 RIL_SIM_IO_v6 *p_args;
2514 char *line;
2515
2516 /* For Convert USIM to SIM */
2517 uint8_t hexSIM[RESPONSE_EF_SIZE * 2 + sizeof(char)] = {0};
2518
2519 memset(&sr, 0, sizeof(sr));
2520
2521 p_args = (RIL_SIM_IO_v6 *)data;
2522
2523 /* FIXME handle pin2 */
2524
2525 if (p_args->data == NULL) {
2526 asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d",
2527 p_args->command, p_args->fileid,
2528 p_args->p1, p_args->p2, p_args->p3);
2529 } else {
2530 asprintf(&cmd, "AT+CRSM=%d,%d,%d,%d,%d,%s",
2531 p_args->command, p_args->fileid,
2532 p_args->p1, p_args->p2, p_args->p3, p_args->data);
2533 }
2534
2535 err = at_send_command_singleline(cmd, "+CRSM:", &p_response);
2536
2537 if (err < 0 || p_response->success == 0) {
2538 goto error;
2539 }
2540
2541 line = p_response->p_intermediates->line;
2542
2543 err = parseSimResponseLine(line, &sr);
2544 if (err < 0) {
2545 goto error;
2546 }
2547 if (sr.simResponse != NULL && // Default to be USIM card
2548 p_args->command == 192) { // Get response
2549 uint8_t *bytes = convertHexStringToBytes(sr.simResponse, strlen(sr.simResponse));
2550 if (bytes == NULL) {
2551 RLOGE("Failed to convert sim response to bytes");
2552 goto error;
2553 }
2554 if (bytes[0] != 0x62) {
2555 RLOGE("Wrong FCP flag, unable to convert to sim ");
2556 free(bytes);
2557 goto error;
2558 }
2559 if (convertUsimToSim(bytes, strlen(sr.simResponse) / 2, hexSIM)) {
2560 sr.simResponse = (char *)hexSIM;
2561 }
2562 free(bytes);
2563 }
2564
2565 RIL_onRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
2566 at_response_free(p_response);
2567 free(cmd);
2568 return;
2569
2570 error:
2571 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2572 at_response_free(p_response);
2573 free(cmd);
2574 }
2575
2576 static int getSimlockRemainTimes(const char* type) {
2577 int err = -1;
2578 int remain_times = -1;
2579 char cmd[32] = {0};
2580 char *line = NULL;
2581 char *lock_type = NULL;
2582 ATResponse *p_response = NULL;
2583
2584 snprintf(cmd, sizeof(cmd), "AT+CPINR=\"%s\"", type);
2585 err = at_send_command_multiline(cmd, "+CPINR:", &p_response);
2586 if (err < 0 || p_response->success == 0) {
2587 goto error;
2588 }
2589
2590 line = p_response->p_intermediates->line;
2591 err = at_tok_start(&line);
2592 if (err < 0) goto error;
2593
2594 err = at_tok_nextstr(&line, &lock_type);
2595 if (err < 0) goto error;
2596
2597 err = at_tok_nextint(&line, &remain_times);
2598 if (err < 0) goto error;
2599
2600 error:
2601 at_response_free(p_response);
2602 return remain_times;
2603 }
2604
2605 static void requestEnterSimPin(int request, void* data, size_t datalen, RIL_Token t)
2606 {
2607 ATResponse *p_response = NULL;
2608 int err;
2609 int remaintimes = -1;
2610 char* cmd = NULL;
2611 const char** strings = (const char**)data;;
2612
2613 if (datalen == sizeof(char*) || datalen == 2 * sizeof(char*)) {
2614 asprintf(&cmd, "AT+CPIN=%s", strings[0]);
2615 } else
2616 goto error;
2617
2618 err = at_send_command_singleline(cmd, "+CPIN:", &p_response);
2619 free(cmd);
2620
2621 if (err < 0 || p_response->success == 0) {
2622 error:
2623 if (request == RIL_REQUEST_ENTER_SIM_PIN) {
2624 remaintimes = getSimlockRemainTimes("SIM PIN");
2625 } else if (request == RIL_REQUEST_ENTER_SIM_PIN2) {
2626 remaintimes = getSimlockRemainTimes("SIM PIN2");
2627 }
2628 RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &remaintimes,
2629 sizeof(remaintimes));
2630 } else {
2631 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2632 }
2633 at_response_free(p_response);
2634 }
2635
2636 static void requestChangeSimPin(int request, void* data, size_t datalen, RIL_Token t)
2637 {
2638 ATResponse *p_response = NULL;
2639 int err;
2640 int remaintimes = -1;
2641 char* cmd = NULL;
2642 const char** strings = (const char**)data;;
2643
2644 if (datalen == 2 * sizeof(char*) || datalen == 3 * sizeof(char*)) {
2645 asprintf(&cmd, "AT+CPIN=%s,%s", strings[0], strings[1]);
2646 } else
2647 goto error;
2648
2649 err = at_send_command_singleline(cmd, "+CPIN:", &p_response);
2650 free(cmd);
2651
2652 if (err < 0 || p_response->success == 0) {
2653 error:
2654 if (request == RIL_REQUEST_CHANGE_SIM_PIN) {
2655 remaintimes = getSimlockRemainTimes("SIM PIN");
2656 } else if (request == RIL_REQUEST_ENTER_SIM_PUK) {
2657 remaintimes = getSimlockRemainTimes("SIM PUK");
2658 } else if (request == RIL_REQUEST_ENTER_SIM_PUK2) {
2659 remaintimes = getSimlockRemainTimes("SIM PUK2");
2660 }
2661 RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &remaintimes,
2662 sizeof(remaintimes));
2663 } else {
2664 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2665 }
2666 at_response_free(p_response);
2667 }
2668
2669 static void requestChangeSimPin2(void *data, size_t datalen, RIL_Token t) {
2670 int err, ret;
2671 int remaintime = -1;
2672 char cmd[64] = {0};
2673 const char **strings = (const char **)data;
2674 ATResponse *p_response = NULL;
2675
2676 if (datalen != 3 * sizeof(char *)) {
2677 goto error;
2678 }
2679
2680 snprintf(cmd, sizeof(cmd), "AT+CPWD=\"P2\",\"%s\",\"%s\"", strings[0],
2681 strings[1]);
2682 err = at_send_command(cmd, &p_response);
2683 if (err < 0 || p_response->success == 0) {
2684 remaintime = getSimlockRemainTimes("SIM PIN2");
2685 goto error;
2686 }
2687
2688 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2689 at_response_free(p_response);
2690 return;
2691
2692 error:
2693 RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &remaintime,
2694 sizeof(remaintime));
2695 at_response_free(p_response);
2696 }
2697
2698 static void requestSendUSSD(void *data, size_t datalen, RIL_Token t)
2699 {
2700 RIL_UNUSED_PARM(datalen);
2701
2702 int err = -1;
2703 char cmd[128] = {0};
2704 const char *ussdRequest = (char *)(data);
2705 ATResponse *p_response = NULL;
2706
2707 snprintf(cmd, sizeof(cmd), "AT+CUSD=1,\"%s\"", ussdRequest);
2708 err = at_send_command(cmd, &p_response);
2709 if (err < 0 || p_response->success == 0) {
2710 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2711 } else {
2712 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2713 }
2714 at_response_free(p_response);
2715 }
2716
2717 static void requestExitEmergencyMode(void *data __unused, size_t datalen __unused, RIL_Token t)
2718 {
2719 int err;
2720 ATResponse *p_response = NULL;
2721
2722 err = at_send_command("AT+WSOS=0", &p_response);
2723
2724 if (err < 0 || p_response->success == 0) {
2725 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2726 return;
2727 }
2728
2729 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2730 }
2731
2732 // TODO: Use all radio types
2733 static int techFromModemType(int mdmtype)
2734 {
2735 int ret = -1;
2736 switch (mdmtype) {
2737 case MDM_CDMA:
2738 ret = RADIO_TECH_1xRTT;
2739 break;
2740 case MDM_EVDO:
2741 ret = RADIO_TECH_EVDO_A;
2742 break;
2743 case MDM_GSM:
2744 ret = RADIO_TECH_GPRS;
2745 break;
2746 case MDM_WCDMA:
2747 ret = RADIO_TECH_HSPA;
2748 break;
2749 case MDM_LTE:
2750 ret = RADIO_TECH_LTE;
2751 case MDM_NR:
2752 ret = RADIO_TECH_NR;
2753 break;
2754 }
2755 return ret;
2756 }
2757
2758 static void requestGetCellInfoList(void *data __unused, size_t datalen __unused, RIL_Token t)
2759 {
2760 uint64_t curTime = ril_nano_time();
2761 RIL_CellInfo_v12 ci[1] =
2762 {
2763 { // ci[0]
2764 1, // cellInfoType
2765 1, // registered
2766 RIL_TIMESTAMP_TYPE_MODEM,
2767 curTime - 1000, // Fake some time in the past
2768 { // union CellInfo
2769 { // RIL_CellInfoGsm gsm
2770 { // gsm.cellIdneityGsm
2771 s_mcc, // mcc
2772 s_mnc, // mnc
2773 s_lac, // lac
2774 s_cid, // cid
2775 0, //arfcn unknown
2776 0xFF, // bsic unknown
2777 },
2778 { // gsm.signalStrengthGsm
2779 10, // signalStrength
2780 0 // bitErrorRate
2781 , INT_MAX // timingAdvance invalid value
2782 }
2783 }
2784 }
2785 }
2786 };
2787
2788 RIL_onRequestComplete(t, RIL_E_SUCCESS, ci, sizeof(ci));
2789 }
2790
2791
2792 static void requestSetCellInfoListRate(void *data, size_t datalen __unused, RIL_Token t)
2793 {
2794 // For now we'll save the rate but no RIL_UNSOL_CELL_INFO_LIST messages
2795 // will be sent.
2796 assert (datalen == sizeof(int));
2797 s_cell_info_rate_ms = ((int *)data)[0];
2798
2799 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2800 }
2801
2802 static void requestGetHardwareConfig(void *data, size_t datalen, RIL_Token t)
2803 {
2804 // TODO - hook this up with real query/info from radio.
2805
2806 RIL_HardwareConfig hwCfg;
2807
2808 RIL_UNUSED_PARM(data);
2809 RIL_UNUSED_PARM(datalen);
2810
2811 hwCfg.type = -1;
2812
2813 RIL_onRequestComplete(t, RIL_E_SUCCESS, &hwCfg, sizeof(hwCfg));
2814 }
2815
2816 static void requestGetTtyMode(void *data, size_t datalen, RIL_Token t)
2817 {
2818 int ttyModeResponse;
2819
2820 RIL_UNUSED_PARM(data);
2821 RIL_UNUSED_PARM(datalen);
2822
2823 ttyModeResponse = (getSIMStatus() == SIM_READY) ? 1 // TTY Full
2824 : 0; // TTY Off
2825
2826 RIL_onRequestComplete(t, RIL_E_SUCCESS, &ttyModeResponse, sizeof(ttyModeResponse));
2827 }
2828
2829 static void requestGetRadioCapability(void *data, size_t datalen, RIL_Token t)
2830 {
2831 RIL_RadioCapability radioCapability;
2832
2833 RIL_UNUSED_PARM(data);
2834 RIL_UNUSED_PARM(datalen);
2835
2836 radioCapability.version = RIL_RADIO_CAPABILITY_VERSION;
2837 radioCapability.session = 0;
2838 radioCapability.phase = 0;
2839 radioCapability.rat = NR | LTE | WCDMA | GSM;
2840 strncpy(radioCapability.logicalModemUuid, "com.android.modem.simulator", MAX_UUID_LENGTH);
2841 radioCapability.status = RC_STATUS_SUCCESS;
2842
2843 RIL_onRequestComplete(t, RIL_E_SUCCESS, &radioCapability, sizeof(radioCapability));
2844 }
2845
2846 static void requestSetRadioCapability(void *data, size_t datalen, RIL_Token t)
2847 {
2848 RIL_RadioCapability* rc = (RIL_RadioCapability*)data;
2849 RLOGV(
2850 "RadioCapability version %d session %d phase %d rat %d "
2851 "logicalModemUuid %s status %d",
2852 rc->version, rc->session, rc->phase, rc->rat, rc->logicalModemUuid,
2853 rc->status);
2854 // TODO(ender): do something about these numbers.
2855 RIL_onRequestComplete(t, RIL_E_SUCCESS, rc, datalen);
2856 }
2857
2858 static void requestGetMute(void *data, size_t datalen, RIL_Token t)
2859 {
2860 RIL_UNUSED_PARM(data);
2861 RIL_UNUSED_PARM(datalen);
2862
2863 int err = -1;
2864 int muteResponse = 0; // Mute disabled
2865 char *line = NULL;
2866 ATResponse *p_response = NULL;
2867
2868 err = at_send_command_singleline("AT+CMUT?", "+CMUX:", &p_response);
2869 if (err < 0 || p_response->success) {
2870 goto done;
2871 }
2872
2873 line = p_response->p_intermediates->line;
2874 err = at_tok_start(&line);
2875 if (err < 0) goto done;
2876
2877 at_tok_nextint(&line, &muteResponse);
2878
2879 done:
2880 RIL_onRequestComplete(t, RIL_E_SUCCESS, &muteResponse, sizeof(muteResponse));
2881 at_response_free(p_response);
2882 }
2883
2884 static void requestSetMute(void *data, size_t datalen, RIL_Token t)
2885 {
2886 RIL_UNUSED_PARM(datalen);
2887
2888 int err = -1;
2889 char cmd[64] = {0};
2890 ATResponse *p_response = NULL;
2891
2892 snprintf(cmd, sizeof(cmd), "AT+CMUT=%d", ((int *)data)[0]);
2893 err = at_send_command(cmd, &p_response);
2894 if (err < 0 || p_response->success) {
2895 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2896 } else {
2897 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2898 }
2899 at_response_free(p_response);
2900 }
2901
2902 static void requestScreenState(void *data, RIL_Token t)
2903 {
2904 int status = *((int *)data);
2905
2906 if (!status) {
2907 /* Suspend */
2908 at_send_command("AT+CEREG=1", NULL);
2909 at_send_command("AT+CREG=1", NULL);
2910 at_send_command("AT+CGREG=1", NULL);
2911 } else {
2912 /* Resume */
2913 at_send_command("AT+CEREG=2", NULL);
2914 at_send_command("AT+CREG=2", NULL);
2915 at_send_command("AT+CGREG=2", NULL);
2916 }
2917
2918 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2919 }
2920
2921 static void requestQueryClip(void *data, size_t datalen, RIL_Token t)
2922 {
2923 RIL_UNUSED_PARM(datalen);
2924 RIL_UNUSED_PARM(data);
2925
2926 int err = -1;
2927 int skip = 0;
2928 int response = 0;
2929 char *line = NULL;
2930 ATResponse *p_response = NULL;
2931
2932 if (getSIMStatus() == SIM_ABSENT) {
2933 RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
2934 return;
2935 }
2936
2937 err = at_send_command_singleline("AT+CLIP?", "+CLIP:", &p_response);
2938 if (err < 0 || p_response->success == 0) {
2939 goto error;
2940 }
2941
2942 line = p_response->p_intermediates->line;
2943 err = at_tok_start(&line);
2944 if (err < 0) goto error;
2945
2946 err = at_tok_nextint(&line, &skip);
2947 if (err < 0) goto error;
2948
2949 err = at_tok_nextint(&line, &response);
2950 if (err < 0) goto error;
2951
2952 RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
2953 at_response_free(p_response);
2954 return;
2955
2956 error:
2957 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2958 at_response_free(p_response);
2959 }
2960
2961 static void requestQueryClir(void *data, size_t datalen, RIL_Token t)
2962 {
2963 RIL_UNUSED_PARM(datalen);
2964 RIL_UNUSED_PARM(data);
2965
2966 int err = -1;
2967 int response[2] = {1, 1};
2968 char *line = NULL;
2969 ATResponse *p_response = NULL;
2970
2971 if (getSIMStatus() == SIM_ABSENT) {
2972 RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
2973 return;
2974 }
2975
2976 err = at_send_command_singleline("AT+CLIR?", "+CLIR:", &p_response);
2977 if (err < 0 || p_response->success == 0) {
2978 goto error;
2979 }
2980
2981 line = p_response->p_intermediates->line;
2982 err = at_tok_start(&line);
2983 if (err < 0) goto error;
2984
2985 err = at_tok_nextint(&line, &response[0]);
2986 if (err < 0) goto error;
2987
2988 err = at_tok_nextint(&line, &response[1]);
2989 if (err < 0) goto error;
2990
2991 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
2992 at_response_free(p_response);
2993 return;
2994
2995 error:
2996 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2997 at_response_free(p_response);
2998 }
2999
3000 static void requestSetClir(void *data, size_t datalen, RIL_Token t)
3001 {
3002 RIL_UNUSED_PARM(datalen);
3003
3004 int err = -1;
3005 int n = ((int *)data)[0];
3006 char cmd[64] = {0};
3007 ATResponse *p_response = NULL;
3008
3009 snprintf(cmd, sizeof(cmd), "AT+CLIR=%d", n);
3010 err = at_send_command(cmd, &p_response);
3011 if (err < 0 || p_response->success == 0) {
3012 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3013 } else {
3014 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3015 }
3016 at_response_free(p_response);
3017 }
3018
3019 static int forwardFromCCFCULine(char *line, RIL_CallForwardInfo *p_forward) {
3020 int err = -1;
3021 int i = 0;
3022
3023 if (line == NULL || p_forward == NULL) {
3024 goto error;
3025 }
3026
3027 err = at_tok_start(&line);
3028 if (err < 0) goto error;
3029
3030 err = at_tok_nextint(&line, &(p_forward->status));
3031 if (err < 0) goto error;
3032
3033 err = at_tok_nextint(&line, &(p_forward->serviceClass));
3034 if (err < 0) goto error;
3035
3036 if (at_tok_hasmore(&line)) {
3037 int numberType = 0;
3038 err = at_tok_nextint(&line, &numberType);
3039 if (err < 0) goto error;
3040
3041 err = at_tok_nextint(&line, &p_forward->toa);
3042 if (err < 0) goto error;
3043
3044 err = at_tok_nextstr(&line, &(p_forward->number));
3045
3046 /* tolerate null here */
3047 if (err < 0) return 0;
3048
3049 if (at_tok_hasmore(&line)) {
3050 for (i = 0; i < 2; i++) {
3051 skipNextComma(&line);
3052 }
3053
3054 if (at_tok_hasmore(&line)) {
3055 err = at_tok_nextint(&line, &p_forward->timeSeconds);
3056 if (err < 0) {
3057 p_forward->timeSeconds = 0;
3058 }
3059 }
3060 }
3061 }
3062
3063 return 0;
3064
3065 error:
3066 return -1;
3067 }
3068
3069 static void requestSetCallForward(RIL_CallForwardInfo *data,
3070 size_t datalen, RIL_Token t) {
3071 int err = -1;
3072 char cmd[128] = {0};
3073 size_t offset = 0;
3074 ATResponse *p_response = NULL;
3075
3076 if (datalen != sizeof(*data) ||
3077 (data->status == 3 && data->number == NULL)) {
3078 goto error;
3079 }
3080
3081 snprintf(cmd, sizeof(cmd), "AT+CCFCU=%d,%d,%d,%d,\"%s\",%d",
3082 data->reason,
3083 data->status,
3084 2,
3085 data->toa,
3086 data->number ? data->number : "",
3087 data->serviceClass);
3088 offset += strlen(cmd);
3089
3090 if (data->serviceClass == 0) {
3091 if (data->timeSeconds != 0 && data->status == 3) {
3092 snprintf(cmd + offset, sizeof(cmd) - offset, ",\"\",\"\",,%d",
3093 data->timeSeconds);
3094 }
3095 } else {
3096 if (data->timeSeconds != 0 && data->status == 3) {
3097 snprintf(cmd + offset, sizeof(cmd) - offset, ",\"\",\"\",,%d",
3098 data->timeSeconds);
3099 } else {
3100 strlcat(cmd, ",\"\"", sizeof(cmd) - offset);
3101 }
3102 }
3103
3104 err = at_send_command_multiline(cmd, "+CCFCU:", &p_response);
3105 if (err < 0 || p_response->success == 0) {
3106 goto error;
3107 }
3108
3109 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3110 at_response_free(p_response);
3111 return;
3112
3113 error:
3114 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3115 at_response_free(p_response);
3116 }
3117
3118 static void requestQueryCallForward(RIL_CallForwardInfo *data,
3119 size_t datalen, RIL_Token t) {
3120 int err = -1;
3121 char cmd[128] = {0};
3122 ATResponse *p_response = NULL;
3123 ATLine *p_cur = NULL;
3124
3125 if (datalen != sizeof(*data)) {
3126 goto error;
3127 }
3128
3129 snprintf(cmd, sizeof(cmd), "AT+CCFCU=%d,2,%d,%d,\"%s\",%d", data->reason, 2,
3130 data->toa, data->number ? data->number : "", data->serviceClass);
3131
3132 err = at_send_command_multiline(cmd, "+CCFCU:", &p_response);
3133 if (err < 0 || p_response->success == 0) {
3134 goto error;
3135 }
3136
3137 RIL_CallForwardInfo **forwardList = NULL, *forwardPool = NULL;
3138 int forwardCount = 0;
3139 int validCount = 0;
3140 int i = 0;
3141
3142 for (p_cur = p_response->p_intermediates; p_cur != NULL;
3143 p_cur = p_cur->p_next, forwardCount++) {
3144 }
3145
3146 forwardList = (RIL_CallForwardInfo **)
3147 alloca(forwardCount * sizeof(RIL_CallForwardInfo *));
3148
3149 forwardPool = (RIL_CallForwardInfo *)
3150 alloca(forwardCount * sizeof(RIL_CallForwardInfo));
3151
3152 memset(forwardPool, 0, forwardCount * sizeof(RIL_CallForwardInfo));
3153
3154 /* init the pointer array */
3155 for (i = 0; i < forwardCount; i++) {
3156 forwardList[i] = &(forwardPool[i]);
3157 }
3158
3159 for (p_cur = p_response->p_intermediates; p_cur != NULL;
3160 p_cur = p_cur->p_next) {
3161 err = forwardFromCCFCULine(p_cur->line, forwardList[validCount]);
3162 forwardList[validCount]->reason = data->reason;
3163 if (err == 0) validCount++;
3164 }
3165
3166 RIL_onRequestComplete(t, RIL_E_SUCCESS, validCount ? forwardList : NULL,
3167 validCount * sizeof (RIL_CallForwardInfo *));
3168 at_response_free(p_response);
3169 return;
3170
3171 error:
3172 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3173 at_response_free(p_response);
3174 }
3175
3176 static void requestQueryCallWaiting(void *data, size_t datalen, RIL_Token t) {
3177 RIL_UNUSED_PARM(datalen);
3178
3179 int err = -1, mode = 0;
3180 int serviceClass = ((int *)data)[0];
3181 int response[2] = {0, 0};
3182 char cmd[32] = {0};
3183 char *line;
3184 ATLine *p_cur;
3185 ATResponse *p_response = NULL;
3186
3187 if (serviceClass == 0) {
3188 snprintf(cmd, sizeof(cmd), "AT+CCWA=1,2");
3189 } else {
3190 snprintf(cmd, sizeof(cmd), "AT+CCWA=1,2,%d", serviceClass);
3191 }
3192 err = at_send_command_multiline(cmd, "+CCWA:", &p_response);
3193 if (err < 0 || p_response->success == 0) {
3194 goto error;
3195 }
3196
3197 for (p_cur = p_response->p_intermediates; p_cur != NULL;
3198 p_cur = p_cur->p_next) {
3199 line = p_cur->line;
3200 err = at_tok_start(&line);
3201 if (err < 0) goto error;
3202
3203 err = at_tok_nextint(&line, &mode);
3204 if (err < 0) goto error;
3205
3206 err = at_tok_nextint(&line, &serviceClass);
3207 if (err < 0) goto error;
3208
3209 response[0] = mode;
3210 response[1] |= serviceClass;
3211 }
3212 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
3213 at_response_free(p_response);
3214 return;
3215
3216 error:
3217 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3218 at_response_free(p_response);
3219 }
3220
3221 static void requestSetCallWaiting(void *data, size_t datalen, RIL_Token t) {
3222 RIL_UNUSED_PARM(datalen);
3223
3224 ATResponse *p_response = NULL;
3225 int err = -1;
3226 char cmd[32] = {0};
3227 int enable = ((int *)data)[0];
3228 int serviceClass = ((int *)data)[1];
3229
3230 if (serviceClass == 0) {
3231 snprintf(cmd, sizeof(cmd), "AT+CCWA=1,%d", enable);
3232 } else {
3233 snprintf(cmd, sizeof(cmd), "AT+CCWA=1,%d,%d", enable, serviceClass);
3234 }
3235
3236 err = at_send_command(cmd, &p_response);
3237 if (err < 0 || p_response->success == 0) {
3238 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3239 } else {
3240 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3241 }
3242 at_response_free(p_response);
3243 }
3244
3245 static void requestSetSuppServiceNotifications(void *data, size_t datalen,
3246 RIL_Token t) {
3247 RIL_UNUSED_PARM(datalen);
3248
3249 int err = 0;
3250 ATResponse *p_response = NULL;
3251 int mode = ((int *)data)[0];
3252 char cmd[32] = {0};
3253
3254 snprintf(cmd, sizeof(cmd), "AT+CSSN=%d,%d", mode, mode);
3255 err = at_send_command(cmd, &p_response);
3256 if (err < 0 || p_response->success == 0) {
3257 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3258 } else {
3259 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3260 }
3261 at_response_free(p_response);
3262 }
3263
3264 static void requestChangeBarringPassword(char **data, size_t datalen, RIL_Token t) {
3265 int err = -1;
3266 int result;
3267 char cmd[64] = {0};
3268 ATResponse *p_response = NULL;
3269
3270 if (datalen != 3 * sizeof(char *) || data[0] == NULL || data[1] == NULL ||
3271 data[2] == NULL || strlen(data[0]) == 0 || strlen(data[1]) == 0 ||
3272 strlen(data[2]) == 0) {
3273 RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
3274 return;
3275 }
3276
3277 snprintf(cmd, sizeof(cmd), "AT+CPWD=\"%s\",\"%s\",\"%s\"", data[0], data[1],
3278 data[2]);
3279
3280 err = at_send_command(cmd, &p_response);
3281 if (err < 0 || p_response->success == 0) {
3282 goto error;
3283 }
3284 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3285 at_response_free(p_response);
3286 return;
3287
3288 error:
3289 RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, NULL, 0);
3290 at_response_free(p_response);
3291 }
3292
3293 static void requestFacilityLock(int request, char **data,
3294 size_t datalen, RIL_Token t) {
3295 int err = -1;
3296 int status = 0;
3297 int serviceClass = 0;
3298 int remainTimes = 10;
3299 char cmd[128] = {0};
3300 char *line = NULL;
3301 ATLine *p_cur = NULL;
3302 ATResponse *p_response = NULL;
3303 RIL_Errno errnoType = RIL_E_GENERIC_FAILURE;
3304
3305 char *type = data[0];
3306
3307 if (datalen != 5 * sizeof(char *)) {
3308 goto error;
3309 }
3310 if (data[0] == NULL || data[1] == NULL ||
3311 (data[2] == NULL && request == RIL_REQUEST_SET_FACILITY_LOCK) ||
3312 strlen(data[0]) == 0 || strlen(data[1]) == 0 ||
3313 (request == RIL_REQUEST_SET_FACILITY_LOCK && strlen(data[2]) == 0 )) {
3314 errnoType = RIL_E_INVALID_ARGUMENTS;
3315 RLOGE("FacilityLock invalid arguments");
3316 goto error;
3317 }
3318
3319 serviceClass = atoi(data[3]);
3320 if (serviceClass == 0) {
3321 snprintf(cmd, sizeof(cmd), "AT+CLCK=\"%s\",%c,\"%s\"", data[0], *data[1],
3322 data[2]);
3323 } else {
3324 snprintf(cmd, sizeof(cmd), "AT+CLCK=\"%s\",%c,\"%s\",%s", data[0],
3325 *data[1], data[2], data[3]);
3326 }
3327
3328 if (*data[1] == '2') { // query status
3329 err = at_send_command_multiline(cmd, "+CLCK: ", &p_response);
3330 if (err < 0 || p_response->success == 0) {
3331 goto error;
3332 }
3333 line = p_response->p_intermediates->line;
3334
3335 err = at_tok_start(&line);
3336 if (err < 0) goto error;
3337
3338 err = at_tok_nextint(&line, &status);
3339 if (err < 0) goto error;
3340
3341 RIL_onRequestComplete(t, RIL_E_SUCCESS, &status, sizeof(int));
3342 at_response_free(p_response);
3343 return;
3344 } else { // unlock/lock this facility
3345 err = at_send_command(cmd, &p_response);
3346 if (err < 0 || p_response->success == 0) {
3347 errnoType = RIL_E_PASSWORD_INCORRECT;
3348 goto error;
3349 }
3350 errnoType = RIL_E_SUCCESS;
3351 }
3352
3353 error:
3354 if (!strcmp(data[0], "SC")) {
3355 remainTimes = getSimlockRemainTimes("SIM PIN");
3356 } else if (!strcmp(data[0], "FD")) {
3357 remainTimes = getSimlockRemainTimes("SIM PIN2");
3358 } else {
3359 remainTimes = 1;
3360 }
3361
3362 RIL_onRequestComplete(t, errnoType, &remainTimes, sizeof(remainTimes));
3363 at_response_free(p_response);
3364 }
3365
3366 static void requestSetSmscAddress(void *data, size_t datalen, RIL_Token t)
3367 {
3368 ATResponse *p_response = NULL;
3369 char cmd[64] = {0};
3370 int err = -1;
3371
3372 if (getSIMStatus() != SIM_READY) {
3373 RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
3374 return;
3375 }
3376
3377 if (data == NULL || strlen(data) == 0) {
3378 RLOGE("SET_SMSC_ADDRESS invalid address: %s", data);
3379 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3380 return;
3381 }
3382
3383 snprintf(cmd, sizeof(cmd), "AT+CSCA=%s,%d", (char *)data, (int)datalen);
3384
3385 err = at_send_command_singleline(cmd, "+CSCA:", &p_response);
3386 if (err < 0 || p_response->success == 0) {
3387 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3388 } else {
3389 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3390 }
3391 at_response_free(p_response);
3392 }
3393
3394 static void requestGetSmscAddress(void *data, size_t datalen, RIL_Token t)
3395 {
3396 RIL_UNUSED_PARM(data);
3397 RIL_UNUSED_PARM(datalen);
3398
3399 ATResponse *p_response = NULL;
3400 int err = -1;
3401 char *decidata = NULL;
3402
3403 err = at_send_command_singleline( "AT+CSCA?", "+CSCA:", &p_response);
3404 if (err < 0 || p_response->success == 0) {
3405 goto error;
3406 }
3407
3408 char *line = p_response->p_intermediates->line;
3409 err = at_tok_start(&line);
3410 if (err < 0) goto error;
3411
3412 err = at_tok_nextstr(&line, &decidata);
3413 if (err < 0) goto error;
3414
3415 RIL_onRequestComplete(t, RIL_E_SUCCESS, decidata, strlen(decidata) + 1);
3416 at_response_free(p_response);
3417 return;
3418
3419 error:
3420 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3421 at_response_free(p_response);
3422 }
3423
3424 static void setGsmBroadcastConfigData(int from, int to, int id, int outStrSize, char *outStr) {
3425 if (from < 0 || from > 0xffff || to < 0 || to > 0xffff) {
3426 RLOGE("setGsmBroadcastConfig data is invalid, [%d, %d]", from, to);
3427 return;
3428 }
3429
3430 if (id != 0) {
3431 strlcat(outStr, ",", outStrSize);
3432 }
3433
3434 int len = strlen(outStr);
3435 if (from == to) {
3436 snprintf(outStr + len, outStrSize - len, "%d", from);
3437 } else {
3438 snprintf(outStr + len, outStrSize - len, "%d-%d", from, to);
3439 }
3440 }
3441
3442 static void requestSetSmsBroadcastConfig(void *data, size_t datalen,
3443 RIL_Token t) {
3444 int i = 0;
3445 int count = datalen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
3446 int size = count * 16;
3447 char cmd[256] = {0};
3448 char *channel = (char *)alloca(size);
3449 char *languageId = (char *)alloca(size);
3450 ATResponse *p_response = NULL;
3451 RIL_GSM_BroadcastSmsConfigInfo **pGsmBci =
3452 (RIL_GSM_BroadcastSmsConfigInfo **)data;
3453 RIL_GSM_BroadcastSmsConfigInfo gsmBci = {0};
3454
3455 memset(channel, 0, size);
3456 memset(languageId, 0, size);
3457 RLOGD("requestSetGsmBroadcastConfig %zu, count %d", datalen, count);
3458
3459 for (i = 0; i < count; i++) {
3460 gsmBci = *(pGsmBci[i]);
3461 setGsmBroadcastConfigData(gsmBci.fromServiceId, gsmBci.toServiceId, i,
3462 size, channel);
3463 setGsmBroadcastConfigData(gsmBci.fromCodeScheme, gsmBci.toCodeScheme, i,
3464 size, languageId);
3465 }
3466
3467 snprintf(cmd, sizeof(cmd), "AT+CSCB=%d,\"%s\",\"%s\"",
3468 (*pGsmBci[0]).selected ? 0 : 1, channel, languageId);
3469 int err = at_send_command_singleline( cmd, "+CSCB:", &p_response);
3470
3471 if (err < 0 || p_response->success == 0) {
3472 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3473 } else {
3474 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3475 }
3476 at_response_free(p_response);
3477 }
3478
3479 static void requestGetSmsBroadcastConfig(void *data, size_t datalen,
3480 RIL_Token t) {
3481 RIL_UNUSED_PARM(data);
3482 RIL_UNUSED_PARM(datalen);
3483
3484 ATResponse *p_response = NULL;
3485 int err = -1, mode, commas = 0, i = 0;
3486 char *line = NULL;
3487 char *serviceIds = NULL, *codeSchemes = NULL, *p = NULL;
3488 char *serviceId = NULL, *codeScheme = NULL;
3489
3490 err = at_send_command_singleline("AT+CSCB?", "+CSCB:", &p_response);
3491 if (err < 0 || p_response->success == 0) {
3492 goto error;
3493 }
3494
3495 line = p_response->p_intermediates->line;
3496 err = at_tok_start(&line);
3497 if (err < 0) goto error;
3498
3499 err = at_tok_nextint(&line, &mode);
3500 if (err < 0) goto error;
3501
3502 err = at_tok_nextstr(&line, &serviceIds);
3503 if (err < 0) goto error;
3504
3505 err = at_tok_nextstr(&line, &codeSchemes);
3506 if (err < 0) goto error;
3507
3508 for (p = serviceIds; *p != '\0'; p++) {
3509 if (*p == ',') {
3510 commas++;
3511 }
3512 }
3513 RIL_GSM_BroadcastSmsConfigInfo **pGsmBci =
3514 (RIL_GSM_BroadcastSmsConfigInfo **)alloca((commas + 1) *
3515 sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
3516 memset(pGsmBci, 0, (commas + 1) * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
3517
3518 for (i = 0; i < commas + 1; i++) {
3519 pGsmBci[i] = (RIL_GSM_BroadcastSmsConfigInfo *)alloca(
3520 sizeof(RIL_GSM_BroadcastSmsConfigInfo));
3521 memset(pGsmBci[i], 0, sizeof(RIL_GSM_BroadcastSmsConfigInfo));
3522
3523 err = at_tok_nextstr(&serviceIds, &serviceId);
3524 if (err < 0) goto error;
3525 pGsmBci[i]->toServiceId = pGsmBci[i]->fromServiceId = 0;
3526 if (strstr(serviceId, "-")) {
3527 sscanf(serviceId,"%d-%d", &pGsmBci[i]->fromServiceId,
3528 &pGsmBci[i]->toServiceId);
3529 }
3530
3531 err = at_tok_nextstr(&codeSchemes, &codeScheme);
3532 if (err < 0) goto error;
3533 pGsmBci[i]->toCodeScheme = pGsmBci[i]->fromCodeScheme = 0;
3534 if (strstr(codeScheme, "-")) {
3535 sscanf(codeScheme, "%d-%d", &pGsmBci[i]->fromCodeScheme,
3536 &pGsmBci[i]->toCodeScheme);
3537 }
3538
3539 pGsmBci[i]->selected = (mode == 0 ? false : true);
3540 }
3541 RIL_onRequestComplete(t, RIL_E_SUCCESS, pGsmBci,
3542 (commas + 1) * sizeof(RIL_GSM_BroadcastSmsConfigInfo *));
3543 at_response_free(p_response);
3544 return;
3545
3546 error:
3547 at_response_free(p_response);
3548 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3549 }
3550
3551 /**
3552 * <AcT>: integer type; access technology selected
3553 * 0 GSM
3554 * 1 GSM Compact
3555 * 2 UTRAN
3556 * 3 GSM w/EGPRS (see NOTE 1)
3557 * 4 UTRAN w/HSDPA (see NOTE 2)
3558 * 5 UTRAN w/HSUPA (see NOTE 2)
3559 * 6 UTRAN w/HSDPA and HSUPA (see NOTE 2)
3560 * 7 E-UTRAN
3561 * 8 EC-GSM-IoT (A/Gb mode) (see NOTE 3)
3562 * 9 E-UTRAN (NB-S1 mode) (see NOTE 4)
3563 * 10 E-UTRA connected to a 5GCN (see NOTE 5)
3564 * 11 NR connected to a 5GCN (see NOTE 5)
3565 * 12 NG-RAN
3566 * 13 E-UTRA-NR dual connectivity (see NOTE 6)
3567 */
3568 int mapRadioAccessNetworkToTech(RIL_RadioAccessNetworks network) {
3569 switch (network) {
3570 case GERAN: // GSM EDGE
3571 return 3;
3572 case UTRAN:
3573 return 6;
3574 case EUTRAN:
3575 return 7;
3576 case NGRAN:
3577 return 11;
3578 default:
3579 return 7; // LTE
3580 }
3581 }
3582
3583 static void requestSetNetworlSelectionManual(void *data, RIL_Token t) {
3584 int err = -1;
3585 char cmd[64] = {0};
3586 ATResponse *p_response = NULL;
3587 RIL_NetworkOperator *operator = (RIL_NetworkOperator *)data;
3588
3589 if (operator->act != UNKNOWN) {
3590 snprintf(cmd, sizeof(cmd), "AT+COPS=1,2,\"%s\"", operator->operatorNumeric);
3591 } else {
3592 snprintf(cmd, sizeof(cmd), "AT+COPS=1,2,\"%s\",%d",
3593 operator->operatorNumeric, operator->act);
3594 }
3595 err = at_send_command(cmd, &p_response);
3596 if (err != 0 || p_response->success == 0) {
3597 goto error;
3598 }
3599
3600 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3601 at_response_free(p_response);
3602 return;
3603
3604 error:
3605 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3606 at_response_free(p_response);
3607 }
3608
3609 static void requestStkServiceIsRunning(RIL_Token t)
3610 {
3611 int err = -1;
3612 ATResponse *p_response = NULL;
3613
3614 s_stkServiceRunning = true;
3615 if (NULL != s_stkUnsolResponse) {
3616 RIL_onUnsolicitedResponse(RIL_UNSOL_STK_PROACTIVE_COMMAND,
3617 s_stkUnsolResponse, strlen(s_stkUnsolResponse) + 1);
3618 free(s_stkUnsolResponse);
3619 s_stkUnsolResponse = NULL;
3620 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3621 return;
3622 }
3623
3624 err = at_send_command_singleline("AT+CUSATD?", "+CUSATD:", &p_response);
3625
3626 if (err < 0 || p_response->success == 0) {
3627 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3628 } else {
3629 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3630 }
3631 at_response_free(p_response);
3632 }
3633
3634 static void requestStkSendEnvelope(void *data, RIL_Token t)
3635 {
3636 int ret = -1, err = -1;
3637 char cmd[128] = {0};
3638 ATResponse *p_response = NULL;
3639
3640 if (data == NULL || strlen((char *)data) == 0) {
3641 RLOGE("STK sendEnvelope data is invalid");
3642 RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
3643 return;
3644 }
3645
3646 snprintf(cmd, sizeof(cmd), "AT+CUSATE=\"%s\"", (char *)data);
3647 err = at_send_command_singleline(cmd, "+CUSATE:", &p_response);
3648 if (err < 0 || p_response->success == 0) {
3649 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3650 } else {
3651 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3652
3653 // type of alpha data is 85, such as 850C546F6F6C6B6974204D656E75
3654 char *p = strstr(p_response->p_intermediates->line, "85");
3655 if (p != NULL) {
3656 char alphaStrHexLen[3] = {0};
3657 char alphaStr[1024] = {0};
3658 uint8_t *alphaBytes = NULL;
3659 int len = 0;
3660
3661 p = p + strlen("85");
3662 strncpy(alphaStrHexLen, p, 2);
3663 len = strtoul(alphaStrHexLen, NULL, 16);
3664 strncpy(alphaStr, p + 2, len * 2);
3665 alphaBytes = convertHexStringToBytes(alphaStr, strlen(alphaStr));
3666 RIL_onUnsolicitedResponse(RIL_UNSOL_STK_CC_ALPHA_NOTIFY, alphaBytes,
3667 strlen((char *)alphaBytes));
3668 free(convertHexStringToBytes);
3669 }
3670 }
3671 at_response_free(p_response);
3672 }
3673
3674 static void requestStksendTerminalResponse(void *data, RIL_Token t)
3675 {
3676 int ret = -1, err = -1;
3677 char cmd[128] = {0};
3678 ATResponse *p_response = NULL;
3679
3680 if (data == NULL || strlen((char *)data) == 0) {
3681 RLOGE("STK sendTerminalResponse data is invalid");
3682 RIL_onRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
3683 return;
3684 }
3685
3686 snprintf(cmd, sizeof(cmd), "AT+CUSATT=\"%s\"", (char *)data);
3687 err = at_send_command_singleline( cmd, "+CUSATT:", &p_response);
3688 if (err < 0 || p_response->success == 0) {
3689 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3690 } else {
3691 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3692 }
3693 at_response_free(p_response);
3694 }
3695
3696 static void requestEccDial(void *data, RIL_Token t) {
3697 char cmd[64] = {0};
3698 const char *clir = NULL;
3699 int err = -1;
3700 RIL_EmergencyDial *p_eccDial = (RIL_EmergencyDial *)data;
3701
3702 switch (p_eccDial->dialInfo.clir) {
3703 case 0: /* subscription default */
3704 clir = "";
3705 break;
3706 case 1: /* invocation */
3707 clir = "I";
3708 break;
3709 case 2: /* suppression */
3710 clir = "i";
3711 break;
3712 default:
3713 break;
3714 }
3715
3716 if (p_eccDial->routing == ROUTING_MERGENCY ||
3717 p_eccDial->routing == ROUTING_UNKNOWN) {
3718 if (p_eccDial->categories == CATEGORY_UNSPECIFIED) {
3719 snprintf(cmd, sizeof(cmd), "ATD%s@,#%s;", p_eccDial->dialInfo.address, clir);
3720 } else {
3721 snprintf(cmd, sizeof(cmd), "ATD%s@%d,#%s;", p_eccDial->dialInfo.address,
3722 p_eccDial->categories, clir);
3723 }
3724 } else { // ROUTING_NORMAL
3725 snprintf(cmd, sizeof(cmd), "ATD%s%s;", p_eccDial->dialInfo.address, clir);
3726 }
3727
3728 err = at_send_command(cmd, NULL);
3729 if (err != 0) goto error;
3730
3731 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3732 return;
3733
3734 error:
3735 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3736 }
3737
3738 void getConfigSlotStatus(RIL_SimSlotStatus_V1_2 *pSimSlotStatus) {
3739 if (pSimSlotStatus == NULL) {
3740 return;
3741 }
3742 if (getSIMStatus() == SIM_ABSENT) {
3743 pSimSlotStatus->base.cardState = RIL_CARDSTATE_ABSENT;
3744 } else {
3745 pSimSlotStatus->base.cardState = RIL_CARDSTATE_PRESENT;
3746 }
3747 // TODO: slot state is always active now
3748 pSimSlotStatus->base.slotState = SLOT_STATE_ACTIVE;
3749
3750 if (pSimSlotStatus->base.cardState != RIL_CARDSTATE_ABSENT) {
3751 pSimSlotStatus->base.atr = "";
3752 pSimSlotStatus->base.iccid = (char *)calloc(64, sizeof(char));
3753 getIccId(pSimSlotStatus->base.iccid, 64);
3754 }
3755
3756 pSimSlotStatus->base.logicalSlotId = 0;
3757 pSimSlotStatus->eid = "";
3758 }
3759
3760 void onIccSlotStatus(RIL_Token t) {
3761 RIL_SimSlotStatus_V1_2 *pSimSlotStatusList =
3762 (RIL_SimSlotStatus_V1_2 *)calloc(SIM_COUNT, sizeof(RIL_SimSlotStatus_V1_2));
3763
3764 getConfigSlotStatus(pSimSlotStatusList);
3765
3766 if (t == NULL) {
3767 RIL_onUnsolicitedResponse(RIL_UNSOL_CONFIG_ICC_SLOT_STATUS, pSimSlotStatusList,
3768 SIM_COUNT * sizeof(RIL_SimSlotStatus_V1_2));
3769 } else {
3770 RIL_onRequestComplete(t, RIL_E_SUCCESS, pSimSlotStatusList,
3771 SIM_COUNT * sizeof(RIL_SimSlotStatus_V1_2));
3772 }
3773
3774 if (pSimSlotStatusList != NULL) {
3775 free(pSimSlotStatusList->base.iccid);
3776 free(pSimSlotStatusList);
3777 }
3778 }
3779
3780 /*** Callback methods from the RIL library to us ***/
3781
3782 /**
3783 * Call from RIL to us to make a RIL_REQUEST
3784 *
3785 * Must be completed with a call to RIL_onRequestComplete()
3786 *
3787 * RIL_onRequestComplete() may be called from any thread, before or after
3788 * this function returns.
3789 *
3790 * Because onRequest function could be called from multiple different thread,
3791 * we must ensure that the underlying at_send_command_* function
3792 * is atomic.
3793 */
3794 static void
3795 onRequest (int request, void *data, size_t datalen, RIL_Token t)
3796 {
3797 ATResponse *p_response;
3798 int err;
3799
3800 RLOGD("onRequest: %s, sState: %d", requestToString(request), sState);
3801
3802 /* Ignore all requests except RIL_REQUEST_GET_SIM_STATUS
3803 * when RADIO_STATE_UNAVAILABLE.
3804 */
3805 if (sState == RADIO_STATE_UNAVAILABLE
3806 && request != RIL_REQUEST_GET_SIM_STATUS
3807 ) {
3808 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
3809 return;
3810 }
3811
3812 /* Ignore all non-power requests when RADIO_STATE_OFF
3813 * (except RIL_REQUEST_GET_SIM_STATUS)
3814 */
3815 if (sState == RADIO_STATE_OFF) {
3816 switch(request) {
3817 case RIL_REQUEST_BASEBAND_VERSION:
3818 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
3819 case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
3820 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
3821 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
3822 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
3823 case RIL_REQUEST_CDMA_SUBSCRIPTION:
3824 case RIL_REQUEST_DEVICE_IDENTITY:
3825 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
3826 case RIL_REQUEST_GET_ACTIVITY_INFO:
3827 case RIL_REQUEST_GET_CARRIER_RESTRICTIONS:
3828 case RIL_REQUEST_GET_CURRENT_CALLS:
3829 case RIL_REQUEST_GET_IMEI:
3830 case RIL_REQUEST_GET_MUTE:
3831 case RIL_REQUEST_SET_MUTE:
3832 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
3833 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
3834 case RIL_REQUEST_GET_RADIO_CAPABILITY:
3835 case RIL_REQUEST_GET_SIM_STATUS:
3836 case RIL_REQUEST_NV_RESET_CONFIG:
3837 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
3838 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
3839 case RIL_REQUEST_QUERY_TTY_MODE:
3840 case RIL_REQUEST_RADIO_POWER:
3841 case RIL_REQUEST_SET_BAND_MODE:
3842 case RIL_REQUEST_SET_CARRIER_RESTRICTIONS:
3843 case RIL_REQUEST_SET_LOCATION_UPDATES:
3844 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
3845 case RIL_REQUEST_SET_TTY_MODE:
3846 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
3847 case RIL_REQUEST_STOP_LCE:
3848 case RIL_REQUEST_VOICE_RADIO_TECH:
3849 case RIL_REQUEST_SCREEN_STATE:
3850 // Process all the above, even though the radio is off
3851 break;
3852
3853 default:
3854 // For all others, say NOT_AVAILABLE because the radio is off
3855 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
3856 return;
3857 }
3858 }
3859
3860 switch (request) {
3861 case RIL_REQUEST_GET_SIM_STATUS: {
3862 RIL_CardStatus_v1_4 *p_card_status;
3863 char *p_buffer;
3864 int buffer_size;
3865
3866 int result = getCardStatus(&p_card_status);
3867 if (result == RIL_E_SUCCESS) {
3868 p_buffer = (char *)p_card_status;
3869 buffer_size = sizeof(*p_card_status);
3870 } else {
3871 p_buffer = NULL;
3872 buffer_size = 0;
3873 }
3874 RIL_onRequestComplete(t, result, p_buffer, buffer_size);
3875 freeCardStatus(p_card_status);
3876 break;
3877 }
3878 case RIL_REQUEST_GET_CURRENT_CALLS:
3879 requestGetCurrentCalls(data, datalen, t);
3880 break;
3881 case RIL_REQUEST_DIAL:
3882 requestDial(data, datalen, t);
3883 break;
3884 case RIL_REQUEST_HANGUP:
3885 requestHangup(data, datalen, t);
3886 break;
3887 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
3888 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
3889 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
3890 case RIL_REQUEST_CONFERENCE:
3891 case RIL_REQUEST_UDUB:
3892 requestCallSelection(data, datalen, t, request);
3893 break;
3894 case RIL_REQUEST_ANSWER:
3895 at_send_command("ATA", NULL);
3896
3897 #ifdef WORKAROUND_ERRONEOUS_ANSWER
3898 s_expectAnswer = 1;
3899 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
3900
3901 if (getSIMStatus() != SIM_READY) {
3902 RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
3903 } else {
3904 // Success or failure is ignored by the upper layer here.
3905 // It will call GET_CURRENT_CALLS and determine success that way.
3906 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3907 }
3908 break;
3909
3910 case RIL_REQUEST_SEPARATE_CONNECTION:
3911 {
3912 char cmd[12];
3913 int party = ((int*)data)[0];
3914
3915 if (getSIMStatus() == SIM_ABSENT) {
3916 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
3917 return;
3918 }
3919 // Make sure that party is in a valid range.
3920 // (Note: The Telephony middle layer imposes a range of 1 to 7.
3921 // It's sufficient for us to just make sure it's single digit.)
3922 if (party > 0 && party < 10) {
3923 sprintf(cmd, "AT+CHLD=2%d", party);
3924 at_send_command(cmd, NULL);
3925 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3926 } else {
3927 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3928 }
3929 }
3930 break;
3931
3932 case RIL_REQUEST_SIGNAL_STRENGTH:
3933 requestSignalStrength(data, datalen, t);
3934 break;
3935 case RIL_REQUEST_VOICE_REGISTRATION_STATE:
3936 case RIL_REQUEST_DATA_REGISTRATION_STATE:
3937 requestRegistrationState(request, data, datalen, t);
3938 break;
3939 case RIL_REQUEST_OPERATOR:
3940 requestOperator(data, datalen, t);
3941 break;
3942 case RIL_REQUEST_RADIO_POWER:
3943 requestRadioPower(data, datalen, t);
3944 break;
3945 case RIL_REQUEST_DTMF: {
3946 char c = ((char *)data)[0];
3947 char *cmd;
3948 asprintf(&cmd, "AT+VTS=%c", (int)c);
3949 at_send_command(cmd, NULL);
3950 free(cmd);
3951 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
3952 break;
3953 }
3954 case RIL_REQUEST_SEND_SMS:
3955 case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
3956 requestSendSMS(data, datalen, t);
3957 break;
3958 case RIL_REQUEST_CDMA_SEND_SMS:
3959 requestCdmaSendSMS(data, datalen, t);
3960 break;
3961 case RIL_REQUEST_IMS_SEND_SMS:
3962 requestImsSendSMS(data, datalen, t);
3963 break;
3964 case RIL_REQUEST_SIM_OPEN_CHANNEL:
3965 requestSimOpenChannel(data, datalen, t);
3966 break;
3967 case RIL_REQUEST_SIM_CLOSE_CHANNEL:
3968 requestSimCloseChannel(data, datalen, t);
3969 break;
3970 case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
3971 requestSimTransmitApduChannel(data, datalen, t);
3972 break;
3973 case RIL_REQUEST_SETUP_DATA_CALL:
3974 requestSetupDataCall(data, datalen, t);
3975 break;
3976 case RIL_REQUEST_DEACTIVATE_DATA_CALL:
3977 requestDeactivateDataCall(data, t);
3978 break;
3979 case RIL_REQUEST_SMS_ACKNOWLEDGE:
3980 requestSMSAcknowledge(data, datalen, t);
3981 break;
3982
3983 case RIL_REQUEST_GET_IMSI:
3984 p_response = NULL;
3985 err = at_send_command_numeric("AT+CIMI", &p_response);
3986
3987 if (err < 0 || p_response->success == 0) {
3988 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
3989 } else {
3990 RIL_onRequestComplete(t, RIL_E_SUCCESS,
3991 p_response->p_intermediates->line, sizeof(char *));
3992 }
3993 at_response_free(p_response);
3994 break;
3995
3996 case RIL_REQUEST_GET_IMEI:
3997 p_response = NULL;
3998 err = at_send_command_numeric("AT+CGSN", &p_response);
3999
4000 if (err < 0 || p_response->success == 0) {
4001 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4002 } else {
4003 RIL_onRequestComplete(t, RIL_E_SUCCESS,
4004 p_response->p_intermediates->line, sizeof(char *));
4005 }
4006 at_response_free(p_response);
4007 break;
4008
4009
4010 case RIL_REQUEST_SIM_IO:
4011 requestSIM_IO(data,datalen,t);
4012 break;
4013
4014 case RIL_REQUEST_SEND_USSD:
4015 requestSendUSSD(data, datalen, t);
4016 break;
4017
4018 case RIL_REQUEST_CANCEL_USSD:
4019 if (getSIMStatus() == SIM_ABSENT) {
4020 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
4021 break;
4022 }
4023 p_response = NULL;
4024 err = at_send_command_numeric("AT+CUSD=2", &p_response);
4025
4026 if (err < 0 || p_response->success == 0) {
4027 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4028 } else {
4029 RIL_onRequestComplete(t, RIL_E_SUCCESS,
4030 p_response->p_intermediates->line, sizeof(char *));
4031 }
4032 at_response_free(p_response);
4033 break;
4034
4035 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
4036 if (getSIMStatus() == SIM_ABSENT) {
4037 RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
4038 break;
4039 }
4040 p_response = NULL;
4041 err = at_send_command("AT+COPS=0", NULL);
4042 if (err < 0 || p_response->success == 0) {
4043 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4044 } else {
4045 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4046 }
4047 at_response_free(p_response);
4048 break;
4049
4050 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
4051 requestSetNetworlSelectionManual(data, t);
4052 break;
4053
4054 case RIL_REQUEST_DATA_CALL_LIST:
4055 requestDataCallList(data, datalen, t);
4056 break;
4057
4058 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
4059 requestQueryNetworkSelectionMode(data, datalen, t);
4060 break;
4061
4062 case RIL_REQUEST_OEM_HOOK_RAW:
4063 // echo back data
4064 RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
4065 break;
4066
4067
4068 case RIL_REQUEST_OEM_HOOK_STRINGS: {
4069 int i;
4070 const char ** cur;
4071
4072 RLOGD("got OEM_HOOK_STRINGS: 0x%8p %lu", data, (long)datalen);
4073
4074
4075 for (i = (datalen / sizeof (char *)), cur = (const char **)data ;
4076 i > 0 ; cur++, i --) {
4077 RLOGD("> '%s'", *cur);
4078 }
4079
4080 // echo back strings
4081 RIL_onRequestComplete(t, RIL_E_SUCCESS, data, datalen);
4082 break;
4083 }
4084
4085 case RIL_REQUEST_WRITE_SMS_TO_SIM:
4086 requestWriteSmsToSim(data, datalen, t);
4087 break;
4088
4089 case RIL_REQUEST_DELETE_SMS_ON_SIM: {
4090 char * cmd;
4091 p_response = NULL;
4092 asprintf(&cmd, "AT+CMGD=%d", ((int *)data)[0]);
4093 err = at_send_command(cmd, &p_response);
4094 free(cmd);
4095 if (err < 0 || p_response->success == 0) {
4096 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4097 } else {
4098 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4099 }
4100 at_response_free(p_response);
4101 break;
4102 }
4103
4104 case RIL_REQUEST_ENTER_SIM_PIN:
4105 case RIL_REQUEST_ENTER_SIM_PIN2:
4106 requestEnterSimPin(request, data, datalen, t);
4107 break;
4108
4109 case RIL_REQUEST_ENTER_SIM_PUK:
4110 case RIL_REQUEST_ENTER_SIM_PUK2:
4111 case RIL_REQUEST_CHANGE_SIM_PIN:
4112 requestChangeSimPin(request, data, datalen, t);
4113 break;
4114
4115 case RIL_REQUEST_CHANGE_SIM_PIN2:
4116 requestChangeSimPin2(data, datalen, t);
4117 break;
4118
4119 case RIL_REQUEST_IMS_REGISTRATION_STATE: {
4120 int reply[2];
4121 //0==unregistered, 1==registered
4122 reply[0] = s_ims_registered;
4123
4124 //to be used when changed to include service supporated info
4125 //reply[1] = s_ims_services;
4126
4127 // FORMAT_3GPP(1) vs FORMAT_3GPP2(2);
4128 reply[1] = s_ims_format;
4129
4130 RLOGD("IMS_REGISTRATION=%d, format=%d ",
4131 reply[0], reply[1]);
4132 if (reply[1] != -1) {
4133 RIL_onRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply));
4134 } else {
4135 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4136 }
4137 break;
4138 }
4139
4140 case RIL_REQUEST_VOICE_RADIO_TECH:
4141 {
4142 int tech = techFromModemType(TECH(sMdmInfo));
4143 if (tech < 0 )
4144 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
4145 else
4146 RIL_onRequestComplete(t, RIL_E_SUCCESS, &tech, sizeof(tech));
4147 }
4148 break;
4149 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
4150 requestSetPreferredNetworkType(request, data, datalen, t);
4151 break;
4152
4153 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
4154 requestGetPreferredNetworkType(request, data, datalen, t);
4155 break;
4156
4157 case RIL_REQUEST_GET_CELL_INFO_LIST:
4158 requestGetCellInfoList(data, datalen, t);
4159 break;
4160
4161 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
4162 requestSetCellInfoListRate(data, datalen, t);
4163 break;
4164
4165 case RIL_REQUEST_GET_HARDWARE_CONFIG:
4166 requestGetHardwareConfig(data, datalen, t);
4167 break;
4168
4169 case RIL_REQUEST_SHUTDOWN:
4170 requestShutdown(t);
4171 break;
4172
4173 case RIL_REQUEST_QUERY_TTY_MODE:
4174 requestGetTtyMode(data, datalen, t);
4175 break;
4176
4177 case RIL_REQUEST_GET_RADIO_CAPABILITY:
4178 requestGetRadioCapability(data, datalen, t);
4179 break;
4180
4181 case RIL_REQUEST_SET_RADIO_CAPABILITY:
4182 requestSetRadioCapability(data, datalen, t);
4183 break;
4184
4185 case RIL_REQUEST_GET_MUTE:
4186 requestGetMute(data, datalen, t);
4187 break;
4188
4189 case RIL_REQUEST_SET_MUTE:
4190 requestSetMute(data, datalen, t);
4191 break;
4192
4193 case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
4194 case RIL_REQUEST_ALLOW_DATA:
4195 case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
4196 case RIL_REQUEST_SET_BAND_MODE:
4197 case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
4198 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
4199 case RIL_REQUEST_SET_LOCATION_UPDATES:
4200 case RIL_REQUEST_SET_TTY_MODE:
4201 case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
4202 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4203 break;
4204
4205 case RIL_REQUEST_BASEBAND_VERSION:
4206 requestCdmaBaseBandVersion(request, data, datalen, t);
4207 break;
4208
4209 case RIL_REQUEST_DEVICE_IDENTITY:
4210 requestDeviceIdentity(request, data, datalen, t);
4211 break;
4212
4213 case RIL_REQUEST_CDMA_SUBSCRIPTION:
4214 requestCdmaSubscription(request, data, datalen, t);
4215 break;
4216
4217 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
4218 requestCdmaGetSubscriptionSource(request, data, datalen, t);
4219 break;
4220
4221 case RIL_REQUEST_START_LCE:
4222 case RIL_REQUEST_STOP_LCE:
4223 case RIL_REQUEST_PULL_LCEDATA:
4224 if (getSIMStatus() == SIM_ABSENT) {
4225 RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
4226 } else {
4227 RIL_onRequestComplete(t, RIL_E_LCE_NOT_SUPPORTED, NULL, 0);
4228 }
4229 break;
4230
4231 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
4232 if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
4233 requestCdmaGetRoamingPreference(request, data, datalen, t);
4234 } else {
4235 RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
4236 }
4237 break;
4238
4239 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
4240 if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
4241 requestCdmaSetSubscriptionSource(request, data, datalen, t);
4242 } else {
4243 // VTS tests expect us to silently do nothing
4244 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4245 }
4246 break;
4247
4248 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
4249 if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
4250 requestCdmaSetRoamingPreference(request, data, datalen, t);
4251 } else {
4252 // VTS tests expect us to silently do nothing
4253 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4254 }
4255 break;
4256
4257 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
4258 if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
4259 requestExitEmergencyMode(data, datalen, t);
4260 } else {
4261 // VTS tests expect us to silently do nothing
4262 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4263 }
4264 break;
4265
4266 case RIL_REQUEST_SCREEN_STATE:
4267 requestScreenState(data, t);
4268 break;
4269
4270 case RIL_REQUEST_SET_DATA_PROFILE:
4271 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4272 break;
4273
4274 case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS:
4275 requestQueryCallForward(data, datalen, t);
4276 break;
4277
4278 case RIL_REQUEST_SET_CALL_FORWARD:
4279 requestSetCallForward(data, datalen, t);
4280 break;
4281
4282 case RIL_REQUEST_QUERY_CLIP:
4283 requestQueryClip(data, datalen, t);
4284 break;
4285
4286 case RIL_REQUEST_GET_CLIR:
4287 requestQueryClir(data, datalen, t);
4288 break;
4289
4290 case RIL_REQUEST_SET_CLIR:
4291 requestSetClir(data, datalen, t);
4292 break;
4293
4294 case RIL_REQUEST_QUERY_CALL_WAITING:
4295 requestQueryCallWaiting(data, datalen, t);
4296 break;
4297
4298 case RIL_REQUEST_SET_CALL_WAITING:
4299 requestSetCallWaiting(data, datalen, t);
4300 break;
4301
4302 case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
4303 requestSetSuppServiceNotifications(data, datalen, t);
4304 break;
4305
4306 case RIL_REQUEST_CHANGE_BARRING_PASSWORD:
4307 requestChangeBarringPassword(data, datalen, t);
4308 break;
4309
4310 case RIL_REQUEST_QUERY_FACILITY_LOCK: {
4311 char *lockData[4];
4312 lockData[0] = ((char **)data)[0];
4313 lockData[1] = "2";
4314 lockData[2] = ((char **)data)[1];
4315 lockData[3] = ((char **)data)[2];
4316 requestFacilityLock(request, lockData, datalen + sizeof(char *), t);
4317 break;
4318 }
4319
4320 case RIL_REQUEST_SET_FACILITY_LOCK:
4321 requestFacilityLock(request, data, datalen, t);
4322 break;
4323
4324 case RIL_REQUEST_GET_SMSC_ADDRESS:
4325 requestGetSmscAddress(data, datalen, t);
4326 break;
4327
4328 case RIL_REQUEST_SET_SMSC_ADDRESS:
4329 requestSetSmscAddress(data, datalen, t);
4330 break;
4331
4332 case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG:
4333 requestSetSmsBroadcastConfig(data, datalen, t);
4334 break;
4335
4336 case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG:
4337 requestGetSmsBroadcastConfig(data, datalen, t);
4338 break;
4339
4340 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
4341 requestStkServiceIsRunning(t);
4342 break;
4343
4344 case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
4345 requestStkSendEnvelope(data, t);
4346 break;
4347
4348 case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
4349 requestStksendTerminalResponse(data, t);
4350 break;
4351
4352 // New requests after P.
4353 case RIL_REQUEST_START_NETWORK_SCAN: // TODO
4354 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4355 break;
4356 case RIL_REQUEST_GET_MODEM_STACK_STATUS: // TODO
4357 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4358 break;
4359 case RIL_REQUEST_ENABLE_MODEM:
4360 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4361 break;
4362 case RIL_REQUEST_EMERGENCY_DIAL:
4363 requestEccDial(data, t);
4364 break;
4365 case RIL_REQUEST_SET_SIM_CARD_POWER:
4366 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4367 break;
4368 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP:
4369 requestSetPreferredNetworkType(request, data, datalen, t);
4370 break;
4371 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP:
4372 requestGetPreferredNetworkType(request, data, datalen, t);
4373 break;
4374 case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS:
4375 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4376 break;
4377
4378 // Radio config requests
4379 case RIL_REQUEST_CONFIG_GET_SLOT_STATUS:
4380 RIL_requestTimedCallback(onIccSlotStatus, (void *)t, NULL);
4381 break;
4382 case RIL_REQUEST_CONFIG_SET_SLOT_MAPPING:
4383 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4384 break;
4385 case RIL_REQUEST_CONFIG_GET_PHONE_CAPABILITY: {
4386 RIL_PhoneCapability *phoneCapability =
4387 (RIL_PhoneCapability *)alloca(sizeof(RIL_PhoneCapability));
4388 phoneCapability->maxActiveData = 1;
4389 // DSDS is 1, and DSDA is 2, now only support DSDS
4390 phoneCapability->maxActiveInternetData = 1;
4391 // DSDA can support internet lingering
4392 phoneCapability->isInternetLingeringSupported = false;
4393 for (int num = 0; num < SIM_COUNT; num++) {
4394 phoneCapability->logicalModemList[num].modemId = num;
4395 }
4396 RIL_onRequestComplete(t, RIL_E_SUCCESS,
4397 phoneCapability, sizeof(RIL_PhoneCapability));
4398 break;
4399 }
4400 case RIL_REQUEST_CONFIG_SET_MODEM_CONFIG:
4401 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4402 break;
4403 case RIL_REQUEST_CONFIG_GET_MODEM_CONFIG: {
4404 RIL_ModemConfig mdConfig;
4405 mdConfig.numOfLiveModems = 1;
4406
4407 RIL_onRequestComplete(t, RIL_E_SUCCESS, &mdConfig, sizeof(RIL_ModemConfig));
4408 break;
4409 }
4410 case RIL_REQUEST_CONFIG_SET_PREFER_DATA_MODEM:
4411 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4412 break;
4413
4414 case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA:
4415 RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
4416 break;
4417
4418 default:
4419 RLOGD("Request not supported. Tech: %d",TECH(sMdmInfo));
4420 RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
4421 break;
4422 }
4423 }
4424
4425 /**
4426 * Synchronous call from the RIL to us to return current radio state.
4427 * RADIO_STATE_UNAVAILABLE should be the initial state.
4428 */
4429 static RIL_RadioState
4430 currentState()
4431 {
4432 return sState;
4433 }
4434 /**
4435 * Call from RIL to us to find out whether a specific request code
4436 * is supported by this implementation.
4437 *
4438 * Return 1 for "supported" and 0 for "unsupported"
4439 */
4440
4441 static int
4442 onSupports (int requestCode __unused)
4443 {
4444 //@@@ todo
4445
4446 return 1;
4447 }
4448
4449 static void onCancel (RIL_Token t __unused)
4450 {
4451 //@@@todo
4452
4453 }
4454
4455 static const char * getVersion(void)
4456 {
4457 return "android reference-ril 1.0";
4458 }
4459
4460 static void
4461 setRadioTechnology(ModemInfo *mdm, int newtech)
4462 {
4463 RLOGD("setRadioTechnology(%d)", newtech);
4464
4465 int oldtech = TECH(mdm);
4466
4467 if (newtech != oldtech) {
4468 RLOGD("Tech change (%d => %d)", oldtech, newtech);
4469 TECH(mdm) = newtech;
4470 if (techFromModemType(newtech) != techFromModemType(oldtech)) {
4471 int tech = techFromModemType(TECH(sMdmInfo));
4472 if (tech > 0 ) {
4473 RIL_onUnsolicitedResponse(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
4474 &tech, sizeof(tech));
4475 }
4476 }
4477 }
4478 }
4479
4480 static void
4481 setRadioState(RIL_RadioState newState)
4482 {
4483 RLOGD("setRadioState(%d)", newState);
4484 RIL_RadioState oldState;
4485
4486 pthread_mutex_lock(&s_state_mutex);
4487
4488 oldState = sState;
4489
4490 if (s_closed > 0) {
4491 // If we're closed, the only reasonable state is
4492 // RADIO_STATE_UNAVAILABLE
4493 // This is here because things on the main thread
4494 // may attempt to change the radio state after the closed
4495 // event happened in another thread
4496 newState = RADIO_STATE_UNAVAILABLE;
4497 }
4498
4499 if (sState != newState || s_closed > 0) {
4500 sState = newState;
4501
4502 pthread_cond_broadcast (&s_state_cond);
4503 }
4504
4505 pthread_mutex_unlock(&s_state_mutex);
4506
4507
4508 /* do these outside of the mutex */
4509 if (sState != oldState) {
4510 RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
4511 NULL, 0);
4512 // Sim state can change as result of radio state change
4513 RIL_onUnsolicitedResponse (RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
4514 NULL, 0);
4515
4516 /* FIXME onSimReady() and onRadioPowerOn() cannot be called
4517 * from the AT reader thread
4518 * Currently, this doesn't happen, but if that changes then these
4519 * will need to be dispatched on the request thread
4520 */
4521 if (sState == RADIO_STATE_ON) {
4522 onRadioPowerOn();
4523 }
4524 }
4525 }
4526
4527 /** Returns RUIM_NOT_READY on error */
4528 static SIM_Status
4529 getRUIMStatus()
4530 {
4531 ATResponse *p_response = NULL;
4532 int err;
4533 int ret;
4534 char *cpinLine;
4535 char *cpinResult;
4536
4537 if (sState == RADIO_STATE_OFF || sState == RADIO_STATE_UNAVAILABLE) {
4538 ret = SIM_NOT_READY;
4539 goto done;
4540 }
4541
4542 err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
4543
4544 if (err != 0) {
4545 ret = SIM_NOT_READY;
4546 goto done;
4547 }
4548
4549 switch (at_get_cme_error(p_response)) {
4550 case CME_SUCCESS:
4551 break;
4552
4553 case CME_SIM_NOT_INSERTED:
4554 ret = SIM_ABSENT;
4555 goto done;
4556
4557 default:
4558 ret = SIM_NOT_READY;
4559 goto done;
4560 }
4561
4562 /* CPIN? has succeeded, now look at the result */
4563
4564 cpinLine = p_response->p_intermediates->line;
4565 err = at_tok_start (&cpinLine);
4566
4567 if (err < 0) {
4568 ret = SIM_NOT_READY;
4569 goto done;
4570 }
4571
4572 err = at_tok_nextstr(&cpinLine, &cpinResult);
4573
4574 if (err < 0) {
4575 ret = SIM_NOT_READY;
4576 goto done;
4577 }
4578
4579 if (0 == strcmp (cpinResult, "SIM PIN")) {
4580 ret = SIM_PIN;
4581 goto done;
4582 } else if (0 == strcmp (cpinResult, "SIM PUK")) {
4583 ret = SIM_PUK;
4584 goto done;
4585 } else if (0 == strcmp (cpinResult, "PH-NET PIN")) {
4586 return SIM_NETWORK_PERSONALIZATION;
4587 } else if (0 != strcmp (cpinResult, "READY")) {
4588 /* we're treating unsupported lock types as "sim absent" */
4589 ret = SIM_ABSENT;
4590 goto done;
4591 }
4592
4593 at_response_free(p_response);
4594 p_response = NULL;
4595 cpinResult = NULL;
4596
4597 ret = SIM_READY;
4598
4599 done:
4600 at_response_free(p_response);
4601 return ret;
4602 }
4603
4604 /** Returns SIM_NOT_READY on error */
4605 static SIM_Status
4606 getSIMStatus()
4607 {
4608 ATResponse *p_response = NULL;
4609 int err;
4610 int ret;
4611 char *cpinLine;
4612 char *cpinResult;
4613
4614 RLOGD("getSIMStatus(). sState: %d",sState);
4615 err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
4616
4617 if (err != 0) {
4618 ret = SIM_NOT_READY;
4619 goto done;
4620 }
4621
4622 switch (at_get_cme_error(p_response)) {
4623 case CME_SUCCESS:
4624 break;
4625
4626 case CME_SIM_NOT_INSERTED:
4627 ret = SIM_ABSENT;
4628 goto done;
4629
4630 default:
4631 ret = SIM_NOT_READY;
4632 goto done;
4633 }
4634
4635 /* CPIN? has succeeded, now look at the result */
4636
4637 cpinLine = p_response->p_intermediates->line;
4638 err = at_tok_start (&cpinLine);
4639
4640 if (err < 0) {
4641 ret = SIM_NOT_READY;
4642 goto done;
4643 }
4644
4645 err = at_tok_nextstr(&cpinLine, &cpinResult);
4646
4647 if (err < 0) {
4648 ret = SIM_NOT_READY;
4649 goto done;
4650 }
4651
4652 if (0 == strcmp (cpinResult, "SIM PIN")) {
4653 ret = SIM_PIN;
4654 goto done;
4655 } else if (0 == strcmp (cpinResult, "SIM PUK")) {
4656 ret = SIM_PUK;
4657 goto done;
4658 } else if (0 == strcmp (cpinResult, "PH-NET PIN")) {
4659 return SIM_NETWORK_PERSONALIZATION;
4660 } else if (0 != strcmp (cpinResult, "READY")) {
4661 /* we're treating unsupported lock types as "sim absent" */
4662 ret = SIM_ABSENT;
4663 goto done;
4664 }
4665
4666 at_response_free(p_response);
4667 p_response = NULL;
4668 cpinResult = NULL;
4669
4670 ret = (sState == RADIO_STATE_ON) ? SIM_READY : SIM_NOT_READY;
4671
4672 done:
4673 at_response_free(p_response);
4674 return ret;
4675 }
4676
4677 static void getIccId(char *iccid, int size) {
4678 int err = 0;
4679 ATResponse *p_response = NULL;
4680
4681 if (iccid == NULL) {
4682 RLOGE("iccid buffer is null");
4683 return;
4684 }
4685 err = at_send_command_numeric("AT+CICCID", &p_response);
4686 if (err < 0 || p_response->success == 0) {
4687 goto error;
4688 }
4689
4690 snprintf(iccid, size, "%s", p_response->p_intermediates->line);
4691
4692 error:
4693 at_response_free(p_response);
4694 }
4695
4696 /**
4697 * Get the current card status.
4698 *
4699 * This must be freed using freeCardStatus.
4700 * @return: On success returns RIL_E_SUCCESS
4701 */
4702 static int getCardStatus(RIL_CardStatus_v1_4 **pp_card_status) {
4703 static RIL_AppStatus app_status_array[] = {
4704 // SIM_ABSENT = 0
4705 { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
4706 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
4707 // SIM_NOT_READY = 1
4708 { RIL_APPTYPE_USIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
4709 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
4710 // SIM_READY = 2
4711 { RIL_APPTYPE_USIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
4712 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
4713 // SIM_PIN = 3
4714 { RIL_APPTYPE_USIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
4715 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
4716 // SIM_PUK = 4
4717 { RIL_APPTYPE_USIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
4718 NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
4719 // SIM_NETWORK_PERSONALIZATION = 5
4720 { RIL_APPTYPE_USIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
4721 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
4722 // RUIM_ABSENT = 6
4723 { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
4724 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
4725 // RUIM_NOT_READY = 7
4726 { RIL_APPTYPE_RUIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
4727 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
4728 // RUIM_READY = 8
4729 { RIL_APPTYPE_RUIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
4730 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
4731 // RUIM_PIN = 9
4732 { RIL_APPTYPE_RUIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
4733 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
4734 // RUIM_PUK = 10
4735 { RIL_APPTYPE_RUIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
4736 NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
4737 // RUIM_NETWORK_PERSONALIZATION = 11
4738 { RIL_APPTYPE_RUIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
4739 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
4740 // ISIM_ABSENT = 12
4741 { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
4742 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
4743 // ISIM_NOT_READY = 13
4744 { RIL_APPTYPE_ISIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
4745 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
4746 // ISIM_READY = 14
4747 { RIL_APPTYPE_ISIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
4748 NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
4749 // ISIM_PIN = 15
4750 { RIL_APPTYPE_ISIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
4751 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
4752 // ISIM_PUK = 16
4753 { RIL_APPTYPE_ISIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
4754 NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
4755 // ISIM_NETWORK_PERSONALIZATION = 17
4756 { RIL_APPTYPE_ISIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
4757 NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
4758
4759 };
4760 RIL_CardState card_state;
4761 int num_apps;
4762
4763 int sim_status = getSIMStatus();
4764 if (sim_status == SIM_ABSENT) {
4765 card_state = RIL_CARDSTATE_ABSENT;
4766 num_apps = 0;
4767 } else {
4768 card_state = RIL_CARDSTATE_PRESENT;
4769 num_apps = 3;
4770 }
4771
4772 // Allocate and initialize base card status.
4773 RIL_CardStatus_v1_4 *p_card_status = calloc(1, sizeof(RIL_CardStatus_v1_4));
4774 p_card_status->base.base.card_state = card_state;
4775 p_card_status->base.base.universal_pin_state = RIL_PINSTATE_UNKNOWN;
4776 p_card_status->base.base.gsm_umts_subscription_app_index = -1;
4777 p_card_status->base.base.cdma_subscription_app_index = -1;
4778 p_card_status->base.base.ims_subscription_app_index = -1;
4779 p_card_status->base.base.num_applications = num_apps;
4780 p_card_status->base.physicalSlotId = 0;
4781 p_card_status->base.atr = NULL;
4782 p_card_status->base.iccid = NULL;
4783 p_card_status->eid = "";
4784 if (sim_status != SIM_ABSENT) {
4785 p_card_status->base.iccid = (char *)calloc(64, sizeof(char));
4786 getIccId(p_card_status->base.iccid, 64);
4787 }
4788
4789 // Initialize application status
4790 int i;
4791 for (i = 0; i < RIL_CARD_MAX_APPS; i++) {
4792 p_card_status->base.base.applications[i] = app_status_array[SIM_ABSENT];
4793 }
4794
4795 // Pickup the appropriate application status
4796 // that reflects sim_status for gsm.
4797 if (num_apps != 0) {
4798 p_card_status->base.base.num_applications = 3;
4799 p_card_status->base.base.gsm_umts_subscription_app_index = 0;
4800 p_card_status->base.base.cdma_subscription_app_index = 1;
4801 p_card_status->base.base.ims_subscription_app_index = 2;
4802
4803 // Get the correct app status
4804 p_card_status->base.base.applications[0] = app_status_array[sim_status];
4805 p_card_status->base.base.applications[1] = app_status_array[sim_status + RUIM_ABSENT];
4806 p_card_status->base.base.applications[2] = app_status_array[sim_status + ISIM_ABSENT];
4807 }
4808
4809 *pp_card_status = p_card_status;
4810 return RIL_E_SUCCESS;
4811 }
4812
4813 /**
4814 * Free the card status returned by getCardStatus
4815 */
4816 static void freeCardStatus(RIL_CardStatus_v1_4 *p_card_status) {
4817 if (p_card_status == NULL) {
4818 return;
4819 }
4820 free(p_card_status->base.iccid);
4821 free(p_card_status);
4822 }
4823
4824 /**
4825 * SIM ready means any commands that access the SIM will work, including:
4826 * AT+CPIN, AT+CSMS, AT+CNMI, AT+CRSM
4827 * (all SMS-related commands)
4828 */
4829
4830 static void pollSIMState (void *param __unused)
4831 {
4832 ATResponse *p_response;
4833 int ret;
4834
4835 if (sState != RADIO_STATE_UNAVAILABLE) {
4836 // no longer valid to poll
4837 return;
4838 }
4839
4840 switch(getSIMStatus()) {
4841 case SIM_ABSENT:
4842 case SIM_PIN:
4843 case SIM_PUK:
4844 case SIM_NETWORK_PERSONALIZATION:
4845 default:
4846 RLOGI("SIM ABSENT or LOCKED");
4847 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
4848 return;
4849
4850 case SIM_NOT_READY:
4851 RIL_requestTimedCallback (pollSIMState, NULL, &TIMEVAL_SIMPOLL);
4852 return;
4853
4854 case SIM_READY:
4855 RLOGI("SIM_READY");
4856 onSIMReady();
4857 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, NULL, 0);
4858 return;
4859 }
4860 }
4861
4862 /** returns 1 if on, 0 if off, and -1 on error */
4863 static int isRadioOn()
4864 {
4865 ATResponse *p_response = NULL;
4866 int err;
4867 char *line;
4868 char ret;
4869
4870 err = at_send_command_singleline("AT+CFUN?", "+CFUN:", &p_response);
4871
4872 if (err < 0 || p_response->success == 0) {
4873 // assume radio is off
4874 goto error;
4875 }
4876
4877 line = p_response->p_intermediates->line;
4878
4879 err = at_tok_start(&line);
4880 if (err < 0) goto error;
4881
4882 err = at_tok_nextbool(&line, &ret);
4883 if (err < 0) goto error;
4884
4885 at_response_free(p_response);
4886
4887 return (int)ret;
4888
4889 error:
4890
4891 at_response_free(p_response);
4892 return -1;
4893 }
4894
4895 /**
4896 * Parse the response generated by a +CTEC AT command
4897 * The values read from the response are stored in current and preferred.
4898 * Both current and preferred may be null. The corresponding value is ignored in that case.
4899 *
4900 * @return: -1 if some error occurs (or if the modem doesn't understand the +CTEC command)
4901 * 1 if the response includes the current technology only
4902 * 0 if the response includes both current technology and preferred mode
4903 */
4904 int parse_technology_response( const char *response, int *current, int32_t *preferred )
4905 {
4906 int err;
4907 char *line, *p;
4908 int ct;
4909 int32_t pt = 0;
4910 char *str_pt;
4911
4912 line = p = strdup(response);
4913 RLOGD("Response: %s", line);
4914 err = at_tok_start(&p);
4915 if (err || !at_tok_hasmore(&p)) {
4916 RLOGD("err: %d. p: %s", err, p);
4917 free(line);
4918 return -1;
4919 }
4920
4921 err = at_tok_nextint(&p, &ct);
4922 if (err) {
4923 free(line);
4924 return -1;
4925 }
4926 if (current) *current = ct;
4927
4928 RLOGD("line remaining after int: %s", p);
4929
4930 err = at_tok_nexthexint(&p, &pt);
4931 if (err) {
4932 free(line);
4933 return 1;
4934 }
4935 if (preferred) {
4936 *preferred = pt;
4937 }
4938 free(line);
4939
4940 return 0;
4941 }
4942
4943 int query_supported_techs( ModemInfo *mdm __unused, int *supported )
4944 {
4945 ATResponse *p_response;
4946 int err, val, techs = 0;
4947 char *tok;
4948 char *line;
4949
4950 RLOGD("query_supported_techs");
4951 err = at_send_command_singleline("AT+CTEC=?", "+CTEC:", &p_response);
4952 if (err || !p_response->success)
4953 goto error;
4954 line = p_response->p_intermediates->line;
4955 err = at_tok_start(&line);
4956 if (err || !at_tok_hasmore(&line))
4957 goto error;
4958 while (!at_tok_nextint(&line, &val)) {
4959 techs |= ( 1 << val );
4960 }
4961 if (supported) *supported = techs;
4962 return 0;
4963 error:
4964 at_response_free(p_response);
4965 return -1;
4966 }
4967
4968 /**
4969 * query_ctec. Send the +CTEC AT command to the modem to query the current
4970 * and preferred modes. It leaves values in the addresses pointed to by
4971 * current and preferred. If any of those pointers are NULL, the corresponding value
4972 * is ignored, but the return value will still reflect if retrieving and parsing of the
4973 * values succeeded.
4974 *
4975 * @mdm Currently unused
4976 * @current A pointer to store the current mode returned by the modem. May be null.
4977 * @preferred A pointer to store the preferred mode returned by the modem. May be null.
4978 * @return -1 on error (or failure to parse)
4979 * 1 if only the current mode was returned by modem (or failed to parse preferred)
4980 * 0 if both current and preferred were returned correctly
4981 */
4982 int query_ctec(ModemInfo *mdm __unused, int *current, int32_t *preferred)
4983 {
4984 ATResponse *response = NULL;
4985 int err;
4986 int res;
4987
4988 RLOGD("query_ctec. current: %p, preferred: %p", current, preferred);
4989 err = at_send_command_singleline("AT+CTEC?", "+CTEC:", &response);
4990 if (!err && response->success) {
4991 res = parse_technology_response(response->p_intermediates->line, current, preferred);
4992 at_response_free(response);
4993 return res;
4994 }
4995 RLOGE("Error executing command: %d. response: %p. status: %d", err, response, response? response->success : -1);
4996 at_response_free(response);
4997 return -1;
4998 }
4999
5000 int is_multimode_modem(ModemInfo *mdm)
5001 {
5002 ATResponse *response;
5003 int err;
5004 char *line;
5005 int tech;
5006 int32_t preferred;
5007
5008 if (query_ctec(mdm, &tech, &preferred) == 0) {
5009 mdm->currentTech = tech;
5010 mdm->preferredNetworkMode = preferred;
5011 if (query_supported_techs(mdm, &mdm->supportedTechs)) {
5012 return 0;
5013 }
5014 return 1;
5015 }
5016 return 0;
5017 }
5018
5019 /**
5020 * Find out if our modem is GSM, CDMA or both (Multimode)
5021 */
5022 static void probeForModemMode(ModemInfo *info)
5023 {
5024 ATResponse *response;
5025 int err;
5026 assert (info);
5027 // Currently, our only known multimode modem is qemu's android modem,
5028 // which implements the AT+CTEC command to query and set mode.
5029 // Try that first
5030
5031 if (is_multimode_modem(info)) {
5032 RLOGI("Found Multimode Modem. Supported techs mask: %8.8x. Current tech: %d",
5033 info->supportedTechs, info->currentTech);
5034 return;
5035 }
5036
5037 /* Being here means that our modem is not multimode */
5038 info->isMultimode = 0;
5039
5040 /* CDMA Modems implement the AT+WNAM command */
5041 err = at_send_command_singleline("AT+WNAM","+WNAM:", &response);
5042 if (!err && response->success) {
5043 at_response_free(response);
5044 // TODO: find out if we really support EvDo
5045 info->supportedTechs = MDM_CDMA | MDM_EVDO;
5046 info->currentTech = MDM_CDMA;
5047 RLOGI("Found CDMA Modem");
5048 return;
5049 }
5050 if (!err) at_response_free(response);
5051 // TODO: find out if modem really supports WCDMA/LTE
5052 info->supportedTechs = MDM_GSM | MDM_WCDMA | MDM_LTE;
5053 info->currentTech = MDM_GSM;
5054 RLOGI("Found GSM Modem");
5055 }
5056
5057 /**
5058 * Initialize everything that can be configured while we're still in
5059 * AT+CFUN=0
5060 */
5061 static void initializeCallback(void *param __unused)
5062 {
5063 ATResponse *p_response = NULL;
5064 int err;
5065
5066 setRadioState (RADIO_STATE_OFF);
5067
5068 at_handshake();
5069
5070 probeForModemMode(sMdmInfo);
5071 /* note: we don't check errors here. Everything important will
5072 be handled in onATTimeout and onATReaderClosed */
5073
5074 /* atchannel is tolerant of echo but it must */
5075 /* have verbose result codes */
5076 at_send_command("ATE0Q0V1", NULL);
5077
5078 /* No auto-answer */
5079 at_send_command("ATS0=0", NULL);
5080
5081 /* Extended errors */
5082 at_send_command("AT+CMEE=1", NULL);
5083
5084 /* Network registration events */
5085 err = at_send_command("AT+CREG=2", &p_response);
5086
5087 /* some handsets -- in tethered mode -- don't support CREG=2 */
5088 if (err < 0 || p_response->success == 0) {
5089 at_send_command("AT+CREG=1", NULL);
5090 }
5091
5092 at_response_free(p_response);
5093
5094 /* GPRS registration events */
5095 at_send_command("AT+CGREG=1", NULL);
5096
5097 /* Call Waiting notifications */
5098 at_send_command("AT+CCWA=1", NULL);
5099
5100 /* Alternating voice/data off */
5101 at_send_command("AT+CMOD=0", NULL);
5102
5103 /* Not muted */
5104 at_send_command("AT+CMUT=0", NULL);
5105
5106 /* +CSSU unsolicited supp service notifications */
5107 at_send_command("AT+CSSN=0,1", NULL);
5108
5109 /* no connected line identification */
5110 at_send_command("AT+COLP=0", NULL);
5111
5112 /* HEX character set */
5113 at_send_command("AT+CSCS=\"HEX\"", NULL);
5114
5115 /* USSD unsolicited */
5116 at_send_command("AT+CUSD=1", NULL);
5117
5118 /* Enable +CGEV GPRS event notifications, but don't buffer */
5119 at_send_command("AT+CGEREP=1,0", NULL);
5120
5121 /* SMS PDU mode */
5122 at_send_command("AT+CMGF=0", NULL);
5123
5124 #ifdef USE_TI_COMMANDS
5125
5126 at_send_command("AT%CPI=3", NULL);
5127
5128 /* TI specific -- notifications when SMS is ready (currently ignored) */
5129 at_send_command("AT%CSTAT=1", NULL);
5130
5131 #endif /* USE_TI_COMMANDS */
5132
5133
5134 /* assume radio is off on error */
5135 if (isRadioOn() > 0) {
5136 setRadioState (RADIO_STATE_ON);
5137 }
5138 }
5139
5140 static void waitForClose()
5141 {
5142 pthread_mutex_lock(&s_state_mutex);
5143
5144 while (s_closed == 0) {
5145 pthread_cond_wait(&s_state_cond, &s_state_mutex);
5146 }
5147
5148 pthread_mutex_unlock(&s_state_mutex);
5149 }
5150
5151 static void sendUnsolImsNetworkStateChanged()
5152 {
5153 #if 0 // to be used when unsol is changed to return data.
5154 int reply[2];
5155 reply[0] = s_ims_registered;
5156 reply[1] = s_ims_services;
5157 reply[1] = s_ims_format;
5158 #endif
5159 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED,
5160 NULL, 0);
5161 }
5162
5163 static int parseProactiveCmdInd(char *response) {
5164 int typePos = 0;
5165 int cmdType = 0;
5166 char tempStr[3] = {0};
5167 char *end = NULL;
5168 StkUnsolEvent ret = STK_UNSOL_EVENT_UNKNOWN;
5169
5170 if (response == NULL || strlen(response) < 3) {
5171 return ret;
5172 }
5173
5174 if (response[2] <= '7') {
5175 typePos = 10;
5176 } else {
5177 typePos = 12;
5178 }
5179
5180 if ((int)strlen(response) < typePos + 1) {
5181 return ret;
5182 }
5183
5184 memcpy(tempStr, &(response[typePos]), 2);
5185 cmdType = strtoul(tempStr, &end, 16);
5186 cmdType = 0xFF & cmdType;
5187 RLOGD("cmdType: %d",cmdType);
5188
5189 switch (cmdType) {
5190 case STK_RUN_AT:
5191 case STK_SEND_DTMF:
5192 case STK_SEND_SMS:
5193 case STK_SEND_SS:
5194 case STK_SEND_USSD:
5195 case STK_PLAY_TONE:
5196 case STK_CLOSE_CHANNEL:
5197 ret = STK_UNSOL_EVENT_NOTIFY;
5198 break;
5199 case STK_REFRESH:
5200 if (strncasecmp(&(response[typePos + 2]), "04", 2) == 0) { // SIM_RESET
5201 RLOGD("Type of Refresh is SIM_RESET");
5202 s_stkServiceRunning = false;
5203 ret = STK_UNSOL_PROACTIVE_CMD;
5204 } else {
5205 ret = STK_UNSOL_EVENT_NOTIFY;
5206 }
5207 break;
5208 default:
5209 ret = STK_UNSOL_PROACTIVE_CMD;
5210 break;
5211 }
5212
5213 if (getSIMStatus() == SIM_ABSENT && s_stkServiceRunning) {
5214 s_stkServiceRunning = false;
5215 }
5216
5217 if (false == s_stkServiceRunning) {
5218 ret = STK_UNSOL_EVENT_UNKNOWN;
5219 s_stkUnsolResponse = (char *)calloc((strlen(response) + 1), sizeof(char));
5220 snprintf(s_stkUnsolResponse, strlen(response) + 1, "%s", response);
5221 RLOGD("STK service is not running [%s]", s_stkUnsolResponse);
5222 }
5223
5224 return ret;
5225 }
5226
5227 /**
5228 * Called by atchannel when an unsolicited line appears
5229 * This is called on atchannel's reader thread. AT commands may
5230 * not be issued here
5231 */
5232 static void onUnsolicited (const char *s, const char *sms_pdu)
5233 {
5234 char *line = NULL, *p;
5235 int err;
5236
5237 /* Ignore unsolicited responses until we're initialized.
5238 * This is OK because the RIL library will poll for initial state
5239 */
5240 if (sState == RADIO_STATE_UNAVAILABLE) {
5241 return;
5242 }
5243
5244 #define CGFPCCFG "%CGFPCCFG:"
5245 if (strStartsWith(s, CGFPCCFG)) {
5246 /* cuttlefish/goldfish specific
5247 */
5248 char *response;
5249 line = p = strdup(s);
5250 RLOGD("got CGFPCCFG line %s and %s\n", s, p);
5251 err = at_tok_start(&line);
5252 if(err) {
5253 RLOGE("invalid CGFPCCFG line %s and %s\n", s, p);
5254 }
5255 #define kSize 5
5256 int configs[kSize];
5257 for (int i=0; i < kSize && !err; ++i) {
5258 err = at_tok_nextint(&line, &(configs[i]));
5259 RLOGD("got i %d, val = %d", i, configs[i]);
5260 }
5261 if(err) {
5262 RLOGE("invalid CGFPCCFG line %s and %s\n", s, p);
5263 } else {
5264 int modem_tech = configs[2];
5265 configs[2] = techFromModemType(modem_tech);
5266 RIL_onUnsolicitedResponse (
5267 RIL_UNSOL_PHYSICAL_CHANNEL_CONFIGS,
5268 configs, kSize);
5269 }
5270 free(p);
5271 } else if (strStartsWith(s, "%CTZV:")) {
5272 /* TI specific -- NITZ time */
5273 char *response;
5274
5275 line = p = strdup(s);
5276 at_tok_start(&p);
5277
5278 err = at_tok_nextstr(&p, &response);
5279
5280 if (err != 0) {
5281 RLOGE("invalid NITZ line %s\n", s);
5282 } else {
5283 RIL_onUnsolicitedResponse (
5284 RIL_UNSOL_NITZ_TIME_RECEIVED,
5285 response, strlen(response) + 1);
5286 }
5287 free(line);
5288 } else if (strStartsWith(s,"+CRING:")
5289 || strStartsWith(s,"RING")
5290 || strStartsWith(s,"NO CARRIER")
5291 || strStartsWith(s,"+CCWA")
5292 ) {
5293 RIL_onUnsolicitedResponse (
5294 RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
5295 NULL, 0);
5296 #ifdef WORKAROUND_FAKE_CGEV
5297 RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL); //TODO use new function
5298 #endif /* WORKAROUND_FAKE_CGEV */
5299 } else if (strStartsWith(s,"+CREG:")
5300 || strStartsWith(s,"+CGREG:")
5301 ) {
5302 RIL_onUnsolicitedResponse (
5303 RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
5304 NULL, 0);
5305 #ifdef WORKAROUND_FAKE_CGEV
5306 RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
5307 #endif /* WORKAROUND_FAKE_CGEV */
5308 } else if (strStartsWith(s, "+CMT:")) {
5309 RIL_onUnsolicitedResponse (
5310 RIL_UNSOL_RESPONSE_NEW_SMS,
5311 sms_pdu, strlen(sms_pdu));
5312 } else if (strStartsWith(s, "+CDS:")) {
5313 RIL_onUnsolicitedResponse (
5314 RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT,
5315 sms_pdu, strlen(sms_pdu));
5316 } else if (strStartsWith(s, "+CGEV:")) {
5317 /* Really, we can ignore NW CLASS and ME CLASS events here,
5318 * but right now we don't since extranous
5319 * RIL_UNSOL_DATA_CALL_LIST_CHANGED calls are tolerated
5320 */
5321 /* can't issue AT commands here -- call on main thread */
5322 RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
5323 #ifdef WORKAROUND_FAKE_CGEV
5324 } else if (strStartsWith(s, "+CME ERROR: 150")) {
5325 RIL_requestTimedCallback (onDataCallListChanged, NULL, NULL);
5326 #endif /* WORKAROUND_FAKE_CGEV */
5327 } else if (strStartsWith(s, "+CTEC: ")) {
5328 int tech, mask;
5329 switch (parse_technology_response(s, &tech, NULL))
5330 {
5331 case -1: // no argument could be parsed.
5332 RLOGE("invalid CTEC line %s\n", s);
5333 break;
5334 case 1: // current mode correctly parsed
5335 case 0: // preferred mode correctly parsed
5336 mask = 1 << tech;
5337 if (mask != MDM_GSM && mask != MDM_CDMA &&
5338 mask != MDM_WCDMA && mask != MDM_LTE) {
5339 RLOGE("Unknown technology %d\n", tech);
5340 } else {
5341 setRadioTechnology(sMdmInfo, tech);
5342 }
5343 break;
5344 }
5345 } else if (strStartsWith(s, "+CCSS: ")) {
5346 int source = 0;
5347 line = p = strdup(s);
5348 if (!line) {
5349 RLOGE("+CCSS: Unable to allocate memory");
5350 return;
5351 }
5352 if (at_tok_start(&p) < 0) {
5353 free(line);
5354 return;
5355 }
5356 if (at_tok_nextint(&p, &source) < 0) {
5357 RLOGE("invalid +CCSS response: %s", line);
5358 free(line);
5359 return;
5360 }
5361 SSOURCE(sMdmInfo) = source;
5362 RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
5363 &source, sizeof(source));
5364 free(line);
5365 } else if (strStartsWith(s, "+WSOS: ")) {
5366 char state = 0;
5367 int unsol;
5368 line = p = strdup(s);
5369 if (!line) {
5370 RLOGE("+WSOS: Unable to allocate memory");
5371 return;
5372 }
5373 if (at_tok_start(&p) < 0) {
5374 free(line);
5375 return;
5376 }
5377 if (at_tok_nextbool(&p, &state) < 0) {
5378 RLOGE("invalid +WSOS response: %s", line);
5379 free(line);
5380 return;
5381 }
5382 free(line);
5383
5384 unsol = state ?
5385 RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE : RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE;
5386
5387 RIL_onUnsolicitedResponse(unsol, NULL, 0);
5388
5389 } else if (strStartsWith(s, "+WPRL: ")) {
5390 int version = -1;
5391 line = p = strdup(s);
5392 if (!line) {
5393 RLOGE("+WPRL: Unable to allocate memory");
5394 return;
5395 }
5396 if (at_tok_start(&p) < 0) {
5397 RLOGE("invalid +WPRL response: %s", s);
5398 free(line);
5399 return;
5400 }
5401 if (at_tok_nextint(&p, &version) < 0) {
5402 RLOGE("invalid +WPRL response: %s", s);
5403 free(line);
5404 return;
5405 }
5406 free(line);
5407 RIL_onUnsolicitedResponse(RIL_UNSOL_CDMA_PRL_CHANGED, &version, sizeof(version));
5408 } else if (strStartsWith(s, "+CFUN: 0")) {
5409 setRadioState(RADIO_STATE_OFF);
5410 } else if (strStartsWith(s, "+CSQ: ")) {
5411 // Accept a response that is at least v6, and up to v12
5412 int minNumOfElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
5413 int maxNumOfElements=sizeof(RIL_SignalStrength_v12)/sizeof(int);
5414 int response[maxNumOfElements];
5415 memset(response, 0, sizeof(response));
5416
5417 line = p = strdup(s);
5418 at_tok_start(&p);
5419
5420 for (int count = 0; count < maxNumOfElements; count++) {
5421 err = at_tok_nextint(&p, &(response[count]));
5422 if (err < 0 && count < minNumOfElements) {
5423 free(line);
5424 return;
5425 }
5426 }
5427
5428 RIL_onUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH,
5429 response, sizeof(response));
5430 free(line);
5431 } else if (strStartsWith(s, "+CUSATEND")) { // session end
5432 RIL_onUnsolicitedResponse(RIL_UNSOL_STK_SESSION_END, NULL, 0);
5433 } else if (strStartsWith(s, "+CUSATP:")) {
5434 line = p = strdup(s);
5435 if (!line) {
5436 RLOGE("+CUSATP: Unable to allocate memory");
5437 return;
5438 }
5439 if (at_tok_start(&p) < 0) {
5440 RLOGE("invalid +CUSATP response: %s", s);
5441 free(line);
5442 return;
5443 }
5444
5445 char *response = NULL;
5446 if (at_tok_nextstr(&p, &response) < 0) {
5447 RLOGE("%s fail", s);
5448 free(line);
5449 return;
5450 }
5451
5452 StkUnsolEvent ret = parseProactiveCmdInd(response);
5453 if (ret == STK_UNSOL_EVENT_NOTIFY) {
5454 RIL_onUnsolicitedResponse(RIL_UNSOL_STK_EVENT_NOTIFY, response,
5455 strlen(response) + 1);
5456 } else if (ret == STK_UNSOL_PROACTIVE_CMD) {
5457 RIL_onUnsolicitedResponse(RIL_UNSOL_STK_PROACTIVE_COMMAND, response,
5458 strlen(response) + 1);
5459 }
5460
5461 free(line);
5462 }
5463 }
5464
5465 /* Called on command or reader thread */
5466 static void onATReaderClosed()
5467 {
5468 RLOGI("AT channel closed\n");
5469 at_close();
5470 s_closed = 1;
5471
5472 setRadioState (RADIO_STATE_UNAVAILABLE);
5473 }
5474
5475 /* Called on command thread */
5476 static void onATTimeout()
5477 {
5478 RLOGI("AT channel timeout; closing\n");
5479 at_close();
5480
5481 s_closed = 1;
5482
5483 /* FIXME cause a radio reset here */
5484
5485 setRadioState (RADIO_STATE_UNAVAILABLE);
5486 }
5487
5488 /* Called to pass hardware configuration information to telephony
5489 * framework.
5490 */
5491 static void setHardwareConfiguration(int num, RIL_HardwareConfig *cfg)
5492 {
5493 RIL_onUnsolicitedResponse(RIL_UNSOL_HARDWARE_CONFIG_CHANGED, cfg, num*sizeof(*cfg));
5494 }
5495
5496 static void usage(char *s __unused)
5497 {
5498 #ifdef RIL_SHLIB
5499 fprintf(stderr, "reference-ril requires: -p <tcp port> or -d /dev/tty_device\n");
5500 #else
5501 fprintf(stderr, "usage: %s [-p <tcp port>] [-d /dev/tty_device]\n", s);
5502 exit(-1);
5503 #endif
5504 }
5505
5506 static void *
5507 mainLoop(void *param __unused)
5508 {
5509 int fd;
5510 int ret;
5511
5512 AT_DUMP("== ", "entering mainLoop()", -1 );
5513 at_set_on_reader_closed(onATReaderClosed);
5514 at_set_on_timeout(onATTimeout);
5515
5516 for (;;) {
5517 fd = -1;
5518 while (fd < 0) {
5519 if (isInEmulator()) {
5520 fd = qemu_open_modem_port();
5521 RLOGD("opening qemu_modem_port %d!", fd);
5522 } else if (s_port > 0) {
5523 fd = socket_network_client("localhost", s_port, SOCK_STREAM);
5524 } else if (s_modem_simulator_port >= 0) {
5525 fd = socket(AF_VSOCK, SOCK_STREAM, 0);
5526 if (fd < 0) {
5527 RLOGD("Can't create AF_VSOCK socket!");
5528 continue;
5529 }
5530 struct sockaddr_vm sa;
5531 memset(&sa, 0, sizeof(struct sockaddr_vm));
5532 sa.svm_family = AF_VSOCK;
5533 sa.svm_cid = VMADDR_CID_HOST;
5534 sa.svm_port = s_modem_simulator_port;
5535
5536 if (connect(fd, (struct sockaddr *)(&sa), sizeof(sa)) < 0) {
5537 RLOGD("Can't connect to port:%ud, errno: %s",
5538 s_modem_simulator_port, strerror(errno));
5539 close(fd);
5540 fd = -1;
5541 continue;
5542 }
5543 } else if (s_device_socket) {
5544 fd = socket_local_client(s_device_path,
5545 ANDROID_SOCKET_NAMESPACE_FILESYSTEM,
5546 SOCK_STREAM);
5547 } else if (s_device_path != NULL) {
5548 fd = open (s_device_path, O_RDWR);
5549 if ( fd >= 0 && !memcmp( s_device_path, "/dev/ttyS", 9 ) ) {
5550 /* disable echo on serial ports */
5551 struct termios ios;
5552 tcgetattr( fd, &ios );
5553 ios.c_lflag = 0; /* disable ECHO, ICANON, etc... */
5554 tcsetattr( fd, TCSANOW, &ios );
5555 }
5556 }
5557
5558 if (fd < 0) {
5559 perror ("opening AT interface. retrying...");
5560 sleep(10);
5561 /* never returns */
5562 }
5563 }
5564
5565 s_closed = 0;
5566 ret = at_open(fd, onUnsolicited);
5567
5568 if (ret < 0) {
5569 RLOGE ("AT error %d on at_open\n", ret);
5570 return 0;
5571 }
5572
5573 RIL_requestTimedCallback(initializeCallback, NULL, &TIMEVAL_0);
5574
5575 // Give initializeCallback a chance to dispatched, since
5576 // we don't presently have a cancellation mechanism
5577 sleep(1);
5578
5579 waitForClose();
5580 RLOGI("Re-opening after close");
5581 }
5582 }
5583
5584 #ifdef RIL_SHLIB
5585
5586 pthread_t s_tid_mainloop;
5587
5588 const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
5589 {
5590 int ret;
5591 int fd = -1;
5592 int opt;
5593 pthread_attr_t attr;
5594
5595 s_rilenv = env;
5596
5597 RLOGD("RIL_Init");
5598 while ( -1 != (opt = getopt(argc, argv, "p:d:s:c:m:"))) {
5599 switch (opt) {
5600 case 'p':
5601 s_port = atoi(optarg);
5602 if (s_port == 0) {
5603 usage(argv[0]);
5604 return NULL;
5605 }
5606 RLOGI("Opening loopback port %d\n", s_port);
5607 break;
5608
5609 case 'd':
5610 s_device_path = optarg;
5611 RLOGI("Opening tty device %s\n", s_device_path);
5612 break;
5613
5614 case 's':
5615 s_device_path = optarg;
5616 s_device_socket = 1;
5617 RLOGI("Opening socket %s\n", s_device_path);
5618 break;
5619
5620 case 'c':
5621 RLOGI("Client id received %s\n", optarg);
5622 break;
5623
5624 case 'm':
5625 s_modem_simulator_port = strtoul(optarg, NULL, 10);
5626 RLOGI("Opening modem simulator port %ud\n", s_modem_simulator_port);
5627 break;
5628
5629 default:
5630 usage(argv[0]);
5631 return NULL;
5632 }
5633 }
5634
5635 if (s_port < 0 && s_device_path == NULL && !isInEmulator() &&
5636 s_modem_simulator_port < 0) {
5637 usage(argv[0]);
5638 return NULL;
5639 }
5640
5641 sMdmInfo = calloc(1, sizeof(ModemInfo));
5642 if (!sMdmInfo) {
5643 RLOGE("Unable to alloc memory for ModemInfo");
5644 return NULL;
5645 }
5646 pthread_attr_init (&attr);
5647 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
5648 ret = pthread_create(&s_tid_mainloop, &attr, mainLoop, NULL);
5649
5650 return &s_callbacks;
5651 }
5652 #else /* RIL_SHLIB */
5653 int main (int argc, char **argv)
5654 {
5655 int ret;
5656 int fd = -1;
5657 int opt;
5658
5659 while ( -1 != (opt = getopt(argc, argv, "p:d:"))) {
5660 switch (opt) {
5661 case 'p':
5662 s_port = atoi(optarg);
5663 if (s_port == 0) {
5664 usage(argv[0]);
5665 }
5666 RLOGI("Opening loopback port %d\n", s_port);
5667 break;
5668
5669 case 'd':
5670 s_device_path = optarg;
5671 RLOGI("Opening tty device %s\n", s_device_path);
5672 break;
5673
5674 case 's':
5675 s_device_path = optarg;
5676 s_device_socket = 1;
5677 RLOGI("Opening socket %s\n", s_device_path);
5678 break;
5679
5680 default:
5681 usage(argv[0]);
5682 }
5683 }
5684
5685 if (s_port < 0 && s_device_path == NULL && !isInEmulator()) {
5686 usage(argv[0]);
5687 }
5688
5689 RIL_register(&s_callbacks);
5690
5691 mainLoop(NULL);
5692
5693 return 0;
5694 }
5695
5696 #endif /* RIL_SHLIB */
5697