/*
** Copyright 2017, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License ioogle/s distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#include "guest/hals/ril/cuttlefish_ril.h"

#include <cutils/properties.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>

#include <map>
#include <set>
#include <string>
#include <vector>

#include "common/libs/device_config/device_config.h"
#include "common/libs/net/netlink_client.h"
#include "common/libs/net/network_interface.h"
#include "common/libs/net/network_interface_manager.h"

#define CUTTLEFISH_RIL_VERSION_STRING "Android Cuttlefish RIL 1.4"

/* Modem Technology bits */
#define MDM_GSM 0x01
#define MDM_WCDMA 0x02
#define MDM_CDMA 0x04
#define MDM_EVDO 0x08
#define MDM_LTE 0x10

typedef enum {
  SIM_ABSENT = 0,
  SIM_NOT_READY = 1,
  SIM_READY = 2,  // SIM_READY means the radio state is RADIO_STATE_SIM_READY
  SIM_PIN = 3,
  SIM_PUK = 4,
  SIM_NETWORK_PERSONALIZATION = 5,
  RUIM_ABSENT = 6,
  RUIM_NOT_READY = 7,
  RUIM_READY = 8,
  RUIM_PIN = 9,
  RUIM_PUK = 10,
  RUIM_NETWORK_PERSONALIZATION = 11
} SIM_Status;

static std::unique_ptr<cvd::DeviceConfig> global_ril_config = nullptr;

static const struct RIL_Env* gce_ril_env;

static const struct timeval TIMEVAL_SIMPOLL = {3, 0};

static time_t gce_ril_start_time;

static void pollSIMState(void* param);

RIL_RadioState gRadioPowerState = RADIO_STATE_OFF;
RIL_RadioAccessFamily default_access = RAF_LTE;

struct DataCall {
  enum AllowedAuthenticationType { kNone = 0, kPap = 1, kChap = 2, kBoth = 3 };

  enum ConnectionType {
    kConnTypeIPv4,
    kConnTypeIPv6,
    kConnTypeIPv4v6,
    kConnTypePPP
  };

  enum LinkState {
    kLinkStateInactive = 0,
    kLinkStateDown = 1,
    kLinkStateUp = 2,
  };

  RIL_RadioTechnology technology_;
  RIL_DataProfile profile_;
  std::string access_point_;
  std::string username_;
  std::string password_;
  AllowedAuthenticationType auth_type_;
  ConnectionType connection_type_;
  LinkState link_state_;
  RIL_DataCallFailCause fail_cause_;
  std::string other_properties_;
};

static std::string gSimPIN = "0000";
static const std::string gSimPUK = "11223344";
static int gSimPINAttempts = 0;
static const int gSimPINAttemptsMax = 3;
static SIM_Status gSimStatus = SIM_NOT_READY;
static bool areUiccApplicationsEnabled = true;

// SetUpNetworkInterface configures IP and Broadcast addresses on a RIL
// controlled network interface.
// This call returns true, if operation was successful.
bool SetUpNetworkInterface(const char* ipaddr, int prefixlen,
                           const char* bcaddr) {
  auto factory = cvd::NetlinkClientFactory::Default();
  std::unique_ptr<cvd::NetlinkClient> nl(factory->New(NETLINK_ROUTE));
  std::unique_ptr<cvd::NetworkInterfaceManager> nm(
      cvd::NetworkInterfaceManager::New(factory));
  std::unique_ptr<cvd::NetworkInterface> ni(nm->Open("rmnet0", "eth1"));

  if (ni) {
    ni->SetName("rmnet0");
    ni->SetAddress(ipaddr);
    ni->SetBroadcastAddress(bcaddr);
    ni->SetPrefixLength(prefixlen);
    ni->SetOperational(true);
    bool res = nm->ApplyChanges(*ni);
    if (!res) ALOGE("Could not configure rmnet0");
    return res;
  }
  return false;
}

// TearDownNetworkInterface disables network interface.
// This call returns true, if operation was successful.
bool TearDownNetworkInterface() {
  auto nm(cvd::NetworkInterfaceManager::New(nullptr));
  auto ni(nm->Open("rmnet0", "eth1"));

  if (ni) {
    ni->SetOperational(false);
    bool res = nm->ApplyChanges(*ni);
    if (!res) ALOGE("Could not disable rmnet0");
    return res;
  }
  return false;
}

static int gNextDataCallId = 8;
static std::map<int, DataCall> gDataCalls;
static bool gRilConnected = false;

static int request_or_send_data_calllist(RIL_Token* t) {
  RIL_Data_Call_Response_v11* responses =
      new RIL_Data_Call_Response_v11[gDataCalls.size()];

  int index = 0;

  ALOGV("Query data call list: %zu data calls tracked.", gDataCalls.size());

  for (std::map<int, DataCall>::iterator iter = gDataCalls.begin();
       iter != gDataCalls.end(); ++iter, ++index) {
    responses[index].status = iter->second.fail_cause_;
    responses[index].suggestedRetryTime = -1;
    responses[index].cid = iter->first;
    responses[index].active = iter->second.link_state_;

    switch (iter->second.connection_type_) {
      case DataCall::kConnTypeIPv4:
        responses[index].type = (char*)"IP";
        break;
      case DataCall::kConnTypeIPv6:
        responses[index].type = (char*)"IPV6";
        break;
      case DataCall::kConnTypeIPv4v6:
        responses[index].type = (char*)"IPV4V6";
        break;
      case DataCall::kConnTypePPP:
        responses[index].type = (char*)"PPP";
        break;
      default:
        responses[index].type = (char*)"IP";
        break;
    }

    responses[index].ifname = (char*)"rmnet0";
    responses[index].addresses =
      const_cast<char*>(global_ril_config->ril_address_and_prefix());
    responses[index].dnses = const_cast<char*>(global_ril_config->ril_dns());
    responses[index].gateways = const_cast<char*>(global_ril_config->ril_gateway());
    responses[index].pcscf = (char*)"";
    responses[index].mtu = 1440;
  }

  bool new_conn_state = (gDataCalls.size() > 0);

  if (gRilConnected != new_conn_state) {
    time_t curr_time;
    time(&curr_time);
    double diff_in_secs = difftime(curr_time, gce_ril_start_time);

    gRilConnected = new_conn_state;

    if (new_conn_state) {
      ALOGV("MOBILE_DATA_CONNECTED %.2lf seconds", diff_in_secs);
    } else {
      ALOGV("MOBILE_DATA_DISCONNECTED %.2lf seconds", diff_in_secs);
    }

    if (property_set("ril.net_connected", new_conn_state ? "1" : "0")) {
      ALOGE("Couldn't set a system property ril.net_connected.");
    }
  }

  if (t != NULL) {
    gce_ril_env->OnRequestComplete(*t, RIL_E_SUCCESS, responses,
                                   gDataCalls.size() * sizeof(*responses));
  } else {
    gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
                                       responses,
                                       gDataCalls.size() * sizeof(*responses));
  }
  delete[] responses;
  return 0;
}

static void request_datacall_fail_cause(RIL_Token t) {
  RIL_DataCallFailCause fail = PDP_FAIL_DATA_REGISTRATION_FAIL;

  if (gDataCalls.size() > 0) {
    fail = gDataCalls.rbegin()->second.fail_cause_;
  }

  ALOGV("Requesting last data call setup fail cause (%d)", fail);
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &fail, sizeof(fail));
};

static void request_data_calllist(void* /*data*/, size_t /*datalen*/,
                                  RIL_Token t) {
  request_or_send_data_calllist(&t);
}

static void request_setup_data_call(void* data, size_t datalen, RIL_Token t) {
  char** details = static_cast<char**>(data);
  const size_t fields = datalen / sizeof(details[0]);

  // There are two different versions of this interface, one providing 7 strings
  // and the other providing 8. The code below will assume the presence of 7
  // strings in all cases, so bail out here if things appear to be wrong. We
  // protect the 8 string case below.
  if (fields < 7) {
    ALOGE("%s returning: called with small datalen %zu", __FUNCTION__, datalen);
    return;
  }

  DataCall call;
  int tech = atoi(details[0]);
  switch (tech) {
    case 0:
    case 2 + RADIO_TECH_1xRTT:
      call.technology_ = RADIO_TECH_1xRTT;
      break;

    case 1:
    case 2 + RADIO_TECH_EDGE:
      call.technology_ = RADIO_TECH_EDGE;
      break;

    default:
      call.technology_ = RIL_RadioTechnology(tech - 2);
      break;
  }

  int profile = atoi(details[1]);
  call.profile_ = RIL_DataProfile(profile);

  if (details[2]) call.access_point_ = details[2];
  if (details[3]) call.username_ = details[3];
  if (details[4]) call.password_ = details[4];

  int auth_type = atoi(details[5]);
  call.auth_type_ = DataCall::AllowedAuthenticationType(auth_type);

  if (!strcmp("IP", details[6])) {
    call.connection_type_ = DataCall::kConnTypeIPv4;
  } else if (!strcmp("IPV6", details[6])) {
    call.connection_type_ = DataCall::kConnTypeIPv6;
  } else if (!strcmp("IPV4V6", details[6])) {
    call.connection_type_ = DataCall::kConnTypeIPv4v6;
  } else if (!strcmp("PPP", details[6])) {
    call.connection_type_ = DataCall::kConnTypePPP;
  } else {
    ALOGW("Unknown / unsupported connection type %s. Falling back to IPv4",
          details[6]);
    call.connection_type_ = DataCall::kConnTypeIPv4;
  }

  if (call.connection_type_ != DataCall::kConnTypeIPv4) {
    ALOGE("Non-IPv4 connections are not supported by Cuttlefish RIL.");
    gce_ril_env->OnRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
    return;
  }

  call.link_state_ = DataCall::kLinkStateUp;
  call.fail_cause_ = PDP_FAIL_NONE;
  if (fields > 7) {
    if (details[7]) call.other_properties_ = details[7];
  }

  if (gDataCalls.empty()) {
    SetUpNetworkInterface(global_ril_config->ril_ipaddr(),
                          global_ril_config->ril_prefixlen(),
                          global_ril_config->ril_broadcast());
  }

  gDataCalls[gNextDataCallId] = call;
  gNextDataCallId++;

  ALOGV("Requesting data call setup to APN %s, technology %s, prof %s",
        details[2], details[0], details[1]);

  request_or_send_data_calllist(&t);

  gRilConnected = (gDataCalls.size() > 0);
}

static void request_teardown_data_call(void* data, size_t /*datalen*/,
                                       RIL_Token t) {
  char** data_strs = (char**)data;
  int call_id = atoi(data_strs[0]);
  int reason = atoi(data_strs[1]);

  ALOGV("Tearing down data call %d, reason: %d", call_id, reason);

  gDataCalls.erase(call_id);
  gRilConnected = (gDataCalls.size() > 0);

  if (!gRilConnected) {
    TearDownNetworkInterface();
  }
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void set_radio_state(RIL_RadioState new_state, RIL_Token t) {
  // From header:
  // Toggle radio on and off (for "airplane" mode)
  // If the radio is is turned off/on the radio modem subsystem
  // is expected return to an initialized state. For instance,
  // any voice and data calls will be terminated and all associated
  // lists emptied.
  gDataCalls.clear();

  gSimStatus = SIM_NOT_READY;
  ALOGV("RIL_RadioState change %d to %d", gRadioPowerState, new_state);
  gRadioPowerState = new_state;

  if (new_state == RADIO_STATE_OFF) {
    TearDownNetworkInterface();
  }

  if (t != NULL) {
    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  }

  gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
                                     NULL, 0);

  pollSIMState(NULL);
}

