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