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