// returns 1 if on, 0 if off, and -1 on error
static void request_radio_power(void* data, size_t /*datalen*/, RIL_Token t) {
  int on = ((int*)data)[0];
  set_radio_state(on ? RADIO_STATE_ON : RADIO_STATE_OFF, t);
}

// TODO(ender): this should be a class member. Move where it belongs.
struct CallState {
  RIL_CallState state;  // e.g. RIL_CALL_HOLDING;
  bool isInternational;
  bool isMobileTerminated;
  bool isVoice;
  bool isMultiParty;

  std::string number;
  std::string name;
  std::string dtmf;

  bool canPresentNumber;
  bool canPresentName;

  CallState()
      : state(RIL_CallState(0)),
        isInternational(false),
        isMobileTerminated(true),
        isVoice(true),
        isMultiParty(false),
        canPresentNumber(true),
        canPresentName(true) {}

  CallState(const std::string& number)
      : state(RIL_CALL_INCOMING),
        isInternational(false),
        isMobileTerminated(true),
        isVoice(true),
        isMultiParty(false),
        number(number),
        name(number),
        canPresentNumber(true),
        canPresentName(true) {}

  bool isBackground() { return state == RIL_CALL_HOLDING; }

  bool isActive() { return state == RIL_CALL_ACTIVE; }

  bool isDialing() { return state == RIL_CALL_DIALING; }

  bool isIncoming() { return state == RIL_CALL_INCOMING; }

  bool isWaiting() { return state == RIL_CALL_WAITING; }

  void addDtmfDigit(char c) {
    dtmf.push_back(c);
    ALOGV("Call to %s: DTMF %s", number.c_str(), dtmf.c_str());
  }

  bool makeBackground() {
    if (state == RIL_CALL_ACTIVE) {
      state = RIL_CALL_HOLDING;
      return true;
    }

    return false;
  }

  bool makeActive() {
    if (state == RIL_CALL_INCOMING || state == RIL_CALL_WAITING ||
        state == RIL_CALL_DIALING || state == RIL_CALL_HOLDING) {
      state = RIL_CALL_ACTIVE;
      return true;
    }

    return false;
  }
};

static int gLastActiveCallIndex = 1;
static int gMicrophoneMute = 0;
static std::map<int, CallState> gActiveCalls;

static void request_get_current_calls(void* /*data*/, size_t /*datalen*/,
                                      RIL_Token t) {
  const int countCalls = gActiveCalls.size();

  RIL_Call** pp_calls = (RIL_Call**)alloca(countCalls * sizeof(RIL_Call*));
  RIL_Call* p_calls = (RIL_Call*)alloca(countCalls * sizeof(RIL_Call));

  memset(p_calls, 0, countCalls * sizeof(RIL_Call));

  /* init the pointer array */
  for (int i = 0; i < countCalls; i++) {
    pp_calls[i] = &(p_calls[i]);
  }

  // TODO(ender): This should be built from calls requested via RequestDial.
  for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
       iter != gActiveCalls.end(); ++iter, ++p_calls) {
    p_calls->state = iter->second.state;
    p_calls->index = iter->first;
    p_calls->toa = iter->second.isInternational ? 145 : 129;
    p_calls->isMpty = iter->second.isMultiParty;
    p_calls->isMT = iter->second.isMobileTerminated;
    p_calls->als = iter->first;
    p_calls->isVoice = iter->second.isVoice;
    p_calls->isVoicePrivacy = 0;
    p_calls->number = strdup(iter->second.number.c_str());
    p_calls->numberPresentation = iter->second.canPresentNumber ? 0 : 1;
    p_calls->name = strdup(iter->second.name.c_str());
    p_calls->namePresentation = iter->second.canPresentName ? 0 : 1;
    p_calls->uusInfo = NULL;

    ALOGV("Call to %s (%s): voice=%d mt=%d type=%d state=%d index=%d",
          p_calls->name, p_calls->number, p_calls->isVoice, p_calls->isMT,
          p_calls->toa, p_calls->state, p_calls->index);
  }

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, pp_calls,
                                 countCalls * sizeof(RIL_Call*));

  ALOGV("Get Current calls: %d calls found.\n", countCalls);
}

static void simulate_pending_calls_answered(void* /*ignore*/) {
  ALOGV("Simulating outgoing call answered.");
  // This also resumes held calls.
  for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
       iter != gActiveCalls.end(); ++iter) {
    if (iter->second.isDialing()) {
      iter->second.makeActive();
    }
  }

  // Only unsolicited here.
  gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,
                                     NULL, 0);
}

static void request_dial(void* data, size_t /*datalen*/, RIL_Token t) {
  RIL_Dial* p_dial = (RIL_Dial*)data;

  ALOGV("Dialing %s, number presentation is %s.", p_dial->address,
        (p_dial->clir == 0) ? "defined by operator"
                            : (p_dial->clir == 1) ? "allowed" : "restricted");

  CallState state(p_dial->address);
  state.isMobileTerminated = false;
  state.state = RIL_CALL_DIALING;

  switch (p_dial->clir) {
    case 0:  // default
    case 1:  // allow
      state.canPresentNumber = true;
      break;

    case 2:  // restrict
      state.canPresentNumber = false;
      break;
  }

  int call_index = gLastActiveCallIndex++;
  gActiveCalls[call_index] = state;

  static const struct timeval kAnswerTime = {5, 0};
  gce_ril_env->RequestTimedCallback(simulate_pending_calls_answered, NULL,
                                    &kAnswerTime);

  // success or failure is ignored by the upper layer here.
  // it will call GET_CURRENT_CALLS and determine success that way
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

void request_set_mute(void* data, size_t /*datalen*/, RIL_Token t) {
  gMicrophoneMute = ((int*)data)[0] != 0;
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

void request_get_mute(RIL_Token t) {
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gMicrophoneMute,
                                 sizeof(gMicrophoneMute));
}

// TODO(ender): this should be a class member. Move where it belongs.
struct SmsMessage {
  enum SmsStatus { kUnread = 0, kRead = 1, kUnsent = 2, kSent = 3 };

  std::string message;
  SmsStatus status;
};

static int gNextMessageId = 1;
static std::map<int, SmsMessage> gMessagesOnSimCard;

static void request_write_sms_to_sim(void* data, size_t /*datalen*/,
                                     RIL_Token t) {
  RIL_SMS_WriteArgs* p_args = (RIL_SMS_WriteArgs*)data;

  SmsMessage message;
  message.status = SmsMessage::SmsStatus(p_args->status);
  message.message = p_args->pdu;

  ALOGV("Storing SMS message: '%s' with state: %s.", message.message.c_str(),
        (message.status < SmsMessage::kUnsent)
            ? ((message.status == SmsMessage::kRead) ? "READ" : "UNREAD")
            : ((message.status == SmsMessage::kSent) ? "SENT" : "UNSENT"));

  // TODO(ender): simulate SIM FULL?
  int index = gNextMessageId++;
  gMessagesOnSimCard[index] = message;

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &index, sizeof(index));
}

static void request_delete_sms_on_sim(void* data, size_t /*datalen*/,
                                      RIL_Token t) {
  int index = *(int*)data;

  ALOGV("Delete SMS message %d", index);

  if (gMessagesOnSimCard.erase(index) == 0) {
    // No such message
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
    return;
  }

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_hangup(void* data, size_t /*datalen*/, RIL_Token t) {
  int* p_line = (int*)data;

  ALOGV("Hanging up call %d.", *p_line);
  std::map<int, CallState>::iterator iter = gActiveCalls.find(*p_line);

  if (iter == gActiveCalls.end()) {
    ALOGV("No such call: %d.", *p_line);
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
  } else {
    gActiveCalls.erase(iter);
    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  }
}

static void request_hangup_waiting(void* /*data*/, size_t /*datalen*/,
                                   RIL_Token t) {
  ALOGV("Hanging up background/held calls.");
  for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
       iter != gActiveCalls.end();) {
    if (iter->second.isBackground()) {
      // C++98 -- std::map::erase doesn't return iterator.
      std::map<int, CallState>::iterator temp = iter++;
      gActiveCalls.erase(temp);
    } else {
      ++iter;
    }
  }
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_hangup_current(RIL_Token t) {
  ALOGV("Hanging up foreground/active calls.");
  // This also resumes held calls.
  for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
       iter != gActiveCalls.end();) {
    if (iter->second.isBackground()) {
      iter->second.makeActive();
      ++iter;
    } else {
      // C++98 -- std::map::erase doesn't return iterator.
      std::map<int, CallState>::iterator temp = iter++;
      gActiveCalls.erase(temp);
    }
  }
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_switch_current_and_waiting(RIL_Token t) {
  ALOGV("Toggle foreground and background calls.");
  // TODO(ender): fix all states. Max 2 calls.
  //   BEFORE                               AFTER
  // Call 1   Call 2                 Call 1       Call 2
  // ACTIVE   HOLDING                HOLDING     ACTIVE
  // ACTIVE   WAITING                HOLDING     ACTIVE
  // HOLDING  WAITING                HOLDING     ACTIVE
  // ACTIVE   IDLE                   HOLDING     IDLE
  // IDLE     IDLE                   IDLE        IDLE
  for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
       iter != gActiveCalls.end(); ++iter) {
    // TODO(ender): call could also be waiting or dialing or...
    if (iter->second.isBackground()) {
      iter->second.makeActive();
    } else {
      iter->second.makeBackground();
    }
  }
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_answer_incoming(RIL_Token t) {
  ALOGV("Answering incoming call.");

  // There's two types of incoming calls:
  // - incoming: we are receiving this call while nothing happens,
  // - waiting: we are receiving this call while we're already talking.
  // We only accept the incoming ones.
  for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
       iter != gActiveCalls.end(); ++iter) {
    if (iter->second.isIncoming()) {
      iter->second.makeActive();
    }
  }
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_combine_multiparty_call(void* /*data*/, size_t /*datalen*/,
                                            RIL_Token t) {
  ALOGW("Conference calls are not supported.");
  gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}

static void request_split_multiparty_call(void* /*data*/, size_t /*datalen*/,
                                          RIL_Token t) {
  ALOGW("Conference calls are not supported.");
  gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}

static void request_udub_on_incoming_calls(RIL_Token t) {
  // UDUB = user determined user busy.
  // We don't exactly do that. We simply drop these calls.
  ALOGV("Reporting busy signal to incoming calls.");
  for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
       iter != gActiveCalls.end();) {
    // If we have an incoming call, there should be no waiting call.
    // If we have a waiting call, then previous incoming call has been answered.
    if (iter->second.isIncoming() || iter->second.isWaiting()) {
      // C++98 -- std::map::erase doesn't return iterator.
      std::map<int, CallState>::iterator temp = iter++;
      gActiveCalls.erase(temp);
    } else {
      ++iter;
    }
  }
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_send_dtmf(void* data, size_t /*datalen*/, RIL_Token t) {
  char c = ((char*)data)[0];
  ALOGV("Sending DTMF digit '%c'", c);

  for (std::map<int, CallState>::iterator iter = gActiveCalls.begin();
       iter != gActiveCalls.end(); ++iter) {
    if (iter->second.isActive()) {
      iter->second.addDtmfDigit(c);
      break;
    }
  }

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_send_dtmf_stop(RIL_Token t) {
  ALOGV("DTMF tone end.");

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

// Check SignalStrength.java file for more details on how these map to signal
// strength bars.
const int kGatewaySignalStrengthMin = 4;
const int kGatewaySignalStrengthMax = 30;
const int kCDMASignalStrengthMin = -110;
const int kCDMASignalStrengthMax = -60;
const int kEVDOSignalStrengthMin = -160;
const int kEVDOSignalStrengthMax = -70;
const int kLTESignalStrengthMin = 4;
const int kLTESignalStrengthMax = 30;

static int gGatewaySignalStrength = kGatewaySignalStrengthMax;
static int gCDMASignalStrength = kCDMASignalStrengthMax;
static int gEVDOSignalStrength = kEVDOSignalStrengthMax;
static int gLTESignalStrength = kLTESignalStrengthMax;

static void request_signal_strength(void* /*data*/, size_t /*datalen*/,
                                    RIL_Token t) {
  // TODO(ender): possible to support newer APIs here.
  RIL_SignalStrength_v10 strength;

  gGatewaySignalStrength += (rand() % 3 - 1);
  gCDMASignalStrength += (rand() % 3 - 1);
  gEVDOSignalStrength += (rand() % 3 - 1);
  gLTESignalStrength += (rand() % 3 - 1);

  if (gGatewaySignalStrength < kGatewaySignalStrengthMin)
    gGatewaySignalStrength = kGatewaySignalStrengthMin;
  if (gGatewaySignalStrength > kGatewaySignalStrengthMax)
    gGatewaySignalStrength = kGatewaySignalStrengthMax;
  if (gCDMASignalStrength < kCDMASignalStrengthMin)
    gCDMASignalStrength = kCDMASignalStrengthMin;
  if (gCDMASignalStrength > kCDMASignalStrengthMax)
    gCDMASignalStrength = kCDMASignalStrengthMax;
  if (gEVDOSignalStrength < kEVDOSignalStrengthMin)
    gEVDOSignalStrength = kEVDOSignalStrengthMin;
  if (gEVDOSignalStrength > kEVDOSignalStrengthMax)
    gEVDOSignalStrength = kEVDOSignalStrengthMax;
  if (gLTESignalStrength < kLTESignalStrengthMin)
    gLTESignalStrength = kLTESignalStrengthMin;
  if (gLTESignalStrength > kLTESignalStrengthMax)
    gLTESignalStrength = kLTESignalStrengthMax;

  strength.GW_SignalStrength.signalStrength = gGatewaySignalStrength;
  strength.GW_SignalStrength.bitErrorRate = 0;  // 0..7%

  strength.CDMA_SignalStrength.dbm = gCDMASignalStrength;
  strength.CDMA_SignalStrength.ecio = 0;  // Ec/Io; keep high to use dbm.

  strength.EVDO_SignalStrength.dbm = gEVDOSignalStrength;
  strength.EVDO_SignalStrength.ecio = 0;  // Ec/Io; keep high to use dbm.

  strength.LTE_SignalStrength.signalStrength = gLTESignalStrength;
  strength.LTE_SignalStrength.rsrp = INT_MAX;   // Invalid = Use signalStrength.
  strength.LTE_SignalStrength.rsrq = INT_MAX;   // Invalid = Use signalStrength.
  strength.LTE_SignalStrength.rssnr = INT_MAX;  // Invalid = Use signalStrength.
  strength.LTE_SignalStrength.cqi = INT_MAX;    // Invalid = Use signalStrength.

  ALOGV("Reporting signal strength: GW=%d CDMA=%d EVDO=%d LTE=%d",
        gGatewaySignalStrength, gCDMASignalStrength, gEVDOSignalStrength,
        gLTESignalStrength);

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &strength, sizeof(strength));
}

static std::map<RIL_PreferredNetworkType, int> gModemSupportedNetworkTypes;

static void init_modem_supported_network_types() {
  gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA] = MDM_GSM | MDM_WCDMA;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_ONLY] = MDM_GSM;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_WCDMA] = MDM_WCDMA;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA_AUTO] =
      MDM_GSM | MDM_WCDMA;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_CDMA_EVDO_AUTO] =
      MDM_CDMA | MDM_EVDO;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_CDMA_ONLY] = MDM_CDMA;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_EVDO_ONLY] = MDM_EVDO;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO] =
      MDM_GSM | MDM_WCDMA | MDM_CDMA | MDM_EVDO;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_CDMA_EVDO] =
      MDM_LTE | MDM_CDMA | MDM_EVDO;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_GSM_WCDMA] =
      MDM_LTE | MDM_GSM | MDM_WCDMA;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA] =
      MDM_LTE | MDM_CDMA | MDM_EVDO | MDM_GSM | MDM_WCDMA;
  gModemSupportedNetworkTypes[PREF_NET_TYPE_LTE_ONLY] = MDM_LTE;
}

