/*
** 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/vsoc_ril.h"

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

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

#include "common/libs/net/netlink_client.h"
#include "common/libs/net/network_interface.h"
#include "common/libs/net/network_interface_manager.h"
#include "common/vsoc/lib/ril_region_view.h"
#include "guest/libs/platform_support/api_level_fixes.h"

#define VSOC_RIL_VERSION_STRING "Android VSoC RIL 1.0"

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

#if VSOC_PLATFORM_SDK_BEFORE(K)
#define RADIO_TECH_3GPP 1
#define RADIO_TECH_3GPP2 2
#endif

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 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;

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;

// 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"));

  if (ni) {
    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"));

  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) {
#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
  RIL_Data_Call_Response_v11* responses =
      new RIL_Data_Call_Response_v11[gDataCalls.size()];
#else
  RIL_Data_Call_Response_v6* responses =
      new RIL_Data_Call_Response_v6[gDataCalls.size()];
#endif

  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;
    }

    auto ril_region_view = vsoc::ril::RilRegionView::GetInstance();

    responses[index].ifname = (char*)"rmnet0";
    responses[index].addresses =
      const_cast<char*>(ril_region_view->address_and_prefix_length());
    responses[index].dnses = (char*)ril_region_view->data()->dns;
    responses[index].gateways = (char*)ril_region_view->data()->gateway;
#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
    responses[index].pcscf = (char*)"";
    responses[index].mtu = 1440;
#endif
  }

  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 VSOC RIL.");
    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, 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()) {
    auto ril_region_view = vsoc::ril::RilRegionView::GetInstance();
    SetUpNetworkInterface(ril_region_view->data()->ipaddr,
                          ril_region_view->data()->prefixlen,
                          ril_region_view->data()->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.
#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
  RIL_SignalStrength_v10 strength;
#else
  RIL_SignalStrength_v6 strength;
#endif

  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));
  }
}

#if VSOC_PLATFORM_SDK_AFTER(L)
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);
}
#endif

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;

#if VSOC_PLATFORM_SDK_AFTER(K)
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));
}
#endif

// 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 VSOC version " VSOC_RIL_VERSION_STRING);
  return VSOC_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;
}

#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
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;

#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
  RIL_CellInfo_v12 ci;
#else
  RIL_CellInfo ci;
#endif

  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);
  }
}
#endif

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["310260"] =
      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));
}

#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
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);
}
#endif
#if VSOC_PLATFORM_SDK_AFTER(J_MR2)
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));
  }
}
#endif

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 = "310260";
      }

      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);
  }
}

#if VSOC_PLATFORM_SDK_AFTER(K)
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);
  }
}
#endif

// 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));
}

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 (except
  // RIL_REQUEST_GET_SIM_STATUS)
  if (gRadioPowerState == RADIO_STATE_OFF &&
      !(request == RIL_REQUEST_RADIO_POWER ||
        request == RIL_REQUEST_GET_SIM_STATUS)) {
    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;
#if VSOC_PLATFORM_SDK_AFTER(J_MR1)
    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;
#endif
    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;

#if VSOC_PLATFORM_SDK_AFTER(L)
    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;
#endif
#if VSOC_PLATFORM_SDK_AFTER(K)
    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;
#endif
#if VSOC_PLATFORM_SDK_AFTER(J_MR2)
    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;

#endif
    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;
    default:
      ALOGE("Request %d not supported.", request);
      gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
      break;
  }
}

#define VSOC_RIL_VERSION 6

static const RIL_RadioFunctions ril_callbacks = {
    VSOC_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;

  TearDownNetworkInterface();

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

  return &ril_callbacks;
}

}  // extern "C"
