blob: 0d33dd902b56e4408e4e6f95587ec12a540a66cb [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));
Alistair Strachan8adbea12018-04-05 09:51:31 -0700117 std::unique_ptr<cvd::NetworkInterface> ni(nm->Open("rmnet0", "eth0"));
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700118
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800119 if (ni) {
Alistair Strachan8adbea12018-04-05 09:51:31 -0700120 ni->SetName("rmnet0");
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800121 ni->SetAddress(ipaddr);
122 ni->SetBroadcastAddress(bcaddr);
Greg Hartmana47dd952017-12-21 21:30:23 -0800123 ni->SetPrefixLength(prefixlen);
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800124 ni->SetOperational(true);
125 bool res = nm->ApplyChanges(*ni);
126 if (!res) ALOGE("Could not configure rmnet0");
127 return res;
128 }
129 return false;
130}
Greg Hartman662dac02017-10-26 23:28:15 -0700131
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700132// TearDownNetworkInterface disables network interface.
133// This call returns true, if operation was successful.
134bool TearDownNetworkInterface() {
Greg Hartman153b1062017-11-11 12:09:21 -0800135 auto nm(cvd::NetworkInterfaceManager::New(nullptr));
Alistair Strachan8adbea12018-04-05 09:51:31 -0700136 auto ni(nm->Open("rmnet0", "eth0"));
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700137
138 if (ni) {
139 ni->SetOperational(false);
140 bool res = nm->ApplyChanges(*ni);
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800141 if (!res) ALOGE("Could not disable rmnet0");
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700142 return res;
143 }
144 return false;
145}
146
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700147static int gNextDataCallId = 8;
148static std::map<int, DataCall> gDataCalls;
149static bool gRilConnected = false;
150
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700151static int request_or_send_data_calllist(RIL_Token* t) {
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700152#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700153 RIL_Data_Call_Response_v11* responses =
154 new RIL_Data_Call_Response_v11[gDataCalls.size()];
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700155#else
156 RIL_Data_Call_Response_v6* responses =
157 new RIL_Data_Call_Response_v6[gDataCalls.size()];
158#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700159
160 int index = 0;
161
162 ALOGV("Query data call list: %zu data calls tracked.", gDataCalls.size());
163
164 for (std::map<int, DataCall>::iterator iter = gDataCalls.begin();
165 iter != gDataCalls.end(); ++iter, ++index) {
166 responses[index].status = iter->second.fail_cause_;
167 responses[index].suggestedRetryTime = -1;
168 responses[index].cid = iter->first;
169 responses[index].active = iter->second.link_state_;
170
171 switch (iter->second.connection_type_) {
172 case DataCall::kConnTypeIPv4:
173 responses[index].type = (char*)"IP";
174 break;
175 case DataCall::kConnTypeIPv6:
176 responses[index].type = (char*)"IPV6";
177 break;
178 case DataCall::kConnTypeIPv4v6:
179 responses[index].type = (char*)"IPV4V6";
180 break;
181 case DataCall::kConnTypePPP:
182 responses[index].type = (char*)"PPP";
183 break;
184 default:
185 responses[index].type = (char*)"IP";
186 break;
187 }
188
Jorge E. Moreirad6c129e2018-01-05 14:52:21 -0800189 auto ril_region_view = vsoc::ril::RilRegionView::GetInstance();
190
Greg Hartman34b5e3c2017-12-21 22:54:43 -0800191 responses[index].ifname = (char*)"rmnet0";
Jorge E. Moreirad6c129e2018-01-05 14:52:21 -0800192 responses[index].addresses =
193 const_cast<char*>(ril_region_view->address_and_prefix_length());
194 responses[index].dnses = (char*)ril_region_view->data()->dns;
195 responses[index].gateways = (char*)ril_region_view->data()->gateway;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700196#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700197 responses[index].pcscf = (char*)"";
198 responses[index].mtu = 1440;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700199#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700200 }
201
202 bool new_conn_state = (gDataCalls.size() > 0);
203
204 if (gRilConnected != new_conn_state) {
205 time_t curr_time;
206 time(&curr_time);
207 double diff_in_secs = difftime(curr_time, gce_ril_start_time);
208
209 gRilConnected = new_conn_state;
210
211 if (new_conn_state) {
212 ALOGV("MOBILE_DATA_CONNECTED %.2lf seconds", diff_in_secs);
213 } else {
214 ALOGV("MOBILE_DATA_DISCONNECTED %.2lf seconds", diff_in_secs);
215 }
216
217 if (property_set("ril.net_connected", new_conn_state ? "1" : "0")) {
218 ALOGE("Couldn't set a system property ril.net_connected.");
219 }
220 }
221
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700222 if (t != NULL) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700223 gce_ril_env->OnRequestComplete(*t, RIL_E_SUCCESS, responses,
224 gDataCalls.size() * sizeof(*responses));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700225 } else {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700226 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
227 responses,
228 gDataCalls.size() * sizeof(*responses));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700229 }
230 delete[] responses;
231 return 0;
232}
233
234static void request_datacall_fail_cause(RIL_Token t) {
235 RIL_DataCallFailCause fail = PDP_FAIL_DATA_REGISTRATION_FAIL;
236
237 if (gDataCalls.size() > 0) {
238 fail = gDataCalls.rbegin()->second.fail_cause_;
239 }
240
241 ALOGV("Requesting last data call setup fail cause (%d)", fail);
242 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &fail, sizeof(fail));
243};
244
Greg Hartman85c495f2017-10-26 23:52:37 -0700245static void request_data_calllist(void* /*data*/, size_t /*datalen*/,
246 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700247 request_or_send_data_calllist(&t);
248}
249
250static void request_setup_data_call(void* data, size_t datalen, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700251 char** details = static_cast<char**>(data);
252 const size_t fields = datalen / sizeof(details[0]);
253
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700254 // There are two different versions of this interface, one providing 7 strings
255 // and the other providing 8. The code below will assume the presence of 7
256 // strings in all cases, so bail out here if things appear to be wrong. We
257 // protect the 8 string case below.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700258 if (fields < 7) {
259 ALOGE("%s returning: called with small datalen %zu", __FUNCTION__, datalen);
260 return;
261 }
262 DataCall call;
263 int tech = atoi(details[0]);
264 switch (tech) {
265 case 0:
266 case 2 + RADIO_TECH_1xRTT:
267 call.technology_ = RADIO_TECH_1xRTT;
268 break;
269
270 case 1:
271 case 2 + RADIO_TECH_EDGE:
272 call.technology_ = RADIO_TECH_EDGE;
273 break;
274
275 default:
276 call.technology_ = RIL_RadioTechnology(tech - 2);
277 break;
278 }
279
280 int profile = atoi(details[1]);
281 call.profile_ = RIL_DataProfile(profile);
282
283 if (details[2]) call.access_point_ = details[2];
284 if (details[3]) call.username_ = details[3];
285 if (details[4]) call.password_ = details[4];
286
287 int auth_type = atoi(details[5]);
288 call.auth_type_ = DataCall::AllowedAuthenticationType(auth_type);
289
290 if (!strcmp("IP", details[6])) {
291 call.connection_type_ = DataCall::kConnTypeIPv4;
292 } else if (!strcmp("IPV6", details[6])) {
293 call.connection_type_ = DataCall::kConnTypeIPv6;
294 } else if (!strcmp("IPV4V6", details[6])) {
295 call.connection_type_ = DataCall::kConnTypeIPv4v6;
296 } else if (!strcmp("PPP", details[6])) {
297 call.connection_type_ = DataCall::kConnTypePPP;
298 } else {
299 ALOGW("Unknown / unsupported connection type %s. Falling back to IPv4",
300 details[6]);
301 call.connection_type_ = DataCall::kConnTypeIPv4;
302 }
303
304 if (call.connection_type_ != DataCall::kConnTypeIPv4) {
Greg Hartman7c01b7c2018-01-10 18:30:22 -0800305 ALOGE("Non-IPv4 connections are not supported by VSOC RIL.");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700306 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
307 return;
308 }
309
310 call.link_state_ = DataCall::kLinkStateUp;
311 call.fail_cause_ = PDP_FAIL_NONE;
312 if (fields > 7) {
313 if (details[7]) call.other_properties_ = details[7];
314 }
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700315
316 if (gDataCalls.empty()) {
Jorge E. Moreirad6c129e2018-01-05 14:52:21 -0800317 auto ril_region_view = vsoc::ril::RilRegionView::GetInstance();
318 SetUpNetworkInterface(ril_region_view->data()->ipaddr,
319 ril_region_view->data()->prefixlen,
320 ril_region_view->data()->broadcast);
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700321 }
322
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700323 gDataCalls[gNextDataCallId] = call;
324 gNextDataCallId++;
325
326 ALOGV("Requesting data call setup to APN %s, technology %s, prof %s",
327 details[2], details[0], details[1]);
328
329 request_or_send_data_calllist(&t);
330
331 gRilConnected = (gDataCalls.size() > 0);
332}
333
Greg Hartman85c495f2017-10-26 23:52:37 -0700334static void request_teardown_data_call(void* data, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700335 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700336 char** data_strs = (char**)data;
337 int call_id = atoi(data_strs[0]);
338 int reason = atoi(data_strs[1]);
339
340 ALOGV("Tearing down data call %d, reason: %d", call_id, reason);
341
342 gDataCalls.erase(call_id);
343 gRilConnected = (gDataCalls.size() > 0);
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -0700344
345 if (!gRilConnected) {
346 TearDownNetworkInterface();
347 }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700348 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
349}
350
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700351static void set_radio_state(RIL_RadioState new_state, RIL_Token t) {
352 // From header:
353 // Toggle radio on and off (for "airplane" mode)
354 // If the radio is is turned off/on the radio modem subsystem
355 // is expected return to an initialized state. For instance,
356 // any voice and data calls will be terminated and all associated
357 // lists emptied.
358 gDataCalls.clear();
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700359
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700360 gSimStatus = SIM_NOT_READY;
Greg Hartman7c01b7c2018-01-10 18:30:22 -0800361 ALOGV("RIL_RadioState change %d to %d", gRadioPowerState, new_state);
362 gRadioPowerState = new_state;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700363
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700364 if (new_state == RADIO_STATE_OFF) {
365 TearDownNetworkInterface();
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700366 }
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700367
368 if (t != NULL) {
369 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
370 }
371
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700372 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
373 NULL, 0);
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700374
375 pollSIMState(NULL);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700376}
377
378// returns 1 if on, 0 if off, and -1 on error
Greg Hartman85c495f2017-10-26 23:52:37 -0700379static void request_radio_power(void* data, size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700380 int on = ((int*)data)[0];
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -0700381 set_radio_state(on ? RADIO_STATE_ON : RADIO_STATE_OFF, t);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700382}
383
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700384// TODO(ender): this should be a class member. Move where it belongs.
385struct CallState {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700386 RIL_CallState state; // e.g. RIL_CALL_HOLDING;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700387 bool isInternational;
388 bool isMobileTerminated;
389 bool isVoice;
390 bool isMultiParty;
391
392 std::string number;
393 std::string name;
394 std::string dtmf;
395
396 bool canPresentNumber;
397 bool canPresentName;
398
399 CallState()
400 : state(RIL_CallState(0)),
401 isInternational(false),
402 isMobileTerminated(true),
403 isVoice(true),
404 isMultiParty(false),
405 canPresentNumber(true),
406 canPresentName(true) {}
407
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700408 CallState(const std::string& number)
409 : state(RIL_CALL_INCOMING),
410 isInternational(false),
411 isMobileTerminated(true),
412 isVoice(true),
413 isMultiParty(false),
414 number(number),
415 name(number),
416 canPresentNumber(true),
417 canPresentName(true) {}
418
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700419 bool isBackground() { return state == RIL_CALL_HOLDING; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700420
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700421 bool isActive() { return state == RIL_CALL_ACTIVE; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700422
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700423 bool isDialing() { return state == RIL_CALL_DIALING; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700424
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700425 bool isIncoming() { return state == RIL_CALL_INCOMING; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700426
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700427 bool isWaiting() { return state == RIL_CALL_WAITING; }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700428
429 void addDtmfDigit(char c) {
430 dtmf.push_back(c);
431 ALOGV("Call to %s: DTMF %s", number.c_str(), dtmf.c_str());
432 }
433
434 bool makeBackground() {
435 if (state == RIL_CALL_ACTIVE) {
436 state = RIL_CALL_HOLDING;
437 return true;
438 }
439
440 return false;
441 }
442
443 bool makeActive() {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700444 if (state == RIL_CALL_INCOMING || state == RIL_CALL_WAITING ||
445 state == RIL_CALL_DIALING || state == RIL_CALL_HOLDING) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700446 state = RIL_CALL_ACTIVE;
447 return true;
448 }
449
450 return false;
451 }
452};
453
454static int gLastActiveCallIndex = 1;
Tomasz Wiszkowski429d6022017-10-17 10:02:05 -0700455static int gMicrophoneMute = 0;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700456static std::map<int, CallState> gActiveCalls;
457
Greg Hartman85c495f2017-10-26 23:52:37 -0700458static void request_get_current_calls(void* /*data*/, size_t /*datalen*/,
459 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700460 const int countCalls = gActiveCalls.size();
461
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700462 RIL_Call** pp_calls = (RIL_Call**)alloca(countCalls * sizeof(RIL_Call*));
463 RIL_Call* p_calls = (RIL_Call*)alloca(countCalls * sizeof(RIL_Call));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700464
465 memset(p_calls, 0, countCalls * sizeof(RIL_Call));
466
467 /* init the pointer array */
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700468 for (int i = 0; i < countCalls; i++) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700469 pp_calls[i] = &(p_calls[i]);
470 }
471
Tomasz Wiszkowski1ef31e42017-09-21 09:09:37 -0700472 // TODO(ender): This should be built from calls requested via RequestDial.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700473 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
474 iter != gActiveCalls.end(); ++iter, ++p_calls) {
475 p_calls->state = iter->second.state;
476 p_calls->index = iter->first;
477 p_calls->toa = iter->second.isInternational ? 145 : 129;
478 p_calls->isMpty = iter->second.isMultiParty;
479 p_calls->isMT = iter->second.isMobileTerminated;
480 p_calls->als = iter->first;
481 p_calls->isVoice = iter->second.isVoice;
482 p_calls->isVoicePrivacy = 0;
483 p_calls->number = strdup(iter->second.number.c_str());
484 p_calls->numberPresentation = iter->second.canPresentNumber ? 0 : 1;
485 p_calls->name = strdup(iter->second.name.c_str());
486 p_calls->namePresentation = iter->second.canPresentName ? 0 : 1;
487 p_calls->uusInfo = NULL;
488
489 ALOGV("Call to %s (%s): voice=%d mt=%d type=%d state=%d index=%d",
490 p_calls->name, p_calls->number, p_calls->isVoice, p_calls->isMT,
491 p_calls->toa, p_calls->state, p_calls->index);
492 }
493
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700494 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, pp_calls,
495 countCalls * sizeof(RIL_Call*));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700496
497 ALOGV("Get Current calls: %d calls found.\n", countCalls);
498}
499
Greg Hartman85c495f2017-10-26 23:52:37 -0700500static void simulate_pending_calls_answered(void* /*ignore*/) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700501 ALOGV("Simulating outgoing call answered.");
502 // This also resumes held calls.
503 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
504 iter != gActiveCalls.end(); ++iter) {
505 if (iter->second.isDialing()) {
506 iter->second.makeActive();
507 }
508 }
509
510 // Only unsolicited here.
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700511 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
512 NULL, 0);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700513}
514
Greg Hartman85c495f2017-10-26 23:52:37 -0700515static void request_dial(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700516 RIL_Dial* p_dial = (RIL_Dial*)data;
517
518 ALOGV("Dialing %s, number presentation is %s.", p_dial->address,
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700519 (p_dial->clir == 0) ? "defined by operator"
520 : (p_dial->clir == 1) ? "allowed" : "restricted");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700521
522 CallState state(p_dial->address);
523 state.isMobileTerminated = false;
524 state.state = RIL_CALL_DIALING;
525
526 switch (p_dial->clir) {
527 case 0: // default
528 case 1: // allow
529 state.canPresentNumber = true;
530 break;
531
532 case 2: // restrict
533 state.canPresentNumber = false;
534 break;
535 }
536
537 int call_index = gLastActiveCallIndex++;
538 gActiveCalls[call_index] = state;
539
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700540 static const struct timeval kAnswerTime = {5, 0};
541 gce_ril_env->RequestTimedCallback(simulate_pending_calls_answered, NULL,
542 &kAnswerTime);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700543
544 // success or failure is ignored by the upper layer here.
545 // it will call GET_CURRENT_CALLS and determine success that way
546 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
547}
548
Greg Hartman85c495f2017-10-26 23:52:37 -0700549void request_set_mute(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski429d6022017-10-17 10:02:05 -0700550 gMicrophoneMute = ((int*)data)[0] != 0;
551 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
552}
553
554void request_get_mute(RIL_Token t) {
555 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gMicrophoneMute,
556 sizeof(gMicrophoneMute));
557}
558
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700559// TODO(ender): this should be a class member. Move where it belongs.
560struct SmsMessage {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700561 enum SmsStatus { kUnread = 0, kRead = 1, kUnsent = 2, kSent = 3 };
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700562
563 std::string message;
564 SmsStatus status;
565};
566
567static int gNextMessageId = 1;
568static std::map<int, SmsMessage> gMessagesOnSimCard;
569
Greg Hartman85c495f2017-10-26 23:52:37 -0700570static void request_write_sms_to_sim(void* data, size_t /*datalen*/,
571 RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700572 RIL_SMS_WriteArgs* p_args = (RIL_SMS_WriteArgs*)data;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700573
574 SmsMessage message;
575 message.status = SmsMessage::SmsStatus(p_args->status);
576 message.message = p_args->pdu;
577
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700578 ALOGV("Storing SMS message: '%s' with state: %s.", message.message.c_str(),
579 (message.status < SmsMessage::kUnsent)
580 ? ((message.status == SmsMessage::kRead) ? "READ" : "UNREAD")
581 : ((message.status == SmsMessage::kSent) ? "SENT" : "UNSENT"));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700582
583 // TODO(ender): simulate SIM FULL?
584 int index = gNextMessageId++;
585 gMessagesOnSimCard[index] = message;
586
587 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &index, sizeof(index));
588}
589
Greg Hartman85c495f2017-10-26 23:52:37 -0700590static void request_delete_sms_on_sim(void* data, size_t /*datalen*/,
591 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700592 int index = *(int*)data;
593
594 ALOGV("Delete SMS message %d", index);
595
596 if (gMessagesOnSimCard.erase(index) == 0) {
597 // No such message
598 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
599 return;
600 }
601
602 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
603}
604
Greg Hartman85c495f2017-10-26 23:52:37 -0700605static void request_hangup(void* data, size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700606 int* p_line = (int*)data;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700607
608 ALOGV("Hanging up call %d.", *p_line);
609 std::map<int, CallState>::iterator iter = gActiveCalls.find(*p_line);
610
611 if (iter == gActiveCalls.end()) {
612 ALOGV("No such call: %d.", *p_line);
613 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
614 } else {
615 gActiveCalls.erase(iter);
616 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
617 }
618}
619
Greg Hartman85c495f2017-10-26 23:52:37 -0700620static void request_hangup_waiting(void* /*data*/, size_t /*datalen*/,
621 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700622 ALOGV("Hanging up background/held calls.");
623 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
624 iter != gActiveCalls.end();) {
625 if (iter->second.isBackground()) {
626 // C++98 -- std::map::erase doesn't return iterator.
627 std::map<int, CallState>::iterator temp = iter++;
628 gActiveCalls.erase(temp);
629 } else {
630 ++iter;
631 }
632 }
633 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
634}
635
636static void request_hangup_current(RIL_Token t) {
637 ALOGV("Hanging up foreground/active calls.");
638 // This also resumes held calls.
639 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
640 iter != gActiveCalls.end();) {
641 if (iter->second.isBackground()) {
642 iter->second.makeActive();
643 ++iter;
644 } else {
645 // C++98 -- std::map::erase doesn't return iterator.
646 std::map<int, CallState>::iterator temp = iter++;
647 gActiveCalls.erase(temp);
648 }
649 }
650 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
651}
652
653static void request_switch_current_and_waiting(RIL_Token t) {
654 ALOGV("Toggle foreground and background calls.");
655 // TODO(ender): fix all states. Max 2 calls.
656 // BEFORE AFTER
657 // Call 1 Call 2 Call 1 Call 2
658 // ACTIVE HOLDING HOLDING ACTIVE
659 // ACTIVE WAITING HOLDING ACTIVE
660 // HOLDING WAITING HOLDING ACTIVE
661 // ACTIVE IDLE HOLDING IDLE
662 // IDLE IDLE IDLE IDLE
663 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
664 iter != gActiveCalls.end(); ++iter) {
665 // TODO(ender): call could also be waiting or dialing or...
666 if (iter->second.isBackground()) {
667 iter->second.makeActive();
668 } else {
669 iter->second.makeBackground();
670 }
671 }
672 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
673}
674
675static void request_answer_incoming(RIL_Token t) {
676 ALOGV("Answering incoming call.");
677
678 // There's two types of incoming calls:
679 // - incoming: we are receiving this call while nothing happens,
680 // - waiting: we are receiving this call while we're already talking.
681 // We only accept the incoming ones.
682 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
683 iter != gActiveCalls.end(); ++iter) {
684 if (iter->second.isIncoming()) {
685 iter->second.makeActive();
686 }
687 }
688 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
689}
690
Greg Hartman85c495f2017-10-26 23:52:37 -0700691static void request_combine_multiparty_call(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700692 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700693 ALOGW("Conference calls are not supported.");
694 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
695}
696
Greg Hartman85c495f2017-10-26 23:52:37 -0700697static void request_split_multiparty_call(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700698 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700699 ALOGW("Conference calls are not supported.");
700 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
701}
702
703static void request_udub_on_incoming_calls(RIL_Token t) {
704 // UDUB = user determined user busy.
705 // We don't exactly do that. We simply drop these calls.
706 ALOGV("Reporting busy signal to incoming calls.");
707 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
708 iter != gActiveCalls.end();) {
709 // If we have an incoming call, there should be no waiting call.
710 // If we have a waiting call, then previous incoming call has been answered.
711 if (iter->second.isIncoming() || iter->second.isWaiting()) {
712 // C++98 -- std::map::erase doesn't return iterator.
713 std::map<int, CallState>::iterator temp = iter++;
714 gActiveCalls.erase(temp);
715 } else {
716 ++iter;
717 }
718 }
719 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
720}
721
Greg Hartman85c495f2017-10-26 23:52:37 -0700722static void request_send_dtmf(void* data, size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700723 char c = ((char*)data)[0];
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700724 ALOGV("Sending DTMF digit '%c'", c);
725
726 for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
727 iter != gActiveCalls.end(); ++iter) {
728 if (iter->second.isActive()) {
729 iter->second.addDtmfDigit(c);
730 break;
731 }
732 }
733
734 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
735}
736
737static void request_send_dtmf_stop(RIL_Token t) {
738 ALOGV("DTMF tone end.");
739
740 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
741}
742
743// Check SignalStrength.java file for more details on how these map to signal
744// strength bars.
745const int kGatewaySignalStrengthMin = 4;
746const int kGatewaySignalStrengthMax = 30;
747const int kCDMASignalStrengthMin = -110;
748const int kCDMASignalStrengthMax = -60;
749const int kEVDOSignalStrengthMin = -160;
750const int kEVDOSignalStrengthMax = -70;
751const int kLTESignalStrengthMin = 4;
752const int kLTESignalStrengthMax = 30;
753
754static int gGatewaySignalStrength = kGatewaySignalStrengthMax;
755static int gCDMASignalStrength = kCDMASignalStrengthMax;
756static int gEVDOSignalStrength = kEVDOSignalStrengthMax;
757static int gLTESignalStrength = kLTESignalStrengthMax;
758
Greg Hartman85c495f2017-10-26 23:52:37 -0700759static void request_signal_strength(void* /*data*/, size_t /*datalen*/,
760 RIL_Token t) {
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700761 // TODO(ender): possible to support newer APIs here.
762#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700763 RIL_SignalStrength_v10 strength;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700764#else
765 RIL_SignalStrength_v6 strength;
766#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700767
768 gGatewaySignalStrength += (rand() % 3 - 1);
769 gCDMASignalStrength += (rand() % 3 - 1);
770 gEVDOSignalStrength += (rand() % 3 - 1);
771 gLTESignalStrength += (rand() % 3 - 1);
772
773 if (gGatewaySignalStrength < kGatewaySignalStrengthMin)
774 gGatewaySignalStrength = kGatewaySignalStrengthMin;
775 if (gGatewaySignalStrength > kGatewaySignalStrengthMax)
776 gGatewaySignalStrength = kGatewaySignalStrengthMax;
777 if (gCDMASignalStrength < kCDMASignalStrengthMin)
778 gCDMASignalStrength = kCDMASignalStrengthMin;
779 if (gCDMASignalStrength > kCDMASignalStrengthMax)
780 gCDMASignalStrength = kCDMASignalStrengthMax;
781 if (gEVDOSignalStrength < kEVDOSignalStrengthMin)
782 gEVDOSignalStrength = kEVDOSignalStrengthMin;
783 if (gEVDOSignalStrength > kEVDOSignalStrengthMax)
784 gEVDOSignalStrength = kEVDOSignalStrengthMax;
785 if (gLTESignalStrength < kLTESignalStrengthMin)
786 gLTESignalStrength = kLTESignalStrengthMin;
787 if (gLTESignalStrength > kLTESignalStrengthMax)
788 gLTESignalStrength = kLTESignalStrengthMax;
789
790 strength.GW_SignalStrength.signalStrength = gGatewaySignalStrength;
791 strength.GW_SignalStrength.bitErrorRate = 0; // 0..7%
792
793 strength.CDMA_SignalStrength.dbm = gCDMASignalStrength;
794 strength.CDMA_SignalStrength.ecio = 0; // Ec/Io; keep high to use dbm.
795
796 strength.EVDO_SignalStrength.dbm = gEVDOSignalStrength;
797 strength.EVDO_SignalStrength.ecio = 0; // Ec/Io; keep high to use dbm.
798
799 strength.LTE_SignalStrength.signalStrength = gLTESignalStrength;
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700800 strength.LTE_SignalStrength.rsrp = INT_MAX; // Invalid = Use signalStrength.
801 strength.LTE_SignalStrength.rsrq = INT_MAX; // Invalid = Use signalStrength.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700802 strength.LTE_SignalStrength.rssnr = INT_MAX; // Invalid = Use signalStrength.
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700803 strength.LTE_SignalStrength.cqi = INT_MAX; // Invalid = Use signalStrength.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700804
805 ALOGV("Reporting signal strength: GW=%d CDMA=%d EVDO=%d LTE=%d",
806 gGatewaySignalStrength, gCDMASignalStrength, gEVDOSignalStrength,
807 gLTESignalStrength);
808
809 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &strength, sizeof(strength));
810}
811
812static std::map<RIL_PreferredNetworkType, int> gModemSupportedNetworkTypes;
813
814static void init_modem_supported_network_types() {
815 gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA] = MDM_GSM | MDM_WCDMA;
816 gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_ONLY] = MDM_GSM;
817 gModemSupportedNetworkTypes[PREF_NET_TYPE_WCDMA] = MDM_WCDMA;
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700818 gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA_AUTO] =
819 MDM_GSM | MDM_WCDMA;
820 gModemSupportedNetworkTypes[PREF_NET_TYPE_CDMA_EVDO_AUTO] =
821 MDM_CDMA | MDM_EVDO;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700822 gModemSupportedNetworkTypes[PREF_NET_TYPE_CDMA_ONLY] = MDM_CDMA;
823 gModemSupportedNetworkTypes[PREF_NET_TYPE_EVDO_ONLY] = MDM_EVDO;
824 gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO] =
825 MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO;
826 gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_CDMA_EVDO] =
827 MDM_LTE | MDM_CDMA | MDM_EVDO;
828 gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_GSM_WCDMA] =
829 MDM_LTE | MDM_GSM | MDM_WCDMA;
830 gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA] =
831 MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA;
832 gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_ONLY] = MDM_LTE;
833}
834
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700835static std::map<RIL_PreferredNetworkType, int> gModemTechnologies;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700836
837RIL_RadioTechnology gDataTechnologiesPreferenceOrder[] = {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700838 RADIO_TECH_LTE, RADIO_TECH_EHRPD, RADIO_TECH_HSPAP, RADIO_TECH_HSPA,
839 RADIO_TECH_HSDPA, RADIO_TECH_HSUPA, RADIO_TECH_EVDO_B, RADIO_TECH_EVDO_A,
840 RADIO_TECH_EVDO_0, RADIO_TECH_1xRTT, RADIO_TECH_UMTS, RADIO_TECH_EDGE,
841 RADIO_TECH_GPRS};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700842
843RIL_RadioTechnology gVoiceTechnologiesPreferenceOrder[] = {
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700844 RADIO_TECH_LTE, RADIO_TECH_EHRPD, RADIO_TECH_EVDO_B, RADIO_TECH_EVDO_A,
845 RADIO_TECH_EVDO_0, RADIO_TECH_1xRTT, RADIO_TECH_IS95B, RADIO_TECH_IS95A,
846 RADIO_TECH_UMTS, RADIO_TECH_GSM};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700847
848static void init_modem_technologies() {
849 gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA] =
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700850 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
851 (1 << RADIO_TECH_UMTS);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700852 gModemTechnologies[PREF_NET_TYPE_GSM_ONLY] =
853 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE);
854 gModemTechnologies[PREF_NET_TYPE_WCDMA] =
855 (1 << RADIO_TECH_EDGE) | (1 << RADIO_TECH_UMTS);
856 gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA_AUTO] =
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700857 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
858 (1 << RADIO_TECH_UMTS);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700859 gModemTechnologies[PREF_NET_TYPE_CDMA_EVDO_AUTO] =
860 (1 << RADIO_TECH_IS95A) | (1 << RADIO_TECH_IS95B) |
861 (1 << RADIO_TECH_1xRTT) | (1 << RADIO_TECH_EVDO_0) |
862 (1 << RADIO_TECH_EVDO_A) | (1 << RADIO_TECH_HSDPA) |
863 (1 << RADIO_TECH_HSUPA) | (1 << RADIO_TECH_HSPA) |
864 (1 << RADIO_TECH_EVDO_B);
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700865 gModemTechnologies[PREF_NET_TYPE_CDMA_ONLY] = (1 << RADIO_TECH_IS95A) |
866 (1 << RADIO_TECH_IS95B) |
867 (1 << RADIO_TECH_1xRTT);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700868 gModemTechnologies[PREF_NET_TYPE_EVDO_ONLY] =
869 (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
870 (1 << RADIO_TECH_EVDO_A) | (1 << RADIO_TECH_HSDPA) |
871 (1 << RADIO_TECH_HSUPA) | (1 << RADIO_TECH_HSPA) |
872 (1 << RADIO_TECH_EVDO_B);
873 gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO] =
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700874 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
875 (1 << RADIO_TECH_UMTS) | (1 << RADIO_TECH_IS95A) |
876 (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) |
877 (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
878 (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) |
879 (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700880 gModemTechnologies[PREF_NET_TYPE_LTE_CDMA_EVDO] =
881 (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) |
882 (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_IS95A) |
883 (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) |
884 (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
885 (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) |
886 (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B);
887 gModemTechnologies[PREF_NET_TYPE_LTE_GSM_WCDMA] =
888 (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) |
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700889 (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) |
890 (1 << RADIO_TECH_EDGE) | (1 << RADIO_TECH_UMTS);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700891
892 gModemTechnologies[PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA] =
893 (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) |
894 (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_IS95A) |
895 (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) |
896 (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
897 (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) |
898 (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B) |
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700899 (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
900 (1 << RADIO_TECH_UMTS);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700901 gModemTechnologies[PREF_NET_TYPE_LTE_ONLY] =
902 (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) | (1 << RADIO_TECH_EHRPD);
903}
904
905static const RIL_PreferredNetworkType gModemDefaultType =
906 PREF_NET_TYPE_LTE_GSM_WCDMA;
907static RIL_PreferredNetworkType gModemCurrentType = gModemDefaultType;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700908static RIL_RadioTechnology gModemVoiceTechnology = RADIO_TECH_LTE;
909
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700910// Report technology change.
911// Select best technology from the list of supported techs.
912// Demotes RADIO_TECH_GSM as it's voice-only.
913static RIL_RadioTechnology getBestDataTechnology(
914 RIL_PreferredNetworkType network_type) {
915 RIL_RadioTechnology technology = RADIO_TECH_GPRS;
916
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700917 std::map<RIL_PreferredNetworkType, int>::iterator iter =
918 gModemTechnologies.find(network_type);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700919
920 ALOGV("Searching for best data technology for network type %d...",
921 network_type);
922
923 // Find which technology bits are lit. Pick the top most.
924 for (size_t tech_index = 0;
925 tech_index < sizeof(gDataTechnologiesPreferenceOrder) /
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700926 sizeof(gDataTechnologiesPreferenceOrder[0]);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700927 ++tech_index) {
928 if (iter->second & (1 << gDataTechnologiesPreferenceOrder[tech_index])) {
929 technology = gDataTechnologiesPreferenceOrder[tech_index];
930 break;
931 }
932 }
933
934 ALOGV("Best data technology: %d.", technology);
935 return technology;
936}
937
938static RIL_RadioTechnology getBestVoiceTechnology(
939 RIL_PreferredNetworkType network_type) {
940 RIL_RadioTechnology technology = RADIO_TECH_GSM;
941
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700942 std::map<RIL_PreferredNetworkType, int>::iterator iter =
943 gModemTechnologies.find(network_type);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700944
945 ALOGV("Searching for best voice technology for network type %d...",
946 network_type);
947
948 // Find which technology bits are lit. Pick the top most.
949 for (size_t tech_index = 0;
950 tech_index < sizeof(gVoiceTechnologiesPreferenceOrder) /
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700951 sizeof(gVoiceTechnologiesPreferenceOrder[0]);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700952 ++tech_index) {
953 if (iter->second & (1 << gVoiceTechnologiesPreferenceOrder[tech_index])) {
954 technology = gVoiceTechnologiesPreferenceOrder[tech_index];
955 break;
956 }
957 }
958
959 ALOGV("Best voice technology: %d.", technology);
960 return technology;
961}
962
963static void setRadioTechnology(RIL_PreferredNetworkType network_type) {
964 RIL_RadioTechnology technology = getBestVoiceTechnology(network_type);
965
966 if (technology != gModemVoiceTechnology) {
967 gModemVoiceTechnology = technology;
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700968 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
969 &gModemVoiceTechnology,
970 sizeof(gModemVoiceTechnology));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700971 }
972}
973
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700974#if VSOC_PLATFORM_SDK_AFTER(L)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700975static void request_get_radio_capability(RIL_Token t) {
976 ALOGV("Requesting radio capability.");
977 RIL_RadioCapability rc;
978 rc.version = RIL_RADIO_CAPABILITY_VERSION;
979 rc.session = 1;
980 rc.phase = RC_PHASE_CONFIGURED;
981 rc.rat = RAF_HSPAP;
Greg Hartman153b1062017-11-11 12:09:21 -0800982 strncpy(rc.logicalModemUuid, "com.google.cvdgce1.modem", MAX_UUID_LENGTH);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700983 rc.status = RC_STATUS_SUCCESS;
984 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &rc, sizeof(rc));
985}
986
Greg Hartman8d9b76e2017-10-26 23:23:40 -0700987static void request_set_radio_capability(void* data, size_t datalen,
988 RIL_Token t) {
989 RIL_RadioCapability* rc = (RIL_RadioCapability*)data;
990 ALOGV(
991 "RadioCapability version %d session %d phase %d rat %d "
992 "logicalModemUuid %s status %d",
993 rc->version, rc->session, rc->phase, rc->rat, rc->logicalModemUuid,
994 rc->status);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700995 // TODO(ender): do something about these numbers.
996 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, rc, datalen);
997}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -0700998#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -0700999
Greg Hartman85c495f2017-10-26 23:52:37 -07001000static void request_set_preferred_network_type(int /*request*/, void* data,
1001 size_t /*datalen*/,
1002 RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001003 RIL_PreferredNetworkType desired_type = *(RIL_PreferredNetworkType*)(data);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001004
1005 // TODO(ender): telephony still believes this phone is GSM only.
1006 ALOGV("Requesting modem technology change -> %d", desired_type);
1007
1008 if (gModemSupportedNetworkTypes.find(desired_type) ==
1009 gModemSupportedNetworkTypes.end()) {
1010 desired_type = gModemSupportedNetworkTypes.begin()->first;
1011 }
1012
1013 if (gModemCurrentType == desired_type) {
1014 ALOGV("Modem technology already set to %d.", desired_type);
1015 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1016 return;
1017 }
1018
1019 int supported_technologies = gModemSupportedNetworkTypes[gModemDefaultType];
1020 int desired_technologies = gModemSupportedNetworkTypes[desired_type];
1021
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001022 ALOGV("Requesting modem technology change %d -> %d", gModemCurrentType,
1023 desired_type);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001024
1025 // Check if we support this technology.
1026 if ((supported_technologies & desired_technologies) != desired_technologies) {
1027 ALOGV("Desired technology is not supported.");
1028 gce_ril_env->OnRequestComplete(t, RIL_E_MODE_NOT_SUPPORTED, NULL, 0);
1029 return;
1030 }
1031
1032 gModemCurrentType = desired_type;
1033 setRadioTechnology(desired_type);
1034 ALOGV("Technology change successful.");
1035 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1036}
1037
Greg Hartman85c495f2017-10-26 23:52:37 -07001038static void request_get_preferred_network_type(int /*request*/, void* /*data*/,
1039 size_t /*datalen*/,
1040 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001041 gce_ril_env->OnRequestComplete(
1042 t, RIL_E_SUCCESS,
1043 const_cast<RIL_PreferredNetworkType*>(&gModemDefaultType),
1044 sizeof(gModemDefaultType));
1045}
1046
1047enum RegistrationState {
1048 kUnregistered = 0,
1049 kRegisteredInHomeNetwork = 1,
1050 kSearchingForOperators = 2,
1051 kRegistrationDenied = 3,
1052 kUnknown = 4,
1053 kRegisteredInRoamingMode = 5,
1054
1055 kUnregistered_EmergencyCallsOnly = 10,
1056 kSearchingForOperators_EmergencyCallsOnly = 12,
1057 kRegistrationDenied_EmergencyCallsOnly = 13,
1058 kUnknown_EmergencyCallsOnly = 14
1059};
1060
1061static const char kCdmaMobileDeviceNumber[] = "5551234567";
1062static const char kCdmaSID[] = "123";
1063static const char kCdmaNID[] = "65535"; // special: indicates free roaming.
1064
Greg Hartman85c495f2017-10-26 23:52:37 -07001065static void request_registration_state(int request, void* /*data*/,
1066 size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001067 char** responseStr = NULL;
1068 int numElements = 0;
1069
1070 // See RIL_REQUEST_VOICE_REGISTRATION_STATE and
1071 // RIL_REQUEST_DATA_REGISTRATION_STATE.
1072 numElements = (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) ? 15 : 6;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001073 responseStr = (char**)malloc(numElements * sizeof(char*));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001074
1075 asprintf(&responseStr[0], "%d", kRegisteredInHomeNetwork);
1076 responseStr[1] = NULL; // LAC - needed for GSM / WCDMA only.
1077 responseStr[2] = NULL; // CID - needed for GSM / WCDMA only.
1078
1079 // This is (and always has been) a huge memory leak.
1080 if (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
1081 ALOGV("Requesting voice registration state.");
1082 asprintf(&responseStr[3], "%d", getBestVoiceTechnology(gModemCurrentType));
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001083 responseStr[4] = strdup("1"); // BSID
1084 responseStr[5] = strdup("123"); // Latitude
1085 responseStr[6] = strdup("222"); // Longitude
1086 responseStr[7] = strdup("0"); // CSS Indicator
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001087 responseStr[8] = strdup(kCdmaSID); // SID
1088 responseStr[9] = strdup(kCdmaNID); // NID
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001089 responseStr[10] = strdup("0"); // Roaming indicator
1090 responseStr[11] = strdup("1"); // System is in PRL
1091 responseStr[12] = strdup("0"); // Default Roaming indicator
1092 responseStr[13] = strdup("0"); // Reason for denial
1093 responseStr[14] = strdup("0"); // Primary Scrambling Code of Current
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001094 } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
1095 ALOGV("Requesting data registration state.");
1096 asprintf(&responseStr[3], "%d", getBestDataTechnology(gModemCurrentType));
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001097 responseStr[4] = strdup(""); // DataServiceDenyReason
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001098 responseStr[5] = strdup("1"); // Max simultaneous data calls.
1099 } else {
1100 ALOGV("Unexpected request type: %d", request);
1101 return;
1102 }
1103
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001104 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, responseStr,
1105 numElements * sizeof(responseStr));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001106}
1107
1108static void request_baseband_version(RIL_Token t) {
Greg Hartman153b1062017-11-11 12:09:21 -08001109 const char* response_str = "CVD_R1.0.0";
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001110
1111 ALOGV("Requested phone baseband version.");
1112
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001113 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, strdup(response_str),
1114 sizeof(response_str));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001115}
1116
1117// Returns true, if modem is CDMA capable.
1118static bool isCDMA() {
1119 switch (gModemCurrentType) {
1120 case PREF_NET_TYPE_GSM_WCDMA:
1121 case PREF_NET_TYPE_GSM_ONLY:
1122 case PREF_NET_TYPE_WCDMA:
1123 case PREF_NET_TYPE_GSM_WCDMA_AUTO:
1124 case PREF_NET_TYPE_LTE_GSM_WCDMA:
1125 case PREF_NET_TYPE_LTE_ONLY:
1126 return false;
1127
1128 case PREF_NET_TYPE_CDMA_EVDO_AUTO:
1129 case PREF_NET_TYPE_CDMA_ONLY:
1130 case PREF_NET_TYPE_EVDO_ONLY:
1131 case PREF_NET_TYPE_LTE_CDMA_EVDO:
1132 case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
1133 case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO:
1134 return true;
Greg Hartman85c495f2017-10-26 23:52:37 -07001135 default:
1136 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001137 }
1138
1139 ALOGE("INVALID MODEM TYPE: %d", gModemCurrentType);
1140 return false;
1141}
1142
1143// Returns true, if modem is GSM capable.
1144// Note, this is not same as !isCDMA().
1145static bool isGSM() {
1146 switch (gModemCurrentType) {
1147 case PREF_NET_TYPE_GSM_WCDMA:
1148 case PREF_NET_TYPE_GSM_ONLY:
1149 case PREF_NET_TYPE_WCDMA:
1150 case PREF_NET_TYPE_GSM_WCDMA_AUTO:
1151 case PREF_NET_TYPE_LTE_GSM_WCDMA:
1152 case PREF_NET_TYPE_LTE_ONLY:
1153 case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO:
1154 return true;
1155
1156 case PREF_NET_TYPE_CDMA_EVDO_AUTO:
1157 case PREF_NET_TYPE_CDMA_ONLY:
1158 case PREF_NET_TYPE_EVDO_ONLY:
1159 case PREF_NET_TYPE_LTE_CDMA_EVDO:
1160 case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
1161 return false;
Greg Hartman85c495f2017-10-26 23:52:37 -07001162 default:
1163 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001164 }
1165
1166 ALOGE("INVALID MODEM TYPE: %d", gModemCurrentType);
1167 return false;
1168}
1169
1170static const char gIdentityGsmImei[] = "12345678902468"; // Luhn cksum = 0.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001171static const char gIdentityGsmImeiSv[] = "01"; // Arbitrary version.
1172static const char gIdentityCdmaEsn[] = "A0123456"; // 8 digits, ^[A-F].*
1173static const char gIdentityCdmaMeid[] =
1174 "A0123456789012"; // 14 digits, ^[A-F].*
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001175
1176static void request_get_imei(RIL_Token t) {
1177 ALOGV("Requesting IMEI");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001178 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
1179 const_cast<char*>(gIdentityGsmImei),
1180 strlen(gIdentityGsmImei));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001181}
1182
1183static void request_get_imei_sv(RIL_Token t) {
1184 ALOGV("Requesting IMEI SV");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001185 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
1186 const_cast<char*>(gIdentityGsmImeiSv),
1187 strlen(gIdentityGsmImeiSv));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001188}
1189
Greg Hartman85c495f2017-10-26 23:52:37 -07001190static void request_device_identity(int /*request*/, void* /*data*/,
1191 size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001192 char* response[4] = {NULL};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001193
1194 ALOGV("Requesting device identity...");
1195
1196 if (isCDMA()) {
1197 response[2] = strdup(&gIdentityCdmaEsn[0]);
1198 response[3] = strdup(&gIdentityCdmaMeid[0]);
1199 }
1200
1201 if (isGSM()) {
1202 response[0] = strdup(&gIdentityGsmImei[0]);
1203 response[1] = strdup(&gIdentityGsmImeiSv[0]);
1204 }
1205
1206 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1207
1208 free(response[0]);
1209 free(response[1]);
1210}
1211
1212// Let's pretend we have SIM for CDMA (by default).
1213static bool gCdmaHasSim = true;
1214static RIL_CdmaSubscriptionSource gCdmaSubscriptionType =
1215 CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;
1216
Greg Hartman85c495f2017-10-26 23:52:37 -07001217static void request_cdma_get_subscription_source(int /*request*/,
1218 void* /*data*/,
1219 size_t /*datalen*/,
1220 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001221 ALOGV("Requesting CDMA Subscription source.");
1222
1223 if (!isCDMA()) {
1224 // No such radio.
1225 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1226 return;
1227 }
1228
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001229 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gCdmaSubscriptionType,
1230 sizeof(gCdmaSubscriptionType));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001231}
1232
Greg Hartman85c495f2017-10-26 23:52:37 -07001233static void request_cdma_set_subscription_source(int /*request*/, void* data,
1234 size_t /*datalen*/,
1235 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001236 ALOGV("Setting CDMA Subscription source.");
1237
1238 if (!isCDMA()) {
1239 // No such radio.
1240 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1241 return;
1242 }
1243
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001244 RIL_CdmaSubscriptionSource new_source = *(RIL_CdmaSubscriptionSource*)(data);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001245
1246 if (new_source == CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM && !gCdmaHasSim) {
1247 // No such radio.
1248 gce_ril_env->OnRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
1249 return;
1250 }
1251
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001252 ALOGV("Changed CDMA subscription type from %d to %d", gCdmaSubscriptionType,
1253 new_source);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001254 gCdmaSubscriptionType = new_source;
1255
1256 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001257 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
1258 &gCdmaSubscriptionType,
1259 sizeof(gCdmaSubscriptionType));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001260}
1261
Greg Hartman85c495f2017-10-26 23:52:37 -07001262static void request_cdma_subscription(int /*request*/, void* /*data*/,
1263 size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001264 ALOGV("Requesting CDMA Subscription.");
1265
1266 if (!isCDMA()) {
1267 // No such radio.
1268 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1269 return;
1270 }
1271
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001272 char* responseStr[5] = {NULL};
1273 responseStr[0] = strdup(&kCdmaMobileDeviceNumber[0]); // MDN
1274 responseStr[1] = strdup(&kCdmaSID[0]); // SID
1275 responseStr[2] = strdup(&kCdmaNID[0]); // NID
1276 responseStr[3] = strdup(&kCdmaMobileDeviceNumber[0]); // MIN
1277 responseStr[4] = strdup("1"); // PRL Version
1278 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, responseStr,
1279 sizeof(responseStr));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001280}
1281
1282static const int gMaxConcurrentVoiceCalls = 4;
1283static const int gMaxConcurrentDataCalls = 4;
1284static const int gMaxConcurrentStandbyConnections = 4;
1285
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001286#if VSOC_PLATFORM_SDK_AFTER(K)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001287static void request_hardware_config(RIL_Token t) {
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001288 RIL_HardwareConfig hw_cfg[2];
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001289
1290 ALOGV("Requesting hardware configuration.");
1291
Greg Hartman153b1062017-11-11 12:09:21 -08001292 strncpy(hw_cfg[0].uuid, "com.google.cvdgce1.modem", sizeof(hw_cfg[0].uuid));
1293 strncpy(hw_cfg[1].uuid, "com.google.cvdgce1.sim", sizeof(hw_cfg[1].uuid));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001294
1295 int technologies = 0; // = unknown.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001296 std::map<RIL_PreferredNetworkType, int>::iterator iter =
1297 gModemTechnologies.find(gModemDefaultType);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001298 if (iter != gModemTechnologies.end()) {
1299 technologies = iter->second;
1300 }
1301
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001302 hw_cfg[0].type = RIL_HARDWARE_CONFIG_MODEM;
1303 hw_cfg[0].state = RIL_HARDWARE_CONFIG_STATE_ENABLED;
1304 hw_cfg[0].cfg.modem.rilModel = 0;
1305 hw_cfg[0].cfg.modem.rat = technologies;
1306 hw_cfg[0].cfg.modem.maxVoice = gMaxConcurrentVoiceCalls;
1307 hw_cfg[0].cfg.modem.maxData = gMaxConcurrentDataCalls;
1308 hw_cfg[0].cfg.modem.maxStandby = gMaxConcurrentStandbyConnections;
1309
1310 hw_cfg[1].type = RIL_HARDWARE_CONFIG_SIM;
1311 hw_cfg[1].state = RIL_HARDWARE_CONFIG_STATE_ENABLED;
1312 memcpy(hw_cfg[1].cfg.sim.modemUuid, hw_cfg[0].uuid,
1313 sizeof(hw_cfg[1].cfg.sim.modemUuid));
1314
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001315 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &hw_cfg, sizeof(hw_cfg));
1316}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001317#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001318
1319// 0 = Home network only, 1 = preferred networks only, 2 = all networks.
1320static int gCdmaRoamingPreference = 2;
1321
Greg Hartman85c495f2017-10-26 23:52:37 -07001322static void request_cdma_get_roaming_preference(int /*request*/, void* /*data*/,
1323 size_t /*datalen*/,
1324 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001325 if (!isCDMA()) {
1326 // No such radio.
1327 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1328 return;
1329 }
1330
1331 ALOGV("Requesting CDMA Roaming preference");
1332
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001333 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gCdmaRoamingPreference,
1334 sizeof(gCdmaRoamingPreference));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001335}
1336
Greg Hartman85c495f2017-10-26 23:52:37 -07001337static void request_cdma_set_roaming_preference(int /*request*/, void* data,
1338 size_t /*datalen*/,
1339 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001340 if (!isCDMA()) {
1341 // No such radio.
1342 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1343 return;
1344 }
1345
1346 int pref = *(int*)data;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001347 ALOGV("Changing CDMA roaming preference: %d -> %d", gCdmaRoamingPreference,
1348 pref);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001349
1350 if ((pref < 0) || (pref > 2)) {
1351 ALOGV("Unsupported roaming preference: %d", pref);
1352 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1353 return;
1354 }
1355
1356 gCdmaRoamingPreference = pref;
1357 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1358}
1359
Greg Hartman85c495f2017-10-26 23:52:37 -07001360static void request_send_ussd(void* /*data*/, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001361 ALOGV("Sending USSD code is currently not supported");
1362 // TODO(ender): support this feature
1363 gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
1364}
1365
1366static void request_cancel_ussd(RIL_Token t) {
1367 ALOGV("Cancelling USSD code is currently not supported");
1368 // TODO(ender): support this feature
1369 gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
1370}
1371
Greg Hartman85c495f2017-10-26 23:52:37 -07001372static void request_exit_emergency_mode(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001373 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001374 ALOGV("Exiting emergency callback mode.");
1375
1376 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1377}
1378
1379static RIL_RadioState gce_ril_current_state() {
1380 ALOGV("Reporting radio state %d", gRadioPowerState);
1381 return gRadioPowerState;
1382}
1383
1384static int gce_ril_on_supports(int requestCode) {
1385 ALOGE("%s: Request code %d not implemented", __FUNCTION__, requestCode);
1386 return 1;
1387}
1388
Greg Hartman85c495f2017-10-26 23:52:37 -07001389static void gce_ril_on_cancel(RIL_Token /*t*/) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001390 ALOGE("Cancel operation not implemented");
1391}
1392
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001393static const char* gce_ril_get_version(void) {
Greg Hartman7c01b7c2018-01-10 18:30:22 -08001394 ALOGV("Reporting VSOC version " VSOC_RIL_VERSION_STRING);
1395 return VSOC_RIL_VERSION_STRING;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001396}
1397
1398static int s_cell_info_rate_ms = INT_MAX;
1399static int s_mcc = 0;
1400static int s_mnc = 0;
1401static int s_lac = 0;
1402static int s_cid = 0;
1403
1404std::vector<RIL_NeighboringCell> gGSMNeighboringCells;
1405
Greg Hartman85c495f2017-10-26 23:52:37 -07001406static void request_get_neighboring_cell_ids(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001407 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001408 ALOGV("Requesting GSM neighboring cell ids");
1409
1410 if (!isGSM() || gGSMNeighboringCells.empty()) {
1411 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1412 return;
1413 }
1414
1415 RIL_NeighboringCell** cells =
1416 new RIL_NeighboringCell*[gGSMNeighboringCells.size()];
1417
1418 for (size_t index = 0; index < gGSMNeighboringCells.size(); ++index) {
1419 cells[index] = &gGSMNeighboringCells[index];
1420 }
1421
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001422 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, cells,
1423 sizeof(RIL_NeighboringCell*));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001424 delete[] cells;
1425}
1426
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001427#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
Greg Hartman85c495f2017-10-26 23:52:37 -07001428static void request_get_cell_info_list(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001429 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001430 struct timespec now;
1431 uint64_t curTime;
1432
1433 ALOGV("Requesting Cell Info List");
1434
1435 clock_gettime(CLOCK_MONOTONIC, &now);
1436 curTime = now.tv_sec * 1000000000LL + now.tv_nsec;
1437
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001438#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001439 RIL_CellInfo_v12 ci;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001440#else
1441 RIL_CellInfo ci;
1442#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001443
1444 if (isGSM()) {
1445 ci.cellInfoType = RIL_CELL_INFO_TYPE_GSM;
1446 ci.registered = 1;
1447 ci.timeStampType = RIL_TIMESTAMP_TYPE_ANTENNA; // Our own timestamp.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001448 ci.timeStamp = curTime - 1000; // Fake time in the past.
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001449 ci.CellInfo.gsm.cellIdentityGsm.mcc = s_mcc;
1450 ci.CellInfo.gsm.cellIdentityGsm.mnc = s_mnc;
1451 ci.CellInfo.gsm.cellIdentityGsm.lac = s_lac;
1452 ci.CellInfo.gsm.cellIdentityGsm.cid = s_cid;
1453 ci.CellInfo.gsm.signalStrengthGsm.signalStrength = 10;
1454 ci.CellInfo.gsm.signalStrengthGsm.bitErrorRate = 0;
1455
1456 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &ci, sizeof(ci));
1457 } else if (isCDMA()) {
1458 // TODO(ender): CDMA cell support. And LTE.
1459 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1460 } else {
1461 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1462 }
1463}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001464#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001465
1466struct NetworkOperator {
1467 std::string long_name;
1468 std::string short_name;
1469 bool is_accessible;
1470
1471 NetworkOperator() {}
1472
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001473 NetworkOperator(const std::string& long_name, const std::string& short_name,
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001474 bool is_accessible)
1475 : long_name(long_name),
1476 short_name(short_name),
1477 is_accessible(is_accessible) {}
1478};
1479
1480static std::map<std::string, NetworkOperator> gNetworkOperators;
1481static std::string gCurrentNetworkOperator = "";
1482
1483enum OperatorSelectionMethod {
1484 kOperatorAutomatic = 0,
1485 kOperatorManual = 1,
1486 kOperatorDeregistered = 2,
1487 kOperatorManualThenAutomatic = 4
1488};
1489
1490static void init_virtual_network() {
1491 gGSMNeighboringCells.resize(1);
1492 gGSMNeighboringCells[0].cid = (char*)"0000";
1493 gGSMNeighboringCells[0].rssi = 75;
1494 gNetworkOperators["310260"] =
1495 NetworkOperator("Android Virtual Operator", "Android", true);
1496 gNetworkOperators["310300"] =
1497 NetworkOperator("Alternative Operator", "Alternative", true);
1498 gNetworkOperators["310400"] =
1499 NetworkOperator("Hermetic Network Operator", "Hermetic", false);
1500}
1501
1502static OperatorSelectionMethod gOperatorSelectionMethod = kOperatorDeregistered;
1503
Greg Hartman85c495f2017-10-26 23:52:37 -07001504static void request_query_network_selection_mode(void* /*data*/,
1505 size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001506 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001507 ALOGV("Query operator selection mode (%d)", gOperatorSelectionMethod);
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001508 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gOperatorSelectionMethod,
1509 sizeof(gOperatorSelectionMethod));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001510}
1511
Greg Hartman85c495f2017-10-26 23:52:37 -07001512static void request_operator(void* /*data*/, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001513 std::map<std::string, NetworkOperator>::iterator iter =
1514 gNetworkOperators.find(gCurrentNetworkOperator);
1515
1516 ALOGV("Requesting current operator info");
1517
1518 if (iter == gNetworkOperators.end()) {
1519 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
1520 return;
1521 }
1522
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001523 const char* response[] = {iter->second.long_name.c_str(),
1524 iter->second.short_name.c_str(),
1525 iter->first.c_str()};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001526
1527 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
1528}
1529
Greg Hartman85c495f2017-10-26 23:52:37 -07001530static void request_query_available_networks(void* /*data*/, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001531 RIL_Token t) {
1532 const char** available_networks =
1533 new const char*[gNetworkOperators.size() * 4];
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001534
1535 ALOGV("Querying available networks.");
1536
1537 // TODO(ender): this should only respond once operator is selected and
1538 // registered.
1539 int index = 0;
1540 for (std::map<std::string, NetworkOperator>::iterator iter =
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001541 gNetworkOperators.begin();
1542 iter != gNetworkOperators.end(); ++iter) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001543 // TODO(ender): wrap in a neat structure maybe?
1544 available_networks[index++] = iter->second.long_name.c_str();
1545 available_networks[index++] = iter->second.short_name.c_str();
1546 available_networks[index++] = iter->first.c_str();
1547 if (!iter->second.is_accessible) {
1548 available_networks[index++] = "forbidden";
1549 } else if (iter->first == gCurrentNetworkOperator) {
1550 available_networks[index++] = "current";
1551 } else {
1552 available_networks[index++] = "available";
1553 }
1554 }
1555
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001556 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &available_networks,
1557 4 * gNetworkOperators.size());
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001558 delete[] available_networks;
1559}
1560
1561static void request_set_automatic_network_selection(RIL_Token t) {
1562 ALOGV("Requesting automatic operator selection");
1563 gCurrentNetworkOperator = gNetworkOperators.begin()->first;
1564 gOperatorSelectionMethod = kOperatorAutomatic;
1565 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1566}
1567
Greg Hartman85c495f2017-10-26 23:52:37 -07001568static void request_set_manual_network_selection(void* data, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001569 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001570 char* mccmnc = (char*)data;
1571
1572 ALOGV("Requesting manual operator selection: %s", mccmnc);
1573
1574 std::map<std::string, NetworkOperator>::iterator iter =
1575 gNetworkOperators.find(mccmnc);
1576
1577 if (iter == gNetworkOperators.end() || iter->second.is_accessible) {
1578 gce_ril_env->OnRequestComplete(t, RIL_E_ILLEGAL_SIM_OR_ME, NULL, 0);
1579 return;
1580 }
1581
1582 gCurrentNetworkOperator = mccmnc;
1583 gOperatorSelectionMethod = kOperatorManual;
1584
1585 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1586}
1587
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001588static const char kDefaultSMSC[] = "00";
1589static int gNextSmsMessageId = 1;
1590
Greg Hartman85c495f2017-10-26 23:52:37 -07001591static void request_cdma_send_SMS(void* /*data*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001592 RIL_SMS_Response response = {0, 0, 0};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001593 // RIL_CDMA_SMS_Message* rcsm = (RIL_CDMA_SMS_Message*) data;
1594
1595 ALOGW("CDMA SMS Send is currently not implemented.");
1596
1597 // Cdma Send SMS implementation will go here:
1598 // But it is not implemented yet.
1599 memset(&response, 0, sizeof(response));
1600 response.messageRef = -1; // This must be BearerData MessageId.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001601 gce_ril_env->OnRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response,
1602 sizeof(response));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001603}
1604
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001605static void request_send_SMS(void* data, RIL_Token t) {
1606 RIL_SMS_Response response = {0, 0, 0};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001607
1608 ALOGV("Send GSM SMS Message");
1609
1610 // SMSC is an address of SMS center or NULL for default.
1611 const char* smsc = ((const char**)data)[0];
1612 if (smsc == NULL) smsc = &kDefaultSMSC[0];
1613
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001614 response.messageRef = gNextSmsMessageId++;
1615 response.ackPDU = NULL;
1616 response.errorCode = 0;
1617
1618 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
1619
1620 // response.messageRef = -1;
1621 // gce_ril_env->OnRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response,
1622 // sizeof(response));
1623}
1624
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001625#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
Greg Hartman85c495f2017-10-26 23:52:37 -07001626static void request_set_cell_info_list_rate(void* data, size_t /*datalen*/,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001627 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001628 // For now we'll save the rate but no RIL_UNSOL_CELL_INFO_LIST messages
1629 // will be sent.
1630 ALOGV("Setting cell info list rate.");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001631 s_cell_info_rate_ms = ((int*)data)[0];
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001632 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1633}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001634#endif
1635#if VSOC_PLATFORM_SDK_AFTER(J_MR2)
Greg Hartman85c495f2017-10-26 23:52:37 -07001636static void request_ims_send_SMS(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001637 RIL_IMS_SMS_Message* args = (RIL_IMS_SMS_Message*)data;
Greg Hartman85c495f2017-10-26 23:52:37 -07001638 RIL_SMS_Response response{};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001639
1640 ALOGV("Send IMS SMS Message");
1641
1642 switch (args->tech) {
1643 case RADIO_TECH_3GPP:
1644 return request_send_SMS(args->message.gsmMessage, t);
1645
1646 case RADIO_TECH_3GPP2:
1647 return request_cdma_send_SMS(args->message.gsmMessage, t);
1648
1649 default:
1650 ALOGE("Invalid SMS format value: %d", args->tech);
1651 response.messageRef = -2;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001652 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, &response,
1653 sizeof(response));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001654 }
1655}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001656#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001657
Greg Hartman85c495f2017-10-26 23:52:37 -07001658static void request_SMS_acknowledge(void* data, size_t /*datalen*/,
1659 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001660 int* ack = (int*)data;
1661
1662 // TODO(ender): we should retain "incoming" sms for later reception.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001663 ALOGV("SMS receipt %ssuccessful (reason %d).", ack[0] ? "" : "un", ack[1]);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001664
1665 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
1666}
1667
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001668struct SimFileCommand {
1669 uint8_t command;
1670 uint16_t efid;
1671 uint8_t param1;
1672 uint8_t param2;
1673 uint8_t param3;
1674
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001675 bool operator<(const SimFileCommand& other) const {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001676 uint64_t sum1, sum2;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001677 sum1 = (command * 1ull << 40) | (efid * 1ull << 24) | (param1 << 16) |
1678 (param2 << 8) | (param3);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001679 sum2 = (other.command * 1ull << 40) | (other.efid * 1ull << 24) |
1680 (other.param1 << 16) | (other.param2 << 8) | (other.param3);
1681 return sum1 < sum2;
1682 }
1683
1684 SimFileCommand(uint8_t cmd, uint16_t efid, uint8_t p1, uint8_t p2, uint8_t p3)
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001685 : command(cmd), efid(efid), param1(p1), param2(p2), param3(p3) {}
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001686};
1687
1688struct SimFileResponse {
1689 uint8_t sw1;
1690 uint8_t sw2;
1691 const char* data;
1692
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001693 SimFileResponse() : sw1(0), sw2(0), data(NULL) {}
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001694
1695 SimFileResponse(uint8_t sw1, uint8_t sw2, const char* data)
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001696 : sw1(sw1), sw2(sw2), data(data) {}
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001697};
1698
1699// TODO(ender): Double check & rewrite these.
1700std::map<SimFileCommand, SimFileResponse> gSimFileSystem;
1701
1702static void init_sim_file_system() {
1703 gSimFileSystem[SimFileCommand(192, 28436, 0, 0, 15)] =
1704 SimFileResponse(144, 0, "000000146f1404001aa0aa01020000");
1705 gSimFileSystem[SimFileCommand(176, 28436, 0, 0, 20)] =
1706 SimFileResponse(144, 0, "416e64726f6964ffffffffffffffffffffffffff");
1707 gSimFileSystem[SimFileCommand(192, 28433, 0, 0, 15)] =
1708 SimFileResponse(144, 0, "000000016f11040011a0aa01020000");
1709 gSimFileSystem[SimFileCommand(176, 28433, 0, 0, 1)] =
1710 SimFileResponse(144, 0, "55");
1711 gSimFileSystem[SimFileCommand(192, 12258, 0, 0, 15)] =
1712 SimFileResponse(144, 0, "0000000a2fe204000fa0aa01020000");
1713 gSimFileSystem[SimFileCommand(176, 12258, 0, 0, 10)] =
1714 SimFileResponse(144, 0, "98101430121181157002");
1715 gSimFileSystem[SimFileCommand(192, 28435, 0, 0, 15)] =
1716 SimFileResponse(144, 0, "000000016f13040011a0aa01020000");
1717 gSimFileSystem[SimFileCommand(176, 28435, 0, 0, 1)] =
1718 SimFileResponse(144, 0, "55");
1719 gSimFileSystem[SimFileCommand(192, 28472, 0, 0, 15)] =
1720 SimFileResponse(144, 0, "0000000f6f3804001aa0aa01020000");
1721 gSimFileSystem[SimFileCommand(176, 28472, 0, 0, 15)] =
1722 SimFileResponse(144, 0, "ff30ffff3c003c03000c0000f03f00");
1723 gSimFileSystem[SimFileCommand(192, 28617, 0, 0, 15)] =
1724 SimFileResponse(144, 0, "000000086fc9040011a0aa01020104");
1725 gSimFileSystem[SimFileCommand(178, 28617, 1, 4, 4)] =
1726 SimFileResponse(144, 0, "01000000");
1727 gSimFileSystem[SimFileCommand(192, 28618, 0, 0, 15)] =
1728 SimFileResponse(144, 0, "0000000a6fca040011a0aa01020105");
1729 gSimFileSystem[SimFileCommand(178, 28618, 1, 4, 5)] =
1730 SimFileResponse(144, 0, "0000000000");
1731 gSimFileSystem[SimFileCommand(192, 28589, 0, 0, 15)] =
1732 SimFileResponse(144, 0, "000000046fad04000aa0aa01020000");
1733 gSimFileSystem[SimFileCommand(176, 28589, 0, 0, 4)] =
1734 SimFileResponse(144, 0, "00000003");
1735 gSimFileSystem[SimFileCommand(192, 28438, 0, 0, 15)] =
1736 SimFileResponse(144, 0, "000000026f1604001aa0aa01020000");
1737 gSimFileSystem[SimFileCommand(176, 28438, 0, 0, 2)] =
1738 SimFileResponse(144, 0, "0233");
1739 gSimFileSystem[SimFileCommand(192, 28486, 0, 0, 15)] =
1740 SimFileResponse(148, 4, NULL);
1741 gSimFileSystem[SimFileCommand(192, 28621, 0, 0, 15)] =
1742 SimFileResponse(148, 4, NULL);
1743 gSimFileSystem[SimFileCommand(192, 28613, 0, 0, 15)] =
1744 SimFileResponse(144, 0, "000000f06fc504000aa0aa01020118");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001745 gSimFileSystem[SimFileCommand(178, 28613, 1, 4, 24)] = SimFileResponse(
1746 144, 0, "43058441aa890affffffffffffffffffffffffffffffffff");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001747 gSimFileSystem[SimFileCommand(192, 28480, 0, 0, 15)] =
1748 SimFileResponse(144, 0, "000000806f40040011a0aa01020120");
1749 // Primary phone number encapsulated
1750 // [51][55][21][43][65][f7] = 1 555 1234 567$
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001751 gSimFileSystem[SimFileCommand(178, 28480, 1, 4, 32)] = SimFileResponse(
1752 144, 0,
1753 "ffffffffffffffffffffffffffffffffffff07915155214365f7ffffffffffff");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001754 gSimFileSystem[SimFileCommand(192, 28615, 0, 0, 15)] =
1755 SimFileResponse(144, 0, "000000406fc7040011a0aa01020120");
1756 // Voice mail number encapsulated
1757 // [56][6f][69][63][65][6d][61][69][6c] = 'Voicemail'
1758 // [51][55][67][45][23][f1] = 1 555 7654 321$
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001759 gSimFileSystem[SimFileCommand(178, 28615, 1, 4, 32)] = SimFileResponse(
1760 144, 0,
1761 "566f6963656d61696cffffffffffffffffff07915155674523f1ffffffffffff");
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001762 gSimFileSystem[SimFileCommand(192, 12037, 0, 0, 15)] =
1763 SimFileResponse(148, 4, NULL);
1764 gSimFileSystem[SimFileCommand(192, 28437, 0, 0, 15)] =
1765 SimFileResponse(148, 4, NULL);
1766 gSimFileSystem[SimFileCommand(192, 28478, 0, 0, 15)] =
1767 SimFileResponse(148, 4, NULL);
1768 gSimFileSystem[SimFileCommand(192, 28450, 0, 0, 15)] =
1769 SimFileResponse(148, 4, NULL);
1770 gSimFileSystem[SimFileCommand(192, 28456, 0, 0, 15)] =
1771 SimFileResponse(148, 4, NULL);
1772 gSimFileSystem[SimFileCommand(192, 28474, 0, 0, 15)] =
1773 SimFileResponse(148, 4, NULL);
1774 gSimFileSystem[SimFileCommand(192, 28481, 0, 0, 15)] =
1775 SimFileResponse(148, 4, NULL);
1776 gSimFileSystem[SimFileCommand(192, 28484, 0, 0, 15)] =
1777 SimFileResponse(148, 4, NULL);
1778 gSimFileSystem[SimFileCommand(192, 28493, 0, 0, 15)] =
1779 SimFileResponse(148, 4, NULL);
1780 gSimFileSystem[SimFileCommand(192, 28619, 0, 0, 15)] =
1781 SimFileResponse(148, 4, NULL);
1782 gSimFileSystem[SimFileCommand(176, 28506, 0, 0, 4)] =
1783 SimFileResponse(144, 0, "00000013");
1784}
1785
Greg Hartman85c495f2017-10-26 23:52:37 -07001786static void request_SIM_IO(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001787 const RIL_SIM_IO_v6& args = *(RIL_SIM_IO_v6*)data;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001788 RIL_SIM_IO_Response sr = {0, 0, 0};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001789
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001790 ALOGV(
1791 "Requesting SIM File IO: %d EFID %x, Params: %d, %d, %d, path: %s, "
1792 "data %s PIN: %s AID: %s",
1793 args.command, args.fileid, args.p1, args.p2, args.p3, args.path,
1794 args.data, args.pin2, args.aidPtr);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001795
1796 SimFileCommand cmd(args.command, args.fileid, args.p1, args.p2, args.p3);
1797
1798 std::map<SimFileCommand, SimFileResponse>::iterator resp =
1799 gSimFileSystem.find(cmd);
1800
1801 if (resp != gSimFileSystem.end()) {
1802 sr.sw1 = resp->second.sw1;
1803 sr.sw2 = resp->second.sw2;
1804 if (resp->second.data) sr.simResponse = strdup(resp->second.data);
1805 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
1806 return;
1807 }
1808
1809 ALOGW("Unsupported SIM File IO command.");
1810 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1811}
1812
Greg Hartman85c495f2017-10-26 23:52:37 -07001813static void request_enter_sim_pin(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001814 const char** pin_aid = (const char**)data;
1815
1816 ALOGV("Entering PIN: %s / %s", pin_aid[0], pin_aid[1]);
1817
1818 ++gSimPINAttempts;
1819 int remaining_attempts = gSimPINAttemptsMax - gSimPINAttempts;
1820
1821 bool is_valid = false;
1822
1823 if (gSimStatus == SIM_PIN) {
1824 is_valid = (gSimPIN == pin_aid[0]);
1825 } else if (gSimStatus == SIM_PUK) {
1826 is_valid = (gSimPUK == pin_aid[0]);
1827 } else {
1828 ALOGV("Unexpected SIM status for unlock: %d", gSimStatus);
1829 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
1830 return;
1831 }
1832
1833 if (!is_valid) {
1834 if (gSimPINAttempts == gSimPINAttemptsMax) {
1835 if (gSimStatus == SIM_PIN) {
1836 gSimStatus = SIM_PUK;
1837 gSimPINAttempts = 0;
1838 } else {
1839 ALOGV("PIN and PUK verification failed; locking SIM card.");
1840 gSimStatus = SIM_NOT_READY;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001841 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001842 return;
1843 }
1844 }
1845
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001846 gce_ril_env->OnRequestComplete(t, RIL_E_PASSWORD_INCORRECT,
1847 &remaining_attempts,
1848 sizeof(remaining_attempts));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001849 } else {
1850 if (gSimStatus == SIM_PUK) {
1851 ALOGV("Resetting SIM PIN to %s", pin_aid[1]);
1852 gSimPIN = pin_aid[1];
1853 }
1854
1855 gSimPINAttempts = 0;
1856 gSimStatus = SIM_READY;
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001857 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &remaining_attempts,
1858 sizeof(remaining_attempts));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001859 }
1860
1861 pollSIMState(NULL);
1862}
1863
1864/**
1865 * No longer POLL.
1866 */
Greg Hartman85c495f2017-10-26 23:52:37 -07001867static void pollSIMState(void* /*param*/) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001868 // TODO(ender): check radio state?
1869
1870 ALOGV("Polling SIM Status.");
1871
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001872 switch (gSimStatus) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001873 case SIM_ABSENT:
1874 case SIM_PIN:
1875 case SIM_PUK:
1876 case SIM_NETWORK_PERSONALIZATION:
1877 default:
1878 ALOGV("SIM Absent or Locked");
Tomasz Wiszkowski31d3a3b2017-09-20 11:06:02 -07001879 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001880
1881 case SIM_NOT_READY:
1882 // Transition directly to READY. Set default network operator.
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -07001883 if (gRadioPowerState == RADIO_STATE_ON) {
1884 gSimStatus = SIM_READY;
Tomasz Wiszkowski31d3a3b2017-09-20 11:06:02 -07001885 gCurrentNetworkOperator = "310260";
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -07001886 }
1887
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001888 gce_ril_env->RequestTimedCallback(pollSIMState, NULL, &TIMEVAL_SIMPOLL);
Tomasz Wiszkowski31d3a3b2017-09-20 11:06:02 -07001889 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001890
1891 case SIM_READY:
1892 ALOGV("SIM Ready. Notifying network state changed.");
Tomasz Wiszkowski31d3a3b2017-09-20 11:06:02 -07001893 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001894 }
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001895
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07001896 if (gRadioPowerState != RADIO_STATE_OFF) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001897 gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
1898 NULL, 0);
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001899 gce_ril_env->OnUnsolicitedResponse(
Tomasz Wiszkowski73b7c0d2017-10-16 11:31:19 -07001900 RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0);
1901 }
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001902}
1903
1904std::map<SIM_Status, RIL_AppStatus> gRilAppStatus;
1905
1906static void init_sim_status() {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001907 gRilAppStatus[SIM_ABSENT] = (RIL_AppStatus){RIL_APPTYPE_UNKNOWN,
1908 RIL_APPSTATE_UNKNOWN,
1909 RIL_PERSOSUBSTATE_UNKNOWN,
1910 NULL,
1911 NULL,
1912 0,
1913 RIL_PINSTATE_UNKNOWN,
1914 RIL_PINSTATE_UNKNOWN};
1915 gRilAppStatus[SIM_NOT_READY] =
1916 (RIL_AppStatus){RIL_APPTYPE_SIM,
1917 RIL_APPSTATE_DETECTED,
1918 RIL_PERSOSUBSTATE_UNKNOWN,
1919 NULL,
1920 NULL,
1921 0,
1922 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
1923 RIL_PINSTATE_ENABLED_NOT_VERIFIED};
1924 gRilAppStatus[SIM_READY] = (RIL_AppStatus){
1925 RIL_APPTYPE_SIM,
1926 RIL_APPSTATE_READY,
1927 RIL_PERSOSUBSTATE_READY,
1928 NULL,
1929 NULL,
1930 0,
1931 RIL_PINSTATE_ENABLED_VERIFIED,
1932 RIL_PINSTATE_ENABLED_VERIFIED,
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07001933 };
Greg Hartman8d9b76e2017-10-26 23:23:40 -07001934 gRilAppStatus[SIM_PIN] = (RIL_AppStatus){RIL_APPTYPE_SIM,
1935 RIL_APPSTATE_PIN,
1936 RIL_PERSOSUBSTATE_UNKNOWN,
1937 NULL,
1938 NULL,
1939 0,
1940 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
1941 RIL_PINSTATE_UNKNOWN};
1942 gRilAppStatus[SIM_PUK] = (RIL_AppStatus){RIL_APPTYPE_SIM,
1943 RIL_APPSTATE_PUK,
1944 RIL_PERSOSUBSTATE_UNKNOWN,
1945 NULL,
1946 NULL,
1947 0,
1948 RIL_PINSTATE_ENABLED_BLOCKED,
1949 RIL_PINSTATE_UNKNOWN};
1950 gRilAppStatus[SIM_NETWORK_PERSONALIZATION] =
1951 (RIL_AppStatus){RIL_APPTYPE_SIM,
1952 RIL_APPSTATE_SUBSCRIPTION_PERSO,
1953 RIL_PERSOSUBSTATE_SIM_NETWORK,
1954 NULL,
1955 NULL,
1956 0,
1957 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
1958 RIL_PINSTATE_UNKNOWN};
1959 gRilAppStatus[RUIM_ABSENT] = (RIL_AppStatus){RIL_APPTYPE_UNKNOWN,
1960 RIL_APPSTATE_UNKNOWN,
1961 RIL_PERSOSUBSTATE_UNKNOWN,
1962 NULL,
1963 NULL,
1964 0,
1965 RIL_PINSTATE_UNKNOWN,
1966 RIL_PINSTATE_UNKNOWN};
1967 gRilAppStatus[RUIM_NOT_READY] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
1968 RIL_APPSTATE_DETECTED,
1969 RIL_PERSOSUBSTATE_UNKNOWN,
1970 NULL,
1971 NULL,
1972 0,
1973 RIL_PINSTATE_UNKNOWN,
1974 RIL_PINSTATE_UNKNOWN};
1975 gRilAppStatus[RUIM_READY] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
1976 RIL_APPSTATE_READY,
1977 RIL_PERSOSUBSTATE_READY,
1978 NULL,
1979 NULL,
1980 0,
1981 RIL_PINSTATE_UNKNOWN,
1982 RIL_PINSTATE_UNKNOWN};
1983 gRilAppStatus[RUIM_PIN] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
1984 RIL_APPSTATE_PIN,
1985 RIL_PERSOSUBSTATE_UNKNOWN,
1986 NULL,
1987 NULL,
1988 0,
1989 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
1990 RIL_PINSTATE_UNKNOWN};
1991 gRilAppStatus[RUIM_PUK] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
1992 RIL_APPSTATE_PUK,
1993 RIL_PERSOSUBSTATE_UNKNOWN,
1994 NULL,
1995 NULL,
1996 0,
1997 RIL_PINSTATE_ENABLED_BLOCKED,
1998 RIL_PINSTATE_UNKNOWN};
1999 gRilAppStatus[RUIM_NETWORK_PERSONALIZATION] =
2000 (RIL_AppStatus){RIL_APPTYPE_RUIM,
2001 RIL_APPSTATE_SUBSCRIPTION_PERSO,
2002 RIL_PERSOSUBSTATE_SIM_NETWORK,
2003 NULL,
2004 NULL,
2005 0,
2006 RIL_PINSTATE_ENABLED_NOT_VERIFIED,
2007 RIL_PINSTATE_UNKNOWN};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002008}
2009
2010/**
2011 * Get the current card status.
2012 */
2013static void getCardStatus(RIL_Token t) {
2014 ALOGV("Querying SIM status.");
2015 RIL_CardStatus_v6 card_status;
2016
2017 if (gSimStatus == SIM_ABSENT) {
2018 card_status.card_state = RIL_CARDSTATE_ABSENT;
2019 card_status.num_applications = 0;
2020 } else {
2021 card_status.card_state = RIL_CARDSTATE_PRESENT;
2022 card_status.num_applications = 1;
2023 }
2024
2025 card_status.universal_pin_state = RIL_PINSTATE_UNKNOWN;
2026 card_status.gsm_umts_subscription_app_index = -1;
2027 card_status.cdma_subscription_app_index = -1;
2028 card_status.ims_subscription_app_index = -1;
2029
2030 // Initialize application status
2031 for (int i = 0; i < RIL_CARD_MAX_APPS; i++) {
2032 card_status.applications[i] = gRilAppStatus[SIM_ABSENT];
2033 }
2034
2035 if (card_status.num_applications > 0) {
2036 card_status.gsm_umts_subscription_app_index = 0;
2037
2038 card_status.applications[0] = gRilAppStatus[gSimStatus];
2039 card_status.universal_pin_state = card_status.applications[0].pin1;
2040 // To enable basic CDMA (currently neither supported nor functional):
2041 // card_status.num_applications = 2;
2042 // card_status.cdma_subscription_app_index = 1;
2043 // card_status.applications[1] =
2044 // gRilAppStatus[SIM_Status(gSimStatus + RUIM_ABSENT)];
2045 }
2046
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002047 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &card_status,
2048 sizeof(card_status));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002049}
2050
2051struct SimSession {
2052 std::string aid;
2053};
2054
2055static int gNextSimSessionId = 1;
2056static std::map<int, SimSession> gSimSessions;
2057
Greg Hartman85c495f2017-10-26 23:52:37 -07002058static void request_sim_open_channel(void* data, size_t /*datalen*/,
2059 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002060 char* aid = (char*)data;
2061 SimSession session;
2062
2063 ALOGV("Requesting new SIM session");
2064
2065 if (aid != NULL) {
2066 session.aid = aid;
2067 }
2068
2069 int response = gNextSimSessionId++;
2070 gSimSessions[response] = session;
2071
2072 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
2073}
2074
Greg Hartman85c495f2017-10-26 23:52:37 -07002075static void request_sim_close_channel(void* data, size_t /*datalen*/,
2076 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002077 int session = *(int*)(data);
2078
2079 ALOGV("Closing SIM session %d", session);
2080
2081 if (gSimSessions.erase(session) == 0) {
2082 // No such session.
2083 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2084 } else {
2085 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2086 }
2087}
2088
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002089#if VSOC_PLATFORM_SDK_AFTER(K)
Greg Hartman85c495f2017-10-26 23:52:37 -07002090static void request_sim_apdu(void* data, size_t /*datalen*/, RIL_Token t) {
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002091 RIL_SIM_APDU* apdu = (RIL_SIM_APDU*)data;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002092
2093 ALOGV("Requesting APDU: Session %d CLA %d INST %d Params: %d %d %d, data %s",
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002094 apdu->sessionid, apdu->cla, apdu->instruction, apdu->p1, apdu->p2,
2095 apdu->p3, apdu->data);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002096
2097 if (gSimSessions.find(apdu->sessionid) != gSimSessions.end()) {
Greg Hartman85c495f2017-10-26 23:52:37 -07002098 RIL_SIM_IO_Response sr{};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002099
2100 // Fallback / default behavior.
2101 sr.sw1 = 144;
2102 sr.sw2 = 0;
2103 sr.simResponse = NULL;
2104
2105 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
2106 } else {
2107 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2108 }
2109}
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002110#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002111
2112// 0 = Lock is available, but disabled.
2113// 1 = Lock is available and enabled,
2114// 2 = lock is neither available nor enabled
2115static const int kFacilityLockAllDisabled = 0;
2116
Greg Hartman85c495f2017-10-26 23:52:37 -07002117static void request_facility_lock(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002118 char** data_vec = (char**)data;
2119
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002120 // TODO(ender): implement this; essentially: AT+CLCK
2121 // See http://www.activexperts.com/sms-component/at/commands/?at=%2BCLCK
2122 // and
2123 // opt/telephony/src/java/com/android/internal/telephony/CommandsInterface.java
2124 // opt/telephony/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
2125
2126 ALOGV("Query Facility Lock Code: %s PIN2: %s Service(s): %s AID: %s",
2127 data_vec[0], data_vec[1], data_vec[2], data_vec[3]);
2128
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002129 // TODO(ender): there should be a bit vector of responses for each of the
2130 // services requested.
2131 // Depending on lock code, facilities may be unlocked or locked. We report
2132 // these are all unlocked, regardless of the query.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002133 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
2134 const_cast<int*>(&kFacilityLockAllDisabled),
2135 sizeof(kFacilityLockAllDisabled));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002136}
2137
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002138static void request_international_subscriber_id_number(RIL_Token t) {
2139 // TODO(ender): Reuse MCC and MNC.
2140 std::string subscriber_id = gCurrentNetworkOperator.c_str();
2141 subscriber_id += "123456789";
2142
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002143 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
2144 strdup(subscriber_id.c_str()), sizeof(char*));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002145}
2146
2147static bool gScreenIsOn = true;
2148
Greg Hartman85c495f2017-10-26 23:52:37 -07002149static void request_set_screen_state(void* data, size_t /*datalen*/,
2150 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002151 gScreenIsOn = *(int*)data ? true : false;
2152 ALOGV("Screen is %s", gScreenIsOn ? "on" : "off");
2153 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2154}
2155
2156// Unsure which section this belongs in.
2157
2158static int gModemTtyMode = 1; // 0 = off, 1 = full, 2 = HCO, 3 = VCO.
Greg Hartman85c495f2017-10-26 23:52:37 -07002159static void request_set_tty_mode(void* data, size_t /*datalen*/, RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002160 int new_tty_mode = *(int*)(data);
2161 ALOGV("Switching modem TTY mode %d -> %d", gModemTtyMode, new_tty_mode);
2162
2163 if (new_tty_mode >= 0 && new_tty_mode <= 3) {
2164 gModemTtyMode = new_tty_mode;
2165 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2166 } else {
2167 gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
2168 }
2169}
2170
2171static void request_get_tty_mode(RIL_Token t) {
2172 ALOGV("Querying TTY mode");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002173 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gModemTtyMode,
2174 sizeof(gModemTtyMode));
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002175}
2176
2177static bool gImsRegistered = false;
2178static int gImsFormat = RADIO_TECH_3GPP;
2179
2180static void request_ims_registration_state(RIL_Token t) {
2181 ALOGV("Querying IMS mode");
2182 int reply[2];
2183 reply[0] = gImsRegistered;
2184 reply[1] = gImsFormat;
2185
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002186 ALOGV("Requesting IMS Registration state: %d, format=%d ", reply[0],
2187 reply[1]);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002188
2189 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply));
2190}
2191
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002192static void gce_ril_on_request(int request, void* data, size_t datalen,
2193 RIL_Token t) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002194 // Ignore all requests except RIL_REQUEST_GET_SIM_STATUS
2195 // when RADIO_STATE_UNAVAILABLE.
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002196 if (gRadioPowerState == RADIO_STATE_UNAVAILABLE &&
2197 request != RIL_REQUEST_GET_SIM_STATUS) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002198 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2199 return;
2200 }
2201
2202 // Ignore all non-power requests when RADIO_STATE_OFF (except
2203 // RIL_REQUEST_GET_SIM_STATUS)
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002204 if (gRadioPowerState == RADIO_STATE_OFF &&
2205 !(request == RIL_REQUEST_RADIO_POWER ||
2206 request == RIL_REQUEST_GET_SIM_STATUS)) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002207 gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
2208 return;
2209 }
2210
2211 ALOGV("Received request %d", request);
2212
2213 switch (request) {
2214 case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS:
2215 request_query_available_networks(data, datalen, t);
2216 break;
2217 case RIL_REQUEST_GET_IMEI:
2218 request_get_imei(t);
2219 break;
2220 case RIL_REQUEST_GET_IMEISV:
2221 request_get_imei_sv(t);
2222 break;
2223 case RIL_REQUEST_DEACTIVATE_DATA_CALL:
2224 request_teardown_data_call(data, datalen, t);
2225 break;
2226 case RIL_REQUEST_SCREEN_STATE:
2227 request_set_screen_state(data, datalen, t);
2228 break;
2229 case RIL_REQUEST_GET_SIM_STATUS:
2230 getCardStatus(t);
2231 break;
2232 case RIL_REQUEST_GET_CURRENT_CALLS:
2233 request_get_current_calls(data, datalen, t);
2234 break;
2235 case RIL_REQUEST_DIAL:
2236 request_dial(data, datalen, t);
2237 break;
2238 case RIL_REQUEST_HANGUP:
2239 request_hangup(data, datalen, t);
2240 break;
2241 case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
2242 request_hangup_waiting(data, datalen, t);
2243 break;
2244 case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
2245 request_hangup_current(t);
2246 break;
2247 case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
2248 request_switch_current_and_waiting(t);
2249 break;
2250 case RIL_REQUEST_ANSWER:
2251 request_answer_incoming(t);
2252 break;
Tomasz Wiszkowski429d6022017-10-17 10:02:05 -07002253 case RIL_REQUEST_SET_MUTE:
2254 request_set_mute(data, datalen, t);
2255 break;
2256 case RIL_REQUEST_GET_MUTE:
2257 request_get_mute(t);
2258 break;
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002259 case RIL_REQUEST_CONFERENCE:
2260 request_combine_multiparty_call(data, datalen, t);
2261 break;
2262 case RIL_REQUEST_SEPARATE_CONNECTION:
2263 request_split_multiparty_call(data, datalen, t);
2264 break;
2265 case RIL_REQUEST_UDUB:
2266 request_udub_on_incoming_calls(t);
2267 break;
2268 case RIL_REQUEST_SIGNAL_STRENGTH:
2269 request_signal_strength(data, datalen, t);
2270 break;
2271 case RIL_REQUEST_VOICE_REGISTRATION_STATE:
2272 case RIL_REQUEST_DATA_REGISTRATION_STATE:
2273 request_registration_state(request, data, datalen, t);
2274 break;
2275 case RIL_REQUEST_OPERATOR:
2276 request_operator(data, datalen, t);
2277 break;
2278 case RIL_REQUEST_RADIO_POWER:
2279 request_radio_power(data, datalen, t);
2280 break;
2281 case RIL_REQUEST_DTMF:
2282 case RIL_REQUEST_DTMF_START:
2283 request_send_dtmf(data, datalen, t);
2284 break;
2285 case RIL_REQUEST_DTMF_STOP:
2286 request_send_dtmf_stop(t);
2287 break;
2288 case RIL_REQUEST_SEND_SMS:
2289 request_send_SMS(data, t);
2290 break;
2291 case RIL_REQUEST_CDMA_SEND_SMS:
2292 request_cdma_send_SMS(data, t);
2293 break;
2294 case RIL_REQUEST_SETUP_DATA_CALL:
2295 request_setup_data_call(data, datalen, t);
2296 break;
2297 case RIL_REQUEST_SMS_ACKNOWLEDGE:
2298 request_SMS_acknowledge(data, datalen, t);
2299 break;
2300 case RIL_REQUEST_GET_IMSI:
2301 request_international_subscriber_id_number(t);
2302 break;
2303 case RIL_REQUEST_QUERY_FACILITY_LOCK:
2304 request_facility_lock(data, datalen, t);
2305 break;
2306 case RIL_REQUEST_SIM_IO:
2307 request_SIM_IO(data, datalen, t);
2308 break;
2309 case RIL_REQUEST_SEND_USSD:
2310 request_send_ussd(data, datalen, t);
2311 break;
2312 case RIL_REQUEST_CANCEL_USSD:
2313 request_cancel_ussd(t);
2314 break;
2315 case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
2316 request_set_automatic_network_selection(t);
2317 break;
2318 case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
2319 request_set_manual_network_selection(data, datalen, t);
2320 break;
2321 case RIL_REQUEST_DATA_CALL_LIST:
2322 request_data_calllist(data, datalen, t);
2323 break;
2324 case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
2325 request_datacall_fail_cause(t);
2326 break;
2327 case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
2328 request_query_network_selection_mode(data, datalen, t);
2329 break;
2330 case RIL_REQUEST_OEM_HOOK_RAW:
2331 case RIL_REQUEST_OEM_HOOK_STRINGS:
2332 ALOGV("OEM Hooks not supported!");
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002333 gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002334 break;
2335 case RIL_REQUEST_WRITE_SMS_TO_SIM:
2336 request_write_sms_to_sim(data, datalen, t);
2337 break;
2338 case RIL_REQUEST_DELETE_SMS_ON_SIM:
2339 request_delete_sms_on_sim(data, datalen, t);
2340 break;
2341 case RIL_REQUEST_ENTER_SIM_PIN:
2342 case RIL_REQUEST_ENTER_SIM_PUK:
2343 case RIL_REQUEST_ENTER_SIM_PIN2:
2344 case RIL_REQUEST_ENTER_SIM_PUK2:
2345 case RIL_REQUEST_CHANGE_SIM_PIN:
2346 case RIL_REQUEST_CHANGE_SIM_PIN2:
2347 request_enter_sim_pin(data, datalen, t);
2348 break;
2349 case RIL_REQUEST_VOICE_RADIO_TECH: {
2350 RIL_RadioTechnology tech = getBestVoiceTechnology(gModemCurrentType);
2351 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &tech, sizeof(tech));
2352 break;
2353 }
2354 case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
2355 request_set_preferred_network_type(request, data, datalen, t);
2356 break;
2357 case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
2358 request_get_preferred_network_type(request, data, datalen, t);
2359 break;
2360 case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
2361 request_get_neighboring_cell_ids(data, datalen, t);
2362 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002363#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002364 case RIL_REQUEST_GET_CELL_INFO_LIST:
2365 request_get_cell_info_list(data, datalen, t);
2366 break;
2367 case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
2368 request_set_cell_info_list_rate(data, datalen, t);
2369 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002370#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002371 case RIL_REQUEST_BASEBAND_VERSION:
2372 request_baseband_version(t);
2373 break;
2374 case RIL_REQUEST_SET_TTY_MODE:
2375 request_set_tty_mode(data, datalen, t);
2376 break;
2377 case RIL_REQUEST_QUERY_TTY_MODE:
2378 request_get_tty_mode(t);
2379 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002380
2381#if VSOC_PLATFORM_SDK_AFTER(L)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002382 case RIL_REQUEST_GET_RADIO_CAPABILITY:
2383 request_get_radio_capability(t);
2384 break;
2385 case RIL_REQUEST_SET_RADIO_CAPABILITY:
2386 request_set_radio_capability(data, datalen, t);
2387 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002388#endif
2389#if VSOC_PLATFORM_SDK_AFTER(K)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002390 case RIL_REQUEST_GET_HARDWARE_CONFIG:
2391 request_hardware_config(t);
2392 break;
2393 case RIL_REQUEST_IMS_REGISTRATION_STATE:
2394 request_ims_registration_state(t);
2395 break;
2396 case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
2397 request_sim_apdu(data, datalen, t);
2398 break;
2399 case RIL_REQUEST_SIM_OPEN_CHANNEL:
2400 request_sim_open_channel(data, datalen, t);
2401 break;
2402 case RIL_REQUEST_SIM_CLOSE_CHANNEL:
2403 request_sim_close_channel(data, datalen, t);
2404 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002405#endif
2406#if VSOC_PLATFORM_SDK_AFTER(J_MR2)
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002407 case RIL_REQUEST_IMS_SEND_SMS:
2408 request_ims_send_SMS(data, datalen, t);
2409 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002410
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002411 case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
2412 ALOGW("INITIAL ATTACH APN");
2413 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2414 break;
Tomasz Wiszkowski27b5dad2017-10-17 09:41:17 -07002415
2416#endif
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002417 case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
2418 gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
2419 break;
2420 case RIL_REQUEST_DEVICE_IDENTITY:
2421 request_device_identity(request, data, datalen, t);
2422 break;
2423 case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
2424 request_cdma_get_subscription_source(request, data, datalen, t);
2425 break;
2426 case RIL_REQUEST_CDMA_SUBSCRIPTION:
2427 request_cdma_subscription(request, data, datalen, t);
2428 break;
2429 case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
2430 request_cdma_set_subscription_source(request, data, datalen, t);
2431 break;
2432 case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
2433 request_cdma_get_roaming_preference(request, data, datalen, t);
2434 break;
2435 case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
2436 request_cdma_set_roaming_preference(request, data, datalen, t);
2437 break;
2438 case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
2439 request_exit_emergency_mode(data, datalen, t);
2440 break;
2441 default:
2442 ALOGE("Request %d not supported.", request);
2443 gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
2444 break;
2445 }
2446}
2447
Greg Hartman7c01b7c2018-01-10 18:30:22 -08002448#define VSOC_RIL_VERSION 6
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002449
2450static const RIL_RadioFunctions ril_callbacks = {
Greg Hartman7c01b7c2018-01-10 18:30:22 -08002451 VSOC_RIL_VERSION, gce_ril_on_request, gce_ril_current_state,
Greg Hartman8d9b76e2017-10-26 23:23:40 -07002452 gce_ril_on_supports, gce_ril_on_cancel, gce_ril_get_version};
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002453
2454extern "C" {
2455
Greg Hartman85c495f2017-10-26 23:52:37 -07002456const RIL_RadioFunctions* RIL_Init(const struct RIL_Env* env, int /*argc*/,
2457 char** /*argv*/) {
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002458 time(&gce_ril_start_time);
2459 gce_ril_env = env;
2460
Tomasz Wiszkowskie5749d52017-09-18 14:58:55 -07002461 TearDownNetworkInterface();
Tomasz Wiszkowski686fe4f2017-09-11 13:32:13 -07002462
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002463 init_modem_supported_network_types();
2464 init_modem_technologies();
2465 init_virtual_network();
2466 init_sim_file_system();
2467 init_sim_status();
2468
Tomasz Wiszkowski29be5f72017-09-08 09:27:35 -07002469 return &ril_callbacks;
2470}
2471
2472} // extern "C"