static std::map<RIL_PreferredNetworkType, int> gModemTechnologies;

RIL_RadioTechnology gDataTechnologiesPreferenceOrder[] = {
    RADIO_TECH_LTE,    RADIO_TECH_EHRPD, RADIO_TECH_HSPAP,  RADIO_TECH_HSPA,
    RADIO_TECH_HSDPA,  RADIO_TECH_HSUPA, RADIO_TECH_EVDO_B, RADIO_TECH_EVDO_A,
    RADIO_TECH_EVDO_0, RADIO_TECH_1xRTT, RADIO_TECH_UMTS,   RADIO_TECH_EDGE,
    RADIO_TECH_GPRS};

RIL_RadioTechnology gVoiceTechnologiesPreferenceOrder[] = {
    RADIO_TECH_LTE,    RADIO_TECH_EHRPD, RADIO_TECH_EVDO_B, RADIO_TECH_EVDO_A,
    RADIO_TECH_EVDO_0, RADIO_TECH_1xRTT, RADIO_TECH_IS95B,  RADIO_TECH_IS95A,
    RADIO_TECH_UMTS,   RADIO_TECH_GSM};

static void init_modem_technologies() {
  gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA] =
      (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
      (1 << RADIO_TECH_UMTS);
  gModemTechnologies[PREF_NET_TYPE_GSM_ONLY] =
      (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE);
  gModemTechnologies[PREF_NET_TYPE_WCDMA] =
      (1 << RADIO_TECH_EDGE) | (1 << RADIO_TECH_UMTS);
  gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA_AUTO] =
      (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
      (1 << RADIO_TECH_UMTS);
  gModemTechnologies[PREF_NET_TYPE_CDMA_EVDO_AUTO] =
      (1 << RADIO_TECH_IS95A) | (1 << RADIO_TECH_IS95B) |
      (1 << RADIO_TECH_1xRTT) | (1 << RADIO_TECH_EVDO_0) |
      (1 << RADIO_TECH_EVDO_A) | (1 << RADIO_TECH_HSDPA) |
      (1 << RADIO_TECH_HSUPA) | (1 << RADIO_TECH_HSPA) |
      (1 << RADIO_TECH_EVDO_B);
  gModemTechnologies[PREF_NET_TYPE_CDMA_ONLY] = (1 << RADIO_TECH_IS95A) |
                                                (1 << RADIO_TECH_IS95B) |
                                                (1 << RADIO_TECH_1xRTT);
  gModemTechnologies[PREF_NET_TYPE_EVDO_ONLY] =
      (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
      (1 << RADIO_TECH_EVDO_A) | (1 << RADIO_TECH_HSDPA) |
      (1 << RADIO_TECH_HSUPA) | (1 << RADIO_TECH_HSPA) |
      (1 << RADIO_TECH_EVDO_B);
  gModemTechnologies[PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO] =
      (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
      (1 << RADIO_TECH_UMTS) | (1 << RADIO_TECH_IS95A) |
      (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) |
      (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
      (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) |
      (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B);
  gModemTechnologies[PREF_NET_TYPE_LTE_CDMA_EVDO] =
      (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) |
      (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_IS95A) |
      (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) |
      (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
      (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) |
      (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B);
  gModemTechnologies[PREF_NET_TYPE_LTE_GSM_WCDMA] =
      (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) |
      (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) |
      (1 << RADIO_TECH_EDGE) | (1 << RADIO_TECH_UMTS);

  gModemTechnologies[PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA] =
      (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) |
      (1 << RADIO_TECH_EHRPD) | (1 << RADIO_TECH_IS95A) |
      (1 << RADIO_TECH_IS95B) | (1 << RADIO_TECH_1xRTT) |
      (1 << RADIO_TECH_EVDO_0) | (1 << RADIO_TECH_EVDO_A) |
      (1 << RADIO_TECH_HSDPA) | (1 << RADIO_TECH_HSUPA) |
      (1 << RADIO_TECH_HSPA) | (1 << RADIO_TECH_EVDO_B) |
      (1 << RADIO_TECH_GSM) | (1 << RADIO_TECH_GPRS) | (1 << RADIO_TECH_EDGE) |
      (1 << RADIO_TECH_UMTS);
  gModemTechnologies[PREF_NET_TYPE_LTE_ONLY] =
      (1 << RADIO_TECH_HSPAP) | (1 << RADIO_TECH_LTE) | (1 << RADIO_TECH_EHRPD);
}

static const RIL_PreferredNetworkType gModemDefaultType =
    PREF_NET_TYPE_LTE_GSM_WCDMA;
static RIL_PreferredNetworkType gModemCurrentType = gModemDefaultType;
static RIL_RadioTechnology gModemVoiceTechnology = RADIO_TECH_LTE;

// Report technology change.
// Select best technology from the list of supported techs.
// Demotes RADIO_TECH_GSM as it's voice-only.
static RIL_RadioTechnology getBestDataTechnology(
    RIL_PreferredNetworkType network_type) {
  RIL_RadioTechnology technology = RADIO_TECH_GPRS;

  std::map<RIL_PreferredNetworkType, int>::iterator iter =
      gModemTechnologies.find(network_type);

  ALOGV("Searching for best data technology for network type %d...",
        network_type);

  // Find which technology bits are lit. Pick the top most.
  for (size_t tech_index = 0;
       tech_index < sizeof(gDataTechnologiesPreferenceOrder) /
                        sizeof(gDataTechnologiesPreferenceOrder[0]);
       ++tech_index) {
    if (iter->second & (1 << gDataTechnologiesPreferenceOrder[tech_index])) {
      technology = gDataTechnologiesPreferenceOrder[tech_index];
      break;
    }
  }

  ALOGV("Best data technology: %d.", technology);
  return technology;
}

static RIL_RadioTechnology getBestVoiceTechnology(
    RIL_PreferredNetworkType network_type) {
  RIL_RadioTechnology technology = RADIO_TECH_GSM;

  std::map<RIL_PreferredNetworkType, int>::iterator iter =
      gModemTechnologies.find(network_type);

  ALOGV("Searching for best voice technology for network type %d...",
        network_type);

  // Find which technology bits are lit. Pick the top most.
  for (size_t tech_index = 0;
       tech_index < sizeof(gVoiceTechnologiesPreferenceOrder) /
                        sizeof(gVoiceTechnologiesPreferenceOrder[0]);
       ++tech_index) {
    if (iter->second & (1 << gVoiceTechnologiesPreferenceOrder[tech_index])) {
      technology = gVoiceTechnologiesPreferenceOrder[tech_index];
      break;
    }
  }

  ALOGV("Best voice technology: %d.", technology);
  return technology;
}

static void setRadioTechnology(RIL_PreferredNetworkType network_type) {
  RIL_RadioTechnology technology = getBestVoiceTechnology(network_type);

  if (technology != gModemVoiceTechnology) {
    gModemVoiceTechnology = technology;
    gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED,
                                       &gModemVoiceTechnology,
                                       sizeof(gModemVoiceTechnology));
  }
}

static void request_get_radio_capability(RIL_Token t) {
  ALOGV("Requesting radio capability.");
  RIL_RadioCapability rc;
  rc.version = RIL_RADIO_CAPABILITY_VERSION;
  rc.session = 1;
  rc.phase = RC_PHASE_CONFIGURED;
  rc.rat = RAF_HSPAP;
  strncpy(rc.logicalModemUuid, "com.google.cvdgce1.modem", MAX_UUID_LENGTH);
  rc.status = RC_STATUS_SUCCESS;
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &rc, sizeof(rc));
}

static void request_set_radio_capability(void* data, size_t datalen,
                                         RIL_Token t) {
  RIL_RadioCapability* rc = (RIL_RadioCapability*)data;
  ALOGV(
      "RadioCapability version %d session %d phase %d rat %d "
      "logicalModemUuid %s status %d",
      rc->version, rc->session, rc->phase, rc->rat, rc->logicalModemUuid,
      rc->status);
  // TODO(ender): do something about these numbers.
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, rc, datalen);
}

static void request_set_preferred_network_type(int /*request*/, void* data,
                                               size_t /*datalen*/,
                                               RIL_Token t) {
  RIL_PreferredNetworkType desired_type = *(RIL_PreferredNetworkType*)(data);

  // TODO(ender): telephony still believes this phone is GSM only.
  ALOGV("Requesting modem technology change -> %d", desired_type);

  if (gModemSupportedNetworkTypes.find(desired_type) ==
      gModemSupportedNetworkTypes.end()) {
    desired_type = gModemSupportedNetworkTypes.begin()->first;
  }

  if (gModemCurrentType == desired_type) {
    ALOGV("Modem technology already set to %d.", desired_type);
    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
    return;
  }

  int supported_technologies = gModemSupportedNetworkTypes[gModemDefaultType];
  int desired_technologies = gModemSupportedNetworkTypes[desired_type];

  ALOGV("Requesting modem technology change %d -> %d", gModemCurrentType,
        desired_type);

  // Check if we support this technology.
  if ((supported_technologies & desired_technologies) != desired_technologies) {
    ALOGV("Desired technology is not supported.");
    gce_ril_env->OnRequestComplete(t, RIL_E_MODE_NOT_SUPPORTED, NULL, 0);
    return;
  }

  gModemCurrentType = desired_type;
  setRadioTechnology(desired_type);
  ALOGV("Technology change successful.");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_get_preferred_network_type(int /*request*/, void* /*data*/,
                                               size_t /*datalen*/,
                                               RIL_Token t) {
  gce_ril_env->OnRequestComplete(
      t, RIL_E_SUCCESS,
      const_cast<RIL_PreferredNetworkType*>(&gModemDefaultType),
      sizeof(gModemDefaultType));
}

enum RegistrationState {
  kUnregistered = 0,
  kRegisteredInHomeNetwork = 1,
  kSearchingForOperators = 2,
  kRegistrationDenied = 3,
  kUnknown = 4,
  kRegisteredInRoamingMode = 5,

  kUnregistered_EmergencyCallsOnly = 10,
  kSearchingForOperators_EmergencyCallsOnly = 12,
  kRegistrationDenied_EmergencyCallsOnly = 13,
  kUnknown_EmergencyCallsOnly = 14
};

static const char kCdmaMobileDeviceNumber[] = "5551234567";
static const char kCdmaSID[] = "123";
static const char kCdmaNID[] = "65535";  // special: indicates free roaming.

static void request_registration_state(int request, void* /*data*/,
                                       size_t /*datalen*/, RIL_Token t) {
  char** responseStr = NULL;
  int numElements = 0;

  // See RIL_REQUEST_VOICE_REGISTRATION_STATE and
  // RIL_REQUEST_DATA_REGISTRATION_STATE.
  numElements = (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) ? 15 : 6;
  responseStr = (char**)malloc(numElements * sizeof(char*));

  asprintf(&responseStr[0], "%d", kRegisteredInHomeNetwork);
  responseStr[1] = NULL;  // LAC - needed for GSM / WCDMA only.
  responseStr[2] = NULL;  // CID - needed for GSM / WCDMA only.

  // This is (and always has been) a huge memory leak.
  if (request == RIL_REQUEST_VOICE_REGISTRATION_STATE) {
    ALOGV("Requesting voice registration state.");
    asprintf(&responseStr[3], "%d", getBestVoiceTechnology(gModemCurrentType));
    responseStr[4] = strdup("1");       // BSID
    responseStr[5] = strdup("123");     // Latitude
    responseStr[6] = strdup("222");     // Longitude
    responseStr[7] = strdup("0");       // CSS Indicator
    responseStr[8] = strdup(kCdmaSID);  // SID
    responseStr[9] = strdup(kCdmaNID);  // NID
    responseStr[10] = strdup("0");      // Roaming indicator
    responseStr[11] = strdup("1");      // System is in PRL
    responseStr[12] = strdup("0");      // Default Roaming indicator
    responseStr[13] = strdup("0");      // Reason for denial
    responseStr[14] = strdup("0");      // Primary Scrambling Code of Current
  } else if (request == RIL_REQUEST_DATA_REGISTRATION_STATE) {
    ALOGV("Requesting data registration state.");
    asprintf(&responseStr[3], "%d", getBestDataTechnology(gModemCurrentType));
    responseStr[4] = strdup("");   // DataServiceDenyReason
    responseStr[5] = strdup("1");  // Max simultaneous data calls.
  } else {
    ALOGV("Unexpected request type: %d", request);
    return;
  }

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, responseStr,
                                 numElements * sizeof(responseStr));
}

static void request_baseband_version(RIL_Token t) {
  const char* response_str = "CVD_R1.0.0";

  ALOGV("Requested phone baseband version.");

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, strdup(response_str),
                                 sizeof(response_str));
}

