blob: b60ad8d757bef9b8ea8db07f27bd5d66a4360d50 [file] [log] [blame]
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001/*
2** Copyright 2017, The Android Open Source Project
3**
4** Licensed under the Apache License, Version 2.0 (the "License");
5** you may not use this file except in compliance with the License.
6** You may obtain a copy of the License at
7**
8** http://www.apache.org/licenses/LICENSE-2.0
9**
10** Unless required by applicable law or agreed to in writing, software
11** distributed under the License ioogle/s distributed on an "AS IS" BASIS,
12** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13** See the License for the specific language governing permissions and
14** limitations under the License.
15*/
16
Tomasz Wiszkowski93ea8052017-09-21 10:02:45 -070017#include "guest/hals/ril/vsoc_ril.h"
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -070018
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -070019#include <cutils/properties.h>
Greg Hartman8d9b76e2017-10-26 23:23:40 -070020#include <string.h>
21#include <sys/types.h>
22#include <time.h>
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -070023
24#include <map>
25#include <set>
26#include <string>
27#include <vector>
28
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -070029#include "common/libs/net/netlink_client.h"
30#include "common/libs/net/network_interface.h"
31#include "common/libs/net/network_interface_manager.h"
Jorge E. Moreirad6c129e2018-01-05 14:52:21 -080032#include "common/vsoc/lib/ril_region_view.h"
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -070033#include "guest/libs/platform_support/api_level_fixes.h"
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -070034
Greg Hartman7c01b7c2018-01-10 18:30:22 -080035#define VSOC_RIL_VERSION_STRING "Android VSoC RIL 1.0"
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -070036
37/* Modem Technology bits */
38#define MDM_GSM 0x01
39#define MDM_WCDMA 0x02
40#define MDM_CDMA 0x04
41#define MDM_EVDO 0x08
42#define MDM_LTE 0x10
43
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -070044#if VSOC_PLATFORM_SDK_BEFORE(K)
45#define RADIO_TECH_3GPP 1
46#define RADIO_TECH_3GPP2 2
47#endif
48
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -070049typedef enum {
50 SIM_ABSENT = 0,
51 SIM_NOT_READY = 1,
52 SIM_READY = 2, // SIM_READY means the radio state is RADIO_STATE_SIM_READY
53 SIM_PIN = 3,
54 SIM_PUK = 4,
55 SIM_NETWORK_PERSONALIZATION = 5,
56 RUIM_ABSENT = 6,
57 RUIM_NOT_READY = 7,
58 RUIM_READY = 8,
59 RUIM_PIN = 9,
60 RUIM_PUK = 10,
61 RUIM_NETWORK_PERSONALIZATION = 11
62} SIM_Status;
63
64static const struct RIL_Env* gce_ril_env;
65
Greg Hartman8d9b76e2017-10-26 23:23:40 -070066static const struct timeval TIMEVAL_SIMPOLL = {3, 0};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -070067
68static time_t gce_ril_start_time;
69
70static void pollSIMState(void* param);
71
72RIL_RadioState gRadioPowerState = RADIO_STATE_OFF;
73
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -070074struct DataCall {
Greg Hartman8d9b76e2017-10-26 23:23:40 -070075 enum AllowedAuthenticationType { kNone = 0, kPap = 1, kChap = 2, kBoth = 3 };
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -070076
77 enum ConnectionType {
78 kConnTypeIPv4,
79 kConnTypeIPv6,
80 kConnTypeIPv4v6,
81 kConnTypePPP
82 };
83
84 enum LinkState {
85 kLinkStateInactive = 0,
86 kLinkStateDown = 1,
87 kLinkStateUp = 2,
88 };
89
90 RIL_RadioTechnology technology_;
91 RIL_DataProfile profile_;
92 std::string access_point_;
93 std::string username_;
94 std::string password_;
95 AllowedAuthenticationType auth_type_;
96 ConnectionType connection_type_;
97 LinkState link_state_;
98 RIL_DataCallFailCause fail_cause_;
99 std::string other_properties_;
100};
101
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700102static std::string gSimPIN = "0000";
103static const std::string gSimPUK = "11223344";
104static int gSimPINAttempts = 0;
105static const int gSimPINAttemptsMax = 3;
106static SIM_Status gSimStatus = SIM_NOT_READY;
107
Greg Hartman662dac02017-10-26 23:28:15 -0700108// SetUpNetworkInterface configures IP and Broadcast addresses on a RIL
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800109// controlled network interface.
Greg Hartman662dac02017-10-26 23:28:15 -0700110// This call returns true, if operation was successful.
Greg Hartman7c01b7c2018-01-10 18:30:22 -0800111bool SetUpNetworkInterface(const char* ipaddr, int prefixlen,
112 const char* bcaddr) {
Greg Hartmana47dd952017-12-21 21:30:23 -0800113 auto factory = cvd::NetlinkClientFactory::Default();
114 std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE));
115 std::unique_ptr<cvd::NetworkInterfaceManager> nm(
116 cvd::NetworkInterfaceManager::New(factory));
117 std::unique_ptr<cvd::NetworkInterface> ni(nm->Open("rmnet0"));
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700118
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800119 if (ni) {
120 ni->SetAddress(ipaddr);
121 ni->SetBroadcastAddress(bcaddr);
Greg Hartmana47dd952017-12-21 21:30:23 -0800122 ni->SetPrefixLength(prefixlen);
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800123 ni->SetOperational(true);
124 bool res = nm->ApplyChanges(*ni);
125 if (!res) ALOGE("Could not configure rmnet0");
126 return res;
127 }
128 return false;
129}
Greg Hartman662dac02017-10-26 23:28:15 -0700130
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700131// TearDownNetworkInterface disables network interface.
132// This call returns true, if operation was successful.
133bool TearDownNetworkInterface() {
Greg Hartman153b1062017-11-11 12:09:21 -0800134 auto nm(cvd::NetworkInterfaceManager::New(nullptr));
Tomasz Wiszkowski719d3152017-10-26 09:58:11 -0700135 auto ni(nm->Open("rmnet0"));
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700136
137 if (ni) {
138 ni->SetOperational(false);
139 bool res = nm->ApplyChanges(*ni);
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800140 if (!res) ALOGE("Could not disable rmnet0");
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700141 return res;
142 }
143 return false;
144}
145
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700146static int gNextDataCallId = 8;
147static std::map<int, DataCall> gDataCalls;
148static bool gRilConnected = false;
149
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700150static int request_or_send_data_calllist(RIL_Token* t) {
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700151#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700152 RIL_Data_Call_Response_v11* responses =
153 new RIL_Data_Call_Response_v11[gDataCalls.size()];
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700154#else
155 RIL_Data_Call_Response_v6* responses =
156 new RIL_Data_Call_Response_v6[gDataCalls.size()];
157#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700158
159 int index = 0;
160
161 ALOGV("Query data call list: %zu data calls tracked.", gDataCalls.size());
162
163 for (std::map<int, DataCall>::iterator iter = gDataCalls.begin();
164 iter != gDataCalls.end(); ++iter, ++index) {
165 responses[index].status = iter->second.fail_cause_;
166 responses[index].suggestedRetryTime = -1;
167 responses[index].cid = iter->first;
168 responses[index].active = iter->second.link_state_;
169
170 switch (iter->second.connection_type_) {
171 case DataCall::kConnTypeIPv4:
172 responses[index].type = (char*)"IP";
173 break;
174 case DataCall::kConnTypeIPv6:
175 responses[index].type = (char*)"IPV6";
176 break;
177 case DataCall::kConnTypeIPv4v6:
178 responses[index].type = (char*)"IPV4V6";
179 break;
180 case DataCall::kConnTypePPP:
181 responses[index].type = (char*)"PPP";
182 break;
183 default:
184 responses[index].type = (char*)"IP";
185 break;
186 }
187
Jorge E. Moreirad6c129e2018-01-05 14:52:21 -0800188 auto ril_region_view = vsoc::ril::RilRegionView::GetInstance();
189
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800190 responses[index].ifname = (char*)"rmnet0";
Jorge E. Moreirad6c129e2018-01-05 14:52:21 -0800191 responses[index].addresses =
192 const_cast<char*>(ril_region_view->address_and_prefix_length());
193 responses[index].dnses = (char*)ril_region_view->data()->dns;
194 responses[index].gateways = (char*)ril_region_view->data()->gateway;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700195#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700196 responses[index].pcscf = (char*)"";
197 responses[index].mtu = 1440;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700198#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700199 }
200
201 bool new_conn_state = (gDataCalls.size() > 0);
202
203 if (gRilConnected != new_conn_state) {
204 time_t curr_time;
205 time(&curr_time);
206 double diff_in_secs = difftime(curr_time, gce_ril_start_time);
207
208 gRilConnected = new_conn_state;
209
210 if (new_conn_state) {
211 ALOGV("MOBILE_DATA_CONNECTED %.2lf seconds", diff_in_secs);
212 } else {
213 ALOGV("MOBILE_DATA_DISCONNECTED %.2lf seconds", diff_in_secs);
214 }
215
216 if (property_set("ril.net_connected", new_conn_state ? "1" : "0")) {
217 ALOGE("Couldn't set a system property ril.net_connected.");
218 }
219 }
220
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700221 if (t != NULL) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700222 gce_ril_env->OnRequestComplete(*t, RIL_E_SUCCESS, responses,
223 gDataCalls.size() * sizeof(*responses));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700224 } else {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700225 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
226 responses,
227 gDataCalls.size() * sizeof(*responses));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700228 }
229 delete[] responses;
230 return 0;
231}
232
233static void request_datacall_fail_cause(RIL_Token t) {
234 RIL_DataCallFailCause fail = PDP_FAIL_DATA_REGISTRATION_FAIL;
235
236 if (gDataCalls.size() > 0) {
237 fail = gDataCalls.rbegin()->second.fail_cause_;
238 }
239
240 ALOGV("Requesting last data call setup fail cause (%d)", fail);
241 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &fail, sizeof(fail));
242};
243
Greg Hartman85c495f2017-10-26 23:52:37 -0700244static void request_data_calllist(void* /*data*/, size_t /*datalen*/,
245 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700246 request_or_send_data_calllist(&t);
247}
248
249static void request_setup_data_call(void* data, size_t datalen, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700250 char** details = static_cast<char**>(data);
251 const size_t fields = datalen / sizeof(details[0]);
252
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700253 // There are two different versions of this interface, one providing 7 strings
254 // and the other providing 8. The code below will assume the presence of 7
255 // strings in all cases, so bail out here if things appear to be wrong. We
256 // protect the 8 string case below.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700257 if (fields < 7) {
258 ALOGE("%s returning: called with small datalen %zu", __FUNCTION__, datalen);
259 return;
260 }
261 DataCall call;
262 int tech = atoi(details[0]);
263 switch (tech) {
264 case 0:
265 case 2 + RADIO_TECH_1xRTT:
266 call.technology_ = RADIO_TECH_1xRTT;
267 break;
268
269 case 1:
270 case 2 + RADIO_TECH_EDGE:
271 call.technology_ = RADIO_TECH_EDGE;
272 break;
273
274 default:
275 call.technology_ = RIL_RadioTechnology(tech - 2);
276 break;
277 }
278
279 int profile = atoi(details[1]);
280 call.profile_ = RIL_DataProfile(profile);
281
282 if (details[2]) call.access_point_ = details[2];
283 if (details[3]) call.username_ = details[3];
284 if (details[4]) call.password_ = details[4];
285
286 int auth_type = atoi(details[5]);
287 call.auth_type_ = DataCall::AllowedAuthenticationType(auth_type);
288
289 if (!strcmp("IP", details[6])) {
290 call.connection_type_ = DataCall::kConnTypeIPv4;
291 } else if (!strcmp("IPV6", details[6])) {
292 call.connection_type_ = DataCall::kConnTypeIPv6;
293 } else if (!strcmp("IPV4V6", details[6])) {
294 call.connection_type_ = DataCall::kConnTypeIPv4v6;
295 } else if (!strcmp("PPP", details[6])) {
296 call.connection_type_ = DataCall::kConnTypePPP;
297 } else {
298 ALOGW("Unknown / unsupported connection type %s. Falling back to IPv4",
299 details[6]);
300 call.connection_type_ = DataCall::kConnTypeIPv4;
301 }
302
303 if (call.connection_type_ != DataCall::kConnTypeIPv4) {
Greg Hartman7c01b7c2018-01-10 18:30:22 -0800304 ALOGE("Non-IPv4 connections are not supported by VSOC RIL.");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700305 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
306 return;
307 }
308
309 call.link_state_ = DataCall::kLinkStateUp;
310 call.fail_cause_ = PDP_FAIL_NONE;
311 if (fields > 7) {
312 if (details[7]) call.other_properties_ = details[7];
313 }
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700314
315 if (gDataCalls.empty()) {
Jorge E. Moreirad6c129e2018-01-05 14:52:21 -0800316 auto ril_region_view = vsoc::ril::RilRegionView::GetInstance();
317 SetUpNetworkInterface(ril_region_view->data()->ipaddr,
318 ril_region_view->data()->prefixlen,
319 ril_region_view->data()->broadcast);
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700320 }
321
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700322 gDataCalls[gNextDataCallId] = call;
323 gNextDataCallId++;
324
325 ALOGV("Requesting data call setup to APN %s, technology %s, prof %s",
326 details[2], details[0], details[1]);
327
328 request_or_send_data_calllist(&t);
329
330 gRilConnected = (gDataCalls.size() > 0);
331}
332
Greg Hartman85c495f2017-10-26 23:52:37 -0700333static void request_teardown_data_call(void* data, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700334 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700335 char** data_strs = (char**)data;
336 int call_id = atoi(data_strs[0]);
337 int reason = atoi(data_strs[1]);
338
339 ALOGV("Tearing down data call %d, reason: %d", call_id, reason);
340
341 gDataCalls.erase(call_id);
342 gRilConnected = (gDataCalls.size() > 0);
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700343
344 if (!gRilConnected) {
345 TearDownNetworkInterface();
346 }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700347 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
348}
349
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700350static void set_radio_state(RIL_RadioState new_state, RIL_Token t) {
351 // From header:
352 // Toggle radio on and off (for "airplane" mode)
353 // If the radio is is turned off/on the radio modem subsystem
354 // is expected return to an initialized state. For instance,
355 // any voice and data calls will be terminated and all associated
356 // lists emptied.
357 gDataCalls.clear();
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700358
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700359 gSimStatus = SIM_NOT_READY;
Greg Hartman7c01b7c2018-01-10 18:30:22 -0800360 ALOGV("RIL_RadioState change %d to %d", gRadioPowerState, new_state);
361 gRadioPowerState = new_state;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700362
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700363 if (new_state == RADIO_STATE_OFF) {
364 TearDownNetworkInterface();
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700365 }
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700366
367 if (t != NULL) {
368 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
369 }
370
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700371 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
372 NULL, 0);
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700373
374 pollSIMState(NULL);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700375}
376
377// returns 1 if on, 0 if off, and -1 on error
Greg Hartman85c495f2017-10-26 23:52:37 -0700378static void request_radio_power(void* data, size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700379 int on = ((int*)data)[0];
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700380 set_radio_state(on ? RADIO_STATE_ON : RADIO_STATE_OFF, t);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700381}
382
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700383// TODO(ender): this should be a class member. Move where it belongs.
384struct CallState {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700385 RIL_CallState state; // e.g. RIL_CALL_HOLDING;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700386 bool isInternational;
387 bool isMobileTerminated;
388 bool isVoice;
389 bool isMultiParty;
390
391 std::string number;
392 std::string name;
393 std::string dtmf;
394
395 bool canPresentNumber;
396 bool canPresentName;
397
398 CallState()
399 : state(RIL_CallState(0)),
400 isInternational(false),
401 isMobileTerminated(true),
402 isVoice(true),
403 isMultiParty(false),
404 canPresentNumber(true),
405 canPresentName(true) {}
406
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700407 CallState(const std::string& number)
408 : state(RIL_CALL_INCOMING),
409 isInternational(false),
410 isMobileTerminated(true),
411 isVoice(true),
412 isMultiParty(false),
413 number(number),
414 name(number),
415 canPresentNumber(true),
416 canPresentName(true) {}
417
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700418 bool isBackground() { return state == RIL_CALL_HOLDING; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700419
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700420 bool isActive() { return state == RIL_CALL_ACTIVE; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700421
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700422 bool isDialing() { return state == RIL_CALL_DIALING; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700423
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700424 bool isIncoming() { return state == RIL_CALL_INCOMING; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700425
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700426 bool isWaiting() { return state == RIL_CALL_WAITING; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700427
428 void addDtmfDigit(char c) {
429 dtmf.push_back(c);
430 ALOGV("Call to %s: DTMF %s", number.c_str(), dtmf.c_str());
431 }
432
433 bool makeBackground() {
434 if (state == RIL_CALL_ACTIVE) {
435 state = RIL_CALL_HOLDING;
436 return true;
437 }
438
439 return false;
440 }
441
442 bool makeActive() {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700443 if (state == RIL_CALL_INCOMING || state == RIL_CALL_WAITING ||
444 state == RIL_CALL_DIALING || state == RIL_CALL_HOLDING) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700445 state = RIL_CALL_ACTIVE;
446 return true;
447 }
448
449 return false;
450 }
451};
452
453static int gLastActiveCallIndex = 1;
Tomasz Wiszkowski429d6022017-10-17 10:02:05 -0700454static int gMicrophoneMute = 0;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700455static std::map<int, CallState> gActiveCalls;
456
Greg Hartman85c495f2017-10-26 23:52:37 -0700457static void request_get_current_calls(void* /*data*/, size_t /*datalen*/,
458 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700459 const int countCalls = gActiveCalls.size();
460
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700461 RIL_Call** pp_calls = (RIL_Call**)alloca(countCalls * sizeof(RIL_Call*));
462 RIL_Call* p_calls = (RIL_Call*)alloca(countCalls * sizeof(RIL_Call));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700463
464 memset(p_calls, 0, countCalls * sizeof(RIL_Call));
465
466 /* init the pointer array */
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700467 for (int i = 0; i < countCalls; i++) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700468 pp_calls[i] = &(p_calls[i]);
469 }
470
Tomasz Wiszkowski1ef31e42017-09-21 09:09:37 -0700471 // TODO(ender): This should be built from calls requested via RequestDial.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700472 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
473 iter != gActiveCalls.end(); ++iter, ++p_calls) {
474 p_calls->state = iter->second.state;
475 p_calls->index = iter->first;
476 p_calls->toa = iter->second.isInternational ? 145 : 129;
477 p_calls->isMpty = iter->second.isMultiParty;
478 p_calls->isMT = iter->second.isMobileTerminated;
479 p_calls->als = iter->first;
480 p_calls->isVoice = iter->second.isVoice;
481 p_calls->isVoicePrivacy = 0;
482 p_calls->number = strdup(iter->second.number.c_str());
483 p_calls->numberPresentation = iter->second.canPresentNumber ? 0 : 1;
484 p_calls->name = strdup(iter->second.name.c_str());
485 p_calls->namePresentation = iter->second.canPresentName ? 0 : 1;
486 p_calls->uusInfo = NULL;
487
488 ALOGV("Call to %s (%s): voice=%d mt=%d type=%d state=%d index=%d",
489 p_calls->name, p_calls->number, p_calls->isVoice, p_calls->isMT,
490 p_calls->toa, p_calls->state, p_calls->index);
491 }
492
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700493 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, pp_calls,
494 countCalls * sizeof(RIL_Call*));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700495
496 ALOGV("Get Current calls: %d calls found.\n", countCalls);
497}
498
Greg Hartman85c495f2017-10-26 23:52:37 -0700499static void simulate_pending_calls_answered(void* /*ignore*/) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700500 ALOGV("Simulating outgoing call answered.");
501 // This also resumes held calls.
502 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
503 iter != gActiveCalls.end(); ++iter) {
504 if (iter->second.isDialing()) {
505 iter->second.makeActive();
506 }
507 }
508
509 // Only unsolicited here.
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700510 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
511 NULL, 0);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700512}
513
Greg Hartman85c495f2017-10-26 23:52:37 -0700514static void request_dial(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700515 RIL_Dial* p_dial = (RIL_Dial*)data;
516
517 ALOGV("Dialing %s, number presentation is %s.", p_dial->address,
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700518 (p_dial->clir == 0) ? "defined by operator"
519 : (p_dial->clir == 1) ? "allowed" : "restricted");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700520
521 CallState state(p_dial->address);
522 state.isMobileTerminated = false;
523 state.state = RIL_CALL_DIALING;
524
525 switch (p_dial->clir) {
526 case 0: // default
527 case 1: // allow
528 state.canPresentNumber = true;
529 break;
530
531 case 2: // restrict
532 state.canPresentNumber = false;
533 break;
534 }
535
536 int call_index = gLastActiveCallIndex++;
537 gActiveCalls[call_index] = state;
538
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700539 static const struct timeval kAnswerTime = {5, 0};
540 gce_ril_env->RequestTimedCallback(simulate_pending_calls_answered, NULL,
541 &kAnswerTime);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700542
543 // success or failure is ignored by the upper layer here.
544 // it will call GET_CURRENT_CALLS and determine success that way
545 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
546}
547
Greg Hartman85c495f2017-10-26 23:52:37 -0700548void request_set_mute(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski429d6022017-10-17 10:02:05 -0700549 gMicrophoneMute = ((int*)data)[0] != 0;
550 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
551}
552
553void request_get_mute(RIL_Token t) {
554 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gMicrophoneMute,
555 sizeof(gMicrophoneMute));
556}
557
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700558// TODO(ender): this should be a class member. Move where it belongs.
559struct SmsMessage {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700560 enum SmsStatus { kUnread = 0, kRead = 1, kUnsent = 2, kSent = 3 };
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700561
562 std::string message;
563 SmsStatus status;
564};
565
566static int gNextMessageId = 1;
567static std::map<int, SmsMessage> gMessagesOnSimCard;
568
Greg Hartman85c495f2017-10-26 23:52:37 -0700569static void request_write_sms_to_sim(void* data, size_t /*datalen*/,
570 RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700571 RIL_SMS_WriteArgs* p_args = (RIL_SMS_WriteArgs*)data;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700572
573 SmsMessage message;
574 message.status = SmsMessage::SmsStatus(p_args->status);
575 message.message = p_args->pdu;
576
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700577 ALOGV("Storing SMS message: '%s' with state: %s.", message.message.c_str(),
578 (message.status < SmsMessage::kUnsent)
579 ? ((message.status == SmsMessage::kRead) ? "READ" : "UNREAD")
580 : ((message.status == SmsMessage::kSent) ? "SENT" : "UNSENT"));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700581
582 // TODO(ender): simulate SIM FULL?
583 int index = gNextMessageId++;
584 gMessagesOnSimCard[index] = message;
585
586 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &index, sizeof(index));
587}
588
Greg Hartman85c495f2017-10-26 23:52:37 -0700589static void request_delete_sms_on_sim(void* data, size_t /*datalen*/,
590 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700591 int index = *(int*)data;
592
593 ALOGV("Delete SMS message %d", index);
594
595 if (gMessagesOnSimCard.erase(index) == 0) {
596 // No such message
597 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
598 return;
599 }
600
601 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
602}
603
Greg Hartman85c495f2017-10-26 23:52:37 -0700604static void request_hangup(void* data, size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700605 int* p_line = (int*)data;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700606
607 ALOGV("Hanging up call %d.", *p_line);
608 std::map<int, CallState>::iterator iter = gActiveCalls.find(*p_line);
609
610 if (iter == gActiveCalls.end()) {
611 ALOGV("No such call: %d.", *p_line);
612 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
613 } else {
614 gActiveCalls.erase(iter);
615 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
616 }
617}
618
Greg Hartman85c495f2017-10-26 23:52:37 -0700619static void request_hangup_waiting(void* /*data*/, size_t /*datalen*/,
620 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700621 ALOGV("Hanging up background/held calls.");
622 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
623 iter != gActiveCalls.end();) {
624 if (iter->second.isBackground()) {
625 // C++98 -- std::map::erase doesn't return iterator.
626 std::map<int, CallState>::iterator temp = iter++;
627 gActiveCalls.erase(temp);
628 } else {
629 ++iter;
630 }
631 }
632 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
633}
634
635static void request_hangup_current(RIL_Token t) {
636 ALOGV("Hanging up foreground/active calls.");
637 // This also resumes held calls.
638 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
639 iter != gActiveCalls.end();) {
640 if (iter->second.isBackground()) {
641 iter->second.makeActive();
642 ++iter;
643 } else {
644 // C++98 -- std::map::erase doesn't return iterator.
645 std::map<int, CallState>::iterator temp = iter++;
646 gActiveCalls.erase(temp);
647 }
648 }
649 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
650}
651
652static void request_switch_current_and_waiting(RIL_Token t) {
653 ALOGV("Toggle foreground and background calls.");
654 // TODO(ender): fix all states. Max 2 calls.
655 // BEFORE AFTER
656 // Call 1 Call 2 Call 1 Call 2
657 // ACTIVE HOLDING HOLDING ACTIVE
658 // ACTIVE WAITING HOLDING ACTIVE
659 // HOLDING WAITING HOLDING ACTIVE
660 // ACTIVE IDLE HOLDING IDLE
661 // IDLE IDLE IDLE IDLE
662 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
663 iter != gActiveCalls.end(); ++iter) {
664 // TODO(ender): call could also be waiting or dialing or...
665 if (iter->second.isBackground()) {
666 iter->second.makeActive();
667 } else {
668 iter->second.makeBackground();
669 }
670 }
671 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
672}
673
674static void request_answer_incoming(RIL_Token t) {
675 ALOGV("Answering incoming call.");
676
677 // There's two types of incoming calls:
678 // - incoming: we are receiving this call while nothing happens,
679 // - waiting: we are receiving this call while we're already talking.
680 // We only accept the incoming ones.
681 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
682 iter != gActiveCalls.end(); ++iter) {
683 if (iter->second.isIncoming()) {
684 iter->second.makeActive();
685 }
686 }
687 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
688}
689
Greg Hartman85c495f2017-10-26 23:52:37 -0700690static void request_combine_multiparty_call(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700691 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700692 ALOGW("Conference calls are not supported.");
693 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
694}
695
Greg Hartman85c495f2017-10-26 23:52:37 -0700696static void request_split_multiparty_call(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700697 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700698 ALOGW("Conference calls are not supported.");
699 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
700}
701
702static void request_udub_on_incoming_calls(RIL_Token t) {
703 // UDUB = user determined user busy.
704 // We don't exactly do that. We simply drop these calls.
705 ALOGV("Reporting busy signal to incoming calls.");
706 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
707 iter != gActiveCalls.end();) {
708 // If we have an incoming call, there should be no waiting call.
709 // If we have a waiting call, then previous incoming call has been answered.
710 if (iter->second.isIncoming() || iter->second.isWaiting()) {
711 // C++98 -- std::map::erase doesn't return iterator.
712 std::map<int, CallState>::iterator temp = iter++;
713 gActiveCalls.erase(temp);
714 } else {
715 ++iter;
716 }
717 }
718 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
719}
720
Greg Hartman85c495f2017-10-26 23:52:37 -0700721static void request_send_dtmf(void* data, size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700722 char c = ((char*)data)[0];
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700723 ALOGV("Sending DTMF digit '%c'", c);
724
725 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
726 iter != gActiveCalls.end(); ++iter) {
727 if (iter->second.isActive()) {
728 iter->second.addDtmfDigit(c);
729 break;
730 }
731 }
732
733 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
734}
735
736static void request_send_dtmf_stop(RIL_Token t) {
737 ALOGV("DTMF tone end.");
738
739 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
740}
741
742// Check SignalStrength.java file for more details on how these map to signal
743// strength bars.
744const int kGatewaySignalStrengthMin = 4;
745const int kGatewaySignalStrengthMax = 30;
746const int kCDMASignalStrengthMin = -110;
747const int kCDMASignalStrengthMax = -60;
748const int kEVDOSignalStrengthMin = -160;
749const int kEVDOSignalStrengthMax = -70;
750const int kLTESignalStrengthMin = 4;
751const int kLTESignalStrengthMax = 30;
752
753static int gGatewaySignalStrength = kGatewaySignalStrengthMax;
754static int gCDMASignalStrength = kCDMASignalStrengthMax;
755static int gEVDOSignalStrength = kEVDOSignalStrengthMax;
756static int gLTESignalStrength = kLTESignalStrengthMax;
757
Greg Hartman85c495f2017-10-26 23:52:37 -0700758static void request_signal_strength(void* /*data*/, size_t /*datalen*/,
759 RIL_Token t) {
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700760 // TODO(ender): possible to support newer APIs here.
761#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700762 RIL_SignalStrength_v10 strength;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700763#else
764 RIL_SignalStrength_v6 strength;
765#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700766
767 gGatewaySignalStrength += (rand() % 3 - 1);
768 gCDMASignalStrength += (rand() % 3 - 1);
769 gEVDOSignalStrength += (rand() % 3 - 1);
770 gLTESignalStrength += (rand() % 3 - 1);
771
772 if (gGatewaySignalStrength < kGatewaySignalStrengthMin)
773 gGatewaySignalStrength = kGatewaySignalStrengthMin;
774 if (gGatewaySignalStrength > kGatewaySignalStrengthMax)
775 gGatewaySignalStrength = kGatewaySignalStrengthMax;
776 if (gCDMASignalStrength < kCDMASignalStrengthMin)
777 gCDMASignalStrength = kCDMASignalStrengthMin;
778 if (gCDMASignalStrength > kCDMASignalStrengthMax)
779 gCDMASignalStrength = kCDMASignalStrengthMax;
780 if (gEVDOSignalStrength < kEVDOSignalStrengthMin)
781 gEVDOSignalStrength = kEVDOSignalStrengthMin;
782 if (gEVDOSignalStrength > kEVDOSignalStrengthMax)
783 gEVDOSignalStrength = kEVDOSignalStrengthMax;
784 if (gLTESignalStrength < kLTESignalStrengthMin)
785 gLTESignalStrength = kLTESignalStrengthMin;
786 if (gLTESignalStrength > kLTESignalStrengthMax)
787 gLTESignalStrength = kLTESignalStrengthMax;
788
789 strength.GW_SignalStrength.signalStrength = gGatewaySignalStrength;
790 strength.GW_SignalStrength.bitErrorRate = 0; // 0..7%
791
792 strength.CDMA_SignalStrength.dbm = gCDMASignalStrength;
793 strength.CDMA_SignalStrength.ecio = 0; // Ec/Io; keep high to use dbm.
794
795 strength.EVDO_SignalStrength.dbm = gEVDOSignalStrength;
796 strength.EVDO_SignalStrength.ecio = 0; // Ec/Io; keep high to use dbm.
797
798 strength.LTE_SignalStrength.signalStrength = gLTESignalStrength;
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700799 strength.LTE_SignalStrength.rsrp = INT_MAX; // Invalid = Use signalStrength.
800 strength.LTE_SignalStrength.rsrq = INT_MAX; // Invalid = Use signalStrength.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700801 strength.LTE_SignalStrength.rssnr = INT_MAX; // Invalid = Use signalStrength.
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700802 strength.LTE_SignalStrength.cqi = INT_MAX; // Invalid = Use signalStrength.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700803
804 ALOGV("Reporting signal strength: GW=%d CDMA=%d EVDO=%d LTE=%d",
805 gGatewaySignalStrength, gCDMASignalStrength, gEVDOSignalStrength,
806 gLTESignalStrength);
807
808 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &strength, sizeof(strength));
809}
810
811static std::map<RIL_PreferredNetworkType, int> gModemSupportedNetworkTypes;
812
813static void init_modem_supported_network_types() {
814 gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA] = MDM_GSM | MDM_WCDMA;
815 gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_ONLY] = MDM_GSM;
816 gModemSupportedNetworkTypes[PREF_NET_TYPE_WCDMA] = MDM_WCDMA;
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700817 gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA_AUTO] =
818 MDM_GSM | MDM_WCDMA;
819 gModemSupportedNetworkTypes[PREF_NET_TYPE_CDMA_EVDO_AUTO] =
820 MDM_CDMA | MDM_EVDO;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700821 gModemSupportedNetworkTypes[PREF_NET_TYPE_CDMA_ONLY] = MDM_CDMA;
822 gModemSupportedNetworkTypes[PREF_NET_TYPE_EVDO_ONLY] = MDM_EVDO;
823 gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO] =
824 MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO;
825 gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_CDMA_EVDO] =
826 MDM_LTE | MDM_CDMA | MDM_EVDO;
827 gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_GSM_WCDMA] =
828 MDM_LTE | MDM_GSM | MDM_WCDMA;
829 gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA] =
830 MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA;
831 gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_ONLY] = MDM_LTE;
832}
833
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700834static std::map<RIL_PreferredNetworkType, int> gModemTechnologies;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700835
836RIL_RadioTechnology gDataTechnologiesPreferenceOrder[] = {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700837 RADIO_TECH_LTE, RADIO_TECH_EHRPD, RADIO_TECH_HSPAP, RADIO_TECH_HSPA,
838 RADIO_TECH_HSDPA, RADIO_TECH_HSUPA, RADIO_TECH_EVDO_B, RADIO_TECH_EVDO_A,
839 RADIO_TECH_EVDO_0, RADIO_TECH_1xRTT, RADIO_TECH_UMTS, RADIO_TECH_EDGE,
840 RADIO_TECH_GPRS};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700841
842RIL_RadioTechnology gVoiceTechnologiesPreferenceOrder[] = {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700843 RADIO_TECH_LTE, RADIO_TECH_EHRPD, RADIO_TECH_EVDO_B, RADIO_TECH_EVDO_A,
844 RADIO_TECH_EVDO_0, RADIO_TECH_1xRTT, RADIO_TECH_IS95B, RADIO_TECH_IS95A,
845 RADIO_TECH_UMTS, RADIO_TECH_GSM};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700846
847static void init_modem_technologies() {
848 gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA] =
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700849 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
850 (1 << RADIO_TECH_UMTS);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700851 gModemTechnologies[PREF_NET_TYPE_GSM_ONLY] =
852 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE);
853 gModemTechnologies[PREF_NET_TYPE_WCDMA] =
854 (1 << RADIO_TECH_EDGE) | (1 << RADIO_TECH_UMTS);
855 gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA_AUTO] =
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700856 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
857 (1 << RADIO_TECH_UMTS);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700858 gModemTechnologies[PREF_NET_TYPE_CDMA_EVDO_AUTO] =
859 (1 << RADIO_TECH_IS95A) | (1 << RADIO_TECH_IS95B) |
860 (1 << RADIO_TECH_1xRTT) | (1 << RADIO_TECH_EVDO_0) |
861 (1 << RADIO_TECH_EVDO_A) | (1 << RADIO_TECH_HSDPA) |
862 (1 << RADIO_TECH_HSUPA) | (1 << RADIO_TECH_HSPA) |
863 (1 << RADIO_TECH_EVDO_B);
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700864 gModemTechnologies[PREF_NET_TYPE_CDMA_ONLY] = (1 << RADIO_TECH_IS95A) |
865 (1 << RADIO_TECH_IS95B) |
866 (1 << RADIO_TECH_1xRTT);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700867 gModemTechnologies[PREF_NET_TYPE_EVDO_ONLY] =
868 (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
869 (1 << RADIO_TECH_EVDO_A) | (1 << RADIO_TECH_HSDPA) |
870 (1 << RADIO_TECH_HSUPA) | (1 << RADIO_TECH_HSPA) |
871 (1 << RADIO_TECH_EVDO_B);
872 gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO] =
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700873 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
874 (1 << RADIO_TECH_UMTS) | (1 << RADIO_TECH_IS95A) |
875 (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) |
876 (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
877 (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) |
878 (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700879 gModemTechnologies[PREF_NET_TYPE_LTE_CDMA_EVDO] =
880 (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) |
881 (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_IS95A) |
882 (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) |
883 (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
884 (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) |
885 (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B);
886 gModemTechnologies[PREF_NET_TYPE_LTE_GSM_WCDMA] =
887 (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) |
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700888 (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) |
889 (1 << RADIO_TECH_EDGE) | (1 << RADIO_TECH_UMTS);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700890
891 gModemTechnologies[PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA] =
892 (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) |
893 (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_IS95A) |
894 (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) |
895 (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
896 (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) |
897 (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B) |
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700898 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
899 (1 << RADIO_TECH_UMTS);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700900 gModemTechnologies[PREF_NET_TYPE_LTE_ONLY] =
901 (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) | (1 << RADIO_TECH_EHRPD);
902}
903
904static const RIL_PreferredNetworkType gModemDefaultType =
905 PREF_NET_TYPE_LTE_GSM_WCDMA;
906static RIL_PreferredNetworkType gModemCurrentType = gModemDefaultType;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700907static RIL_RadioTechnology gModemVoiceTechnology = RADIO_TECH_LTE;
908
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700909// Report technology change.
910// Select best technology from the list of supported techs.
911// Demotes RADIO_TECH_GSM as it's voice-only.
912static RIL_RadioTechnology getBestDataTechnology(
913 RIL_PreferredNetworkType network_type) {
914 RIL_RadioTechnology technology = RADIO_TECH_GPRS;
915
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700916 std::map<RIL_PreferredNetworkType, int>::iterator iter =
917 gModemTechnologies.find(network_type);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700918
919 ALOGV("Searching for best data technology for network type %d...",
920 network_type);
921
922 // Find which technology bits are lit. Pick the top most.
923 for (size_t tech_index = 0;
924 tech_index < sizeof(gDataTechnologiesPreferenceOrder) /
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700925 sizeof(gDataTechnologiesPreferenceOrder[0]);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700926 ++tech_index) {
927 if (iter->second & (1 << gDataTechnologiesPreferenceOrder[tech_index])) {
928 technology = gDataTechnologiesPreferenceOrder[tech_index];
929 break;
930 }
931 }
932
933 ALOGV("Best data technology: %d.", technology);
934 return technology;
935}
936
937static RIL_RadioTechnology getBestVoiceTechnology(
938 RIL_PreferredNetworkType network_type) {
939 RIL_RadioTechnology technology = RADIO_TECH_GSM;
940
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700941 std::map<RIL_PreferredNetworkType, int>::iterator iter =
942 gModemTechnologies.find(network_type);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700943
944 ALOGV("Searching for best voice technology for network type %d...",
945 network_type);
946
947 // Find which technology bits are lit. Pick the top most.
948 for (size_t tech_index = 0;
949 tech_index < sizeof(gVoiceTechnologiesPreferenceOrder) /
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700950 sizeof(gVoiceTechnologiesPreferenceOrder[0]);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700951 ++tech_index) {
952 if (iter->second & (1 << gVoiceTechnologiesPreferenceOrder[tech_index])) {
953 technology = gVoiceTechnologiesPreferenceOrder[tech_index];
954 break;
955 }
956 }
957
958 ALOGV("Best voice technology: %d.", technology);
959 return technology;
960}
961
962static void setRadioTechnology(RIL_PreferredNetworkType network_type) {
963 RIL_RadioTechnology technology = getBestVoiceTechnology(network_type);
964
965 if (technology != gModemVoiceTechnology) {
966 gModemVoiceTechnology = technology;
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700967 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
968 &gModemVoiceTechnology,
969 sizeof(gModemVoiceTechnology));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700970 }
971}
972
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700973#if VSOC_PLATFORM_SDK_AFTER(L)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700974static void request_get_radio_capability(RIL_Token t) {
975 ALOGV("Requesting radio capability.");
976 RIL_RadioCapability rc;
977 rc.version = RIL_RADIO_CAPABILITY_VERSION;
978 rc.session = 1;
979 rc.phase = RC_PHASE_CONFIGURED;
980 rc.rat = RAF_HSPAP;
Greg Hartman153b1062017-11-11 12:09:21 -0800981 strncpy(rc.logicalModemUuid, "com.google.cvdgce1.modem", MAX_UUID_LENGTH);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700982 rc.status = RC_STATUS_SUCCESS;
983 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &rc, sizeof(rc));
984}
985
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700986static void request_set_radio_capability(void* data, size_t datalen,
987 RIL_Token t) {
988 RIL_RadioCapability* rc = (RIL_RadioCapability*)data;
989 ALOGV(
990 "RadioCapability version %d session %d phase %d rat %d "
991 "logicalModemUuid %s status %d",
992 rc->version, rc->session, rc->phase, rc->rat, rc->logicalModemUuid,
993 rc->status);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700994 // TODO(ender): do something about these numbers.
995 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, rc, datalen);
996}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700997#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700998
Greg Hartman85c495f2017-10-26 23:52:37 -0700999static void request_set_preferred_network_type(int /*request*/, void* data,
1000 size_t /*datalen*/,
1001 RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001002 RIL_PreferredNetworkType desired_type = *(RIL_PreferredNetworkType*)(data);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001003
1004 // TODO(ender): telephony still believes this phone is GSM only.
1005 ALOGV("Requesting modem technology change -> %d", desired_type);
1006
1007 if (gModemSupportedNetworkTypes.find(desired_type) ==
1008 gModemSupportedNetworkTypes.end()) {
1009 desired_type = gModemSupportedNetworkTypes.begin()->first;
1010 }
1011
1012 if (gModemCurrentType == desired_type) {
1013 ALOGV("Modem technology already set to %d.", desired_type);
1014 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1015 return;
1016 }
1017
1018 int supported_technologies = gModemSupportedNetworkTypes[gModemDefaultType];
1019 int desired_technologies = gModemSupportedNetworkTypes[desired_type];
1020
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001021 ALOGV("Requesting modem technology change %d -> %d", gModemCurrentType,
1022 desired_type);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001023
1024 // Check if we support this technology.
1025 if ((supported_technologies & desired_technologies) != desired_technologies) {
1026 ALOGV("Desired technology is not supported.");
1027 gce_ril_env->OnRequestComplete(t, RIL_E_MODE_NOT_SUPPORTED, NULL, 0);
1028 return;
1029 }
1030
1031 gModemCurrentType = desired_type;
1032 setRadioTechnology(desired_type);
1033 ALOGV("Technology change successful.");
1034 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1035}
1036
Greg Hartman85c495f2017-10-26 23:52:37 -07001037static void request_get_preferred_network_type(int /*request*/, void* /*data*/,
1038 size_t /*datalen*/,
1039 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001040 gce_ril_env->OnRequestComplete(
1041 t, RIL_E_SUCCESS,
1042 const_cast<RIL_PreferredNetworkType*>(&gModemDefaultType),
1043 sizeof(gModemDefaultType));
1044}
1045
1046enum RegistrationState {
1047 kUnregistered = 0,
1048 kRegisteredInHomeNetwork = 1,
1049 kSearchingForOperators = 2,
1050 kRegistrationDenied = 3,
1051 kUnknown = 4,
1052 kRegisteredInRoamingMode = 5,
1053
1054 kUnregistered_EmergencyCallsOnly = 10,
1055 kSearchingForOperators_EmergencyCallsOnly = 12,
1056 kRegistrationDenied_EmergencyCallsOnly = 13,
1057 kUnknown_EmergencyCallsOnly = 14
1058};
1059
1060static const char kCdmaMobileDeviceNumber[] = "5551234567";
1061static const char kCdmaSID[] = "123";
1062static const char kCdmaNID[] = "65535"; // special: indicates free roaming.
1063
Greg Hartman85c495f2017-10-26 23:52:37 -07001064static void request_registration_state(int request, void* /*data*/,
1065 size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001066 char** responseStr = NULL;
1067 int numElements = 0;
1068
1069 // See RIL_REQUEST_VOICE_REGISTRATION_STATE and
1070 // RIL_REQUEST_DATA_REGISTRATION_STATE.
1071 numElements = (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) ? 15 : 6;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001072 responseStr = (char**)malloc(numElements * sizeof(char*));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001073
1074 asprintf(&responseStr[0], "%d", kRegisteredInHomeNetwork);
1075 responseStr[1] = NULL; // LAC - needed for GSM / WCDMA only.
1076 responseStr[2] = NULL; // CID - needed for GSM / WCDMA only.
1077
1078 // This is (and always has been) a huge memory leak.
1079 if (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1080 ALOGV("Requesting voice registration state.");
1081 asprintf(&responseStr[3], "%d", getBestVoiceTechnology(gModemCurrentType));
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001082 responseStr[4] = strdup("1"); // BSID
1083 responseStr[5] = strdup("123"); // Latitude
1084 responseStr[6] = strdup("222"); // Longitude
1085 responseStr[7] = strdup("0"); // CSS Indicator
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001086 responseStr[8] = strdup(kCdmaSID); // SID
1087 responseStr[9] = strdup(kCdmaNID); // NID
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001088 responseStr[10] = strdup("0"); // Roaming indicator
1089 responseStr[11] = strdup("1"); // System is in PRL
1090 responseStr[12] = strdup("0"); // Default Roaming indicator
1091 responseStr[13] = strdup("0"); // Reason for denial
1092 responseStr[14] = strdup("0"); // Primary Scrambling Code of Current
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001093 } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1094 ALOGV("Requesting data registration state.");
1095 asprintf(&responseStr[3], "%d", getBestDataTechnology(gModemCurrentType));
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001096 responseStr[4] = strdup(""); // DataServiceDenyReason
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001097 responseStr[5] = strdup("1"); // Max simultaneous data calls.
1098 } else {
1099 ALOGV("Unexpected request type: %d", request);
1100 return;
1101 }
1102
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001103 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, responseStr,
1104 numElements * sizeof(responseStr));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001105}
1106
1107static void request_baseband_version(RIL_Token t) {
Greg Hartman153b1062017-11-11 12:09:21 -08001108 const char* response_str = "CVD_R1.0.0";
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001109
1110 ALOGV("Requested phone baseband version.");
1111
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001112 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, strdup(response_str),
1113 sizeof(response_str));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001114}
1115
1116// Returns true, if modem is CDMA capable.
1117static bool isCDMA() {
1118 switch (gModemCurrentType) {
1119 case PREF_NET_TYPE_GSM_WCDMA:
1120 case PREF_NET_TYPE_GSM_ONLY:
1121 case PREF_NET_TYPE_WCDMA:
1122 case PREF_NET_TYPE_GSM_WCDMA_AUTO:
1123 case PREF_NET_TYPE_LTE_GSM_WCDMA:
1124 case PREF_NET_TYPE_LTE_ONLY:
1125 return false;
1126
1127 case PREF_NET_TYPE_CDMA_EVDO_AUTO:
1128 case PREF_NET_TYPE_CDMA_ONLY:
1129 case PREF_NET_TYPE_EVDO_ONLY:
1130 case PREF_NET_TYPE_LTE_CDMA_EVDO:
1131 case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
1132 case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO:
1133 return true;
Greg Hartman85c495f2017-10-26 23:52:37 -07001134 default:
1135 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001136 }
1137
1138 ALOGE("INVALID MODEM TYPE: %d", gModemCurrentType);
1139 return false;
1140}
1141
1142// Returns true, if modem is GSM capable.
1143// Note, this is not same as !isCDMA().
1144static bool isGSM() {
1145 switch (gModemCurrentType) {
1146 case PREF_NET_TYPE_GSM_WCDMA:
1147 case PREF_NET_TYPE_GSM_ONLY:
1148 case PREF_NET_TYPE_WCDMA:
1149 case PREF_NET_TYPE_GSM_WCDMA_AUTO:
1150 case PREF_NET_TYPE_LTE_GSM_WCDMA:
1151 case PREF_NET_TYPE_LTE_ONLY:
1152 case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO:
1153 return true;
1154
1155 case PREF_NET_TYPE_CDMA_EVDO_AUTO:
1156 case PREF_NET_TYPE_CDMA_ONLY:
1157 case PREF_NET_TYPE_EVDO_ONLY:
1158 case PREF_NET_TYPE_LTE_CDMA_EVDO:
1159 case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
1160 return false;
Greg Hartman85c495f2017-10-26 23:52:37 -07001161 default:
1162 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001163 }
1164
1165 ALOGE("INVALID MODEM TYPE: %d", gModemCurrentType);
1166 return false;
1167}
1168
1169static const char gIdentityGsmImei[] = "12345678902468"; // Luhn cksum = 0.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001170static const char gIdentityGsmImeiSv[] = "01"; // Arbitrary version.
1171static const char gIdentityCdmaEsn[] = "A0123456"; // 8 digits, ^[A-F].*
1172static const char gIdentityCdmaMeid[] =
1173 "A0123456789012"; // 14 digits, ^[A-F].*
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001174
1175static void request_get_imei(RIL_Token t) {
1176 ALOGV("Requesting IMEI");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001177 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
1178 const_cast<char*>(gIdentityGsmImei),
1179 strlen(gIdentityGsmImei));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001180}
1181
1182static void request_get_imei_sv(RIL_Token t) {
1183 ALOGV("Requesting IMEI SV");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001184 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
1185 const_cast<char*>(gIdentityGsmImeiSv),
1186 strlen(gIdentityGsmImeiSv));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001187}
1188
Greg Hartman85c495f2017-10-26 23:52:37 -07001189static void request_device_identity(int /*request*/, void* /*data*/,
1190 size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001191 char* response[4] = {NULL};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001192
1193 ALOGV("Requesting device identity...");
1194
1195 if (isCDMA()) {
1196 response[2] = strdup(&gIdentityCdmaEsn[0]);
1197 response[3] = strdup(&gIdentityCdmaMeid[0]);
1198 }
1199
1200 if (isGSM()) {
1201 response[0] = strdup(&gIdentityGsmImei[0]);
1202 response[1] = strdup(&gIdentityGsmImeiSv[0]);
1203 }
1204
1205 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1206
1207 free(response[0]);
1208 free(response[1]);
1209}
1210
1211// Let's pretend we have SIM for CDMA (by default).
1212static bool gCdmaHasSim = true;
1213static RIL_CdmaSubscriptionSource gCdmaSubscriptionType =
1214 CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
1215
Greg Hartman85c495f2017-10-26 23:52:37 -07001216static void request_cdma_get_subscription_source(int /*request*/,
1217 void* /*data*/,
1218 size_t /*datalen*/,
1219 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001220 ALOGV("Requesting CDMA Subscription source.");
1221
1222 if (!isCDMA()) {
1223 // No such radio.
1224 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1225 return;
1226 }
1227
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001228 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gCdmaSubscriptionType,
1229 sizeof(gCdmaSubscriptionType));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001230}
1231
Greg Hartman85c495f2017-10-26 23:52:37 -07001232static void request_cdma_set_subscription_source(int /*request*/, void* data,
1233 size_t /*datalen*/,
1234 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001235 ALOGV("Setting CDMA Subscription source.");
1236
1237 if (!isCDMA()) {
1238 // No such radio.
1239 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1240 return;
1241 }
1242
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001243 RIL_CdmaSubscriptionSource new_source = *(RIL_CdmaSubscriptionSource*)(data);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001244
1245 if (new_source == CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM && !gCdmaHasSim) {
1246 // No such radio.
1247 gce_ril_env->OnRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
1248 return;
1249 }
1250
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001251 ALOGV("Changed CDMA subscription type from %d to %d", gCdmaSubscriptionType,
1252 new_source);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001253 gCdmaSubscriptionType = new_source;
1254
1255 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001256 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
1257 &gCdmaSubscriptionType,
1258 sizeof(gCdmaSubscriptionType));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001259}
1260
Greg Hartman85c495f2017-10-26 23:52:37 -07001261static void request_cdma_subscription(int /*request*/, void* /*data*/,
1262 size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001263 ALOGV("Requesting CDMA Subscription.");
1264
1265 if (!isCDMA()) {
1266 // No such radio.
1267 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1268 return;
1269 }
1270
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001271 char* responseStr[5] = {NULL};
1272 responseStr[0] = strdup(&kCdmaMobileDeviceNumber[0]); // MDN
1273 responseStr[1] = strdup(&kCdmaSID[0]); // SID
1274 responseStr[2] = strdup(&kCdmaNID[0]); // NID
1275 responseStr[3] = strdup(&kCdmaMobileDeviceNumber[0]); // MIN
1276 responseStr[4] = strdup("1"); // PRL Version
1277 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, responseStr,
1278 sizeof(responseStr));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001279}
1280
1281static const int gMaxConcurrentVoiceCalls = 4;
1282static const int gMaxConcurrentDataCalls = 4;
1283static const int gMaxConcurrentStandbyConnections = 4;
1284
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001285#if VSOC_PLATFORM_SDK_AFTER(K)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001286static void request_hardware_config(RIL_Token t) {
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001287 RIL_HardwareConfig hw_cfg[2];
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001288
1289 ALOGV("Requesting hardware configuration.");
1290
Greg Hartman153b1062017-11-11 12:09:21 -08001291 strncpy(hw_cfg[0].uuid, "com.google.cvdgce1.modem", sizeof(hw_cfg[0].uuid));
1292 strncpy(hw_cfg[1].uuid, "com.google.cvdgce1.sim", sizeof(hw_cfg[1].uuid));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001293
1294 int technologies = 0; // = unknown.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001295 std::map<RIL_PreferredNetworkType, int>::iterator iter =
1296 gModemTechnologies.find(gModemDefaultType);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001297 if (iter != gModemTechnologies.end()) {
1298 technologies = iter->second;
1299 }
1300
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001301 hw_cfg[0].type = RIL_HARDWARE_CONFIG_MODEM;
1302 hw_cfg[0].state = RIL_HARDWARE_CONFIG_STATE_ENABLED;
1303 hw_cfg[0].cfg.modem.rilModel = 0;
1304 hw_cfg[0].cfg.modem.rat = technologies;
1305 hw_cfg[0].cfg.modem.maxVoice = gMaxConcurrentVoiceCalls;
1306 hw_cfg[0].cfg.modem.maxData = gMaxConcurrentDataCalls;
1307 hw_cfg[0].cfg.modem.maxStandby = gMaxConcurrentStandbyConnections;
1308
1309 hw_cfg[1].type = RIL_HARDWARE_CONFIG_SIM;
1310 hw_cfg[1].state = RIL_HARDWARE_CONFIG_STATE_ENABLED;
1311 memcpy(hw_cfg[1].cfg.sim.modemUuid, hw_cfg[0].uuid,
1312 sizeof(hw_cfg[1].cfg.sim.modemUuid));
1313
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001314 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &hw_cfg, sizeof(hw_cfg));
1315}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001316#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001317
1318// 0 = Home network only, 1 = preferred networks only, 2 = all networks.
1319static int gCdmaRoamingPreference = 2;
1320
Greg Hartman85c495f2017-10-26 23:52:37 -07001321static void request_cdma_get_roaming_preference(int /*request*/, void* /*data*/,
1322 size_t /*datalen*/,
1323 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001324 if (!isCDMA()) {
1325 // No such radio.
1326 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1327 return;
1328 }
1329
1330 ALOGV("Requesting CDMA Roaming preference");
1331
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001332 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gCdmaRoamingPreference,
1333 sizeof(gCdmaRoamingPreference));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001334}
1335
Greg Hartman85c495f2017-10-26 23:52:37 -07001336static void request_cdma_set_roaming_preference(int /*request*/, void* data,
1337 size_t /*datalen*/,
1338 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001339 if (!isCDMA()) {
1340 // No such radio.
1341 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1342 return;
1343 }
1344
1345 int pref = *(int*)data;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001346 ALOGV("Changing CDMA roaming preference: %d -> %d", gCdmaRoamingPreference,
1347 pref);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001348
1349 if ((pref < 0) || (pref > 2)) {
1350 ALOGV("Unsupported roaming preference: %d", pref);
1351 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1352 return;
1353 }
1354
1355 gCdmaRoamingPreference = pref;
1356 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1357}
1358
Greg Hartman85c495f2017-10-26 23:52:37 -07001359static void request_send_ussd(void* /*data*/, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001360 ALOGV("Sending USSD code is currently not supported");
1361 // TODO(ender): support this feature
1362 gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
1363}
1364
1365static void request_cancel_ussd(RIL_Token t) {
1366 ALOGV("Cancelling USSD code is currently not supported");
1367 // TODO(ender): support this feature
1368 gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
1369}
1370
Greg Hartman85c495f2017-10-26 23:52:37 -07001371static void request_exit_emergency_mode(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001372 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001373 ALOGV("Exiting emergency callback mode.");
1374
1375 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1376}
1377
1378static RIL_RadioState gce_ril_current_state() {
1379 ALOGV("Reporting radio state %d", gRadioPowerState);
1380 return gRadioPowerState;
1381}
1382
1383static int gce_ril_on_supports(int requestCode) {
1384 ALOGE("%s: Request code %d not implemented", __FUNCTION__, requestCode);
1385 return 1;
1386}
1387
Greg Hartman85c495f2017-10-26 23:52:37 -07001388static void gce_ril_on_cancel(RIL_Token /*t*/) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001389 ALOGE("Cancel operation not implemented");
1390}
1391
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001392static const char* gce_ril_get_version(void) {
Greg Hartman7c01b7c2018-01-10 18:30:22 -08001393 ALOGV("Reporting VSOC version " VSOC_RIL_VERSION_STRING);
1394 return VSOC_RIL_VERSION_STRING;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001395}
1396
1397static int s_cell_info_rate_ms = INT_MAX;
1398static int s_mcc = 0;
1399static int s_mnc = 0;
1400static int s_lac = 0;
1401static int s_cid = 0;
1402
1403std::vector<RIL_NeighboringCell> gGSMNeighboringCells;
1404
Greg Hartman85c495f2017-10-26 23:52:37 -07001405static void request_get_neighboring_cell_ids(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001406 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001407 ALOGV("Requesting GSM neighboring cell ids");
1408
1409 if (!isGSM() || gGSMNeighboringCells.empty()) {
1410 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1411 return;
1412 }
1413
1414 RIL_NeighboringCell** cells =
1415 new RIL_NeighboringCell*[gGSMNeighboringCells.size()];
1416
1417 for (size_t index = 0; index < gGSMNeighboringCells.size(); ++index) {
1418 cells[index] = &gGSMNeighboringCells[index];
1419 }
1420
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001421 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, cells,
1422 sizeof(RIL_NeighboringCell*));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001423 delete[] cells;
1424}
1425
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001426#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
Greg Hartman85c495f2017-10-26 23:52:37 -07001427static void request_get_cell_info_list(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001428 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001429 struct timespec now;
1430 uint64_t curTime;
1431
1432 ALOGV("Requesting Cell Info List");
1433
1434 clock_gettime(CLOCK_MONOTONIC, &now);
1435 curTime = now.tv_sec * 1000000000LL + now.tv_nsec;
1436
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001437#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001438 RIL_CellInfo_v12 ci;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001439#else
1440 RIL_CellInfo ci;
1441#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001442
1443 if (isGSM()) {
1444 ci.cellInfoType = RIL_CELL_INFO_TYPE_GSM;
1445 ci.registered = 1;
1446 ci.timeStampType = RIL_TIMESTAMP_TYPE_ANTENNA; // Our own timestamp.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001447 ci.timeStamp = curTime - 1000; // Fake time in the past.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001448 ci.CellInfo.gsm.cellIdentityGsm.mcc = s_mcc;
1449 ci.CellInfo.gsm.cellIdentityGsm.mnc = s_mnc;
1450 ci.CellInfo.gsm.cellIdentityGsm.lac = s_lac;
1451 ci.CellInfo.gsm.cellIdentityGsm.cid = s_cid;
1452 ci.CellInfo.gsm.signalStrengthGsm.signalStrength = 10;
1453 ci.CellInfo.gsm.signalStrengthGsm.bitErrorRate = 0;
1454
1455 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &ci, sizeof(ci));
1456 } else if (isCDMA()) {
1457 // TODO(ender): CDMA cell support. And LTE.
1458 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1459 } else {
1460 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1461 }
1462}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001463#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001464
1465struct NetworkOperator {
1466 std::string long_name;
1467 std::string short_name;
1468 bool is_accessible;
1469
1470 NetworkOperator() {}
1471
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001472 NetworkOperator(const std::string& long_name, const std::string& short_name,
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001473 bool is_accessible)
1474 : long_name(long_name),
1475 short_name(short_name),
1476 is_accessible(is_accessible) {}
1477};
1478
1479static std::map<std::string, NetworkOperator> gNetworkOperators;
1480static std::string gCurrentNetworkOperator = "";
1481
1482enum OperatorSelectionMethod {
1483 kOperatorAutomatic = 0,
1484 kOperatorManual = 1,
1485 kOperatorDeregistered = 2,
1486 kOperatorManualThenAutomatic = 4
1487};
1488
1489static void init_virtual_network() {
1490 gGSMNeighboringCells.resize(1);
1491 gGSMNeighboringCells[0].cid = (char*)"0000";
1492 gGSMNeighboringCells[0].rssi = 75;
1493 gNetworkOperators["310260"] =
1494 NetworkOperator("Android Virtual Operator", "Android", true);
1495 gNetworkOperators["310300"] =
1496 NetworkOperator("Alternative Operator", "Alternative", true);
1497 gNetworkOperators["310400"] =
1498 NetworkOperator("Hermetic Network Operator", "Hermetic", false);
1499}
1500
1501static OperatorSelectionMethod gOperatorSelectionMethod = kOperatorDeregistered;
1502
Greg Hartman85c495f2017-10-26 23:52:37 -07001503static void request_query_network_selection_mode(void* /*data*/,
1504 size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001505 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001506 ALOGV("Query operator selection mode (%d)", gOperatorSelectionMethod);
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001507 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gOperatorSelectionMethod,
1508 sizeof(gOperatorSelectionMethod));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001509}
1510
Greg Hartman85c495f2017-10-26 23:52:37 -07001511static void request_operator(void* /*data*/, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001512 std::map<std::string, NetworkOperator>::iterator iter =
1513 gNetworkOperators.find(gCurrentNetworkOperator);
1514
1515 ALOGV("Requesting current operator info");
1516
1517 if (iter == gNetworkOperators.end()) {
1518 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1519 return;
1520 }
1521
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001522 const char* response[] = {iter->second.long_name.c_str(),
1523 iter->second.short_name.c_str(),
1524 iter->first.c_str()};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001525
1526 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
1527}
1528
Greg Hartman85c495f2017-10-26 23:52:37 -07001529static void request_query_available_networks(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001530 RIL_Token t) {
1531 const char** available_networks =
1532 new const char*[gNetworkOperators.size() * 4];
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001533
1534 ALOGV("Querying available networks.");
1535
1536 // TODO(ender): this should only respond once operator is selected and
1537 // registered.
1538 int index = 0;
1539 for (std::map<std::string, NetworkOperator>::iterator iter =
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001540 gNetworkOperators.begin();
1541 iter != gNetworkOperators.end(); ++iter) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001542 // TODO(ender): wrap in a neat structure maybe?
1543 available_networks[index++] = iter->second.long_name.c_str();
1544 available_networks[index++] = iter->second.short_name.c_str();
1545 available_networks[index++] = iter->first.c_str();
1546 if (!iter->second.is_accessible) {
1547 available_networks[index++] = "forbidden";
1548 } else if (iter->first == gCurrentNetworkOperator) {
1549 available_networks[index++] = "current";
1550 } else {
1551 available_networks[index++] = "available";
1552 }
1553 }
1554
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001555 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &available_networks,
1556 4 * gNetworkOperators.size());
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001557 delete[] available_networks;
1558}
1559
1560static void request_set_automatic_network_selection(RIL_Token t) {
1561 ALOGV("Requesting automatic operator selection");
1562 gCurrentNetworkOperator = gNetworkOperators.begin()->first;
1563 gOperatorSelectionMethod = kOperatorAutomatic;
1564 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1565}
1566
Greg Hartman85c495f2017-10-26 23:52:37 -07001567static void request_set_manual_network_selection(void* data, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001568 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001569 char* mccmnc = (char*)data;
1570
1571 ALOGV("Requesting manual operator selection: %s", mccmnc);
1572
1573 std::map<std::string, NetworkOperator>::iterator iter =
1574 gNetworkOperators.find(mccmnc);
1575
1576 if (iter == gNetworkOperators.end() || iter->second.is_accessible) {
1577 gce_ril_env->OnRequestComplete(t, RIL_E_ILLEGAL_SIM_OR_ME, NULL, 0);
1578 return;
1579 }
1580
1581 gCurrentNetworkOperator = mccmnc;
1582 gOperatorSelectionMethod = kOperatorManual;
1583
1584 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1585}
1586
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001587static const char kDefaultSMSC[] = "00";
1588static int gNextSmsMessageId = 1;
1589
Greg Hartman85c495f2017-10-26 23:52:37 -07001590static void request_cdma_send_SMS(void* /*data*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001591 RIL_SMS_Response response = {0, 0, 0};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001592 // RIL_CDMA_SMS_Message* rcsm = (RIL_CDMA_SMS_Message*) data;
1593
1594 ALOGW("CDMA SMS Send is currently not implemented.");
1595
1596 // Cdma Send SMS implementation will go here:
1597 // But it is not implemented yet.
1598 memset(&response, 0, sizeof(response));
1599 response.messageRef = -1; // This must be BearerData MessageId.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001600 gce_ril_env->OnRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response,
1601 sizeof(response));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001602}
1603
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001604static void request_send_SMS(void* data, RIL_Token t) {
1605 RIL_SMS_Response response = {0, 0, 0};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001606
1607 ALOGV("Send GSM SMS Message");
1608
1609 // SMSC is an address of SMS center or NULL for default.
1610 const char* smsc = ((const char**)data)[0];
1611 if (smsc == NULL) smsc = &kDefaultSMSC[0];
1612
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001613 response.messageRef = gNextSmsMessageId++;
1614 response.ackPDU = NULL;
1615 response.errorCode = 0;
1616
1617 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1618
1619 // response.messageRef = -1;
1620 // gce_ril_env->OnRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response,
1621 // sizeof(response));
1622}
1623
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001624#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
Greg Hartman85c495f2017-10-26 23:52:37 -07001625static void request_set_cell_info_list_rate(void* data, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001626 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001627 // For now we'll save the rate but no RIL_UNSOL_CELL_INFO_LIST messages
1628 // will be sent.
1629 ALOGV("Setting cell info list rate.");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001630 s_cell_info_rate_ms = ((int*)data)[0];
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001631 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1632}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001633#endif
1634#if VSOC_PLATFORM_SDK_AFTER(J_MR2)
Greg Hartman85c495f2017-10-26 23:52:37 -07001635static void request_ims_send_SMS(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001636 RIL_IMS_SMS_Message* args = (RIL_IMS_SMS_Message*)data;
Greg Hartman85c495f2017-10-26 23:52:37 -07001637 RIL_SMS_Response response{};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001638
1639 ALOGV("Send IMS SMS Message");
1640
1641 switch (args->tech) {
1642 case RADIO_TECH_3GPP:
1643 return request_send_SMS(args->message.gsmMessage, t);
1644
1645 case RADIO_TECH_3GPP2:
1646 return request_cdma_send_SMS(args->message.gsmMessage, t);
1647
1648 default:
1649 ALOGE("Invalid SMS format value: %d", args->tech);
1650 response.messageRef = -2;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001651 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, &response,
1652 sizeof(response));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001653 }
1654}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001655#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001656
Greg Hartman85c495f2017-10-26 23:52:37 -07001657static void request_SMS_acknowledge(void* data, size_t /*datalen*/,
1658 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001659 int* ack = (int*)data;
1660
1661 // TODO(ender): we should retain "incoming" sms for later reception.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001662 ALOGV("SMS receipt %ssuccessful (reason %d).", ack[0] ? "" : "un", ack[1]);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001663
1664 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1665}
1666
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001667struct SimFileCommand {
1668 uint8_t command;
1669 uint16_t efid;
1670 uint8_t param1;
1671 uint8_t param2;
1672 uint8_t param3;
1673
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001674 bool operator<(const SimFileCommand& other) const {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001675 uint64_t sum1, sum2;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001676 sum1 = (command * 1ull << 40) | (efid * 1ull << 24) | (param1 << 16) |
1677 (param2 << 8) | (param3);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001678 sum2 = (other.command * 1ull << 40) | (other.efid * 1ull << 24) |
1679 (other.param1 << 16) | (other.param2 << 8) | (other.param3);
1680 return sum1 < sum2;
1681 }
1682
1683 SimFileCommand(uint8_t cmd, uint16_t efid, uint8_t p1, uint8_t p2, uint8_t p3)
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001684 : command(cmd), efid(efid), param1(p1), param2(p2), param3(p3) {}
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001685};
1686
1687struct SimFileResponse {
1688 uint8_t sw1;
1689 uint8_t sw2;
1690 const char* data;
1691
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001692 SimFileResponse() : sw1(0), sw2(0), data(NULL) {}
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001693
1694 SimFileResponse(uint8_t sw1, uint8_t sw2, const char* data)
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001695 : sw1(sw1), sw2(sw2), data(data) {}
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001696};
1697
1698// TODO(ender): Double check & rewrite these.
1699std::map<SimFileCommand, SimFileResponse> gSimFileSystem;
1700
1701static void init_sim_file_system() {
1702 gSimFileSystem[SimFileCommand(192, 28436, 0, 0, 15)] =
1703 SimFileResponse(144, 0, "000000146f1404001aa0aa01020000");
1704 gSimFileSystem[SimFileCommand(176, 28436, 0, 0, 20)] =
1705 SimFileResponse(144, 0, "416e64726f6964ffffffffffffffffffffffffff");
1706 gSimFileSystem[SimFileCommand(192, 28433, 0, 0, 15)] =
1707 SimFileResponse(144, 0, "000000016f11040011a0aa01020000");
1708 gSimFileSystem[SimFileCommand(176, 28433, 0, 0, 1)] =
1709 SimFileResponse(144, 0, "55");
1710 gSimFileSystem[SimFileCommand(192, 12258, 0, 0, 15)] =
1711 SimFileResponse(144, 0, "0000000a2fe204000fa0aa01020000");
1712 gSimFileSystem[SimFileCommand(176, 12258, 0, 0, 10)] =
1713 SimFileResponse(144, 0, "98101430121181157002");
1714 gSimFileSystem[SimFileCommand(192, 28435, 0, 0, 15)] =
1715 SimFileResponse(144, 0, "000000016f13040011a0aa01020000");
1716 gSimFileSystem[SimFileCommand(176, 28435, 0, 0, 1)] =
1717 SimFileResponse(144, 0, "55");
1718 gSimFileSystem[SimFileCommand(192, 28472, 0, 0, 15)] =
1719 SimFileResponse(144, 0, "0000000f6f3804001aa0aa01020000");
1720 gSimFileSystem[SimFileCommand(176, 28472, 0, 0, 15)] =
1721 SimFileResponse(144, 0, "ff30ffff3c003c03000c0000f03f00");
1722 gSimFileSystem[SimFileCommand(192, 28617, 0, 0, 15)] =
1723 SimFileResponse(144, 0, "000000086fc9040011a0aa01020104");
1724 gSimFileSystem[SimFileCommand(178, 28617, 1, 4, 4)] =
1725 SimFileResponse(144, 0, "01000000");
1726 gSimFileSystem[SimFileCommand(192, 28618, 0, 0, 15)] =
1727 SimFileResponse(144, 0, "0000000a6fca040011a0aa01020105");
1728 gSimFileSystem[SimFileCommand(178, 28618, 1, 4, 5)] =
1729 SimFileResponse(144, 0, "0000000000");
1730 gSimFileSystem[SimFileCommand(192, 28589, 0, 0, 15)] =
1731 SimFileResponse(144, 0, "000000046fad04000aa0aa01020000");
1732 gSimFileSystem[SimFileCommand(176, 28589, 0, 0, 4)] =
1733 SimFileResponse(144, 0, "00000003");
1734 gSimFileSystem[SimFileCommand(192, 28438, 0, 0, 15)] =
1735 SimFileResponse(144, 0, "000000026f1604001aa0aa01020000");
1736 gSimFileSystem[SimFileCommand(176, 28438, 0, 0, 2)] =
1737 SimFileResponse(144, 0, "0233");
1738 gSimFileSystem[SimFileCommand(192, 28486, 0, 0, 15)] =
1739 SimFileResponse(148, 4, NULL);
1740 gSimFileSystem[SimFileCommand(192, 28621, 0, 0, 15)] =
1741 SimFileResponse(148, 4, NULL);
1742 gSimFileSystem[SimFileCommand(192, 28613, 0, 0, 15)] =
1743 SimFileResponse(144, 0, "000000f06fc504000aa0aa01020118");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001744 gSimFileSystem[SimFileCommand(178, 28613, 1, 4, 24)] = SimFileResponse(
1745 144, 0, "43058441aa890affffffffffffffffffffffffffffffffff");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001746 gSimFileSystem[SimFileCommand(192, 28480, 0, 0, 15)] =
1747 SimFileResponse(144, 0, "000000806f40040011a0aa01020120");
1748 // Primary phone number encapsulated
1749 // [51][55][21][43][65][f7] = 1 555 1234 567$
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001750 gSimFileSystem[SimFileCommand(178, 28480, 1, 4, 32)] = SimFileResponse(
1751 144, 0,
1752 "ffffffffffffffffffffffffffffffffffff07915155214365f7ffffffffffff");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001753 gSimFileSystem[SimFileCommand(192, 28615, 0, 0, 15)] =
1754 SimFileResponse(144, 0, "000000406fc7040011a0aa01020120");
1755 // Voice mail number encapsulated
1756 // [56][6f][69][63][65][6d][61][69][6c] = 'Voicemail'
1757 // [51][55][67][45][23][f1] = 1 555 7654 321$
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001758 gSimFileSystem[SimFileCommand(178, 28615, 1, 4, 32)] = SimFileResponse(
1759 144, 0,
1760 "566f6963656d61696cffffffffffffffffff07915155674523f1ffffffffffff");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001761 gSimFileSystem[SimFileCommand(192, 12037, 0, 0, 15)] =
1762 SimFileResponse(148, 4, NULL);
1763 gSimFileSystem[SimFileCommand(192, 28437, 0, 0, 15)] =
1764 SimFileResponse(148, 4, NULL);
1765 gSimFileSystem[SimFileCommand(192, 28478, 0, 0, 15)] =
1766 SimFileResponse(148, 4, NULL);
1767 gSimFileSystem[SimFileCommand(192, 28450, 0, 0, 15)] =
1768 SimFileResponse(148, 4, NULL);
1769 gSimFileSystem[SimFileCommand(192, 28456, 0, 0, 15)] =
1770 SimFileResponse(148, 4, NULL);
1771 gSimFileSystem[SimFileCommand(192, 28474, 0, 0, 15)] =
1772 SimFileResponse(148, 4, NULL);
1773 gSimFileSystem[SimFileCommand(192, 28481, 0, 0, 15)] =
1774 SimFileResponse(148, 4, NULL);
1775 gSimFileSystem[SimFileCommand(192, 28484, 0, 0, 15)] =
1776 SimFileResponse(148, 4, NULL);
1777 gSimFileSystem[SimFileCommand(192, 28493, 0, 0, 15)] =
1778 SimFileResponse(148, 4, NULL);
1779 gSimFileSystem[SimFileCommand(192, 28619, 0, 0, 15)] =
1780 SimFileResponse(148, 4, NULL);
1781 gSimFileSystem[SimFileCommand(176, 28506, 0, 0, 4)] =
1782 SimFileResponse(144, 0, "00000013");
1783}
1784
Greg Hartman85c495f2017-10-26 23:52:37 -07001785static void request_SIM_IO(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001786 const RIL_SIM_IO_v6& args = *(RIL_SIM_IO_v6*)data;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001787 RIL_SIM_IO_Response sr = {0, 0, 0};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001788
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001789 ALOGV(
1790 "Requesting SIM File IO: %d EFID %x, Params: %d, %d, %d, path: %s, "
1791 "data %s PIN: %s AID: %s",
1792 args.command, args.fileid, args.p1, args.p2, args.p3, args.path,
1793 args.data, args.pin2, args.aidPtr);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001794
1795 SimFileCommand cmd(args.command, args.fileid, args.p1, args.p2, args.p3);
1796
1797 std::map<SimFileCommand, SimFileResponse>::iterator resp =
1798 gSimFileSystem.find(cmd);
1799
1800 if (resp != gSimFileSystem.end()) {
1801 sr.sw1 = resp->second.sw1;
1802 sr.sw2 = resp->second.sw2;
1803 if (resp->second.data) sr.simResponse = strdup(resp->second.data);
1804 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
1805 return;
1806 }
1807
1808 ALOGW("Unsupported SIM File IO command.");
1809 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1810}
1811
Greg Hartman85c495f2017-10-26 23:52:37 -07001812static void request_enter_sim_pin(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001813 const char** pin_aid = (const char**)data;
1814
1815 ALOGV("Entering PIN: %s / %s", pin_aid[0], pin_aid[1]);
1816
1817 ++gSimPINAttempts;
1818 int remaining_attempts = gSimPINAttemptsMax - gSimPINAttempts;
1819
1820 bool is_valid = false;
1821
1822 if (gSimStatus == SIM_PIN) {
1823 is_valid = (gSimPIN == pin_aid[0]);
1824 } else if (gSimStatus == SIM_PUK) {
1825 is_valid = (gSimPUK == pin_aid[0]);
1826 } else {
1827 ALOGV("Unexpected SIM status for unlock: %d", gSimStatus);
1828 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1829 return;
1830 }
1831
1832 if (!is_valid) {
1833 if (gSimPINAttempts == gSimPINAttemptsMax) {
1834 if (gSimStatus == SIM_PIN) {
1835 gSimStatus = SIM_PUK;
1836 gSimPINAttempts = 0;
1837 } else {
1838 ALOGV("PIN and PUK verification failed; locking SIM card.");
1839 gSimStatus = SIM_NOT_READY;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001840 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001841 return;
1842 }
1843 }
1844
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001845 gce_ril_env->OnRequestComplete(t, RIL_E_PASSWORD_INCORRECT,
1846 &remaining_attempts,
1847 sizeof(remaining_attempts));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001848 } else {
1849 if (gSimStatus == SIM_PUK) {
1850 ALOGV("Resetting SIM PIN to %s", pin_aid[1]);
1851 gSimPIN = pin_aid[1];
1852 }
1853
1854 gSimPINAttempts = 0;
1855 gSimStatus = SIM_READY;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001856 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &remaining_attempts,
1857 sizeof(remaining_attempts));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001858 }
1859
1860 pollSIMState(NULL);
1861}
1862
1863/**
1864 * No longer POLL.
1865 */
Greg Hartman85c495f2017-10-26 23:52:37 -07001866static void pollSIMState(void* /*param*/) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001867 // TODO(ender): check radio state?
1868
1869 ALOGV("Polling SIM Status.");
1870
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001871 switch (gSimStatus) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001872 case SIM_ABSENT:
1873 case SIM_PIN:
1874 case SIM_PUK:
1875 case SIM_NETWORK_PERSONALIZATION:
1876 default:
1877 ALOGV("SIM Absent or Locked");
Tomasz Wiszkowski31d3a3b2017-09-20 11:06:02 -07001878 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001879
1880 case SIM_NOT_READY:
1881 // Transition directly to READY. Set default network operator.
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -07001882 if (gRadioPowerState == RADIO_STATE_ON) {
1883 gSimStatus = SIM_READY;
Tomasz Wiszkowski31d3a3b2017-09-20 11:06:02 -07001884 gCurrentNetworkOperator = "310260";
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -07001885 }
1886
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001887 gce_ril_env->RequestTimedCallback(pollSIMState, NULL, &TIMEVAL_SIMPOLL);
Tomasz Wiszkowski31d3a3b2017-09-20 11:06:02 -07001888 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001889
1890 case SIM_READY:
1891 ALOGV("SIM Ready. Notifying network state changed.");
Tomasz Wiszkowski31d3a3b2017-09-20 11:06:02 -07001892 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001893 }
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001894
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001895 if (gRadioPowerState != RADIO_STATE_OFF) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001896 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
1897 NULL, 0);
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001898 gce_ril_env->OnUnsolicitedResponse(
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001899 RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0);
1900 }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001901}
1902
1903std::map<SIM_Status, RIL_AppStatus> gRilAppStatus;
1904
1905static void init_sim_status() {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001906 gRilAppStatus[SIM_ABSENT] = (RIL_AppStatus){RIL_APPTYPE_UNKNOWN,
1907 RIL_APPSTATE_UNKNOWN,
1908 RIL_PERSOSUBSTATE_UNKNOWN,
1909 NULL,
1910 NULL,
1911 0,
1912 RIL_PINSTATE_UNKNOWN,
1913 RIL_PINSTATE_UNKNOWN};
1914 gRilAppStatus[SIM_NOT_READY] =
1915 (RIL_AppStatus){RIL_APPTYPE_SIM,
1916 RIL_APPSTATE_DETECTED,
1917 RIL_PERSOSUBSTATE_UNKNOWN,
1918 NULL,
1919 NULL,
1920 0,
1921 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
1922 RIL_PINSTATE_ENABLED_NOT_VERIFIED};
1923 gRilAppStatus[SIM_READY] = (RIL_AppStatus){
1924 RIL_APPTYPE_SIM,
1925 RIL_APPSTATE_READY,
1926 RIL_PERSOSUBSTATE_READY,
1927 NULL,
1928 NULL,
1929 0,
1930 RIL_PINSTATE_ENABLED_VERIFIED,
1931 RIL_PINSTATE_ENABLED_VERIFIED,
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001932 };
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001933 gRilAppStatus[SIM_PIN] = (RIL_AppStatus){RIL_APPTYPE_SIM,
1934 RIL_APPSTATE_PIN,
1935 RIL_PERSOSUBSTATE_UNKNOWN,
1936 NULL,
1937 NULL,
1938 0,
1939 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
1940 RIL_PINSTATE_UNKNOWN};
1941 gRilAppStatus[SIM_PUK] = (RIL_AppStatus){RIL_APPTYPE_SIM,
1942 RIL_APPSTATE_PUK,
1943 RIL_PERSOSUBSTATE_UNKNOWN,
1944 NULL,
1945 NULL,
1946 0,
1947 RIL_PINSTATE_ENABLED_BLOCKED,
1948 RIL_PINSTATE_UNKNOWN};
1949 gRilAppStatus[SIM_NETWORK_PERSONALIZATION] =
1950 (RIL_AppStatus){RIL_APPTYPE_SIM,
1951 RIL_APPSTATE_SUBSCRIPTION_PERSO,
1952 RIL_PERSOSUBSTATE_SIM_NETWORK,
1953 NULL,
1954 NULL,
1955 0,
1956 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
1957 RIL_PINSTATE_UNKNOWN};
1958 gRilAppStatus[RUIM_ABSENT] = (RIL_AppStatus){RIL_APPTYPE_UNKNOWN,
1959 RIL_APPSTATE_UNKNOWN,
1960 RIL_PERSOSUBSTATE_UNKNOWN,
1961 NULL,
1962 NULL,
1963 0,
1964 RIL_PINSTATE_UNKNOWN,
1965 RIL_PINSTATE_UNKNOWN};
1966 gRilAppStatus[RUIM_NOT_READY] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
1967 RIL_APPSTATE_DETECTED,
1968 RIL_PERSOSUBSTATE_UNKNOWN,
1969 NULL,
1970 NULL,
1971 0,
1972 RIL_PINSTATE_UNKNOWN,
1973 RIL_PINSTATE_UNKNOWN};
1974 gRilAppStatus[RUIM_READY] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
1975 RIL_APPSTATE_READY,
1976 RIL_PERSOSUBSTATE_READY,
1977 NULL,
1978 NULL,
1979 0,
1980 RIL_PINSTATE_UNKNOWN,
1981 RIL_PINSTATE_UNKNOWN};
1982 gRilAppStatus[RUIM_PIN] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
1983 RIL_APPSTATE_PIN,
1984 RIL_PERSOSUBSTATE_UNKNOWN,
1985 NULL,
1986 NULL,
1987 0,
1988 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
1989 RIL_PINSTATE_UNKNOWN};
1990 gRilAppStatus[RUIM_PUK] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
1991 RIL_APPSTATE_PUK,
1992 RIL_PERSOSUBSTATE_UNKNOWN,
1993 NULL,
1994 NULL,
1995 0,
1996 RIL_PINSTATE_ENABLED_BLOCKED,
1997 RIL_PINSTATE_UNKNOWN};
1998 gRilAppStatus[RUIM_NETWORK_PERSONALIZATION] =
1999 (RIL_AppStatus){RIL_APPTYPE_RUIM,
2000 RIL_APPSTATE_SUBSCRIPTION_PERSO,
2001 RIL_PERSOSUBSTATE_SIM_NETWORK,
2002 NULL,
2003 NULL,
2004 0,
2005 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
2006 RIL_PINSTATE_UNKNOWN};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002007}
2008
2009/**
2010 * Get the current card status.
2011 */
2012static void getCardStatus(RIL_Token t) {
2013 ALOGV("Querying SIM status.");
2014 RIL_CardStatus_v6 card_status;
2015
2016 if (gSimStatus == SIM_ABSENT) {
2017 card_status.card_state = RIL_CARDSTATE_ABSENT;
2018 card_status.num_applications = 0;
2019 } else {
2020 card_status.card_state = RIL_CARDSTATE_PRESENT;
2021 card_status.num_applications = 1;
2022 }
2023
2024 card_status.universal_pin_state = RIL_PINSTATE_UNKNOWN;
2025 card_status.gsm_umts_subscription_app_index = -1;
2026 card_status.cdma_subscription_app_index = -1;
2027 card_status.ims_subscription_app_index = -1;
2028
2029 // Initialize application status
2030 for (int i = 0; i < RIL_CARD_MAX_APPS; i++) {
2031 card_status.applications[i] = gRilAppStatus[SIM_ABSENT];
2032 }
2033
2034 if (card_status.num_applications > 0) {
2035 card_status.gsm_umts_subscription_app_index = 0;
2036
2037 card_status.applications[0] = gRilAppStatus[gSimStatus];
2038 card_status.universal_pin_state = card_status.applications[0].pin1;
2039 // To enable basic CDMA (currently neither supported nor functional):
2040 // card_status.num_applications = 2;
2041 // card_status.cdma_subscription_app_index = 1;
2042 // card_status.applications[1] =
2043 // gRilAppStatus[SIM_Status(gSimStatus + RUIM_ABSENT)];
2044 }
2045
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002046 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &card_status,
2047 sizeof(card_status));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002048}
2049
2050struct SimSession {
2051 std::string aid;
2052};
2053
2054static int gNextSimSessionId = 1;
2055static std::map<int, SimSession> gSimSessions;
2056
Greg Hartman85c495f2017-10-26 23:52:37 -07002057static void request_sim_open_channel(void* data, size_t /*datalen*/,
2058 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002059 char* aid = (char*)data;
2060 SimSession session;
2061
2062 ALOGV("Requesting new SIM session");
2063
2064 if (aid != NULL) {
2065 session.aid = aid;
2066 }
2067
2068 int response = gNextSimSessionId++;
2069 gSimSessions[response] = session;
2070
2071 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
2072}
2073
Greg Hartman85c495f2017-10-26 23:52:37 -07002074static void request_sim_close_channel(void* data, size_t /*datalen*/,
2075 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002076 int session = *(int*)(data);
2077
2078 ALOGV("Closing SIM session %d", session);
2079
2080 if (gSimSessions.erase(session) == 0) {
2081 // No such session.
2082 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2083 } else {
2084 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2085 }
2086}
2087
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002088#if VSOC_PLATFORM_SDK_AFTER(K)
Greg Hartman85c495f2017-10-26 23:52:37 -07002089static void request_sim_apdu(void* data, size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002090 RIL_SIM_APDU* apdu = (RIL_SIM_APDU*)data;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002091
2092 ALOGV("Requesting APDU: Session %d CLA %d INST %d Params: %d %d %d, data %s",
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002093 apdu->sessionid, apdu->cla, apdu->instruction, apdu->p1, apdu->p2,
2094 apdu->p3, apdu->data);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002095
2096 if (gSimSessions.find(apdu->sessionid) != gSimSessions.end()) {
Greg Hartman85c495f2017-10-26 23:52:37 -07002097 RIL_SIM_IO_Response sr{};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002098
2099 // Fallback / default behavior.
2100 sr.sw1 = 144;
2101 sr.sw2 = 0;
2102 sr.simResponse = NULL;
2103
2104 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
2105 } else {
2106 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2107 }
2108}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002109#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002110
2111// 0 = Lock is available, but disabled.
2112// 1 = Lock is available and enabled,
2113// 2 = lock is neither available nor enabled
2114static const int kFacilityLockAllDisabled = 0;
2115
Greg Hartman85c495f2017-10-26 23:52:37 -07002116static void request_facility_lock(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002117 char** data_vec = (char**)data;
2118
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002119 // TODO(ender): implement this; essentially: AT+CLCK
2120 // See http://www.activexperts.com/sms-component/at/commands/?at=%2BCLCK
2121 // and
2122 // opt/telephony/src/java/com/android/internal/telephony/CommandsInterface.java
2123 // opt/telephony/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
2124
2125 ALOGV("Query Facility Lock Code: %s PIN2: %s Service(s): %s AID: %s",
2126 data_vec[0], data_vec[1], data_vec[2], data_vec[3]);
2127
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002128 // TODO(ender): there should be a bit vector of responses for each of the
2129 // services requested.
2130 // Depending on lock code, facilities may be unlocked or locked. We report
2131 // these are all unlocked, regardless of the query.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002132 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
2133 const_cast<int*>(&kFacilityLockAllDisabled),
2134 sizeof(kFacilityLockAllDisabled));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002135}
2136
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002137static void request_international_subscriber_id_number(RIL_Token t) {
2138 // TODO(ender): Reuse MCC and MNC.
2139 std::string subscriber_id = gCurrentNetworkOperator.c_str();
2140 subscriber_id += "123456789";
2141
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002142 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
2143 strdup(subscriber_id.c_str()), sizeof(char*));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002144}
2145
2146static bool gScreenIsOn = true;
2147
Greg Hartman85c495f2017-10-26 23:52:37 -07002148static void request_set_screen_state(void* data, size_t /*datalen*/,
2149 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002150 gScreenIsOn = *(int*)data ? true : false;
2151 ALOGV("Screen is %s", gScreenIsOn ? "on" : "off");
2152 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2153}
2154
2155// Unsure which section this belongs in.
2156
2157static int gModemTtyMode = 1; // 0 = off, 1 = full, 2 = HCO, 3 = VCO.
Greg Hartman85c495f2017-10-26 23:52:37 -07002158static void request_set_tty_mode(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002159 int new_tty_mode = *(int*)(data);
2160 ALOGV("Switching modem TTY mode %d -> %d", gModemTtyMode, new_tty_mode);
2161
2162 if (new_tty_mode >= 0 && new_tty_mode <= 3) {
2163 gModemTtyMode = new_tty_mode;
2164 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2165 } else {
2166 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2167 }
2168}
2169
2170static void request_get_tty_mode(RIL_Token t) {
2171 ALOGV("Querying TTY mode");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002172 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gModemTtyMode,
2173 sizeof(gModemTtyMode));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002174}
2175
2176static bool gImsRegistered = false;
2177static int gImsFormat = RADIO_TECH_3GPP;
2178
2179static void request_ims_registration_state(RIL_Token t) {
2180 ALOGV("Querying IMS mode");
2181 int reply[2];
2182 reply[0] = gImsRegistered;
2183 reply[1] = gImsFormat;
2184
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002185 ALOGV("Requesting IMS Registration state: %d, format=%d ", reply[0],
2186 reply[1]);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002187
2188 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply));
2189}
2190
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002191static void gce_ril_on_request(int request, void* data, size_t datalen,
2192 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002193 // Ignore all requests except RIL_REQUEST_GET_SIM_STATUS
2194 // when RADIO_STATE_UNAVAILABLE.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002195 if (gRadioPowerState == RADIO_STATE_UNAVAILABLE &&
2196 request != RIL_REQUEST_GET_SIM_STATUS) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002197 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2198 return;
2199 }
2200
2201 // Ignore all non-power requests when RADIO_STATE_OFF (except
2202 // RIL_REQUEST_GET_SIM_STATUS)
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002203 if (gRadioPowerState == RADIO_STATE_OFF &&
2204 !(request == RIL_REQUEST_RADIO_POWER ||
2205 request == RIL_REQUEST_GET_SIM_STATUS)) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002206 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2207 return;
2208 }
2209
2210 ALOGV("Received request %d", request);
2211
2212 switch (request) {
2213 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS:
2214 request_query_available_networks(data, datalen, t);
2215 break;
2216 case RIL_REQUEST_GET_IMEI:
2217 request_get_imei(t);
2218 break;
2219 case RIL_REQUEST_GET_IMEISV:
2220 request_get_imei_sv(t);
2221 break;
2222 case RIL_REQUEST_DEACTIVATE_DATA_CALL:
2223 request_teardown_data_call(data, datalen, t);
2224 break;
2225 case RIL_REQUEST_SCREEN_STATE:
2226 request_set_screen_state(data, datalen, t);
2227 break;
2228 case RIL_REQUEST_GET_SIM_STATUS:
2229 getCardStatus(t);
2230 break;
2231 case RIL_REQUEST_GET_CURRENT_CALLS:
2232 request_get_current_calls(data, datalen, t);
2233 break;
2234 case RIL_REQUEST_DIAL:
2235 request_dial(data, datalen, t);
2236 break;
2237 case RIL_REQUEST_HANGUP:
2238 request_hangup(data, datalen, t);
2239 break;
2240 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
2241 request_hangup_waiting(data, datalen, t);
2242 break;
2243 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
2244 request_hangup_current(t);
2245 break;
2246 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
2247 request_switch_current_and_waiting(t);
2248 break;
2249 case RIL_REQUEST_ANSWER:
2250 request_answer_incoming(t);
2251 break;
Tomasz Wiszkowski429d6022017-10-17 10:02:05 -07002252 case RIL_REQUEST_SET_MUTE:
2253 request_set_mute(data, datalen, t);
2254 break;
2255 case RIL_REQUEST_GET_MUTE:
2256 request_get_mute(t);
2257 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002258 case RIL_REQUEST_CONFERENCE:
2259 request_combine_multiparty_call(data, datalen, t);
2260 break;
2261 case RIL_REQUEST_SEPARATE_CONNECTION:
2262 request_split_multiparty_call(data, datalen, t);
2263 break;
2264 case RIL_REQUEST_UDUB:
2265 request_udub_on_incoming_calls(t);
2266 break;
2267 case RIL_REQUEST_SIGNAL_STRENGTH:
2268 request_signal_strength(data, datalen, t);
2269 break;
2270 case RIL_REQUEST_VOICE_REGISTRATION_STATE:
2271 case RIL_REQUEST_DATA_REGISTRATION_STATE:
2272 request_registration_state(request, data, datalen, t);
2273 break;
2274 case RIL_REQUEST_OPERATOR:
2275 request_operator(data, datalen, t);
2276 break;
2277 case RIL_REQUEST_RADIO_POWER:
2278 request_radio_power(data, datalen, t);
2279 break;
2280 case RIL_REQUEST_DTMF:
2281 case RIL_REQUEST_DTMF_START:
2282 request_send_dtmf(data, datalen, t);
2283 break;
2284 case RIL_REQUEST_DTMF_STOP:
2285 request_send_dtmf_stop(t);
2286 break;
2287 case RIL_REQUEST_SEND_SMS:
2288 request_send_SMS(data, t);
2289 break;
2290 case RIL_REQUEST_CDMA_SEND_SMS:
2291 request_cdma_send_SMS(data, t);
2292 break;
2293 case RIL_REQUEST_SETUP_DATA_CALL:
2294 request_setup_data_call(data, datalen, t);
2295 break;
2296 case RIL_REQUEST_SMS_ACKNOWLEDGE:
2297 request_SMS_acknowledge(data, datalen, t);
2298 break;
2299 case RIL_REQUEST_GET_IMSI:
2300 request_international_subscriber_id_number(t);
2301 break;
2302 case RIL_REQUEST_QUERY_FACILITY_LOCK:
2303 request_facility_lock(data, datalen, t);
2304 break;
2305 case RIL_REQUEST_SIM_IO:
2306 request_SIM_IO(data, datalen, t);
2307 break;
2308 case RIL_REQUEST_SEND_USSD:
2309 request_send_ussd(data, datalen, t);
2310 break;
2311 case RIL_REQUEST_CANCEL_USSD:
2312 request_cancel_ussd(t);
2313 break;
2314 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
2315 request_set_automatic_network_selection(t);
2316 break;
2317 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
2318 request_set_manual_network_selection(data, datalen, t);
2319 break;
2320 case RIL_REQUEST_DATA_CALL_LIST:
2321 request_data_calllist(data, datalen, t);
2322 break;
2323 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
2324 request_datacall_fail_cause(t);
2325 break;
2326 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
2327 request_query_network_selection_mode(data, datalen, t);
2328 break;
2329 case RIL_REQUEST_OEM_HOOK_RAW:
2330 case RIL_REQUEST_OEM_HOOK_STRINGS:
2331 ALOGV("OEM Hooks not supported!");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002332 gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002333 break;
2334 case RIL_REQUEST_WRITE_SMS_TO_SIM:
2335 request_write_sms_to_sim(data, datalen, t);
2336 break;
2337 case RIL_REQUEST_DELETE_SMS_ON_SIM:
2338 request_delete_sms_on_sim(data, datalen, t);
2339 break;
2340 case RIL_REQUEST_ENTER_SIM_PIN:
2341 case RIL_REQUEST_ENTER_SIM_PUK:
2342 case RIL_REQUEST_ENTER_SIM_PIN2:
2343 case RIL_REQUEST_ENTER_SIM_PUK2:
2344 case RIL_REQUEST_CHANGE_SIM_PIN:
2345 case RIL_REQUEST_CHANGE_SIM_PIN2:
2346 request_enter_sim_pin(data, datalen, t);
2347 break;
2348 case RIL_REQUEST_VOICE_RADIO_TECH: {
2349 RIL_RadioTechnology tech = getBestVoiceTechnology(gModemCurrentType);
2350 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &tech, sizeof(tech));
2351 break;
2352 }
2353 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
2354 request_set_preferred_network_type(request, data, datalen, t);
2355 break;
2356 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
2357 request_get_preferred_network_type(request, data, datalen, t);
2358 break;
2359 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
2360 request_get_neighboring_cell_ids(data, datalen, t);
2361 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002362#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002363 case RIL_REQUEST_GET_CELL_INFO_LIST:
2364 request_get_cell_info_list(data, datalen, t);
2365 break;
2366 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
2367 request_set_cell_info_list_rate(data, datalen, t);
2368 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002369#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002370 case RIL_REQUEST_BASEBAND_VERSION:
2371 request_baseband_version(t);
2372 break;
2373 case RIL_REQUEST_SET_TTY_MODE:
2374 request_set_tty_mode(data, datalen, t);
2375 break;
2376 case RIL_REQUEST_QUERY_TTY_MODE:
2377 request_get_tty_mode(t);
2378 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002379
2380#if VSOC_PLATFORM_SDK_AFTER(L)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002381 case RIL_REQUEST_GET_RADIO_CAPABILITY:
2382 request_get_radio_capability(t);
2383 break;
2384 case RIL_REQUEST_SET_RADIO_CAPABILITY:
2385 request_set_radio_capability(data, datalen, t);
2386 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002387#endif
2388#if VSOC_PLATFORM_SDK_AFTER(K)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002389 case RIL_REQUEST_GET_HARDWARE_CONFIG:
2390 request_hardware_config(t);
2391 break;
2392 case RIL_REQUEST_IMS_REGISTRATION_STATE:
2393 request_ims_registration_state(t);
2394 break;
2395 case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
2396 request_sim_apdu(data, datalen, t);
2397 break;
2398 case RIL_REQUEST_SIM_OPEN_CHANNEL:
2399 request_sim_open_channel(data, datalen, t);
2400 break;
2401 case RIL_REQUEST_SIM_CLOSE_CHANNEL:
2402 request_sim_close_channel(data, datalen, t);
2403 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002404#endif
2405#if VSOC_PLATFORM_SDK_AFTER(J_MR2)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002406 case RIL_REQUEST_IMS_SEND_SMS:
2407 request_ims_send_SMS(data, datalen, t);
2408 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002409
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002410 case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
2411 ALOGW("INITIAL ATTACH APN");
2412 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2413 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002414
2415#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002416 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
2417 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2418 break;
2419 case RIL_REQUEST_DEVICE_IDENTITY:
2420 request_device_identity(request, data, datalen, t);
2421 break;
2422 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
2423 request_cdma_get_subscription_source(request, data, datalen, t);
2424 break;
2425 case RIL_REQUEST_CDMA_SUBSCRIPTION:
2426 request_cdma_subscription(request, data, datalen, t);
2427 break;
2428 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
2429 request_cdma_set_subscription_source(request, data, datalen, t);
2430 break;
2431 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
2432 request_cdma_get_roaming_preference(request, data, datalen, t);
2433 break;
2434 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
2435 request_cdma_set_roaming_preference(request, data, datalen, t);
2436 break;
2437 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
2438 request_exit_emergency_mode(data, datalen, t);
2439 break;
2440 default:
2441 ALOGE("Request %d not supported.", request);
2442 gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
2443 break;
2444 }
2445}
2446
Greg Hartman7c01b7c2018-01-10 18:30:22 -08002447#define VSOC_RIL_VERSION 6
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002448
2449static const RIL_RadioFunctions ril_callbacks = {
Greg Hartman7c01b7c2018-01-10 18:30:22 -08002450 VSOC_RIL_VERSION, gce_ril_on_request, gce_ril_current_state,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002451 gce_ril_on_supports, gce_ril_on_cancel, gce_ril_get_version};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002452
2453extern "C" {
2454
Greg Hartman85c495f2017-10-26 23:52:37 -07002455const RIL_RadioFunctions* RIL_Init(const struct RIL_Env* env, int /*argc*/,
2456 char** /*argv*/) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002457 time(&gce_ril_start_time);
2458 gce_ril_env = env;
2459
Tomasz Wiszkowskie5749d52017-09-18 14:58:55 -07002460 TearDownNetworkInterface();
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -07002461
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002462 init_modem_supported_network_types();
2463 init_modem_technologies();
2464 init_virtual_network();
2465 init_sim_file_system();
2466 init_sim_status();
2467
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002468 return &ril_callbacks;
2469}
2470
2471} // extern "C"