// Returns true, if modem is CDMA capable.
static bool isCDMA() {
  switch (gModemCurrentType) {
    case PREF_NET_TYPE_GSM_WCDMA:
    case PREF_NET_TYPE_GSM_ONLY:
    case PREF_NET_TYPE_WCDMA:
    case PREF_NET_TYPE_GSM_WCDMA_AUTO:
    case PREF_NET_TYPE_LTE_GSM_WCDMA:
    case PREF_NET_TYPE_LTE_ONLY:
      return false;

    case PREF_NET_TYPE_CDMA_EVDO_AUTO:
    case PREF_NET_TYPE_CDMA_ONLY:
    case PREF_NET_TYPE_EVDO_ONLY:
    case PREF_NET_TYPE_LTE_CDMA_EVDO:
    case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
    case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO:
      return true;
    default:
      break;
  }

  ALOGE("INVALID MODEM TYPE: %d", gModemCurrentType);
  return false;
}

// Returns true, if modem is GSM capable.
// Note, this is not same as !isCDMA().
static bool isGSM() {
  switch (gModemCurrentType) {
    case PREF_NET_TYPE_GSM_WCDMA:
    case PREF_NET_TYPE_GSM_ONLY:
    case PREF_NET_TYPE_WCDMA:
    case PREF_NET_TYPE_GSM_WCDMA_AUTO:
    case PREF_NET_TYPE_LTE_GSM_WCDMA:
    case PREF_NET_TYPE_LTE_ONLY:
    case PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO:
      return true;

    case PREF_NET_TYPE_CDMA_EVDO_AUTO:
    case PREF_NET_TYPE_CDMA_ONLY:
    case PREF_NET_TYPE_EVDO_ONLY:
    case PREF_NET_TYPE_LTE_CDMA_EVDO:
    case PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA:
      return false;
    default:
      break;
  }

  ALOGE("INVALID MODEM TYPE: %d", gModemCurrentType);
  return false;
}

static const char gIdentityGsmImei[] = "12345678902468";  // Luhn cksum = 0.
static const char gIdentityGsmImeiSv[] = "01";            // Arbitrary version.
static const char gIdentityCdmaEsn[] = "A0123456";        // 8 digits, ^[A-F].*
static const char gIdentityCdmaMeid[] =
    "A0123456789012";  // 14 digits, ^[A-F].*

static void request_get_imei(RIL_Token t) {
  ALOGV("Requesting IMEI");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
                                 const_cast<char*>(gIdentityGsmImei),
                                 strlen(gIdentityGsmImei));
}

static void request_get_imei_sv(RIL_Token t) {
  ALOGV("Requesting IMEI SV");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
                                 const_cast<char*>(gIdentityGsmImeiSv),
                                 strlen(gIdentityGsmImeiSv));
}

static void request_device_identity(int /*request*/, void* /*data*/,
                                    size_t /*datalen*/, RIL_Token t) {
  char* response[4] = {NULL};

  ALOGV("Requesting device identity...");

  if (isCDMA()) {
    response[2] = strdup(&gIdentityCdmaEsn[0]);
    response[3] = strdup(&gIdentityCdmaMeid[0]);
  }

  if (isGSM()) {
    response[0] = strdup(&gIdentityGsmImei[0]);
    response[1] = strdup(&gIdentityGsmImeiSv[0]);
  }

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));

  free(response[0]);
  free(response[1]);
}

// Let's pretend we have SIM for CDMA (by default).
static bool gCdmaHasSim = true;
static RIL_CdmaSubscriptionSource gCdmaSubscriptionType =
    CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM;

static void request_cdma_get_subscription_source(int /*request*/,
                                                 void* /*data*/,
                                                 size_t /*datalen*/,
                                                 RIL_Token t) {
  ALOGV("Requesting CDMA Subscription source.");

  if (!isCDMA()) {
    // No such radio.
    gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
    return;
  }

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gCdmaSubscriptionType,
                                 sizeof(gCdmaSubscriptionType));
}

static void request_cdma_set_subscription_source(int /*request*/, void* data,
                                                 size_t /*datalen*/,
                                                 RIL_Token t) {
  ALOGV("Setting CDMA Subscription source.");

  if (!isCDMA()) {
    // No such radio.
    gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
    return;
  }

  RIL_CdmaSubscriptionSource new_source = *(RIL_CdmaSubscriptionSource*)(data);

  if (new_source == CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM && !gCdmaHasSim) {
    // No such radio.
    gce_ril_env->OnRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
    return;
  }

  ALOGV("Changed CDMA subscription type from %d to %d", gCdmaSubscriptionType,
        new_source);
  gCdmaSubscriptionType = new_source;

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED,
                                     &gCdmaSubscriptionType,
                                     sizeof(gCdmaSubscriptionType));
}

static void request_cdma_subscription(int /*request*/, void* /*data*/,
                                      size_t /*datalen*/, RIL_Token t) {
  ALOGV("Requesting CDMA Subscription.");

  if (!isCDMA()) {
    // No such radio.
    gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
    return;
  }

  char* responseStr[5] = {NULL};
  responseStr[0] = strdup(&kCdmaMobileDeviceNumber[0]);  // MDN
  responseStr[1] = strdup(&kCdmaSID[0]);                 // SID
  responseStr[2] = strdup(&kCdmaNID[0]);                 // NID
  responseStr[3] = strdup(&kCdmaMobileDeviceNumber[0]);  // MIN
  responseStr[4] = strdup("1");                          // PRL Version
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, responseStr,
                                 sizeof(responseStr));
}

static const int gMaxConcurrentVoiceCalls = 4;
static const int gMaxConcurrentDataCalls = 4;
static const int gMaxConcurrentStandbyConnections = 4;

static void request_hardware_config(RIL_Token t) {
  RIL_HardwareConfig hw_cfg[2];

  ALOGV("Requesting hardware configuration.");

  strncpy(hw_cfg[0].uuid, "com.google.cvdgce1.modem", sizeof(hw_cfg[0].uuid));
  strncpy(hw_cfg[1].uuid, "com.google.cvdgce1.sim", sizeof(hw_cfg[1].uuid));

  int technologies = 0;  // = unknown.
  std::map<RIL_PreferredNetworkType, int>::iterator iter =
      gModemTechnologies.find(gModemDefaultType);
  if (iter != gModemTechnologies.end()) {
    technologies = iter->second;
  }

  hw_cfg[0].type = RIL_HARDWARE_CONFIG_MODEM;
  hw_cfg[0].state = RIL_HARDWARE_CONFIG_STATE_ENABLED;
  hw_cfg[0].cfg.modem.rilModel = 0;
  hw_cfg[0].cfg.modem.rat = technologies;
  hw_cfg[0].cfg.modem.maxVoice = gMaxConcurrentVoiceCalls;
  hw_cfg[0].cfg.modem.maxData = gMaxConcurrentDataCalls;
  hw_cfg[0].cfg.modem.maxStandby = gMaxConcurrentStandbyConnections;

  hw_cfg[1].type = RIL_HARDWARE_CONFIG_SIM;
  hw_cfg[1].state = RIL_HARDWARE_CONFIG_STATE_ENABLED;
  memcpy(hw_cfg[1].cfg.sim.modemUuid, hw_cfg[0].uuid,
         sizeof(hw_cfg[1].cfg.sim.modemUuid));

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &hw_cfg, sizeof(hw_cfg));
}

// 0 = Home network only, 1 = preferred networks only, 2 = all networks.
static int gCdmaRoamingPreference = 2;

static void request_cdma_get_roaming_preference(int /*request*/, void* /*data*/,
                                                size_t /*datalen*/,
                                                RIL_Token t) {
  if (!isCDMA()) {
    // No such radio.
    gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
    return;
  }

  ALOGV("Requesting CDMA Roaming preference");

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gCdmaRoamingPreference,
                                 sizeof(gCdmaRoamingPreference));
}

static void request_cdma_set_roaming_preference(int /*request*/, void* data,
                                                size_t /*datalen*/,
                                                RIL_Token t) {
  if (!isCDMA()) {
    // No such radio.
    gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
    return;
  }

  int pref = *(int*)data;
  ALOGV("Changing CDMA roaming preference: %d -> %d", gCdmaRoamingPreference,
        pref);

  if ((pref < 0) || (pref > 2)) {
    ALOGV("Unsupported roaming preference: %d", pref);
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
    return;
  }

  gCdmaRoamingPreference = pref;
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_send_ussd(void* /*data*/, size_t /*datalen*/, RIL_Token t) {
  ALOGV("Sending USSD code is currently not supported");
  // TODO(ender): support this feature
  gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
}

static void request_cancel_ussd(RIL_Token t) {
  ALOGV("Cancelling USSD code is currently not supported");
  // TODO(ender): support this feature
  gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
}

static void request_exit_emergency_mode(void* /*data*/, size_t /*datalen*/,
                                        RIL_Token t) {
  ALOGV("Exiting emergency callback mode.");

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static RIL_RadioState gce_ril_current_state() {
  ALOGV("Reporting radio state %d", gRadioPowerState);
  return gRadioPowerState;
}

static int gce_ril_on_supports(int requestCode) {
  ALOGE("%s: Request code %d not implemented", __FUNCTION__, requestCode);
  return 1;
}

static void gce_ril_on_cancel(RIL_Token /*t*/) {
  ALOGE("Cancel operation not implemented");
}

static const char* gce_ril_get_version(void) {
  ALOGV("Reporting Cuttlefish version " CUTTLEFISH_RIL_VERSION_STRING);
  return CUTTLEFISH_RIL_VERSION_STRING;
}

static int s_cell_info_rate_ms = INT_MAX;
static int s_mcc = 0;
static int s_mnc = 0;
static int s_lac = 0;
static int s_cid = 0;

std::vector<RIL_NeighboringCell> gGSMNeighboringCells;

static void request_get_neighboring_cell_ids(void* /*data*/, size_t /*datalen*/,
                                             RIL_Token t) {
  ALOGV("Requesting GSM neighboring cell ids");

  if (!isGSM() || gGSMNeighboringCells.empty()) {
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
    return;
  }

  RIL_NeighboringCell** cells =
      new RIL_NeighboringCell*[gGSMNeighboringCells.size()];

  for (size_t index = 0; index < gGSMNeighboringCells.size(); ++index) {
    cells[index] = &gGSMNeighboringCells[index];
  }

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, cells,
                                 sizeof(RIL_NeighboringCell*));
  delete[] cells;
}

static void request_get_cell_info_list(void* /*data*/, size_t /*datalen*/,
                                       RIL_Token t) {
  struct timespec now;
  uint64_t curTime;

  ALOGV("Requesting Cell Info List");

  clock_gettime(CLOCK_MONOTONIC, &now);
  curTime = now.tv_sec * 1000000000LL + now.tv_nsec;

  RIL_CellInfo_v12 ci;

  if (isGSM()) {
    ci.cellInfoType = RIL_CELL_INFO_TYPE_GSM;
    ci.registered = 1;
    ci.timeStampType = RIL_TIMESTAMP_TYPE_ANTENNA;  // Our own timestamp.
    ci.timeStamp = curTime - 1000;                  // Fake time in the past.
    ci.CellInfo.gsm.cellIdentityGsm.mcc = s_mcc;
    ci.CellInfo.gsm.cellIdentityGsm.mnc = s_mnc;
    ci.CellInfo.gsm.cellIdentityGsm.lac = s_lac;
    ci.CellInfo.gsm.cellIdentityGsm.cid = s_cid;
    ci.CellInfo.gsm.signalStrengthGsm.signalStrength = 10;
    ci.CellInfo.gsm.signalStrengthGsm.bitErrorRate = 0;

    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &ci, sizeof(ci));
  } else if (isCDMA()) {
    // TODO(ender): CDMA cell support. And LTE.
    gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
  } else {
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
  }
}

struct NetworkOperator {
  std::string long_name;
  std::string short_name;
  bool is_accessible;

  NetworkOperator() {}

  NetworkOperator(const std::string& long_name, const std::string& short_name,
                  bool is_accessible)
      : long_name(long_name),
        short_name(short_name),
        is_accessible(is_accessible) {}
};

static std::map<std::string, NetworkOperator> gNetworkOperators;
static std::string gCurrentNetworkOperator = "";

enum OperatorSelectionMethod {
  kOperatorAutomatic = 0,
  kOperatorManual = 1,
  kOperatorDeregistered = 2,
  kOperatorManualThenAutomatic = 4
};

static void init_virtual_network() {
  gGSMNeighboringCells.resize(1);
  gGSMNeighboringCells[0].cid = (char*)"0000";
  gGSMNeighboringCells[0].rssi = 75;
  gNetworkOperators["311740"] =
      NetworkOperator("Android Virtual Operator", "Android", true);
  gNetworkOperators["310300"] =
      NetworkOperator("Alternative Operator", "Alternative", true);
  gNetworkOperators["310400"] =
      NetworkOperator("Hermetic Network Operator", "Hermetic", false);
}

static OperatorSelectionMethod gOperatorSelectionMethod = kOperatorDeregistered;

static void request_query_network_selection_mode(void* /*data*/,
                                                 size_t /*datalen*/,
                                                 RIL_Token t) {
  ALOGV("Query operator selection mode (%d)", gOperatorSelectionMethod);
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gOperatorSelectionMethod,
                                 sizeof(gOperatorSelectionMethod));
}

static void request_operator(void* /*data*/, size_t /*datalen*/, RIL_Token t) {
  std::map<std::string, NetworkOperator>::iterator iter =
      gNetworkOperators.find(gCurrentNetworkOperator);

  ALOGV("Requesting current operator info");

  if (iter == gNetworkOperators.end()) {
    gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
    return;
  }

  const char* response[] = {iter->second.long_name.c_str(),
                            iter->second.short_name.c_str(),
                            iter->first.c_str()};

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
}

static void request_query_available_networks(void* /*data*/, size_t /*datalen*/,
                                             RIL_Token t) {
  const char** available_networks =
      new const char*[gNetworkOperators.size() * 4];

  ALOGV("Querying available networks.");

  // TODO(ender): this should only respond once operator is selected and
  // registered.
  int index = 0;
  for (std::map<std::string, NetworkOperator>::iterator iter =
           gNetworkOperators.begin();
       iter != gNetworkOperators.end(); ++iter) {
    // TODO(ender): wrap in a neat structure maybe?
    available_networks[index++] = iter->second.long_name.c_str();
    available_networks[index++] = iter->second.short_name.c_str();
    available_networks[index++] = iter->first.c_str();
    if (!iter->second.is_accessible) {
      available_networks[index++] = "forbidden";
    } else if (iter->first == gCurrentNetworkOperator) {
      available_networks[index++] = "current";
    } else {
      available_networks[index++] = "available";
    }
  }

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &available_networks,
                                 4 * gNetworkOperators.size());
  delete[] available_networks;
}

static void request_set_automatic_network_selection(RIL_Token t) {
  ALOGV("Requesting automatic operator selection");
  gCurrentNetworkOperator = gNetworkOperators.begin()->first;
  gOperatorSelectionMethod = kOperatorAutomatic;
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_set_manual_network_selection(void* data, size_t /*datalen*/,
                                                 RIL_Token t) {
  char* mccmnc = (char*)data;

  ALOGV("Requesting manual operator selection: %s", mccmnc);

  std::map<std::string, NetworkOperator>::iterator iter =
      gNetworkOperators.find(mccmnc);

  if (iter == gNetworkOperators.end() || iter->second.is_accessible) {
    gce_ril_env->OnRequestComplete(t, RIL_E_ILLEGAL_SIM_OR_ME, NULL, 0);
    return;
  }

  gCurrentNetworkOperator = mccmnc;
  gOperatorSelectionMethod = kOperatorManual;

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static const char kDefaultSMSC[] = "00";
static int gNextSmsMessageId = 1;

static void request_cdma_send_SMS(void* /*data*/, RIL_Token t) {
  RIL_SMS_Response response = {0, 0, 0};
  // RIL_CDMA_SMS_Message* rcsm = (RIL_CDMA_SMS_Message*) data;

  ALOGW("CDMA SMS Send is currently not implemented.");

  // Cdma Send SMS implementation will go here:
  // But it is not implemented yet.
  memset(&response, 0, sizeof(response));
  response.messageRef = -1;  // This must be BearerData MessageId.
  gce_ril_env->OnRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response,
                                 sizeof(response));
}

static void request_send_SMS(void* data, RIL_Token t) {
  RIL_SMS_Response response = {0, 0, 0};

  ALOGV("Send GSM SMS Message");

  // SMSC is an address of SMS center or NULL for default.
  const char* smsc = ((const char**)data)[0];
  if (smsc == NULL) smsc = &kDefaultSMSC[0];

  response.messageRef = gNextSmsMessageId++;
  response.ackPDU = NULL;
  response.errorCode = 0;

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));

  // response.messageRef = -1;
  // gce_ril_env->OnRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response,
  //                                sizeof(response));
}

static void request_set_cell_info_list_rate(void* data, size_t /*datalen*/,
                                            RIL_Token t) {
  // For now we'll save the rate but no RIL_UNSOL_CELL_INFO_LIST messages
  // will be sent.
  ALOGV("Setting cell info list rate.");
  s_cell_info_rate_ms = ((int*)data)[0];
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}
static void request_ims_send_SMS(void* data, size_t /*datalen*/, RIL_Token t) {
  RIL_IMS_SMS_Message* args = (RIL_IMS_SMS_Message*)data;
  RIL_SMS_Response response{};

  ALOGV("Send IMS SMS Message");

  switch (args->tech) {
    case RADIO_TECH_3GPP:
      return request_send_SMS(args->message.gsmMessage, t);

    case RADIO_TECH_3GPP2:
      return request_cdma_send_SMS(args->message.gsmMessage, t);

    default:
      ALOGE("Invalid SMS format value: %d", args->tech);
      response.messageRef = -2;
      gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, &response,
                                     sizeof(response));
  }
}

static void request_SMS_acknowledge(void* data, size_t /*datalen*/,
                                    RIL_Token t) {
  int* ack = (int*)data;

  // TODO(ender): we should retain "incoming" sms for later reception.
  ALOGV("SMS receipt %ssuccessful (reason %d).", ack[0] ? "" : "un", ack[1]);

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

struct SimFileCommand {
  uint8_t command;
  uint16_t efid;
  uint8_t param1;
  uint8_t param2;
  uint8_t param3;

  bool operator<(const SimFileCommand& other) const {
    uint64_t sum1, sum2;
    sum1 = (command * 1ull << 40) | (efid * 1ull << 24) | (param1 << 16) |
           (param2 << 8) | (param3);
    sum2 = (other.command * 1ull << 40) | (other.efid * 1ull << 24) |
           (other.param1 << 16) | (other.param2 << 8) | (other.param3);
    return sum1 < sum2;
  }

  SimFileCommand(uint8_t cmd, uint16_t efid, uint8_t p1, uint8_t p2, uint8_t p3)
      : command(cmd), efid(efid), param1(p1), param2(p2), param3(p3) {}
};

struct SimFileResponse {
  uint8_t sw1;
  uint8_t sw2;
  const char* data;

  SimFileResponse() : sw1(0), sw2(0), data(NULL) {}

  SimFileResponse(uint8_t sw1, uint8_t sw2, const char* data)
      : sw1(sw1), sw2(sw2), data(data) {}
};

// TODO(ender): Double check & rewrite these.
std::map<SimFileCommand, SimFileResponse> gSimFileSystem;

static void init_sim_file_system() {
  gSimFileSystem[SimFileCommand(192, 28436, 0, 0, 15)] =
      SimFileResponse(144, 0, "000000146f1404001aa0aa01020000");
  gSimFileSystem[SimFileCommand(176, 28436, 0, 0, 20)] =
      SimFileResponse(144, 0, "416e64726f6964ffffffffffffffffffffffffff");
  gSimFileSystem[SimFileCommand(192, 28433, 0, 0, 15)] =
      SimFileResponse(144, 0, "000000016f11040011a0aa01020000");
  gSimFileSystem[SimFileCommand(176, 28433, 0, 0, 1)] =
      SimFileResponse(144, 0, "55");
  gSimFileSystem[SimFileCommand(192, 12258, 0, 0, 15)] =
      SimFileResponse(144, 0, "0000000a2fe204000fa0aa01020000");
  gSimFileSystem[SimFileCommand(176, 12258, 0, 0, 10)] =
      SimFileResponse(144, 0, "98101430121181157002");
  gSimFileSystem[SimFileCommand(192, 28435, 0, 0, 15)] =
      SimFileResponse(144, 0, "000000016f13040011a0aa01020000");
  gSimFileSystem[SimFileCommand(176, 28435, 0, 0, 1)] =
      SimFileResponse(144, 0, "55");
  gSimFileSystem[SimFileCommand(192, 28472, 0, 0, 15)] =
      SimFileResponse(144, 0, "0000000f6f3804001aa0aa01020000");
  gSimFileSystem[SimFileCommand(176, 28472, 0, 0, 15)] =
      SimFileResponse(144, 0, "ff30ffff3c003c03000c0000f03f00");
  gSimFileSystem[SimFileCommand(192, 28617, 0, 0, 15)] =
      SimFileResponse(144, 0, "000000086fc9040011a0aa01020104");
  gSimFileSystem[SimFileCommand(178, 28617, 1, 4, 4)] =
      SimFileResponse(144, 0, "01000000");
  gSimFileSystem[SimFileCommand(192, 28618, 0, 0, 15)] =
      SimFileResponse(144, 0, "0000000a6fca040011a0aa01020105");
  gSimFileSystem[SimFileCommand(178, 28618, 1, 4, 5)] =
      SimFileResponse(144, 0, "0000000000");
  gSimFileSystem[SimFileCommand(192, 28589, 0, 0, 15)] =
      SimFileResponse(144, 0, "000000046fad04000aa0aa01020000");
  gSimFileSystem[SimFileCommand(176, 28589, 0, 0, 4)] =
      SimFileResponse(144, 0, "00000003");
  gSimFileSystem[SimFileCommand(192, 28438, 0, 0, 15)] =
      SimFileResponse(144, 0, "000000026f1604001aa0aa01020000");
  gSimFileSystem[SimFileCommand(176, 28438, 0, 0, 2)] =
      SimFileResponse(144, 0, "0233");
  gSimFileSystem[SimFileCommand(192, 28486, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28621, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28613, 0, 0, 15)] =
      SimFileResponse(144, 0, "000000f06fc504000aa0aa01020118");
  gSimFileSystem[SimFileCommand(178, 28613, 1, 4, 24)] = SimFileResponse(
      144, 0, "43058441aa890affffffffffffffffffffffffffffffffff");
  gSimFileSystem[SimFileCommand(192, 28480, 0, 0, 15)] =
      SimFileResponse(144, 0, "000000806f40040011a0aa01020120");
  // Primary phone number encapsulated
  // [51][55][21][43][65][f7] = 1 555 1234 567$
  gSimFileSystem[SimFileCommand(178, 28480, 1, 4, 32)] = SimFileResponse(
      144, 0,
      "ffffffffffffffffffffffffffffffffffff07915155214365f7ffffffffffff");
  gSimFileSystem[SimFileCommand(192, 28615, 0, 0, 15)] =
      SimFileResponse(144, 0, "000000406fc7040011a0aa01020120");
  // Voice mail number encapsulated
  // [56][6f][69][63][65][6d][61][69][6c] = 'Voicemail'
  // [51][55][67][45][23][f1] = 1 555 7654 321$
  gSimFileSystem[SimFileCommand(178, 28615, 1, 4, 32)] = SimFileResponse(
      144, 0,
      "566f6963656d61696cffffffffffffffffff07915155674523f1ffffffffffff");
  gSimFileSystem[SimFileCommand(192, 12037, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28437, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28478, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28450, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28456, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28474, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28481, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28484, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28493, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(192, 28619, 0, 0, 15)] =
      SimFileResponse(148, 4, NULL);
  gSimFileSystem[SimFileCommand(176, 28506, 0, 0, 4)] =
      SimFileResponse(144, 0, "00000013");
}

static void request_SIM_IO(void* data, size_t /*datalen*/, RIL_Token t) {
  const RIL_SIM_IO_v6& args = *(RIL_SIM_IO_v6*)data;
  RIL_SIM_IO_Response sr = {0, 0, 0};

  ALOGV(
      "Requesting SIM File IO: %d EFID %x, Params: %d, %d, %d, path: %s, "
      "data %s PIN: %s AID: %s",
      args.command, args.fileid, args.p1, args.p2, args.p3, args.path,
      args.data, args.pin2, args.aidPtr);

  SimFileCommand cmd(args.command, args.fileid, args.p1, args.p2, args.p3);

  std::map<SimFileCommand, SimFileResponse>::iterator resp =
      gSimFileSystem.find(cmd);

  if (resp != gSimFileSystem.end()) {
    sr.sw1 = resp->second.sw1;
    sr.sw2 = resp->second.sw2;
    if (resp->second.data) sr.simResponse = strdup(resp->second.data);
    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
    return;
  }

  ALOGW("Unsupported SIM File IO command.");
  gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}

static void request_enter_sim_pin(void* data, size_t /*datalen*/, RIL_Token t) {
  const char** pin_aid = (const char**)data;

  ALOGV("Entering PIN: %s / %s", pin_aid[0], pin_aid[1]);

  ++gSimPINAttempts;
  int remaining_attempts = gSimPINAttemptsMax - gSimPINAttempts;

  bool is_valid = false;

  if (gSimStatus == SIM_PIN) {
    is_valid = (gSimPIN == pin_aid[0]);
  } else if (gSimStatus == SIM_PUK) {
    is_valid = (gSimPUK == pin_aid[0]);
  } else {
    ALOGV("Unexpected SIM status for unlock: %d", gSimStatus);
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
    return;
  }

  if (!is_valid) {
    if (gSimPINAttempts == gSimPINAttemptsMax) {
      if (gSimStatus == SIM_PIN) {
        gSimStatus = SIM_PUK;
        gSimPINAttempts = 0;
      } else {
        ALOGV("PIN and PUK verification failed; locking SIM card.");
        gSimStatus = SIM_NOT_READY;
        gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
        return;
      }
    }

    gce_ril_env->OnRequestComplete(t, RIL_E_PASSWORD_INCORRECT,
                                   &remaining_attempts,
                                   sizeof(remaining_attempts));
  } else {
    if (gSimStatus == SIM_PUK) {
      ALOGV("Resetting SIM PIN to %s", pin_aid[1]);
      gSimPIN = pin_aid[1];
    }

    gSimPINAttempts = 0;
    gSimStatus = SIM_READY;
    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &remaining_attempts,
                                   sizeof(remaining_attempts));
  }

  pollSIMState(NULL);
}

/**
 * No longer POLL.
 */
static void pollSIMState(void* /*param*/) {
  // TODO(ender): check radio state?

  ALOGV("Polling SIM Status.");

  switch (gSimStatus) {
    case SIM_ABSENT:
    case SIM_PIN:
    case SIM_PUK:
    case SIM_NETWORK_PERSONALIZATION:
    default:
      ALOGV("SIM Absent or Locked");
      break;

    case SIM_NOT_READY:
      // Transition directly to READY. Set default network operator.
      if (gRadioPowerState == RADIO_STATE_ON) {
        gSimStatus = SIM_READY;
        gCurrentNetworkOperator = "311740";
      }

      gce_ril_env->RequestTimedCallback(pollSIMState, NULL, &TIMEVAL_SIMPOLL);
      break;

    case SIM_READY:
      ALOGV("SIM Ready. Notifying network state changed.");
      break;
  }

  if (gRadioPowerState != RADIO_STATE_OFF) {
    gce_ril_env->OnUnsolicitedResponse(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED,
                                       NULL, 0);
    gce_ril_env->OnUnsolicitedResponse(
        RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, NULL, 0);
  }
}

std::map<SIM_Status, RIL_AppStatus> gRilAppStatus;

static void init_sim_status() {
  gRilAppStatus[SIM_ABSENT] = (RIL_AppStatus){RIL_APPTYPE_UNKNOWN,
                                              RIL_APPSTATE_UNKNOWN,
                                              RIL_PERSOSUBSTATE_UNKNOWN,
                                              NULL,
                                              NULL,
                                              0,
                                              RIL_PINSTATE_UNKNOWN,
                                              RIL_PINSTATE_UNKNOWN};
  gRilAppStatus[SIM_NOT_READY] =
      (RIL_AppStatus){RIL_APPTYPE_SIM,
                      RIL_APPSTATE_DETECTED,
                      RIL_PERSOSUBSTATE_UNKNOWN,
                      NULL,
                      NULL,
                      0,
                      RIL_PINSTATE_ENABLED_NOT_VERIFIED,
                      RIL_PINSTATE_ENABLED_NOT_VERIFIED};
  gRilAppStatus[SIM_READY] = (RIL_AppStatus){
      RIL_APPTYPE_SIM,
      RIL_APPSTATE_READY,
      RIL_PERSOSUBSTATE_READY,
      NULL,
      NULL,
      0,
      RIL_PINSTATE_ENABLED_VERIFIED,
      RIL_PINSTATE_ENABLED_VERIFIED,
  };
  gRilAppStatus[SIM_PIN] = (RIL_AppStatus){RIL_APPTYPE_SIM,
                                           RIL_APPSTATE_PIN,
                                           RIL_PERSOSUBSTATE_UNKNOWN,
                                           NULL,
                                           NULL,
                                           0,
                                           RIL_PINSTATE_ENABLED_NOT_VERIFIED,
                                           RIL_PINSTATE_UNKNOWN};
  gRilAppStatus[SIM_PUK] = (RIL_AppStatus){RIL_APPTYPE_SIM,
                                           RIL_APPSTATE_PUK,
                                           RIL_PERSOSUBSTATE_UNKNOWN,
                                           NULL,
                                           NULL,
                                           0,
                                           RIL_PINSTATE_ENABLED_BLOCKED,
                                           RIL_PINSTATE_UNKNOWN};
  gRilAppStatus[SIM_NETWORK_PERSONALIZATION] =
      (RIL_AppStatus){RIL_APPTYPE_SIM,
                      RIL_APPSTATE_SUBSCRIPTION_PERSO,
                      RIL_PERSOSUBSTATE_SIM_NETWORK,
                      NULL,
                      NULL,
                      0,
                      RIL_PINSTATE_ENABLED_NOT_VERIFIED,
                      RIL_PINSTATE_UNKNOWN};
  gRilAppStatus[RUIM_ABSENT] = (RIL_AppStatus){RIL_APPTYPE_UNKNOWN,
                                               RIL_APPSTATE_UNKNOWN,
                                               RIL_PERSOSUBSTATE_UNKNOWN,
                                               NULL,
                                               NULL,
                                               0,
                                               RIL_PINSTATE_UNKNOWN,
                                               RIL_PINSTATE_UNKNOWN};
  gRilAppStatus[RUIM_NOT_READY] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
                                                  RIL_APPSTATE_DETECTED,
                                                  RIL_PERSOSUBSTATE_UNKNOWN,
                                                  NULL,
                                                  NULL,
                                                  0,
                                                  RIL_PINSTATE_UNKNOWN,
                                                  RIL_PINSTATE_UNKNOWN};
  gRilAppStatus[RUIM_READY] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
                                              RIL_APPSTATE_READY,
                                              RIL_PERSOSUBSTATE_READY,
                                              NULL,
                                              NULL,
                                              0,
                                              RIL_PINSTATE_UNKNOWN,
                                              RIL_PINSTATE_UNKNOWN};
  gRilAppStatus[RUIM_PIN] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
                                            RIL_APPSTATE_PIN,
                                            RIL_PERSOSUBSTATE_UNKNOWN,
                                            NULL,
                                            NULL,
                                            0,
                                            RIL_PINSTATE_ENABLED_NOT_VERIFIED,
                                            RIL_PINSTATE_UNKNOWN};
  gRilAppStatus[RUIM_PUK] = (RIL_AppStatus){RIL_APPTYPE_RUIM,
                                            RIL_APPSTATE_PUK,
                                            RIL_PERSOSUBSTATE_UNKNOWN,
                                            NULL,
                                            NULL,
                                            0,
                                            RIL_PINSTATE_ENABLED_BLOCKED,
                                            RIL_PINSTATE_UNKNOWN};
  gRilAppStatus[RUIM_NETWORK_PERSONALIZATION] =
      (RIL_AppStatus){RIL_APPTYPE_RUIM,
                      RIL_APPSTATE_SUBSCRIPTION_PERSO,
                      RIL_PERSOSUBSTATE_SIM_NETWORK,
                      NULL,
                      NULL,
                      0,
                      RIL_PINSTATE_ENABLED_NOT_VERIFIED,
                      RIL_PINSTATE_UNKNOWN};
}

/**
 * Get the current card status.
 */
static void getCardStatus(RIL_Token t) {
  ALOGV("Querying SIM status.");
  RIL_CardStatus_v6 card_status;

  if (gSimStatus == SIM_ABSENT) {
    card_status.card_state = RIL_CARDSTATE_ABSENT;
    card_status.num_applications = 0;
  } else {
    card_status.card_state = RIL_CARDSTATE_PRESENT;
    card_status.num_applications = 1;
  }

  card_status.universal_pin_state = RIL_PINSTATE_UNKNOWN;
  card_status.gsm_umts_subscription_app_index = -1;
  card_status.cdma_subscription_app_index = -1;
  card_status.ims_subscription_app_index = -1;

  // Initialize application status
  for (int i = 0; i < RIL_CARD_MAX_APPS; i++) {
    card_status.applications[i] = gRilAppStatus[SIM_ABSENT];
  }

  if (card_status.num_applications > 0) {
    card_status.gsm_umts_subscription_app_index = 0;

    card_status.applications[0] = gRilAppStatus[gSimStatus];
    card_status.universal_pin_state = card_status.applications[0].pin1;
    // To enable basic CDMA (currently neither supported nor functional):
    //    card_status.num_applications = 2;
    //    card_status.cdma_subscription_app_index = 1;
    //    card_status.applications[1] =
    //        gRilAppStatus[SIM_Status(gSimStatus + RUIM_ABSENT)];
  }

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &card_status,
                                 sizeof(card_status));
}

struct SimSession {
  std::string aid;
};

static int gNextSimSessionId = 1;
static std::map<int, SimSession> gSimSessions;

static void request_sim_open_channel(void* data, size_t /*datalen*/,
                                     RIL_Token t) {
  char* aid = (char*)data;
  SimSession session;

  ALOGV("Requesting new SIM session");

  if (aid != NULL) {
    session.aid = aid;
  }

  int response = gNextSimSessionId++;
  gSimSessions[response] = session;

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response));
}

static void request_sim_close_channel(void* data, size_t /*datalen*/,
                                      RIL_Token t) {
  int session = *(int*)(data);

  ALOGV("Closing SIM session %d", session);

  if (gSimSessions.erase(session) == 0) {
    // No such session.
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
  } else {
    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  }
}

static void request_sim_apdu(void* data, size_t /*datalen*/, RIL_Token t) {
  RIL_SIM_APDU* apdu = (RIL_SIM_APDU*)data;

  ALOGV("Requesting APDU: Session %d CLA %d INST %d Params: %d %d %d, data %s",
        apdu->sessionid, apdu->cla, apdu->instruction, apdu->p1, apdu->p2,
        apdu->p3, apdu->data);

  if (gSimSessions.find(apdu->sessionid) != gSimSessions.end()) {
    RIL_SIM_IO_Response sr{};

    // Fallback / default behavior.
    sr.sw1 = 144;
    sr.sw2 = 0;
    sr.simResponse = NULL;

    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &sr, sizeof(sr));
  } else {
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
  }
}

// 0 = Lock is available, but disabled.
// 1 = Lock is available and enabled,
// 2 = lock is neither available nor enabled
static const int kFacilityLockAllDisabled = 0;

static void request_facility_lock(void* data, size_t /*datalen*/, RIL_Token t) {
  char** data_vec = (char**)data;

  // TODO(ender): implement this; essentially: AT+CLCK
  // See http://www.activexperts.com/sms-component/at/commands/?at=%2BCLCK
  // and
  // opt/telephony/src/java/com/android/internal/telephony/CommandsInterface.java
  // opt/telephony/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java

  ALOGV("Query Facility Lock Code: %s PIN2: %s Service(s): %s AID: %s",
        data_vec[0], data_vec[1], data_vec[2], data_vec[3]);

  // TODO(ender): there should be a bit vector of responses for each of the
  // services requested.
  // Depending on lock code, facilities may be unlocked or locked. We report
  // these are all unlocked, regardless of the query.
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
                                 const_cast<int*>(&kFacilityLockAllDisabled),
                                 sizeof(kFacilityLockAllDisabled));
}

static void request_international_subscriber_id_number(RIL_Token t) {
  // TODO(ender): Reuse MCC and MNC.
  std::string subscriber_id = gCurrentNetworkOperator.c_str();
  subscriber_id += "123456789";

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS,
                                 strdup(subscriber_id.c_str()), sizeof(char*));
}

static bool gScreenIsOn = true;

static void request_set_screen_state(void* data, size_t /*datalen*/,
                                     RIL_Token t) {
  gScreenIsOn = *(int*)data ? true : false;
  ALOGV("Screen is %s", gScreenIsOn ? "on" : "off");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

// Unsure which section this belongs in.

static int gModemTtyMode = 1;  // 0 = off, 1 = full, 2 = HCO, 3 = VCO.
static void request_set_tty_mode(void* data, size_t /*datalen*/, RIL_Token t) {
  int new_tty_mode = *(int*)(data);
  ALOGV("Switching modem TTY mode %d -> %d", gModemTtyMode, new_tty_mode);

  if (new_tty_mode >= 0 && new_tty_mode <= 3) {
    gModemTtyMode = new_tty_mode;
    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  } else {
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
  }
}

static void request_get_tty_mode(RIL_Token t) {
  ALOGV("Querying TTY mode");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &gModemTtyMode,
                                 sizeof(gModemTtyMode));
}

static bool gImsRegistered = false;
static int gImsFormat = RADIO_TECH_3GPP;

static void request_ims_registration_state(RIL_Token t) {
  ALOGV("Querying IMS mode");
  int reply[2];
  reply[0] = gImsRegistered;
  reply[1] = gImsFormat;

  ALOGV("Requesting IMS Registration state: %d, format=%d ", reply[0],
        reply[1]);

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply));
}

// New functions after P.
static void request_start_network_scan(RIL_Token t) {
  ALOGV("Scanning network - void");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

static void request_set_preferred_network_type_bitmap(int /*request*/, void* data,
                                               size_t /*datalen*/,
                                               RIL_Token t) {
  RIL_RadioAccessFamily desired_access = *(RIL_RadioAccessFamily*)(data);

  ALOGV("Requesting modem technology change %d -> %d", default_access, desired_access);

  /** TODO future implementation: set modem type based on radio access family.
   * 1) find supported_technologies and desired_technologies
   * 2) return RIL_E_MODE_NOT_SUPPORTED error if not supported
   */
  default_access = desired_access;
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

static void request_get_preferred_network_type_bitmap(int /*request*/, void* /*data*/,
                                               size_t /*datalen*/,
                                               RIL_Token t) {
  ALOGV("Requesting modem radio access family: %d", default_access);
  gce_ril_env->OnRequestComplete(
      t, RIL_E_SUCCESS, (RIL_RadioAccessFamily*)(&default_access), sizeof(default_access));
}

static void request_emergency_dial(int /*request*/, void* /*data*/, size_t /*datalen*/,
    RIL_Token t) {
  ALOGV("Emergency dial");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

static void request_set_sim_card_power(int /*request*/, void* /*data*/, size_t /*datalen*/,
    RIL_Token t) {
  ALOGV("Set sim card power - void");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

static void request_get_modem_stack_status(int /*request*/, RIL_Token t) {
  ALOGV("Getting modem stack status - void");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

static void request_enable_modem(int /*request*/, RIL_Token t) {
  ALOGV("Enabling modem - void");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

static void request_set_system_selection_channels(int /*request*/, RIL_Token t) {
  ALOGV("request_set_system_selection_channels - void");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

// New functions after Q.
static void request_set_signal_strength_reporting_criteria(int /*request*/, void* /*data*/,
                                                           size_t /*datalen*/, RIL_Token t) {
    ALOGV("request_set_signal_strength_reporting_criteria - void");
    gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
    return;
}

static void request_enable_uicc_applications(int /*request*/, void* data,
                                             size_t datalen,
                                             RIL_Token t) {
  ALOGV("Enable uicc applications.");

  if (data == NULL || datalen != sizeof(int)) {
    gce_ril_env->OnRequestComplete(t, RIL_E_INTERNAL_ERR, NULL, 0);
    return;
  }

  bool enable = *(int *)(data) != 0;

  ALOGV("areUiccApplicationsEnabled change from %d to %d", areUiccApplicationsEnabled, enable);

  areUiccApplicationsEnabled = enable;

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}

static void request_are_uicc_applications_enabled(int /*request*/, void* /*data*/,
                                                  size_t /*datalen*/,
                                                  RIL_Token t) {
  ALOGV("Getting whether uicc applications are enabled.");

  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &areUiccApplicationsEnabled, sizeof(bool));
}

static void request_set_radio_power(RIL_Token t) {
  ALOGV("request_set_radio_power - void");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

static void request_enter_sim_depersonalization(RIL_Token t) {
  ALOGV("request_enter_sim_depersonalization - void");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

static void request_cdma_send_sms_expect_more(RIL_Token t) {
  ALOGV("request_cdma_send_sms_expect_more - void");
  gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
  return;
}

static void gce_ril_on_request(int request, void* data, size_t datalen,
                               RIL_Token t) {
  // Ignore all requests except RIL_REQUEST_GET_SIM_STATUS
  // when RADIO_STATE_UNAVAILABLE.
  if (gRadioPowerState == RADIO_STATE_UNAVAILABLE &&
      request != RIL_REQUEST_GET_SIM_STATUS) {
    gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
    return;
  }

  // Ignore all non-power requests when RADIO_STATE_OFF.
  if (gRadioPowerState == RADIO_STATE_OFF) {
    switch (request) {
      case RIL_REQUEST_GET_SIM_STATUS:
      case RIL_REQUEST_OPERATOR:
      case RIL_REQUEST_RADIO_POWER:
      case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
        // Process all the above, even though the radio is off
        break;
      default:
        gce_ril_env->OnRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
        return;
    }
  }

  ALOGV("Received request %d", request);

  switch (request) {
    case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS:
      request_query_available_networks(data, datalen, t);
      break;
    case RIL_REQUEST_GET_IMEI:
      request_get_imei(t);
      break;
    case RIL_REQUEST_GET_IMEISV:
      request_get_imei_sv(t);
      break;
    case RIL_REQUEST_DEACTIVATE_DATA_CALL:
      request_teardown_data_call(data, datalen, t);
      break;
    case RIL_REQUEST_SCREEN_STATE:
      request_set_screen_state(data, datalen, t);
      break;
    case RIL_REQUEST_GET_SIM_STATUS:
      getCardStatus(t);
      break;
    case RIL_REQUEST_GET_CURRENT_CALLS:
      request_get_current_calls(data, datalen, t);
      break;
    case RIL_REQUEST_DIAL:
      request_dial(data, datalen, t);
      break;
    case RIL_REQUEST_HANGUP:
      request_hangup(data, datalen, t);
      break;
    case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
      request_hangup_waiting(data, datalen, t);
      break;
    case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
      request_hangup_current(t);
      break;
    case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
      request_switch_current_and_waiting(t);
      break;
    case RIL_REQUEST_ANSWER:
      request_answer_incoming(t);
      break;
    case RIL_REQUEST_SET_MUTE:
      request_set_mute(data, datalen, t);
      break;
    case RIL_REQUEST_GET_MUTE:
      request_get_mute(t);
      break;
    case RIL_REQUEST_CONFERENCE:
      request_combine_multiparty_call(data, datalen, t);
      break;
    case RIL_REQUEST_SEPARATE_CONNECTION:
      request_split_multiparty_call(data, datalen, t);
      break;
    case RIL_REQUEST_UDUB:
      request_udub_on_incoming_calls(t);
      break;
    case RIL_REQUEST_SIGNAL_STRENGTH:
      request_signal_strength(data, datalen, t);
      break;
    case RIL_REQUEST_VOICE_REGISTRATION_STATE:
    case RIL_REQUEST_DATA_REGISTRATION_STATE:
      request_registration_state(request, data, datalen, t);
      break;
    case RIL_REQUEST_OPERATOR:
      request_operator(data, datalen, t);
      break;
    case RIL_REQUEST_RADIO_POWER:
      request_radio_power(data, datalen, t);
      break;
    case RIL_REQUEST_DTMF:
    case RIL_REQUEST_DTMF_START:
      request_send_dtmf(data, datalen, t);
      break;
    case RIL_REQUEST_DTMF_STOP:
      request_send_dtmf_stop(t);
      break;
    case RIL_REQUEST_SEND_SMS:
      request_send_SMS(data, t);
      break;
    case RIL_REQUEST_CDMA_SEND_SMS:
      request_cdma_send_SMS(data, t);
      break;
    case RIL_REQUEST_SETUP_DATA_CALL:
      request_setup_data_call(data, datalen, t);
      break;
    case RIL_REQUEST_SMS_ACKNOWLEDGE:
      request_SMS_acknowledge(data, datalen, t);
      break;
    case RIL_REQUEST_GET_IMSI:
      request_international_subscriber_id_number(t);
      break;
    case RIL_REQUEST_QUERY_FACILITY_LOCK:
      request_facility_lock(data, datalen, t);
      break;
    case RIL_REQUEST_SIM_IO:
      request_SIM_IO(data, datalen, t);
      break;
    case RIL_REQUEST_SEND_USSD:
      request_send_ussd(data, datalen, t);
      break;
    case RIL_REQUEST_CANCEL_USSD:
      request_cancel_ussd(t);
      break;
    case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
      request_set_automatic_network_selection(t);
      break;
    case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
      request_set_manual_network_selection(data, datalen, t);
      break;
    case RIL_REQUEST_DATA_CALL_LIST:
      request_data_calllist(data, datalen, t);
      break;
    case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
      request_datacall_fail_cause(t);
      break;
    case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
      request_query_network_selection_mode(data, datalen, t);
      break;
    case RIL_REQUEST_OEM_HOOK_RAW:
    case RIL_REQUEST_OEM_HOOK_STRINGS:
      ALOGV("OEM Hooks not supported!");
      gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
      break;
    case RIL_REQUEST_WRITE_SMS_TO_SIM:
      request_write_sms_to_sim(data, datalen, t);
      break;
    case RIL_REQUEST_DELETE_SMS_ON_SIM:
      request_delete_sms_on_sim(data, datalen, t);
      break;
    case RIL_REQUEST_ENTER_SIM_PIN:
    case RIL_REQUEST_ENTER_SIM_PUK:
    case RIL_REQUEST_ENTER_SIM_PIN2:
    case RIL_REQUEST_ENTER_SIM_PUK2:
    case RIL_REQUEST_CHANGE_SIM_PIN:
    case RIL_REQUEST_CHANGE_SIM_PIN2:
      request_enter_sim_pin(data, datalen, t);
      break;
    case RIL_REQUEST_VOICE_RADIO_TECH: {
      RIL_RadioTechnology tech = getBestVoiceTechnology(gModemCurrentType);
      gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, &tech, sizeof(tech));
      break;
    }
    case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
      request_set_preferred_network_type(request, data, datalen, t);
      break;
    case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
      request_get_preferred_network_type(request, data, datalen, t);
      break;
    case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
      request_get_neighboring_cell_ids(data, datalen, t);
      break;
    case RIL_REQUEST_GET_CELL_INFO_LIST:
      request_get_cell_info_list(data, datalen, t);
      break;
    case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
      request_set_cell_info_list_rate(data, datalen, t);
      break;
    case RIL_REQUEST_BASEBAND_VERSION:
      request_baseband_version(t);
      break;
    case RIL_REQUEST_SET_TTY_MODE:
      request_set_tty_mode(data, datalen, t);
      break;
    case RIL_REQUEST_QUERY_TTY_MODE:
      request_get_tty_mode(t);
      break;
    case RIL_REQUEST_GET_RADIO_CAPABILITY:
      request_get_radio_capability(t);
      break;
    case RIL_REQUEST_SET_RADIO_CAPABILITY:
      request_set_radio_capability(data, datalen, t);
      break;
    case RIL_REQUEST_SET_DATA_PROFILE:
      gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
      break;
    case RIL_REQUEST_GET_HARDWARE_CONFIG:
      request_hardware_config(t);
      break;
    case RIL_REQUEST_IMS_REGISTRATION_STATE:
      request_ims_registration_state(t);
      break;
    case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
      request_sim_apdu(data, datalen, t);
      break;
    case RIL_REQUEST_SIM_OPEN_CHANNEL:
      request_sim_open_channel(data, datalen, t);
      break;
    case RIL_REQUEST_SIM_CLOSE_CHANNEL:
      request_sim_close_channel(data, datalen, t);
      break;
    case RIL_REQUEST_IMS_SEND_SMS:
      request_ims_send_SMS(data, datalen, t);
      break;
    case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
      ALOGW("INITIAL ATTACH APN");
      gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
      break;

// New requests after P.
    case RIL_REQUEST_START_NETWORK_SCAN:
      request_start_network_scan(t);
      break;
    case RIL_REQUEST_GET_MODEM_STACK_STATUS:
      request_get_modem_stack_status(request, t);
      break;
    case RIL_REQUEST_ENABLE_MODEM:
      request_enable_modem(request, t);
      break;
    case RIL_REQUEST_EMERGENCY_DIAL:
      request_emergency_dial(request, data, datalen, t);
      break;
    case RIL_REQUEST_SET_SIM_CARD_POWER:
      request_set_sim_card_power(request, data, datalen, t);
      break;
    case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP:
      request_get_preferred_network_type_bitmap(request, data, datalen, t);
      break;
    case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP:
      request_set_preferred_network_type_bitmap(request, data, datalen, t);
      break;
    case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS:
      request_set_system_selection_channels(request, t);
      break;
    case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
      gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
      break;
    case RIL_REQUEST_DEVICE_IDENTITY:
      request_device_identity(request, data, datalen, t);
      break;
    case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
      request_cdma_get_subscription_source(request, data, datalen, t);
      break;
    case RIL_REQUEST_CDMA_SUBSCRIPTION:
      request_cdma_subscription(request, data, datalen, t);
      break;
    case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
      request_cdma_set_subscription_source(request, data, datalen, t);
      break;
    case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
      request_cdma_get_roaming_preference(request, data, datalen, t);
      break;
    case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
      request_cdma_set_roaming_preference(request, data, datalen, t);
      break;
    case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
      request_exit_emergency_mode(data, datalen, t);
      break;

// New requests after Q.
    case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA:
      request_set_signal_strength_reporting_criteria(request, data, datalen, t);
      break;
    case RIL_REQUEST_ENABLE_UICC_APPLICATIONS:
      request_enable_uicc_applications(request, data, datalen, t);
      break;
    case RIL_REQUEST_ARE_UICC_APPLICATIONS_ENABLED:
      request_are_uicc_applications_enabled(request, data, datalen, t);
      break;
    case RIL_REQUEST_SET_RADIO_POWER:
      request_set_radio_power(t);
      break;
    case RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION:
      request_enter_sim_depersonalization(t);
      break;
    case RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE:
      request_cdma_send_sms_expect_more(t);
      break;
    default:
      ALOGE("Request %d not supported.", request);
      gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
      break;
  }
}

#define CUTTLEFISH_RIL_VERSION 6

static const RIL_RadioFunctions ril_callbacks = {
    CUTTLEFISH_RIL_VERSION,     gce_ril_on_request, gce_ril_current_state,
    gce_ril_on_supports, gce_ril_on_cancel,  gce_ril_get_version};

extern "C" {

const RIL_RadioFunctions* RIL_Init(const struct RIL_Env* env, int /*argc*/,
                                   char** /*argv*/) {
  time(&gce_ril_start_time);
  gce_ril_env = env;

  global_ril_config = cvd::DeviceConfig::Get();
  if (!global_ril_config) {
    ALOGE("Failed to open device configuration!!!");
    return nullptr;
  }

  TearDownNetworkInterface();

  init_modem_supported_network_types();
  init_modem_technologies();
  init_virtual_network();
  init_sim_file_system();
  init_sim_status();

  return &ril_callbacks;
}

}  // extern "C"
