Merge "Migrate device/google/cuttlefish_common to androidx.test" into cuttlefish-testing
diff --git a/Android.bp b/Android.bp
index a604f8c..624154c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -26,6 +26,13 @@
     host_supported: true,
 }
 
+cc_library_headers {
+    name: "cuttlefish_common_headers_product",
+    product_specific: true,
+    export_include_dirs: ["."],
+    host_supported: true,
+}
+
 // TODO(b/67435044) Update the include paths and remove this
 cc_library_headers {
     name: "cuttlefish_glog",
@@ -34,6 +41,14 @@
     host_supported: true,
 }
 
+// TODO(b/67435044) Update the include paths and remove this
+cc_library_headers {
+    name: "cuttlefish_glog_product",
+    product_specific: true,
+    export_include_dirs: ["common/libs"],
+    host_supported: true,
+}
+
 cc_defaults {
     name: "cuttlefish_base",
     gnu_extensions: false,
@@ -58,6 +73,29 @@
 }
 
 cc_defaults {
+    name: "cuttlefish_guest_product_only",
+    product_specific: true,
+    gnu_extensions: false,
+    header_libs: [
+        "cuttlefish_common_headers_product",
+        "cuttlefish_kernel_headers_product",
+        "cuttlefish_shared_config_product",
+    ],
+    target: {
+        host: {
+            host_ldlibs: ["-lrt"],
+            cflags: ["-DCUTTLEFISH_HOST"],
+            compile_multilib: "64",
+        },
+        // We don't need Darwin host-side builds
+        darwin: {
+            enabled: false,
+        },
+    },
+    cflags: ["-Werror", "-Wall"],
+}
+
+cc_defaults {
     name: "cuttlefish_guest_only",
     defaults: ["cuttlefish_base"],
 }
@@ -131,6 +169,7 @@
         "libbase",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
 
 cc_binary_host {
@@ -166,6 +205,7 @@
         "libgtest_host",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
 
 cc_test_host {
@@ -178,6 +218,7 @@
         "libbase",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
 
 cc_binary_host {
diff --git a/OWNERS b/OWNERS
index 5c0d0bd..3f32871 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,5 +1,7 @@
+astrachan@google.com
 ghartman@google.com
 jemoreira@google.com
-haining@google.com
 malchev@google.com
 schuffelen@google.com
+muntsinger@google.com
+rammuthiah@google.com
\ No newline at end of file
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..71249ba
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,16 @@
+{
+  "presubmit": [
+    {
+      "name": "circqueue_test",
+      "host": true
+    },
+    {
+      "name": "lock_test",
+      "host": true
+    },
+    {
+      "name": "vsoc_graphics_test",
+      "host": true
+    }
+  ]
+}
diff --git a/common/frontend/socket_vsock_proxy/main.cpp b/common/frontend/socket_vsock_proxy/main.cpp
index 7f7248a..ac421a3 100644
--- a/common/frontend/socket_vsock_proxy/main.cpp
+++ b/common/frontend/socket_vsock_proxy/main.cpp
@@ -140,14 +140,24 @@
             << FLAGS_vsock_port;
   auto server = cvd::SharedFD::SocketLocalServer(FLAGS_tcp_port, SOCK_STREAM);
   CHECK(server->IsOpen()) << "Could not start server on " << FLAGS_tcp_port;
+  LOG(INFO) << "Accepting client connections";
+  int last_failure_reason = 0;
   while (true) {
-    LOG(INFO) << "waiting for client connection";
     auto client_socket = cvd::SharedFD::Accept(*server);
     CHECK(client_socket->IsOpen()) << "error creating client socket";
-    LOG(INFO) << "client socket accepted";
     cvd::SharedFD vsock_socket = cvd::SharedFD::VsockClient(
         FLAGS_vsock_guest_cid, FLAGS_vsock_port, SOCK_STREAM);
-    if (!vsock_socket->IsOpen()) {
+    if (vsock_socket->IsOpen()) {
+      last_failure_reason = 0;
+      LOG(INFO) << "Connected to vsock:" << FLAGS_vsock_guest_cid << ":"
+                << FLAGS_vsock_port;
+    } else {
+      // Don't log if the previous connection failed with the same error
+      if (last_failure_reason != vsock_socket->GetErrno()) {
+        last_failure_reason = vsock_socket->GetErrno();
+        LOG(ERROR) << "Unable to connect to vsock server: "
+                   << vsock_socket->StrError();
+      }
       continue;
     }
     auto thread = std::thread(HandleConnection, std::move(vsock_socket),
diff --git a/common/libs/Android.bp b/common/libs/Android.bp
index 17a4c9d..e70e6ab 100644
--- a/common/libs/Android.bp
+++ b/common/libs/Android.bp
@@ -15,6 +15,7 @@
 
 subdirs = [
     "auto_resources",
+    "device_config",
     "fs",
     "net",
     "strings",
diff --git a/common/libs/auto_resources/Android.bp b/common/libs/auto_resources/Android.bp
index 2c575ce..482585e 100644
--- a/common/libs/auto_resources/Android.bp
+++ b/common/libs/auto_resources/Android.bp
@@ -21,6 +21,14 @@
     defaults: ["cuttlefish_host_and_guest"],
 }
 
+cc_library_static {
+    name: "cuttlefish_auto_resources_static",
+    srcs: [
+        "auto_resources.cpp",
+    ],
+    defaults: ["cuttlefish_guest_product_only"],
+}
+
 cc_test_host {
     name: "auto_free_buffer_test",
     srcs: [
@@ -33,4 +41,5 @@
         "libgmock",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
diff --git a/common/libs/auto_resources/TEST_MAPPING b/common/libs/auto_resources/TEST_MAPPING
new file mode 100644
index 0000000..1e34e75
--- /dev/null
+++ b/common/libs/auto_resources/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit": [
+    {
+      "name": "auto_free_buffer_test",
+      "host": true
+    }
+  ]
+}
diff --git a/common/libs/constants/ril.h b/common/libs/constants/ril.h
deleted file mode 100644
index b9c3e8a..0000000
--- a/common/libs/constants/ril.h
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-/*
- * Copyright (C) 2019 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 is 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.
- */
-
-#if defined(CUTTLEFISH_HOST)
-#define CF_PROPERTY_PREFIX "androidboot"
-#else
-#define CF_PROPERTY_PREFIX "ro.boot"
-#endif
-
-#define CUTTLEFISH_RIL_ADDR_PROPERTY CF_PROPERTY_PREFIX ".cuttlefish_ril_addr"
-#define CUTTLEFISH_RIL_GATEWAY_PROPERTY \
-  CF_PROPERTY_PREFIX ".cuttlefish_ril_gateway"
-#define CUTTLEFISH_RIL_DNS_PROPERTY CF_PROPERTY_PREFIX ".cuttlefish_ril_dns"
-#define CUTTLEFISH_RIL_BROADCAST_PROPERTY \
-  CF_PROPERTY_PREFIX ".cuttlefish_ril_broadcast"
-#define CUTTLEFISH_RIL_PREFIXLEN_PROPERTY \
-  CF_PROPERTY_PREFIX ".cuttlefish_ril_prefixlen"
diff --git a/common/libs/device_config/Android.bp b/common/libs/device_config/Android.bp
new file mode 100644
index 0000000..36c8ddb
--- /dev/null
+++ b/common/libs/device_config/Android.bp
@@ -0,0 +1,51 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+cc_library_shared {
+    name: "libcuttlefish_device_config",
+    srcs: [
+        "device_config.cpp",
+    ],
+    header_libs: [
+        "cuttlefish_glog",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+        "libcuttlefish_fs",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_utils",
+    ],
+    target: {
+        host: {
+            srcs: [
+                "host_device_config.cpp",
+            ],
+            static_libs: [
+                "libcuttlefish_host_config",
+                "libjsoncpp",
+            ],
+        },
+        android: {
+            srcs: [
+                "guest_device_config.cpp",
+            ],
+            shared_libs: [
+                "libcutils",
+            ],
+        },
+    },
+    defaults: ["cuttlefish_host_and_guest"],
+}
diff --git a/common/libs/device_config/device_config.cpp b/common/libs/device_config/device_config.cpp
new file mode 100644
index 0000000..26bb9a1
--- /dev/null
+++ b/common/libs/device_config/device_config.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 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 is 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 "device_config.h"
+
+#include <stdio.h>
+
+#include <sstream>
+#include <type_traits>
+
+#include <glog/logging.h>
+
+namespace cvd {
+
+// TODO(jemoreira): Endianness when on arm64 guest and x86 host is a problem
+// Raw data is sent through a vsocket from host to guest, this assert tries to
+// ensure the binary representation of the struct is the same in both sides.
+static_assert(sizeof(DeviceConfig::RawData) == 68 &&
+                  std::is_trivial<DeviceConfig::RawData>().value,
+              "DeviceConfigRawData needs to be the same in host and guess, did "
+              "you forget to update the size?");
+
+namespace {
+
+static constexpr auto kDataSize = sizeof(DeviceConfig::RawData);
+
+}  // namespace
+
+bool DeviceConfig::SendRawData(cvd::SharedFD fd) {
+  std::size_t sent = 0;
+  auto buffer = reinterpret_cast<uint8_t*>(&data_);
+  while (sent < kDataSize) {
+    auto bytes = fd->Write(buffer + sent, kDataSize - sent);
+    if (bytes < 0) {
+      // Don't log here, let the caller do it.
+      return false;
+    }
+    sent += bytes;
+  }
+  return true;
+}
+
+void DeviceConfig::generate_address_and_prefix() {
+  std::ostringstream ss;
+  ss << ril_ipaddr() << "/" << ril_prefixlen();
+  ril_address_and_prefix_ = ss.str();
+}
+
+}  // namespace cvd
\ No newline at end of file
diff --git a/common/libs/device_config/device_config.h b/common/libs/device_config/device_config.h
new file mode 100644
index 0000000..3fb2648
--- /dev/null
+++ b/common/libs/device_config/device_config.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2019 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 is 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.
+ */
+
+#pragma once
+
+#include <common/libs/fs/shared_fd.h>
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#ifdef CUTTLEFISH_HOST
+#include <host/libs/config/cuttlefish_config.h>
+#endif
+
+namespace cvd {
+
+class DeviceConfig {
+ public:
+  /**
+   * WARNING: Consider the possibility of different endianness between host and
+   * guest when adding fields of more than one byte to this struct:
+   * This struct is meant to be sent from host to guest so the binary
+   * representation must be the same. There is a static test that checks for
+   * alignment problems, but there is no such thing for endianness.
+   */
+  struct RawData {
+    struct {
+      char ipaddr[16];  // xxx.xxx.xxx.xxx\0 = 16 bytes
+      char gateway[16];
+      char dns[16];
+      char broadcast[16];
+      uint8_t prefixlen;
+      uint8_t reserved[3];
+    } ril;
+  };
+
+  static std::unique_ptr<DeviceConfig> Get();
+
+  bool SendRawData(cvd::SharedFD fd);
+
+  const char* ril_address_and_prefix() const {
+    return ril_address_and_prefix_.c_str();
+  };
+  const char* ril_ipaddr() const { return data_.ril.ipaddr; }
+  const char* ril_gateway() const { return data_.ril.gateway; }
+  const char* ril_dns() const { return data_.ril.dns; }
+  const char* ril_broadcast() const { return data_.ril.broadcast; }
+  int ril_prefixlen() const { return data_.ril.prefixlen; }
+
+ private:
+  void generate_address_and_prefix();
+#ifdef CUTTLEFISH_HOST
+  DeviceConfig() = default;
+  bool InitializeNetworkConfiguration(const vsoc::CuttlefishConfig& config);
+#else
+  explicit DeviceConfig(const RawData& data);
+#endif
+
+  RawData data_;
+  std::string ril_address_and_prefix_;
+};
+
+}  // namespace cvd
diff --git a/common/libs/device_config/guest_device_config.cpp b/common/libs/device_config/guest_device_config.cpp
new file mode 100644
index 0000000..90d2528
--- /dev/null
+++ b/common/libs/device_config/guest_device_config.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 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 is 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 <cutils/properties.h>
+#include <glog/logging.h>
+
+#include "device_config.h"
+
+namespace cvd {
+
+namespace {
+
+static constexpr auto kDataSize = sizeof(DeviceConfig::RawData);
+
+bool GetRawFromServer(DeviceConfig::RawData* data) {
+  auto port_property = "ro.boot.cuttlefish_config_server_port";
+  auto port = property_get_int32(port_property, -1);
+  if (port < 0) {
+    LOG(ERROR) << "Unable to get config server port from property: " <<
+        port_property;
+    return false;
+  }
+  auto config_server =
+      cvd::SharedFD::VsockClient(2 /*host cid*/, port, SOCK_STREAM);
+  if (!config_server->IsOpen()) {
+    LOG(ERROR) << "Unable to connect to config server: "
+               << config_server->StrError();
+    return false;
+  }
+  uint8_t* buffer = reinterpret_cast<uint8_t*>(data);
+  size_t read_idx = 0;
+  while (read_idx < kDataSize) {
+    auto read = config_server->Read(buffer + read_idx, kDataSize - read_idx);
+    if (read == 0) {
+      LOG(ERROR) << "Unexpected EOF while reading from config server, read "
+                 << read_idx << " bytes, expected " << kDataSize;
+      return false;
+    }
+    if (read < 0) {
+      LOG(ERROR) << "Error reading from config server: "
+                 << config_server->StrError();
+      return false;
+    }
+    read_idx += read;
+  }
+  return true;
+}
+
+}  // namespace
+
+std::unique_ptr<DeviceConfig> DeviceConfig::Get() {
+  DeviceConfig::RawData data;
+  if (!GetRawFromServer(&data)) return nullptr;
+
+  return std::unique_ptr<DeviceConfig>(new DeviceConfig(data));
+}
+
+DeviceConfig::DeviceConfig(const DeviceConfig::RawData& data) : data_(data) {
+  generate_address_and_prefix();
+}
+
+}  // namespace cvd
diff --git a/host/commands/launch/ril_config.cc b/common/libs/device_config/host_device_config.cpp
similarity index 65%
rename from host/commands/launch/ril_config.cc
rename to common/libs/device_config/host_device_config.cpp
index 195256a..052e9bf 100644
--- a/host/commands/launch/ril_config.cc
+++ b/common/libs/device_config/host_device_config.cpp
@@ -15,23 +15,20 @@
  */
 
 #include <arpa/inet.h>
+#include <glog/logging.h>
 #include <ifaddrs.h>
 #include <stdio.h>
 #include <string.h>
+#include <sys/types.h>
 
-#include <memory>
-#include <sstream>
-#include <string>
+#include "device_config.h"
 
-#include <glog/logging.h>
-
-#include "common/libs/constants/ril.h"
-#include "host/commands/launch/ril_config.h"
+namespace cvd {
 
 namespace {
 
-int number_of_ones(unsigned long val) {
-  int ret = 0;
+uint8_t number_of_ones(unsigned long val) {
+  uint8_t ret = 0;
   while (val) {
     ret += val % 2;
     val >>= 1;
@@ -41,7 +38,7 @@
 
 class NetConfig {
  public:
-  uint32_t ril_prefixlen = -1;
+  uint8_t ril_prefixlen = -1;
   std::string ril_ipaddr;
   std::string ril_gateway;
   std::string ril_dns = "8.8.8.8";
@@ -54,16 +51,12 @@
     LOG(INFO) << "gateway = " << ril_gateway;
     LOG(INFO) << "dns = " << ril_dns;
     LOG(INFO) << "broadcast = " << ril_broadcast;
-    LOG(INFO) << "prefix length = " << ril_prefixlen;
+    LOG(INFO) << "prefix length = " << static_cast<int>(ril_prefixlen);
     return ret;
   }
 
  private:
   bool ParseIntefaceAttributes(struct ifaddrs* ifa) {
-    // if (ifa->ifa_addr->sa_family != AF_INET) {
-    //   LOG(ERROR) << "The " << ifa->ifa_name << " interface is not IPv4";
-    //   return false;
-    // }
     struct sockaddr_in* sa;
     char* addr_str;
 
@@ -122,30 +115,50 @@
   }
 };
 
-template <typename T>
-std::string BuildPropertyDefinition(const std::string& prop_name,
-                                  const T& prop_value) {
-  std::ostringstream stream;
-  stream << prop_name << "=" << prop_value;
-  return stream.str();
+inline void CopyChars(char* dest, size_t size, const char* src) {
+  auto res = snprintf(dest, size, "%s", src);
+  if (res >= static_cast<int>(size)) {
+    LOG(ERROR) << "Longer(" << res << ") than expected(" << (size - 1)
+               << ") config string was truncated: " << dest;
+  }
 }
+
 }  // namespace
 
-void ConfigureRil(vsoc::CuttlefishConfig* config) {
+std::unique_ptr<DeviceConfig> DeviceConfig::Get() {
+  auto config = vsoc::CuttlefishConfig::Get();
+  if (!config) return nullptr;
+  std::unique_ptr<DeviceConfig> dev_config(new DeviceConfig());
+  if (!dev_config->InitializeNetworkConfiguration(*config)) {
+    return nullptr;
+  }
+  return dev_config;
+}
+
+bool DeviceConfig::InitializeNetworkConfiguration(
+    const vsoc::CuttlefishConfig& config) {
   NetConfig netconfig;
-  if (!netconfig.ObtainConfig(config->mobile_bridge_name())) {
+  if (!netconfig.ObtainConfig(config.mobile_bridge_name())) {
     LOG(ERROR) << "Unable to obtain the network configuration";
-    return;
+    return false;
   }
 
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_ADDR_PROPERTY, netconfig.ril_ipaddr));
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_GATEWAY_PROPERTY, netconfig.ril_gateway));
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_DNS_PROPERTY, netconfig.ril_dns));
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_BROADCAST_PROPERTY, netconfig.ril_broadcast));
-  config->add_kernel_cmdline(BuildPropertyDefinition(
-      CUTTLEFISH_RIL_PREFIXLEN_PROPERTY, netconfig.ril_prefixlen));
+  auto res = snprintf(data_.ril.ipaddr, sizeof(data_.ril.ipaddr), "%s",
+                      netconfig.ril_ipaddr.c_str());
+  if (res >= (int)sizeof(data_.ril.ipaddr)) {
+    LOG(ERROR) << "Longer than expected config string was truncated: "
+               << data_.ril.ipaddr;
+  }
+  CopyChars(data_.ril.gateway, sizeof(data_.ril.gateway),
+            netconfig.ril_gateway.c_str());
+  CopyChars(data_.ril.dns, sizeof(data_.ril.dns), netconfig.ril_dns.c_str());
+  CopyChars(data_.ril.broadcast, sizeof(data_.ril.broadcast),
+            netconfig.ril_broadcast.c_str());
+  data_.ril.prefixlen = netconfig.ril_prefixlen;
+
+  generate_address_and_prefix();
+
+  return true;
 }
+
+}  // namespace cvd
diff --git a/common/libs/fs/Android.bp b/common/libs/fs/Android.bp
index 1522c50..9255b4f 100644
--- a/common/libs/fs/Android.bp
+++ b/common/libs/fs/Android.bp
@@ -26,3 +26,20 @@
     ],
     defaults: ["cuttlefish_host_and_guest"],
 }
+
+cc_library_static {
+    name: "libcuttlefish_fs_static",
+    static_libs: [
+        "cuttlefish_auto_resources_static",
+    ],
+    srcs: [
+        "gce_fs.cpp",
+        "shared_fd.cpp",
+    ],
+    shared_libs: [
+        "libbase",
+        "liblog",
+    ],
+    stl: "libc++_static",
+    defaults: ["cuttlefish_guest_product_only"],
+}
diff --git a/common/libs/fs/shared_fd.cpp b/common/libs/fs/shared_fd.cpp
index c96d85b..6ca2826 100644
--- a/common/libs/fs/shared_fd.cpp
+++ b/common/libs/fs/shared_fd.cpp
@@ -429,7 +429,6 @@
   addr.svm_cid = cid;
   auto casted_addr = reinterpret_cast<sockaddr*>(&addr);
   if (vsock->Connect(casted_addr, sizeof(addr)) == -1) {
-    LOG(ERROR) << "Connect failed (" << vsock->StrError() << ")";
     return SharedFD::ErrorFD(vsock->GetErrno());
   }
   return vsock;
diff --git a/common/libs/net/Android.bp b/common/libs/net/Android.bp
index feb3b88..ea53f71 100644
--- a/common/libs/net/Android.bp
+++ b/common/libs/net/Android.bp
@@ -44,4 +44,5 @@
         "libgtest_host",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
diff --git a/common/libs/net/TEST_MAPPING b/common/libs/net/TEST_MAPPING
new file mode 100644
index 0000000..a06d72a
--- /dev/null
+++ b/common/libs/net/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit": [
+    {
+      "name": "cuttlefish_net_tests",
+      "host": true
+    }
+  ]
+}
diff --git a/common/libs/time/Android.bp b/common/libs/time/Android.bp
index a390f68..972958f 100644
--- a/common/libs/time/Android.bp
+++ b/common/libs/time/Android.bp
@@ -30,4 +30,5 @@
         "cuttlefish_time",
     ],
     defaults: ["cuttlefish_host_only"],
+    test_suites: ["general-tests"],
 }
diff --git a/common/libs/time/TEST_MAPPING b/common/libs/time/TEST_MAPPING
new file mode 100644
index 0000000..4c95014
--- /dev/null
+++ b/common/libs/time/TEST_MAPPING
@@ -0,0 +1,8 @@
+{
+  "presubmit": [
+    {
+      "name": "monotonic_time_test",
+      "host": true
+    }
+  ]
+}
diff --git a/common/libs/utils/files.cpp b/common/libs/utils/files.cpp
index 654d971..432e8da 100644
--- a/common/libs/utils/files.cpp
+++ b/common/libs/utils/files.cpp
@@ -20,6 +20,7 @@
 
 #include <array>
 #include <climits>
+#include <cstdio>
 #include <cstdlib>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -27,6 +28,11 @@
 
 namespace cvd {
 
+bool FileExists(const std::string& path) {
+  struct stat st;
+  return stat(path.c_str(), &st) == 0;
+}
+
 bool FileHasContent(const std::string& path) {
   return FileSize(path) > 0;
 }
@@ -67,4 +73,9 @@
   return st.st_size;
 }
 
+bool RemoveFile(const std::string& file) {
+  LOG(INFO) << "Removing " << file;
+  return remove(file.c_str()) == 0;
+}
+
 }  // namespace cvd
diff --git a/common/libs/utils/files.h b/common/libs/utils/files.h
index ce689ac..d05501d 100644
--- a/common/libs/utils/files.h
+++ b/common/libs/utils/files.h
@@ -20,9 +20,11 @@
 #include <string>
 
 namespace cvd {
+bool FileExists(const std::string& path);
 bool FileHasContent(const std::string& path);
 bool DirectoryExists(const std::string& path);
 off_t FileSize(const std::string& path);
+bool RemoveFile(const std::string& file);
 
 // The returned value may contain .. or . if these are present in the path
 // argument.
diff --git a/common/libs/utils/subprocess.cpp b/common/libs/utils/subprocess.cpp
index 773a56c..18dbbeb 100644
--- a/common/libs/utils/subprocess.cpp
+++ b/common/libs/utils/subprocess.cpp
@@ -188,6 +188,17 @@
   return retval;
 }
 
+Command::ParameterBuilder::~ParameterBuilder() {
+  Build();
+}
+void Command::ParameterBuilder::Build()  {
+  auto param = stream_.str();
+  stream_ = std::stringstream();
+  if (param.size()) {
+    cmd_->AddParameter(param);
+  }
+}
+
 Command::~Command() {
   // Close all inherited file descriptors
   for(const auto& entry: inherited_fds_) {
diff --git a/common/libs/utils/subprocess.h b/common/libs/utils/subprocess.h
index a7485c2..a299798 100644
--- a/common/libs/utils/subprocess.h
+++ b/common/libs/utils/subprocess.h
@@ -85,6 +85,24 @@
            BuildParameter(stream, args...);
   }
  public:
+  class ParameterBuilder {
+  public:
+    ParameterBuilder(Command* cmd) : cmd_(cmd) {};
+    ParameterBuilder(ParameterBuilder&& builder) = default;
+    ~ParameterBuilder();
+
+    template<typename T>
+    ParameterBuilder& operator<<(T t) {
+      cmd_->BuildParameter(&stream_, t);
+      return *this;
+    }
+
+    void Build();
+  private:
+    cvd::Command* cmd_;
+    std::stringstream stream_;
+  };
+
   Command(const std::string& executable) {
     command_.push_back(executable);
   }
@@ -117,6 +135,10 @@
     return false;
   }
 
+  ParameterBuilder GetParameterBuilder() {
+    return ParameterBuilder(this);
+  }
+
   // Redirects the standard IO of the command.
   bool RedirectStdIO(Subprocess::StdIOChannel channel, cvd::SharedFD shared_fd);
 
diff --git a/common/vsoc/lib/screen_region_view.h b/common/vsoc/lib/screen_region_view.h
index 9092986..aef4359 100644
--- a/common/vsoc/lib/screen_region_view.h
+++ b/common/vsoc/lib/screen_region_view.h
@@ -32,7 +32,8 @@
     : public vsoc::TypedRegionView<ScreenRegionView,
                                    vsoc::layout::screen::ScreenLayout> {
  public:
-  static int align(int input, int alignment = kAlignment) {
+  static int align(int input) {
+    auto constexpr alignment = 16;
     return (input + alignment - 1) & -alignment;
   }
 
@@ -95,7 +96,6 @@
   static constexpr int kGreenBits = 8;
   static constexpr int kBlueBits = 8;
   static constexpr uint32_t kFbPixelFormat = vsoc::VSOC_PIXEL_FORMAT_RGBA_8888;
-  static constexpr int kAlignment = 8;
 
  protected:
   const uint8_t* first_buffer() const;
diff --git a/guest/Android.bp b/guest/Android.bp
index ba07c2e..6b2406c 100644
--- a/guest/Android.bp
+++ b/guest/Android.bp
@@ -15,6 +15,7 @@
 
 subdirs = [
     "commands",
-    "hals/health",
-    "hals/hwcomposer",
+    "hals",
+    "monitoring",
+    "vsoc/lib",
 ]
diff --git a/guest/commands/Android.bp b/guest/commands/Android.bp
index 5c7c3c2..df15067 100644
--- a/guest/commands/Android.bp
+++ b/guest/commands/Android.bp
@@ -15,4 +15,8 @@
 
 subdirs = [
   "vsock_logcat",
+  "ip_link_add",
+  "usbforward",
+  "vport_trigger",
+  "vsoc_input_service",
 ]
diff --git a/guest/commands/ip_link_add/Android.bp b/guest/commands/ip_link_add/Android.bp
new file mode 100644
index 0000000..d84a5d1
--- /dev/null
+++ b/guest/commands/ip_link_add/Android.bp
@@ -0,0 +1,27 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+
+cc_binary {
+    name: "ip_link_add",
+    srcs: [
+        "main.cpp",
+    ],
+    shared_libs: [
+        "cuttlefish_net",
+        "cuttlefish_auto_resources",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/commands/ip_link_add/Android.mk b/guest/commands/ip_link_add/Android.mk
deleted file mode 100644
index 993dea6..0000000
--- a/guest/commands/ip_link_add/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright (C) 2018 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 is 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := ip_link_add
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := main.cpp
-LOCAL_SHARED_LIBRARIES := cuttlefish_net cuttlefish_auto_resources
-LOCAL_C_INCLUDES := device/google/cuttlefish_common
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_EXECUTABLE)
diff --git a/guest/commands/usbforward/Android.bp b/guest/commands/usbforward/Android.bp
new file mode 100644
index 0000000..a639567
--- /dev/null
+++ b/guest/commands/usbforward/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+
+cc_binary {
+    name: "usbforward",
+    srcs: [
+        "main.cpp",
+        "usb_server.cpp",
+        "transport_request.cpp",
+    ],
+    shared_libs: [
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libusb",
+        "libbase",
+        "liblog",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"UsbForward\"",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/commands/usbforward/Android.mk b/guest/commands/usbforward/Android.mk
deleted file mode 100644
index c8d219d..0000000
--- a/guest/commands/usbforward/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 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 is 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_MODULE := usbforward
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := \
-    main.cpp \
-    usb_server.cpp \
-    transport_request.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_HEADER_LIBRARIES := \
-    libcutils_headers
-
-LOCAL_SHARED_LIBRARIES := \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libusb \
-    libbase \
-    liblog
-
-LOCAL_CFLAGS += -DLOG_TAG=\"UsbForward\"
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
-
diff --git a/guest/commands/usbforward/usb_server.cpp b/guest/commands/usbforward/usb_server.cpp
index 8c72137..e8f5525 100644
--- a/guest/commands/usbforward/usb_server.cpp
+++ b/guest/commands/usbforward/usb_server.cpp
@@ -276,7 +276,7 @@
 }
 
 int USBServer::HandleDeviceEvent(libusb_context*, libusb_device*,
-                                 libusb_hotplug_event event, void* self_raw) {
+                                 libusb_hotplug_event, void* self_raw) {
   auto self = reinterpret_cast<USBServer*>(self_raw);
   int64_t dummy = 1;
   self->device_event_fd_->Write(&dummy, sizeof(dummy));
diff --git a/guest/commands/vport_trigger/Android.bp b/guest/commands/vport_trigger/Android.bp
new file mode 100644
index 0000000..621b9c5
--- /dev/null
+++ b/guest/commands/vport_trigger/Android.bp
@@ -0,0 +1,26 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+
+cc_binary {
+    name: "vport_trigger",
+    srcs: [
+        "main.cpp",
+    ],
+    shared_libs: [
+        "libcutils",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/commands/vport_trigger/Android.mk b/guest/commands/vport_trigger/Android.mk
deleted file mode 100644
index e994ce9..0000000
--- a/guest/commands/vport_trigger/Android.mk
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2018 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 is 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := vport_trigger
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := main.cpp
-LOCAL_SHARED_LIBRARIES := libcutils
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_EXECUTABLE)
diff --git a/guest/commands/vsoc_input_service/Android.bp b/guest/commands/vsoc_input_service/Android.bp
new file mode 100644
index 0000000..76aae19
--- /dev/null
+++ b/guest/commands/vsoc_input_service/Android.bp
@@ -0,0 +1,35 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+
+cc_binary {
+    name: "vsoc_input_service",
+    srcs: [
+        "main.cpp",
+        "virtual_device_base.cpp",
+        "virtual_power_button.cpp",
+        "virtual_keyboard.cpp",
+        "virtual_touchscreen.cpp",
+        "vsoc_input_service.cpp",
+    ],
+    shared_libs: [
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libbase",
+        "liblog",
+        "vsoc_lib",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/commands/vsoc_input_service/Android.mk b/guest/commands/vsoc_input_service/Android.mk
deleted file mode 100644
index 2256ba5..0000000
--- a/guest/commands/vsoc_input_service/Android.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright (C) 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 is 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.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_MODULE := vsoc_input_service
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := \
-    virtual_device_base.cpp \
-    virtual_power_button.cpp \
-    virtual_keyboard.cpp \
-    virtual_touchscreen.cpp \
-    vsoc_input_service.cpp \
-    main.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_SHARED_LIBRARIES := \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libbase \
-    liblog \
-    vsoc_lib
-
-LOCAL_CFLAGS += -DLOG_TAG=\"VSoCInputService\" \
-    -Wall -Werror
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
diff --git a/guest/commands/vsock_logcat/main.cpp b/guest/commands/vsock_logcat/main.cpp
index 2dd4318..51d97e3 100644
--- a/guest/commands/vsock_logcat/main.cpp
+++ b/guest/commands/vsock_logcat/main.cpp
@@ -18,6 +18,10 @@
 
 #include <string.h>
 
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
 #include <fstream>
 #include <sstream>
 #include <string>
@@ -27,14 +31,19 @@
 #include <glog/logging.h>
 
 #include "common/libs/fs/shared_fd.h"
+#include "common/libs/utils/files.h"
 #include "common/libs/utils/subprocess.h"
 
 DEFINE_uint32(port, property_get_int32("ro.boot.vsock_logcat_port", 0),
               "VSOCK port to send logcat output to");
 DEFINE_uint32(cid, 2, "VSOCK CID to send logcat output to");
+DEFINE_string(pipe_name, "/dev/cf_logcat_pipe",
+              "The path for the named pipe logcat will write to");
 
 namespace {
 
+constexpr char kLogcatExitMsg[] = "\nDetected exit of logcat process\n\n";
+
 class ServiceStatus {
  public:
   static const char* kServiceStatusProperty;
@@ -63,7 +72,7 @@
   char status_[PROP_VALUE_MAX];
 };
 
-const char* ServiceStatus::kServiceStatusProperty = "vsock_logcat_status";
+const char* ServiceStatus::kServiceStatusProperty = "vendor.vsock_logcat_status";
 const char* ServiceStatus::kStatusStarted = "started";
 const char* ServiceStatus::kStatusFailed = "failed";
 
@@ -106,32 +115,26 @@
                << ServiceStatus::kServiceStatusProperty;
   }
 
-  cvd::Command logcat_cmd("/system/bin/logcat");
-  logcat_cmd.AddParameter("-b");
-  logcat_cmd.AddParameter("all");
-  logcat_cmd.AddParameter("-v");
-  logcat_cmd.AddParameter("threadtime");
-  logcat_cmd.AddParameter("*:V");
-
-  logcat_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, log_fd);
-
-  while (true) {
-    int wstatus;
-    logcat_cmd.Start().Wait(&wstatus, 0);
-    std::ostringstream exit_msg_builder;
-    exit_msg_builder << std::endl
-                     << "Logcat process exited with wstatus " << wstatus
-                     << ", restarting ..." << std::endl
-                     << std::endl;
-    auto exit_msg = exit_msg_builder.str();
-    size_t written = log_fd->Write(exit_msg.c_str(), exit_msg.size());
-    if (written != exit_msg.size()) {
-      std::ostringstream ss;
-      ss << exit_msg << std::endl
-         << "Unable to write complete message on socket: "
-         << log_fd->StrError();
-      LogFailed(ss.str(), &status);
-      return 2;
+  if (cvd::FileExists(FLAGS_pipe_name)) {
+    LOG(WARNING) << "The file " << FLAGS_pipe_name << " already exists. Deleting...";
+    cvd::RemoveFile(FLAGS_pipe_name);
+  }
+  auto pipe = mkfifo(FLAGS_pipe_name.c_str(), 0600);
+  if (pipe != 0) {
+    LOG(FATAL) << "unable to create pipe: " << strerror(errno);
+  }
+  property_set("vendor.ser.cf-logcat", FLAGS_pipe_name.c_str());
+  while (1) {
+    auto conn = cvd::SharedFD::Open(FLAGS_pipe_name.c_str(), O_RDONLY);
+    while (conn->IsOpen()) {
+      char buff[4096];
+      auto read = conn->Read(buff, sizeof(buff));
+      if (read) {
+        log_fd->Write(buff, read);
+      } else {
+        conn->Close();
+      }
     }
+    log_fd->Write(kLogcatExitMsg, sizeof(kLogcatExitMsg) - 1);
   }
 }
diff --git a/guest/hals/Android.bp b/guest/hals/Android.bp
new file mode 100644
index 0000000..6d01e72
--- /dev/null
+++ b/guest/hals/Android.bp
@@ -0,0 +1,20 @@
+//
+// Copyright (C) 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 is 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.
+
+subdirs = [
+    "gps",
+    "health",
+    "hwcomposer",
+]
diff --git a/guest/hals/gps/Android.bp b/guest/hals/gps/Android.bp
new file mode 100644
index 0000000..22c5998
--- /dev/null
+++ b/guest/hals/gps/Android.bp
@@ -0,0 +1,34 @@
+// Copyright (C) 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 is 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.
+
+// HAL module implemenation, not prelinked and stored in
+// hw/<LIGHTS_HARDWARE_MODULE_ID>.<ro.hardware>.so
+cc_library_shared {
+    name: "gps.cutf",
+    relative_install_path: "hw",
+    srcs: [
+        "gps_vsoc.cpp",
+        "gps_thread.cpp",
+    ],
+    shared_libs: [
+        "liblog",
+        "libcutils",
+    ],
+    header_libs: ["libhardware_headers"],
+    cflags: [
+        "-Wno-missing-field-initializers",
+        "-DLOG_TAG=\"VSoCGPS\"",
+    ],
+    defaults: ["cuttlefish_guest_only"],
+}
diff --git a/guest/hals/gps/Android.mk b/guest/hals/gps/Android.mk
deleted file mode 100644
index 9443980..0000000
--- a/guest/hals/gps/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 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 is 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.
-
-LOCAL_PATH := $(call my-dir)
-
-# HAL module implemenation, not prelinked and stored in
-# hw/<LIGHTS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-
-ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 21; echo $$?))
-LOCAL_MODULE_RELATIVE_PATH := hw
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-endif
-LOCAL_MULTILIB := first
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_SRC_FILES := gps_vsoc.cpp gps_thread.cpp
-LOCAL_MODULE := gps.cutf
-LOCAL_C_INCLUDES := device/google/cuttlefish_common
-
-LOCAL_HEADER_LIBRARIES := \
-    libhardware_headers
-
-LOCAL_CFLAGS := \
-    -Wall -Werror -Wno-missing-field-initializers \
-    -DLOG_TAG=\"VSoCGPS\" \
-    $(VSOC_VERSION_CFLAGS)
-LOCAL_VENDOR_MODULE := true
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/guest/hals/gralloc/legacy/Android.mk b/guest/hals/gralloc/legacy/Android.mk
index 57dae50..4bbc9c0 100644
--- a/guest/hals/gralloc/legacy/Android.mk
+++ b/guest/hals/gralloc/legacy/Android.mk
@@ -29,7 +29,7 @@
     $(VSOC_VERSION_CFLAGS)
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := gralloc.cutf
+LOCAL_MODULE := gralloc.cutf_ashmem
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_MODULE_TAGS := optional
 
diff --git a/guest/hals/gralloc/legacy/gralloc.cpp b/guest/hals/gralloc/legacy/gralloc.cpp
index 960b886..f890932 100644
--- a/guest/hals/gralloc/legacy/gralloc.cpp
+++ b/guest/hals/gralloc/legacy/gralloc.cpp
@@ -64,7 +64,7 @@
   // a gralloc buffer in this format.
   ALOG_ASSERT(format != HAL_PIXEL_FORMAT_RGB_888);
   if (format == HAL_PIXEL_FORMAT_YV12) {
-    bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w, 16);
+    bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w);
   } else {
     bytes_per_line = ScreenRegionView::align(bytes_per_pixel * w);
   }
diff --git a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h b/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
index 7f79002..16e2b33 100644
--- a/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
+++ b/guest/hals/gralloc/legacy/gralloc_vsoc_priv.h
@@ -285,9 +285,9 @@
 #ifdef GRALLOC_MODULE_API_VERSION_0_2
     case HAL_PIXEL_FORMAT_YCbCr_420_888:
 #endif
-      out->ystride = vsoc::screen::ScreenRegionView::align(width, 16);
+      out->ystride = vsoc::screen::ScreenRegionView::align(width);
       out->cstride =
-          vsoc::screen::ScreenRegionView::align(out->ystride / 2, 16);
+          vsoc::screen::ScreenRegionView::align(out->ystride / 2);
       out->chroma_step = 1;
       out->y = it;
       it += out->ystride * height;
@@ -331,8 +331,8 @@
     case HAL_PIXEL_FORMAT_RGB_888:
     case HAL_PIXEL_FORMAT_RGB_565:*/
     default:
-      w16 = vsoc::screen::ScreenRegionView::align(w, 16);
-      h16 = vsoc::screen::ScreenRegionView::align(h, 16);
+      w16 = vsoc::screen::ScreenRegionView::align(w);
+      h16 = vsoc::screen::ScreenRegionView::align(h);
       return bytes_per_pixel * w16 * h16 +
              vsoc::screen::ScreenRegionView::kSwiftShaderPadding;
   }
diff --git a/guest/hals/hwcomposer/cutf_cvm/Android.bp b/guest/hals/hwcomposer/cutf_cvm/Android.bp
index 7bf1faa..09bccd8 100644
--- a/guest/hals/hwcomposer/cutf_cvm/Android.bp
+++ b/guest/hals/hwcomposer/cutf_cvm/Android.bp
@@ -14,13 +14,31 @@
 
 
 cc_library_shared {
-    name: "hwcomposer.cutf_cvm",
+    name: "hwcomposer.cutf_cvm_ashmem",
     relative_install_path: "hw",
     defaults: ["cuttlefish_guest_only"],
     vendor: true,
-    srcs: ["hwcomposer.cpp"],
-    include_dirs: ["device/google/cuttlefish_common"],
+    srcs: [
+        "hwcomposer.cpp",
+        "geometry_utils.cpp",
+        "vsoc_composer.cpp",
+        "base_composer.cpp",
+    ],
+    include_dirs: [
+        "device/google/cuttlefish_common",
+    ],
     export_include_dirs: ["."],
     static_libs: ["libyuv_static", "hwcomposer_common"],
-    shared_libs: ["liblog", "libhardware"],
+    shared_libs: [
+        "liblog",
+        "libhardware",
+        "libbase",
+        "libcutils",
+        "libutils",
+        "libsync",
+        "libhardware",
+        "libjpeg",
+        "libcuttlefish_utils",
+        "libcuttlefish_fs",
+    ],
 }
diff --git a/guest/hals/hwcomposer/cutf_cvm/base_composer.cpp b/guest/hals/hwcomposer/cutf_cvm/base_composer.cpp
new file mode 100644
index 0000000..23be7e1
--- /dev/null
+++ b/guest/hals/hwcomposer/cutf_cvm/base_composer.cpp
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2016 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 is 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 "base_composer.h"
+
+#include <string.h>
+
+#include <cutils/properties.h>
+#include <hardware/gralloc.h>
+#include <log/log.h>
+
+#include <common/libs/utils/size_utils.h>
+#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
+
+namespace cvd {
+
+BaseComposer::BaseComposer(int64_t vsync_base_timestamp)
+    : vsync_base_timestamp_(vsync_base_timestamp) {
+  vsync_period_ns_ = 1000000000 / frame_buffer_.refresh_rate();
+  hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
+                reinterpret_cast<const hw_module_t**>(&gralloc_module_));
+}
+
+BaseComposer::~BaseComposer() {}
+
+void BaseComposer::Dump(char* buff __unused, int buff_len __unused) {}
+
+int BaseComposer::PostFrameBufferTarget(buffer_handle_t buffer_handle) {
+  int fb_index = frame_buffer_.NextScreenBuffer();
+  void* frame_buffer = frame_buffer_.GetBuffer(fb_index);
+  const private_handle_t* p_handle =
+      reinterpret_cast<const private_handle_t*>(buffer_handle);
+  void* buffer;
+  int retval = gralloc_module_->lock(gralloc_module_, buffer_handle,
+                                     GRALLOC_USAGE_SW_READ_OFTEN, 0, 0,
+                                     p_handle->x_res, p_handle->y_res, &buffer);
+  if (retval != 0) {
+    ALOGE("Got error code %d from lock function", retval);
+    return -1;
+  }
+  memcpy(frame_buffer, buffer, frame_buffer_.buffer_size());
+  frame_buffer_.Broadcast(fb_index);
+  return 0;
+}  // namespace cvd
+
+int BaseComposer::PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers) {
+  // find unsupported overlays
+  for (size_t i = 0; i < num_layers; i++) {
+    if (IS_TARGET_FRAMEBUFFER(layers[i].compositionType)) {
+      continue;
+    }
+    layers[i].compositionType = HWC_FRAMEBUFFER;
+  }
+  return 0;
+}
+
+int BaseComposer::SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
+  for (size_t idx = 0; idx < num_layers; idx++) {
+    if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
+      return PostFrameBufferTarget(layers[idx].handle);
+    }
+  }
+  return -1;
+}
+
+FrameBuffer::FrameBuffer()
+    : screen_server_(cvd::SharedFD::VsockClient(
+          2, property_get_int32("ro.boot.vsock_frames_port", 5580),
+          SOCK_STREAM)),
+      broadcast_thread_([this]() { BroadcastLoop(); }) {
+  if (screen_server_->IsOpen()) {
+    // TODO(b/128842613): Get this info from the configuration server
+    int32_t screen_params[4];
+    auto res = screen_server_->Read(screen_params, sizeof(screen_params));
+    if (res == sizeof(screen_params)) {
+      x_res_ = screen_params[0];
+      y_res_ = screen_params[1];
+      dpi_ = screen_params[2];
+      refresh_rate_ = screen_params[3];
+    } else {
+      LOG(ERROR) << "Unable to get screen configuration parameters from screen "
+                 << "server (" << res << "): " << screen_server_->StrError();
+    }
+  } else {
+    LOG(ERROR) << "Unable to connect to screen server: "
+               << screen_server_->StrError();
+  }
+  // This needs to happen no matter what, otherwise there won't be a buffer for
+  // the set calls to compose on.
+  inner_buffer_ = std::vector<char>(FrameBuffer::buffer_size() * 8);
+}
+
+FrameBuffer::~FrameBuffer() {
+  running_ = false;
+  broadcast_thread_.join();
+}
+
+int FrameBuffer::NextScreenBuffer() {
+  int num_buffers = inner_buffer_.size() / buffer_size();
+  last_frame_buffer_ =
+      num_buffers > 0 ? (last_frame_buffer_ + 1) % num_buffers : -1;
+  return last_frame_buffer_;
+}
+
+void FrameBuffer::BroadcastLoop() {
+  if (!screen_server_->IsOpen()) {
+    LOG(ERROR) << "Broadcaster thread exiting due to no connection to screen"
+               << " server. Compositions will occur, but frames won't be sent"
+               << " anywhere";
+    return;
+  }
+  int32_t current_seq = 0;
+  int32_t current_offset;
+  while (running_) {
+    {
+      std::unique_lock<std::mutex> lock(mutex_);
+      while (current_seq == current_seq_) {
+        cond_var_.wait(lock);
+      }
+      current_offset = current_offset_;
+      current_seq = current_seq_;
+    }
+    int32_t size = buffer_size();
+    screen_server_->Write(&size, sizeof(size));
+    auto buff = static_cast<char*>(GetBuffer(current_offset));
+    while (size > 0) {
+      auto written = screen_server_->Write(buff, size);
+      size -= written;
+      buff += written;
+    }
+  }
+}
+
+void FrameBuffer::Broadcast(int32_t offset) {
+  std::lock_guard<std::mutex> lock(mutex_);
+  current_offset_ = offset;
+  current_seq_++;
+  cond_var_.notify_all();
+}
+void* FrameBuffer::GetBuffer(int fb_index) {
+  return &inner_buffer_[buffer_size() * fb_index];
+}
+size_t FrameBuffer::buffer_size() {
+  return (line_length() * y_res()) + 4;
+}
+int32_t FrameBuffer::x_res() { return x_res_; }
+int32_t FrameBuffer::y_res() { return y_res_; }
+int32_t FrameBuffer::line_length() {
+  return cvd::AlignToPowerOf2(x_res() * bytes_per_pixel(), 4);
+}
+int32_t FrameBuffer::bytes_per_pixel() { return 4; }
+int32_t FrameBuffer::dpi() { return dpi_; }
+int32_t FrameBuffer::refresh_rate() { return refresh_rate_; }
+
+}  // namespace cvd
diff --git a/guest/hals/hwcomposer/cutf_cvm/base_composer.h b/guest/hals/hwcomposer/cutf_cvm/base_composer.h
new file mode 100644
index 0000000..5a23176
--- /dev/null
+++ b/guest/hals/hwcomposer/cutf_cvm/base_composer.h
@@ -0,0 +1,98 @@
+#pragma once
+/*
+ * Copyright (C) 2016 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 is 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 <functional>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#include <hardware/gralloc.h>
+#include <common/libs/fs/shared_fd.h>
+#include "hwcomposer.h"
+
+namespace cvd {
+
+class FrameBuffer{
+ public:
+  FrameBuffer();
+  ~FrameBuffer();
+
+  void Broadcast(int32_t offset);
+  int NextScreenBuffer();
+  void* GetBuffer(int fb_index);
+  size_t buffer_size();
+  int32_t x_res();
+  int32_t y_res();
+  int32_t line_length();
+  int32_t bytes_per_pixel();
+  int32_t dpi();
+  int32_t refresh_rate();
+ private:
+  void BroadcastLoop();
+
+  std::vector<char> inner_buffer_;
+  int last_frame_buffer_ = 0;
+  cvd::SharedFD screen_server_;
+  std::thread broadcast_thread_;
+  int32_t current_offset_ = 0;
+  int32_t current_seq_ = 0;
+  std::mutex mutex_;
+  std::condition_variable cond_var_;
+  bool running_ = true;
+  int32_t x_res_{720};
+  int32_t y_res_{1280};
+  int32_t dpi_{160};
+  int32_t refresh_rate_{60};
+};
+
+class BaseComposer {
+ public:
+  BaseComposer(int64_t vsync_base_timestamp);
+  ~BaseComposer();
+
+  // Sets the composition type of each layer and returns the number of layers
+  // to be composited by the hwcomposer.
+  int PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers);
+  // Returns 0 if successful.
+  int SetLayers(size_t num_layers, vsoc_hwc_layer* layers);
+  void Dump(char* buff, int buff_len);
+
+  int32_t x_res() {
+    return frame_buffer_.x_res();
+  }
+  int32_t y_res() {
+    return frame_buffer_.y_res();
+  }
+  int32_t dpi() {
+    return frame_buffer_.dpi();
+  }
+  int32_t refresh_rate() {
+    return frame_buffer_.refresh_rate();
+  }
+
+ protected:
+  const gralloc_module_t* gralloc_module_;
+  int64_t vsync_base_timestamp_;
+  int32_t vsync_period_ns_;
+  FrameBuffer frame_buffer_;
+
+ private:
+  // Returns buffer offset or negative on error.
+  int PostFrameBufferTarget(buffer_handle_t handle);
+};
+
+}  // namespace cvd
diff --git a/guest/hals/hwcomposer/cutf_cvm/geometry_utils.cpp b/guest/hals/hwcomposer/cutf_cvm/geometry_utils.cpp
new file mode 100644
index 0000000..75b7a61
--- /dev/null
+++ b/guest/hals/hwcomposer/cutf_cvm/geometry_utils.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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 is 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 "geometry_utils.h"
+#include <algorithm>
+#include <utility>
+
+namespace cvd {
+
+bool LayersOverlap(const vsoc_hwc_layer& layer1, const vsoc_hwc_layer& layer2) {
+  int left1 = layer1.displayFrame.left;
+  int right1 = layer1.displayFrame.right;
+  int top1 = layer1.displayFrame.top;
+  int bottom1 = layer1.displayFrame.bottom;
+
+  int left2 = layer2.displayFrame.left;
+  int right2 = layer2.displayFrame.right;
+  int top2 = layer2.displayFrame.top;
+  int bottom2 = layer2.displayFrame.bottom;
+
+  bool overlap_x = left1 < right2 && left2 < right1;
+  bool overlap_y = top1 < bottom2 && top2 < bottom1;
+
+  return overlap_x && overlap_y;
+}
+
+}  // namespace cvd
diff --git a/host/commands/launch/ril_config.h b/guest/hals/hwcomposer/cutf_cvm/geometry_utils.h
similarity index 74%
rename from host/commands/launch/ril_config.h
rename to guest/hals/hwcomposer/cutf_cvm/geometry_utils.h
index 49a43e8..937283f 100644
--- a/host/commands/launch/ril_config.h
+++ b/guest/hals/hwcomposer/cutf_cvm/geometry_utils.h
@@ -1,7 +1,6 @@
 #pragma once
-
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -16,6 +15,10 @@
  * limitations under the License.
  */
 
-#include "host/libs/config/cuttlefish_config.h"
+#include "hwcomposer.h"
 
-void ConfigureRil(vsoc::CuttlefishConfig* config);
\ No newline at end of file
+namespace cvd {
+
+bool LayersOverlap(const vsoc_hwc_layer& layer1, const vsoc_hwc_layer& layer2);
+
+}  // namespace cvd
diff --git a/guest/hals/hwcomposer/cutf_cvm/hwcomposer.cpp b/guest/hals/hwcomposer/cutf_cvm/hwcomposer.cpp
index 954688e..3db7f80 100644
--- a/guest/hals/hwcomposer/cutf_cvm/hwcomposer.cpp
+++ b/guest/hals/hwcomposer/cutf_cvm/hwcomposer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2016 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.
@@ -14,207 +14,470 @@
  * limitations under the License.
  */
 
+// Versions of hwcomposer we implement:
+// JB: 0.3
+// JB-MR1 to N : 1.1
+// N-MR1 to ... : We report 1.1 but SurfaceFlinger has the option to use an
+// adapter to treat our 1.1 hwcomposer as a 2.0. If SF stops using that adapter
+// to support 1.1 implementations it can be copied into cuttlefish from
+// frameworks/native/services/surfaceflinger/DisplayHardware/HWC2On1Adapter.*
+
 #define LOG_TAG "hwc.cf_x86"
-#define HWC_REMOVE_DEPRECATED_VERSIONS 1
-#define IS_TARGET_FRAMEBUFFER(x) ((x) == HWC_FRAMEBUFFER_TARGET)
-#define IS_PRIMARY_DISPLAY(x) ((x) == HWC_DISPLAY_PRIMARY)
-#define CUTF_CVM_HWC_DEVICE_API_VERSION HWC_DEVICE_API_VERSION_1_1
+
+#include <guest/libs/platform_support/api_level_fixes.h>
 
 #include <errno.h>
+#include <fcntl.h>
+#include <math.h>
+#include <poll.h>
 #include <pthread.h>
 #include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+
 #include <string>
 
-#include "log/log.h"
+#define HWC_REMOVE_DEPRECATED_VERSIONS 1
+
+#include <cutils/compiler.h>
+#include <log/log.h>
+#include <cutils/properties.h>
+#include <hardware/gralloc.h>
+#include <hardware/hardware.h>
+#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer_defs.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+
+#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
 #include "guest/hals/hwcomposer/common/hwcomposer.h"
-#include "guest/libs/platform_support/api_level_fixes.h"
-#include "hardware/hwcomposer.h"
-#include "hardware/hwcomposer_defs.h"
+#include <sync/sync.h>
 
-typedef hwc_composer_device_1_t cutf_cvm_hwc_device;
+#include "base_composer.h"
+#include "geometry_utils.h"
+#include "hwcomposer.h"
+#include "vsoc_composer.h"
 
-struct cutf_cvm_hwc_composer_device_1_t {
-  cutf_cvm_hwc_device base;
+#ifdef USE_OLD_HWCOMPOSER
+typedef cvd::BaseComposer InnerComposerType;
+#else
+typedef cvd::VSoCComposer InnerComposerType;
+#endif
+
+typedef InnerComposerType ComposerType;
+
+struct vsoc_hwc_composer_device_1_t {
+  vsoc_hwc_device base;
   cvd::hwc_composer_device_data_t vsync_data;
+  ComposerType* composer;
 };
 
-static int cutf_cvm_hwc_prepare(cutf_cvm_hwc_device* dev __unused, size_t numDisplays,
-                            hwc_display_contents_1_t** displays) {
-  hwc_display_contents_1_t* list = displays[HWC_DISPLAY_PRIMARY];
-  if (!numDisplays || !displays || !list)
-    return 0;
+namespace {
 
-  for (size_t i = 0; i < list->numHwLayers; i++) {
-    if (IS_TARGET_FRAMEBUFFER(list->hwLayers[i].compositionType)) {
-      continue;
-    }
-    list->hwLayers[i].compositionType = HWC_FRAMEBUFFER;
+std::string CompositionString(int type) {
+  switch (type) {
+    case HWC_FRAMEBUFFER:
+      return "Framebuffer";
+    case HWC_OVERLAY:
+      return "Overlay";
+    case HWC_BACKGROUND:
+      return "Background";
+    case HWC_FRAMEBUFFER_TARGET:
+      return "FramebufferTarget";
+#if VSOC_PLATFORM_SDK_AFTER(K)
+    case HWC_SIDEBAND:
+      return "Sideband";
+    case HWC_CURSOR_OVERLAY:
+      return "CursorOverlay";
+#endif
+    default:
+      return std::string("Unknown (") + std::to_string(type) + ")";
   }
+}
+
+void LogLayers(int num_layers, vsoc_hwc_layer* layers, int invalid) {
+  ALOGE("Layers:");
+  for (int idx = 0; idx < num_layers; ++idx) {
+    std::string log_line;
+    if (idx == invalid) {
+      log_line = "Invalid layer: ";
+    }
+    log_line +=
+        "Composition Type: " + CompositionString(layers[idx].compositionType);
+    ALOGE("%s", log_line.c_str());
+  }
+}
+
+// Ensures that the layer does not include any inconsistencies
+bool IsValidLayer(const vsoc_hwc_layer& layer) {
+  if (layer.flags & HWC_SKIP_LAYER) {
+    // A layer we are asked to skip validate should not be marked as skip
+    ALOGE("%s: Layer is marked as skip", __FUNCTION__);
+    return false;
+  }
+  // Check displayFrame
+  if (layer.displayFrame.left > layer.displayFrame.right ||
+      layer.displayFrame.top > layer.displayFrame.bottom) {
+    ALOGE(
+        "%s: Malformed rectangle (displayFrame): [left = %d, right = %d, top = "
+        "%d, bottom = %d]",
+        __FUNCTION__, layer.displayFrame.left, layer.displayFrame.right,
+        layer.displayFrame.top, layer.displayFrame.bottom);
+    return false;
+  }
+  // Validate the handle
+  if (private_handle_t::validate(layer.handle) != 0) {
+    ALOGE("%s: Layer contains an invalid gralloc handle.", __FUNCTION__);
+    return false;
+  }
+  const private_handle_t* p_handle =
+      reinterpret_cast<const private_handle_t*>(layer.handle);
+  // Check sourceCrop
+  if (layer.sourceCrop.left > layer.sourceCrop.right ||
+      layer.sourceCrop.top > layer.sourceCrop.bottom) {
+    ALOGE(
+        "%s: Malformed rectangle (sourceCrop): [left = %d, right = %d, top = "
+        "%d, bottom = %d]",
+        __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
+        layer.sourceCrop.top, layer.sourceCrop.bottom);
+    return false;
+  }
+  if (layer.sourceCrop.left < 0 || layer.sourceCrop.top < 0 ||
+      layer.sourceCrop.right > p_handle->x_res ||
+      layer.sourceCrop.bottom > p_handle->y_res) {
+    ALOGE(
+        "%s: Invalid sourceCrop for buffer handle: sourceCrop = [left = %d, "
+        "right = %d, top = %d, bottom = %d], handle = [width = %d, height = "
+        "%d]",
+        __FUNCTION__, layer.sourceCrop.left, layer.sourceCrop.right,
+        layer.sourceCrop.top, layer.sourceCrop.bottom, p_handle->x_res,
+        p_handle->y_res);
+    return false;
+  }
+  return true;
+}
+
+bool IsValidComposition(int num_layers, vsoc_hwc_layer* layers, bool on_set) {
+  if (num_layers == 0) {
+    ALOGE("Composition requested with 0 layers");
+    return false;
+  }
+  // Sometimes the hwcomposer receives a prepare and set calls with no other
+  // layer than the FRAMEBUFFER_TARGET with a null handler. We treat this case
+  // independently as a valid composition, but issue a warning about it.
+  if (num_layers == 1 && layers[0].compositionType == HWC_FRAMEBUFFER_TARGET &&
+      layers[0].handle == NULL) {
+    ALOGW("Received request for empty composition, treating as valid noop");
+    return true;
+  }
+  // The FRAMEBUFFER_TARGET layer needs to be sane only if
+  // there is at least one layer marked HWC_FRAMEBUFFER or if there is no layer
+  // marked HWC_OVERLAY (i.e some layers where composed with OpenGL, no layer
+  // marked overlay or framebuffer means that surfaceflinger decided to go for
+  // OpenGL without asking the hwcomposer first)
+  bool check_fb_target = true;
+  for (int idx = 0; idx < num_layers; ++idx) {
+    if (layers[idx].compositionType == HWC_FRAMEBUFFER) {
+      // There is at least one, so it needs to be checked.
+      // It may have been set to false before, so ensure it's set to true.
+      check_fb_target = true;
+      break;
+    }
+    if (layers[idx].compositionType == HWC_OVERLAY) {
+      // At least one overlay, we may not need to.
+      check_fb_target = false;
+    }
+  }
+
+  for (int idx = 0; idx < num_layers; ++idx) {
+    switch (layers[idx].compositionType) {
+    case HWC_FRAMEBUFFER_TARGET:
+      // In the call to prepare() the framebuffer target does not have a valid
+      // buffer_handle, so we don't validate it yet.
+      if (on_set && check_fb_target && !IsValidLayer(layers[idx])) {
+        ALOGE("%s: Invalid layer found", __FUNCTION__);
+        LogLayers(num_layers, layers, idx);
+        return false;
+      }
+      break;
+    case HWC_OVERLAY:
+      if (!(layers[idx].flags & HWC_SKIP_LAYER) &&
+          !IsValidLayer(layers[idx])) {
+        ALOGE("%s: Invalid layer found", __FUNCTION__);
+        LogLayers(num_layers, layers, idx);
+        return false;
+      }
+      break;
+    }
+  }
+  return true;
+}
+
+}
+
+#if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
+static int vsoc_hwc_prepare(vsoc_hwc_device* dev, hwc_layer_list_t* list) {
+#else
+static int vsoc_hwc_prepare(vsoc_hwc_device* dev, size_t numDisplays,
+                            hwc_display_contents_1_t** displays) {
+  if (!numDisplays || !displays) return 0;
+
+  hwc_display_contents_1_t* list = displays[HWC_DISPLAY_PRIMARY];
+
+  if (!list) return 0;
+#endif
+  if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], false)) {
+    LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
+    return -1;
+  }
+  reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->PrepareLayers(
+      list->numHwLayers, &list->hwLayers[0]);
   return 0;
 }
 
-static int cutf_cvm_hwc_set(cutf_cvm_hwc_device* dev __unused, size_t numDisplays __unused,
-                        hwc_display_contents_1_t** displays __unused) {
-  // TODO: b/125482910
-  return 0;
+#if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
+int vsoc_hwc_set(struct hwc_composer_device* dev, hwc_display_t dpy,
+                 hwc_surface_t sur, hwc_layer_list_t* list) {
+  if (list->numHwLayers == 1 &&
+      layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) {
+    ALOGW("Received request for empty composition, treating as valid noop");
+    return 0;
+  }
+  if (!IsValidComposition(list->numHwLayers, &list->hwLayers[0], true)) {
+    LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
+    return -1;
+  }
+  return reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)
+      ->composer->SetLayers(list->numHwLayers, &list->hwLayers[0]);
 }
+#else
+static int vsoc_hwc_set(vsoc_hwc_device* dev, size_t numDisplays,
+                        hwc_display_contents_1_t** displays) {
+  if (!numDisplays || !displays) return 0;
 
-static void cutf_cvm_hwc_register_procs(cutf_cvm_hwc_device* dev,
+  hwc_display_contents_1_t* contents = displays[HWC_DISPLAY_PRIMARY];
+  if (!contents) return 0;
+
+  vsoc_hwc_layer* layers = &contents->hwLayers[0];
+  if (contents->numHwLayers == 1 &&
+      layers[0].compositionType == HWC_FRAMEBUFFER_TARGET) {
+    ALOGW("Received request for empty composition, treating as valid noop");
+    return 0;
+  }
+  if (!IsValidComposition(contents->numHwLayers, layers, true)) {
+    LOG_ALWAYS_FATAL("%s: Invalid composition requested", __FUNCTION__);
+    return -1;
+  }
+  int retval =
+      reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->SetLayers(
+          contents->numHwLayers, layers);
+
+  int closedFds = 0;
+  for (size_t index = 0; index < contents->numHwLayers; ++index) {
+    if (layers[index].acquireFenceFd != -1) {
+      close(layers[index].acquireFenceFd);
+      layers[index].acquireFenceFd = -1;
+      ++closedFds;
+    }
+  }
+  if (closedFds) {
+    ALOGI("Saw %zu layers, closed=%d", contents->numHwLayers, closedFds);
+  }
+
+  // TODO(ghartman): This should be set before returning. On the next set it
+  // should be signalled when we load the new frame.
+  contents->retireFenceFd = -1;
+  return retval;
+}
+#endif
+
+static void vsoc_hwc_register_procs(vsoc_hwc_device* dev,
                                     const hwc_procs_t* procs) {
-  struct cutf_cvm_hwc_composer_device_1_t* pdev =
-      (struct cutf_cvm_hwc_composer_device_1_t*)dev;
+  struct vsoc_hwc_composer_device_1_t* pdev =
+      (struct vsoc_hwc_composer_device_1_t*)dev;
   pdev->vsync_data.procs = procs;
 }
 
-static int cutf_cvm_hwc_query(cutf_cvm_hwc_device* dev __unused, int what __unused, int* value) {
-  // TODO: b/125482910
-  struct cutf_cvm_hwc_composer_device_1_t* pdev =
-      (struct cutf_cvm_hwc_composer_device_1_t*)dev;
+static int vsoc_hwc_query(vsoc_hwc_device* dev, int what, int* value) {
+  struct vsoc_hwc_composer_device_1_t* pdev =
+      (struct vsoc_hwc_composer_device_1_t*)dev;
+
   switch (what) {
     case HWC_BACKGROUND_LAYER_SUPPORTED:
-      *value = 0;
+      // we support the background layer
+      value[0] = 0;
       break;
     case HWC_VSYNC_PERIOD:
-      *value = pdev->vsync_data.vsync_period_ns;
+      value[0] = pdev->vsync_data.vsync_period_ns;
       break;
     default:
       // unsupported query
-      ALOGE("%s: badness unsupported query what=%d", __FUNCTION__, what);
+      ALOGE("%s badness unsupported query what=%d", __FUNCTION__, what);
       return -EINVAL;
   }
   return 0;
 }
 
-static int cutf_cvm_hwc_event_control(
-    cutf_cvm_hwc_device* /*dev*/, int /*dpy*/, int event __unused, int /*enabled*/) {
-  // TODO: b/125482910
+static int vsoc_hwc_event_control(
+#if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
+    vsoc_hwc_device* /*dev*/, int event, int /*enabled*/) {
+#else
+    vsoc_hwc_device* /*dev*/, int /*dpy*/, int event, int /*enabled*/) {
+#endif
+
+  if (event == HWC_EVENT_VSYNC) {
+    return 0;
+  }
+  return -EINVAL;
+}
+
+static int vsoc_hwc_blank(vsoc_hwc_device* /*dev*/, int disp, int /*blank*/) {
+  if (!IS_PRIMARY_DISPLAY(disp)) return -EINVAL;
   return 0;
 }
 
-static int cutf_cvm_hwc_blank(cutf_cvm_hwc_device* /*dev*/, int disp __unused, int /*blank*/) {
-  // TODO: b/125482910
-  return 0;
+static void vsoc_hwc_dump(vsoc_hwc_device* dev, char* buff, int buff_len) {
+  reinterpret_cast<vsoc_hwc_composer_device_1_t*>(dev)->composer->Dump(
+      buff, buff_len);
 }
 
-static void cutf_cvm_hwc_dump(cutf_cvm_hwc_device* dev __unused, char* buff __unused, int buff_len __unused) {
-  // TODO: b/125482910
+static int vsoc_hwc_get_display_configs(vsoc_hwc_device* /*dev*/, int disp,
+                                        uint32_t* configs, size_t* numConfigs) {
+  if (*numConfigs == 0) return 0;
+
+  if (IS_PRIMARY_DISPLAY(disp)) {
+    configs[0] = 0;
+    *numConfigs = 1;
+    return 0;
+  }
+
+  return -EINVAL;
 }
 
-static int cutf_cvm_hwc_get_display_configs(cutf_cvm_hwc_device* /*dev*/, int disp __unused,
-                                        uint32_t* configs __unused, size_t* numConfigs __unused) {
-  // TODO: b/125482910
-  return 0;
-}
-
-static int32_t cutf_cvm_hwc_attribute(struct cutf_cvm_hwc_composer_device_1_t* pdev,
+#if VSOC_PLATFORM_SDK_AFTER(J)
+static int32_t vsoc_hwc_attribute(struct vsoc_hwc_composer_device_1_t* pdev,
                                   const uint32_t attribute) {
-  // TODO: b/125482910
   switch (attribute) {
     case HWC_DISPLAY_VSYNC_PERIOD:
       return pdev->vsync_data.vsync_period_ns;
     case HWC_DISPLAY_WIDTH:
-      return 720;
+      return pdev->composer->x_res();
     case HWC_DISPLAY_HEIGHT:
-      return 1280;
+      return pdev->composer->y_res();
     case HWC_DISPLAY_DPI_X:
-      ALOGI("%s: Reporting DPI_X of %d", __FUNCTION__, 1);
+      ALOGI("Reporting DPI_X of %d", pdev->composer->dpi());
       // The number of pixels per thousand inches
-      return 240000;
+      return pdev->composer->dpi() * 1000;
     case HWC_DISPLAY_DPI_Y:
-      ALOGI("%s: Reporting DPI_Y of %d", __FUNCTION__, 1);
+      ALOGI("Reporting DPI_Y of %d", pdev->composer->dpi());
       // The number of pixels per thousand inches
-      return 240000;
+      return pdev->composer->dpi() * 1000;
     default:
-      ALOGE("%s: unknown display attribute %u", __FUNCTION__, attribute);
+      ALOGE("unknown display attribute %u", attribute);
       return -EINVAL;
   }
 }
 
-static int cutf_cvm_hwc_get_display_attributes(cutf_cvm_hwc_device* dev __unused, int disp __unused,
+static int vsoc_hwc_get_display_attributes(vsoc_hwc_device* dev, int disp,
                                            uint32_t config __unused,
-                                           const uint32_t* attributes __unused,
-                                           int32_t* values __unused) {
-  struct cutf_cvm_hwc_composer_device_1_t* pdev =
-      (struct cutf_cvm_hwc_composer_device_1_t*)dev;
+                                           const uint32_t* attributes,
+                                           int32_t* values) {
+  struct vsoc_hwc_composer_device_1_t* pdev =
+      (struct vsoc_hwc_composer_device_1_t*)dev;
 
   if (!IS_PRIMARY_DISPLAY(disp)) {
-    ALOGE("%s: unknown display type %u", __FUNCTION__, disp);
+    ALOGE("unknown display type %u", disp);
     return -EINVAL;
   }
 
   for (int i = 0; attributes[i] != HWC_DISPLAY_NO_ATTRIBUTE; i++) {
-    values[i] = cutf_cvm_hwc_attribute(pdev, attributes[i]);
+    values[i] = vsoc_hwc_attribute(pdev, attributes[i]);
   }
 
   return 0;
 }
+#endif
 
-static int cutf_cvm_hwc_close(hw_device_t* device) {
-  struct cutf_cvm_hwc_composer_device_1_t* dev =
-      (struct cutf_cvm_hwc_composer_device_1_t*)device;
+static int vsoc_hwc_close(hw_device_t* device) {
+  struct vsoc_hwc_composer_device_1_t* dev =
+      (struct vsoc_hwc_composer_device_1_t*)device;
+  ALOGE("vsoc_hwc_close");
+  pthread_kill(dev->vsync_data.vsync_thread, SIGTERM);
+  pthread_join(dev->vsync_data.vsync_thread, NULL);
+  delete dev->composer;
   delete dev;
   return 0;
 }
 
-static int cutf_cvm_hwc_open(const struct hw_module_t* module, const char* name,
+static int vsoc_hwc_open(const struct hw_module_t* module, const char* name,
                          struct hw_device_t** device) {
   ALOGI("%s", __FUNCTION__);
-  if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
-    ALOGE("%s: called with bad name %s", __FUNCTION__, name);
+  if (strcmp(name, HWC_HARDWARE_COMPOSER)) {
+    ALOGE("%s called with bad name %s", __FUNCTION__, name);
     return -EINVAL;
   }
 
-  cutf_cvm_hwc_composer_device_1_t* dev = new cutf_cvm_hwc_composer_device_1_t();
+  vsoc_hwc_composer_device_1_t* dev = new vsoc_hwc_composer_device_1_t();
   if (!dev) {
-    ALOGE("%s: failed to allocate dev", __FUNCTION__);
+    ALOGE("%s failed to allocate dev", __FUNCTION__);
     return -ENOMEM;
   }
 
-  const int refreshRate = 60;
-  const int nsPerSec = 1000000000;
-  dev->vsync_data.vsync_period_ns = nsPerSec / refreshRate;
   struct timespec rt;
-  if (clock_gettime(CLOCK_MONOTONIC, &rt) != 0) {
-    ALOGE("%s: error in clock_gettime: %s", __FUNCTION__, strerror(errno));
+  if (clock_gettime(CLOCK_MONOTONIC, &rt) == -1) {
+    ALOGE("%s:%d error in vsync thread clock_gettime: %s", __FILE__, __LINE__,
+          strerror(errno));
   }
-  dev->vsync_data.vsync_base_timestamp = int64_t(rt.tv_sec) * nsPerSec + rt.tv_nsec;
+  dev->vsync_data.vsync_base_timestamp = int64_t(rt.tv_sec) * 1e9 + rt.tv_nsec;
 
   dev->base.common.tag = HARDWARE_DEVICE_TAG;
-  dev->base.common.version = CUTF_CVM_HWC_DEVICE_API_VERSION;
+  dev->base.common.version = VSOC_HWC_DEVICE_API_VERSION;
   dev->base.common.module = const_cast<hw_module_t*>(module);
-  dev->base.common.close = cutf_cvm_hwc_close;
+  dev->base.common.close = vsoc_hwc_close;
 
-  dev->base.prepare = cutf_cvm_hwc_prepare;
-  dev->base.set = cutf_cvm_hwc_set;
-  dev->base.query = cutf_cvm_hwc_query;
-  dev->base.registerProcs = cutf_cvm_hwc_register_procs;
-  dev->base.dump = cutf_cvm_hwc_dump;
-  dev->base.blank = cutf_cvm_hwc_blank;
-  dev->base.eventControl = cutf_cvm_hwc_event_control;
-  dev->base.getDisplayConfigs = cutf_cvm_hwc_get_display_configs;
-  dev->base.getDisplayAttributes = cutf_cvm_hwc_get_display_attributes;
-
-  int ret = pthread_create(&dev->vsync_data.vsync_thread, NULL, cvd::hwc_vsync_thread, &dev->vsync_data);
-  if (ret != 0) {
-    ALOGE("%s: failed to start vsync thread: %s", __FUNCTION__, strerror(ret));
-    dev->base.common.close(&dev->base.common);
-    return -ret;
+  dev->base.prepare = vsoc_hwc_prepare;
+  dev->base.set = vsoc_hwc_set;
+  dev->base.query = vsoc_hwc_query;
+  dev->base.registerProcs = vsoc_hwc_register_procs;
+  dev->base.dump = vsoc_hwc_dump;
+#if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
+  static hwc_methods_t hwc_methods = {vsoc_hwc_event_control};
+  dev->base.methods = &hwc_methods;
+#else
+  dev->base.blank = vsoc_hwc_blank;
+  dev->base.eventControl = vsoc_hwc_event_control;
+  dev->base.getDisplayConfigs = vsoc_hwc_get_display_configs;
+  dev->base.getDisplayAttributes = vsoc_hwc_get_display_attributes;
+#endif
+  dev->composer = new ComposerType(dev->vsync_data.vsync_base_timestamp);
+  dev->vsync_data.vsync_period_ns = 1000000000 / dev->composer->refresh_rate();
+  int ret = pthread_create(&dev->vsync_data.vsync_thread,
+                           NULL, cvd::hwc_vsync_thread, &dev->vsync_data);
+  if (ret) {
+    ALOGE("failed to start vsync thread: %s", strerror(ret));
+    ret = -ret;
+    delete dev;
+  } else {
+    *device = &dev->base.common;
   }
 
-  *device = &dev->base.common;
   return ret;
 }
 
-static struct hw_module_methods_t cutf_cvm_hwc_module_methods = {
-    cutf_cvm_hwc_open,
+static struct hw_module_methods_t vsoc_hwc_module_methods = {
+    vsoc_hwc_open,
 };
 
 hwc_module_t HAL_MODULE_INFO_SYM = {{HARDWARE_MODULE_TAG,
                                      HWC_MODULE_API_VERSION_0_1,
                                      HARDWARE_HAL_API_VERSION,
                                      HWC_HARDWARE_MODULE_ID,
-                                     "cutf_cvm hwcomposer module",
+                                     "VSOC hwcomposer module",
                                      "Google",
-                                     &cutf_cvm_hwc_module_methods,
+                                     &vsoc_hwc_module_methods,
                                      NULL,
                                      {0}}};
diff --git a/guest/hals/hwcomposer/cutf_cvm/hwcomposer.h b/guest/hals/hwcomposer/cutf_cvm/hwcomposer.h
new file mode 100644
index 0000000..a6b8121
--- /dev/null
+++ b/guest/hals/hwcomposer/cutf_cvm/hwcomposer.h
@@ -0,0 +1,35 @@
+#pragma once
+/*
+ * Copyright (C) 2016 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 is 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/libs/platform_support/api_level_fixes.h>
+
+#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer_defs.h>
+
+#if VSOC_PLATFORM_SDK_BEFORE(J_MR1)
+typedef hwc_composer_device_t vsoc_hwc_device;
+typedef hwc_layer_t vsoc_hwc_layer;
+#define IS_TARGET_FRAMEBUFFER(x) false
+#define IS_PRIMARY_DISPLAY(x) true
+#define VSOC_HWC_DEVICE_API_VERSION HWC_DEVICE_API_VERSION_0_3
+#else
+typedef hwc_composer_device_1_t vsoc_hwc_device;
+typedef hwc_layer_1_t vsoc_hwc_layer;
+#define IS_TARGET_FRAMEBUFFER(x) ((x) == HWC_FRAMEBUFFER_TARGET)
+#define IS_PRIMARY_DISPLAY(x) ((x) == HWC_DISPLAY_PRIMARY)
+#define VSOC_HWC_DEVICE_API_VERSION HWC_DEVICE_API_VERSION_1_1
+#endif
diff --git a/guest/hals/hwcomposer/cutf_cvm/vsoc_composer.cpp b/guest/hals/hwcomposer/cutf_cvm/vsoc_composer.cpp
new file mode 100644
index 0000000..5b55e84
--- /dev/null
+++ b/guest/hals/hwcomposer/cutf_cvm/vsoc_composer.cpp
@@ -0,0 +1,608 @@
+/*
+ * Copyright (C) 2016 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 is 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 "vsoc_composer.h"
+
+#include <algorithm>
+#include <cstdlib>
+#include <utility>
+#include <vector>
+
+#include <log/log.h>
+#include <hardware/hwcomposer.h>
+#include <hardware/hwcomposer_defs.h>
+#include <libyuv.h>
+#include <system/graphics.h>
+
+#include <common/libs/utils/size_utils.h>
+
+#include "geometry_utils.h"
+
+namespace cvd {
+
+namespace {
+
+bool LayerNeedsScaling(const vsoc_hwc_layer& layer) {
+  int from_w = layer.sourceCrop.right - layer.sourceCrop.left;
+  int from_h = layer.sourceCrop.bottom - layer.sourceCrop.top;
+  int to_w = layer.displayFrame.right - layer.displayFrame.left;
+  int to_h = layer.displayFrame.bottom - layer.displayFrame.top;
+
+  bool not_rot_scale = from_w != to_w || from_h != to_h;
+  bool rot_scale = from_w != to_h || from_h != to_w;
+
+  bool needs_rot = layer.transform & HAL_TRANSFORM_ROT_90;
+
+  return needs_rot ? rot_scale : not_rot_scale;
+}
+
+bool LayerNeedsBlending(const vsoc_hwc_layer& layer) {
+  return layer.blending != HWC_BLENDING_NONE;
+}
+
+bool LayerNeedsAttenuation(const vsoc_hwc_layer& layer) {
+  return layer.blending == HWC_BLENDING_COVERAGE;
+}
+
+struct BufferSpec;
+typedef int (*ConverterFunction)(const BufferSpec& src, const BufferSpec& dst,
+                                 bool v_flip);
+int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool v_flip);
+int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool v_flip);
+ConverterFunction GetConverter(uint32_t format) {
+  switch (format) {
+    case HAL_PIXEL_FORMAT_RGBA_8888:
+    case HAL_PIXEL_FORMAT_RGBX_8888:
+    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
+      return &DoCopy;
+
+    case HAL_PIXEL_FORMAT_YV12:
+      return &ConvertFromYV12;
+
+    // Unsupported formats
+    // TODO(jemoreira): Conversion from these formats should be implemented as
+    // we find evidence of its usage.
+    // case HAL_PIXEL_FORMAT_BGRA_8888:
+
+    // case HAL_PIXEL_FORMAT_RGB_888:
+    // case HAL_PIXEL_FORMAT_RGB_565:
+
+    // case HAL_PIXEL_FORMAT_sRGB_A_8888:
+    // case HAL_PIXEL_FORMAT_sRGB_X_8888:
+
+    // case HAL_PIXEL_FORMAT_Y8:
+    // case HAL_PIXEL_FORMAT_Y16:
+
+    // case HAL_PIXEL_FORMAT_RAW_SENSOR:
+    // case HAL_PIXEL_FORMAT_BLOB:
+
+    // case HAL_PIXEL_FORMAT_YCbCr_420_888:
+    // case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    // case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+    // case HAL_PIXEL_FORMAT_YCbCr_422_I:
+    default:
+      ALOGW("Unsupported format: 0x%04x, returning null converter function",
+            format);
+  }
+  return NULL;
+}
+
+// Whether we support a given format
+bool IsFormatSupported(uint32_t format) { return GetConverter(format) != NULL; }
+
+bool CanCompositeLayer(const vsoc_hwc_layer& layer) {
+  if (layer.handle == NULL) {
+    ALOGW("%s received a layer with a null handler", __FUNCTION__);
+    return false;
+  }
+  int format = reinterpret_cast<const private_handle_t*>(layer.handle)->format;
+  if (!IsFormatSupported(format)) {
+    ALOGD("Unsupported pixel format: 0x%x, doing software composition instead",
+          format);
+    return false;
+  }
+  return true;
+}
+
+/*******************************************************************************
+Libyuv's convert functions only allow the combination of any rotation (multiple
+of 90 degrees) and a vertical flip, but not horizontal flips.
+Surfaceflinger's transformations are expressed in terms of a vertical flip, a
+horizontal flip and/or a single 90 degrees clockwise rotation (see
+NATIVE_WINDOW_TRANSFORM_HINT documentation on system/window.h for more insight).
+The following code allows to turn a horizontal flip into a 180 degrees rotation
+and a vertical flip.
+*******************************************************************************/
+libyuv::RotationMode GetRotationFromTransform(uint32_t transform) {
+  uint32_t rotation =
+      (transform & HAL_TRANSFORM_ROT_90) ? 1 : 0;          // 1 * ROT90 bit
+  rotation += (transform & HAL_TRANSFORM_FLIP_H) ? 2 : 0;  // 2 * VFLIP bit
+  return static_cast<libyuv::RotationMode>(90 * rotation);
+}
+
+bool GetVFlipFromTransform(uint32_t transform) {
+  // vertical flip xor horizontal flip
+  return ((transform & HAL_TRANSFORM_FLIP_V) >> 1) ^
+         (transform & HAL_TRANSFORM_FLIP_H);
+}
+
+struct BufferSpec {
+  uint8_t* buffer;
+  size_t size;
+  int width;
+  int height;
+  int stride;
+  int crop_x;
+  int crop_y;
+  int crop_width;
+  int crop_height;
+  uint32_t format;
+
+  BufferSpec(uint8_t* buffer, size_t size, int width, int height, int stride)
+      : buffer(buffer),
+        size(size),
+        width(width),
+        height(height),
+        stride(stride),
+        crop_x(0),
+        crop_y(0),
+        crop_width(width),
+        crop_height(height),
+        format(HAL_PIXEL_FORMAT_RGBA_8888) {}
+};
+
+int ConvertFromYV12(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
+  // use the stride in pixels as the source width
+  int stride_in_pixels = src.stride / formatToBytesPerPixel(src.format);
+
+  // The following calculation of plane offsets and alignments are based on
+  // swiftshader's Sampler::setTextureLevel() implementation
+  // (Renderer/Sampler.cpp:225)
+  uint8_t* src_y = src.buffer;
+  int stride_y = stride_in_pixels;
+  uint8_t* src_v = src_y + stride_y * src.height;
+  int stride_v = cvd::AlignToPowerOf2(stride_y / 2, 4);
+  uint8_t* src_u = src_v + stride_v *  src.height / 2;
+  int stride_u = cvd::AlignToPowerOf2(stride_y / 2, 4);
+
+  // Adjust for crop
+  src_y += src.crop_y * stride_y + src.crop_x;
+  src_v += (src.crop_y / 2) * stride_v + (src.crop_x / 2);
+  src_u += (src.crop_y / 2) * stride_u + (src.crop_x / 2);
+  uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride +
+                        dst.crop_x * formatToBytesPerPixel(dst.format);
+
+  // YV12 is the same as I420, with the U and V planes swapped
+  return libyuv::I420ToARGB(src_y, stride_y, src_v, stride_v, src_u, stride_u,
+                            dst_buffer, dst.stride, dst.crop_width,
+                            v_flip ? -dst.crop_height : dst.crop_height);
+}
+
+int DoConversion(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
+  return (*GetConverter(src.format))(src, dst, v_flip);
+}
+
+int DoCopy(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
+  // Point to the upper left corner of the crop rectangle
+  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
+                        src.crop_x * formatToBytesPerPixel(src.format);
+  uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride +
+                        dst.crop_x * formatToBytesPerPixel(dst.format);
+  int width = src.crop_width;
+  int height = src.crop_height;
+
+  if (v_flip) {
+    height = -height;
+  }
+
+  // HAL formats are named based on the order of the pixel componets on the
+  // byte stream, while libyuv formats are named based on the order of those
+  // pixel components in an integer written from left to right. So
+  // libyuv::FOURCC_ARGB is equivalent to HAL_PIXEL_FORMAT_BGRA_8888.
+  return libyuv::ARGBCopy(src_buffer, src.stride, dst_buffer, dst.stride, width,
+                          height);
+}
+
+int DoRotation(const BufferSpec& src, const BufferSpec& dst,
+               libyuv::RotationMode rotation, bool v_flip) {
+  // Point to the upper left corner of the crop rectangles
+  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
+                        src.crop_x * formatToBytesPerPixel(src.format);
+  uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride +
+                        dst.crop_x * formatToBytesPerPixel(dst.format);
+  int width = src.crop_width;
+  int height = src.crop_height;
+
+  if (v_flip) {
+    height = -height;
+  }
+
+  return libyuv::ARGBRotate(src_buffer, src.stride, dst_buffer, dst.stride,
+                            width, height, rotation);
+}
+
+int DoScaling(const BufferSpec& src, const BufferSpec& dst, bool v_flip) {
+  // Point to the upper left corner of the crop rectangles
+  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
+                        src.crop_x * formatToBytesPerPixel(src.format);
+  uint8_t* dst_buffer = dst.buffer + dst.crop_y * dst.stride +
+                        dst.crop_x * formatToBytesPerPixel(dst.format);
+  int src_width = src.crop_width;
+  int src_height = src.crop_height;
+  int dst_width = dst.crop_width;
+  int dst_height = dst.crop_height;
+
+  if (v_flip) {
+    src_height = -src_height;
+  }
+
+  return libyuv::ARGBScale(src_buffer, src.stride, src_width, src_height,
+                           dst_buffer, dst.stride, dst_width, dst_height,
+                           libyuv::kFilterBilinear);
+}
+
+int DoAttenuation(const BufferSpec& src, const BufferSpec& dest, bool v_flip) {
+  // Point to the upper left corner of the crop rectangles
+  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
+                        src.crop_x * formatToBytesPerPixel(src.format);
+  uint8_t* dst_buffer = dest.buffer + dest.crop_y * dest.stride +
+                        dest.crop_x * formatToBytesPerPixel(dest.format);
+  int width = dest.crop_width;
+  int height = dest.crop_height;
+
+  if (v_flip) {
+    height = -height;
+  }
+
+  return libyuv::ARGBAttenuate(src_buffer, src.stride, dst_buffer, dest.stride,
+                               width, height);
+}
+
+int DoBlending(const BufferSpec& src, const BufferSpec& dest, bool v_flip) {
+  // Point to the upper left corner of the crop rectangles
+  uint8_t* src_buffer = src.buffer + src.crop_y * src.stride +
+                        src.crop_x * formatToBytesPerPixel(src.format);
+  uint8_t* dst_buffer = dest.buffer + dest.crop_y * dest.stride +
+                        dest.crop_x * formatToBytesPerPixel(dest.format);
+  int width = dest.crop_width;
+  int height = dest.crop_height;
+
+  if (v_flip) {
+    height = -height;
+  }
+
+  // libyuv's ARGB format is hwcomposer's BGRA format, since blending only cares
+  // for the position of alpha in the pixel and not the position of the colors
+  // this function is perfectly usable.
+  return libyuv::ARGBBlend(src_buffer, src.stride, dst_buffer, dest.stride,
+                           dst_buffer, dest.stride, width, height);
+}
+
+}  // namespace
+
+void VSoCComposer::CompositeLayer(vsoc_hwc_layer* src_layer,
+                                  int buffer_idx) {
+  libyuv::RotationMode rotation =
+      GetRotationFromTransform(src_layer->transform);
+
+  const private_handle_t* src_priv_handle =
+      reinterpret_cast<const private_handle_t*>(src_layer->handle);
+
+  // TODO(jemoreira): Remove the hardcoded fomat.
+  bool needs_conversion = src_priv_handle->format != HAL_PIXEL_FORMAT_RGBX_8888;
+  bool needs_scaling = LayerNeedsScaling(*src_layer);
+  bool needs_rotation = rotation != libyuv::kRotate0;
+  bool needs_transpose = needs_rotation && rotation != libyuv::kRotate180;
+  bool needs_vflip = GetVFlipFromTransform(src_layer->transform);
+  bool needs_attenuation = LayerNeedsAttenuation(*src_layer);
+  bool needs_blending = LayerNeedsBlending(*src_layer);
+  bool needs_copy = !(needs_conversion || needs_scaling || needs_rotation ||
+                      needs_vflip || needs_attenuation || needs_blending);
+
+  uint8_t* src_buffer;
+  uint8_t* dst_buffer = reinterpret_cast<uint8_t*>(
+      frame_buffer_.GetBuffer(buffer_idx));
+  int retval = gralloc_module_->lock(
+      gralloc_module_, src_layer->handle, GRALLOC_USAGE_SW_READ_OFTEN, 0, 0,
+      src_priv_handle->x_res, src_priv_handle->y_res,
+      reinterpret_cast<void**>(&src_buffer));
+  if (retval) {
+    ALOGE("Got error code %d from lock function", retval);
+    return;
+  }
+  if (retval) {
+    ALOGE("Got error code %d from lock function", retval);
+    // TODO(jemoreira): Use a lock_guard-like object.
+    gralloc_module_->unlock(gralloc_module_, src_priv_handle);
+    return;
+  }
+
+  BufferSpec src_layer_spec(src_buffer, src_priv_handle->total_size,
+                            src_priv_handle->x_res, src_priv_handle->y_res,
+                            src_priv_handle->stride_in_pixels *
+                                formatToBytesPerPixel(src_priv_handle->format));
+  src_layer_spec.crop_x = src_layer->sourceCrop.left;
+  src_layer_spec.crop_y = src_layer->sourceCrop.top;
+  src_layer_spec.crop_width =
+      src_layer->sourceCrop.right - src_layer->sourceCrop.left;
+  src_layer_spec.crop_height =
+      src_layer->sourceCrop.bottom - src_layer->sourceCrop.top;
+  src_layer_spec.format = src_priv_handle->format;
+
+  BufferSpec dst_layer_spec(dst_buffer, frame_buffer_.buffer_size(),
+                            frame_buffer_.x_res(), frame_buffer_.y_res(),
+                            frame_buffer_.line_length());
+  dst_layer_spec.crop_x = src_layer->displayFrame.left;
+  dst_layer_spec.crop_y = src_layer->displayFrame.top;
+  dst_layer_spec.crop_width =
+      src_layer->displayFrame.right - src_layer->displayFrame.left;
+  dst_layer_spec.crop_height =
+      src_layer->displayFrame.bottom - src_layer->displayFrame.top;
+  // TODO(jemoreira): Remove the hardcoded fomat.
+  dst_layer_spec.format = HAL_PIXEL_FORMAT_RGBX_8888;
+
+  // Add the destination layer to the bottom of the buffer stack
+  std::vector<BufferSpec> dest_buffer_stack(1, dst_layer_spec);
+
+  // If more than operation is to be performed, a temporary buffer is needed for
+  // each additional operation
+
+  // N operations need N destination buffers, the destination layer (the
+  // framebuffer) is one of them, so only N-1 temporary buffers are needed.
+  // Vertical flip is not taken into account because it can be done together
+  // with any other operation.
+  int needed_tmp_buffers = (needs_conversion ? 1 : 0) +
+                           (needs_scaling ? 1 : 0) + (needs_rotation ? 1 : 0) +
+                           (needs_attenuation ? 1 : 0) +
+                           (needs_blending ? 1 : 0) + (needs_copy ? 1 : 0) - 1;
+
+  int x_res = src_layer->displayFrame.right - src_layer->displayFrame.left;
+  int y_res = src_layer->displayFrame.bottom - src_layer->displayFrame.top;
+  size_t output_frame_size =
+      x_res *
+    cvd::AlignToPowerOf2(y_res * frame_buffer_.bytes_per_pixel(), 4);
+  while (needed_tmp_buffers > 0) {
+    BufferSpec tmp(RotateTmpBuffer(needed_tmp_buffers), output_frame_size,
+                   x_res, y_res,
+                   cvd::AlignToPowerOf2(
+                       x_res * frame_buffer_.bytes_per_pixel(), 4));
+    dest_buffer_stack.push_back(tmp);
+    needed_tmp_buffers--;
+  }
+
+  // Conversion and scaling should always be the first operations, so that every
+  // other operation works on equally sized frames (garanteed to fit in the tmp
+  // buffers)
+
+  // TODO(jemoreira): We are converting to ARGB as the first step under the
+  // assumption that scaling ARGB is faster than scaling I420 (the most common).
+  // This should be confirmed with testing.
+  if (needs_conversion) {
+    BufferSpec& dst_buffer_spec = dest_buffer_stack.back();
+    if (needs_scaling || needs_transpose) {
+      // If a rotation or a scaling operation are needed the dimensions at the
+      // top of the buffer stack are wrong (wrong sizes for scaling, swapped
+      // width and height for 90 and 270 rotations).
+      // Make width and height match the crop sizes on the source
+      int src_width = src_layer_spec.crop_width;
+      int src_height = src_layer_spec.crop_height;
+      int dst_stride = cvd::AlignToPowerOf2(
+          src_width * frame_buffer_.bytes_per_pixel(), 4);
+      size_t needed_size = dst_stride * src_height;
+      dst_buffer_spec.width = src_width;
+      dst_buffer_spec.height = src_height;
+      // Ajust the stride accordingly
+      dst_buffer_spec.stride = dst_stride;
+      // Crop sizes also need to be adjusted
+      dst_buffer_spec.crop_width = src_width;
+      dst_buffer_spec.crop_height = src_height;
+      dst_buffer_spec.size = needed_size;
+      // crop_x and y are fine at 0, format is already set to match destination
+
+      // In case of a scale, the source frame may be bigger than the default tmp
+      // buffer size
+      if (needed_size > tmp_buffer_.size() / kNumTmpBufferPieces) {
+        dst_buffer_spec.buffer = GetSpecialTmpBuffer(needed_size);
+      }
+    }
+    retval = DoConversion(src_layer_spec, dst_buffer_spec, needs_vflip);
+    if (retval) {
+      ALOGE("Got error code %d from DoConversion function", retval);
+    }
+    needs_vflip = false;
+    src_layer_spec = dst_buffer_spec;
+    dest_buffer_stack.pop_back();
+  }
+
+  if (needs_scaling) {
+    BufferSpec& dst_buffer_spec = dest_buffer_stack.back();
+    if (needs_transpose) {
+      // If a rotation is needed, the temporary buffer has the correct size but
+      // needs to be transposed and have its stride updated accordingly. The
+      // crop sizes also needs to be transposed, but not the x and y since they
+      // are both zero in a temporary buffer (and it is a temporary buffer
+      // because a rotation will be performed next).
+      std::swap(dst_buffer_spec.width, dst_buffer_spec.height);
+      std::swap(dst_buffer_spec.crop_width, dst_buffer_spec.crop_height);
+      // TODO (jemoreira): Aligment (To align here may cause the needed size to
+      // be bigger than the buffer, so care should be taken)
+      dst_buffer_spec.stride =
+          dst_buffer_spec.width * frame_buffer_.bytes_per_pixel();
+    }
+    retval = DoScaling(src_layer_spec, dst_buffer_spec, needs_vflip);
+    needs_vflip = false;
+    if (retval) {
+      ALOGE("Got error code %d from DoScaling function", retval);
+    }
+    src_layer_spec = dst_buffer_spec;
+    dest_buffer_stack.pop_back();
+  }
+
+  if (needs_rotation) {
+    retval = DoRotation(src_layer_spec, dest_buffer_stack.back(), rotation,
+                        needs_vflip);
+    needs_vflip = false;
+    if (retval) {
+      ALOGE("Got error code %d from DoTransform function", retval);
+    }
+    src_layer_spec = dest_buffer_stack.back();
+    dest_buffer_stack.pop_back();
+  }
+
+  if (needs_attenuation) {
+    retval =
+        DoAttenuation(src_layer_spec, dest_buffer_stack.back(), needs_vflip);
+    needs_vflip = false;
+    if (retval) {
+      ALOGE("Got error code %d from DoBlending function", retval);
+    }
+    src_layer_spec = dest_buffer_stack.back();
+    dest_buffer_stack.pop_back();
+  }
+
+  if (needs_copy) {
+    retval = DoCopy(src_layer_spec, dest_buffer_stack.back(), needs_vflip);
+    needs_vflip = false;
+    if (retval) {
+      ALOGE("Got error code %d from DoBlending function", retval);
+    }
+    src_layer_spec = dest_buffer_stack.back();
+    dest_buffer_stack.pop_back();
+  }
+
+  // Blending (if needed) should always be the last operation, so that it reads
+  // and writes in the destination layer and not some temporary buffer.
+  if (needs_blending) {
+    retval = DoBlending(src_layer_spec, dest_buffer_stack.back(), needs_vflip);
+    needs_vflip = false;
+    if (retval) {
+      ALOGE("Got error code %d from DoBlending function", retval);
+    }
+    // Don't need to assign destination to source in the last one
+    dest_buffer_stack.pop_back();
+  }
+
+  gralloc_module_->unlock(gralloc_module_, src_priv_handle);
+}
+
+/* static */ const int VSoCComposer::kNumTmpBufferPieces = 2;
+
+VSoCComposer::VSoCComposer(int64_t vsync_base_timestamp)
+    : BaseComposer(vsync_base_timestamp),
+      tmp_buffer_(kNumTmpBufferPieces *
+                  frame_buffer_.buffer_size()) {}
+
+VSoCComposer::~VSoCComposer() {}
+
+int VSoCComposer::PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers) {
+  int composited_layers_count = 0;
+
+  // Loop over layers in inverse order of z-index
+  for (size_t layer_index = num_layers; layer_index > 0;) {
+    // Decrement here to be able to compare unsigned integer with 0 in the
+    // loop condition
+    --layer_index;
+    if (IS_TARGET_FRAMEBUFFER(layers[layer_index].compositionType)) {
+      continue;
+    }
+    if (layers[layer_index].flags & HWC_SKIP_LAYER) {
+      continue;
+    }
+    if (layers[layer_index].compositionType == HWC_BACKGROUND) {
+      layers[layer_index].compositionType = HWC_FRAMEBUFFER;
+      continue;
+    }
+    layers[layer_index].compositionType = HWC_OVERLAY;
+    // Hwcomposer cannot draw below software-composed layers, so we need
+    // to mark those HWC_FRAMEBUFFER as well.
+    for (size_t top_idx = layer_index + 1; top_idx < num_layers; ++top_idx) {
+      // layers marked as skip are in a state that makes them unreliable to
+      // read, so it's best to assume they cover the whole screen
+      if (layers[top_idx].flags & HWC_SKIP_LAYER ||
+          (layers[top_idx].compositionType == HWC_FRAMEBUFFER &&
+           LayersOverlap(layers[layer_index], layers[top_idx]))) {
+        layers[layer_index].compositionType = HWC_FRAMEBUFFER;
+        break;
+      }
+    }
+    if (layers[layer_index].compositionType == HWC_OVERLAY &&
+        !CanCompositeLayer(layers[layer_index])) {
+      layers[layer_index].compositionType = HWC_FRAMEBUFFER;
+    }
+    if (layers[layer_index].compositionType == HWC_OVERLAY) {
+      ++composited_layers_count;
+    }
+  }
+  return composited_layers_count;
+}
+
+int VSoCComposer::SetLayers(size_t num_layers, vsoc_hwc_layer* layers) {
+  int targetFbs = 0;
+  int buffer_idx = frame_buffer_.NextScreenBuffer();
+
+  // The framebuffer target layer should be composed if at least one layers was
+  // marked HWC_FRAMEBUFFER or if it's the only layer in the composition
+  // (unlikely)
+  bool fb_target = true;
+  for (size_t idx = 0; idx < num_layers; idx++) {
+    if (layers[idx].compositionType == HWC_FRAMEBUFFER) {
+      // At least one was found
+      fb_target = true;
+      break;
+    }
+    if (layers[idx].compositionType == HWC_OVERLAY) {
+      // Not the only layer in the composition
+      fb_target = false;
+    }
+  }
+
+  // When the framebuffer target needs to be composed, it has to go first.
+  if (fb_target) {
+    for (size_t idx = 0; idx < num_layers; idx++) {
+      if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
+        CompositeLayer(&layers[idx], buffer_idx);
+        break;
+      }
+    }
+  }
+
+  for (size_t idx = 0; idx < num_layers; idx++) {
+    if (IS_TARGET_FRAMEBUFFER(layers[idx].compositionType)) {
+      ++targetFbs;
+    }
+    if (layers[idx].compositionType == HWC_OVERLAY &&
+        !(layers[idx].flags & HWC_SKIP_LAYER)) {
+      CompositeLayer(&layers[idx], buffer_idx);
+    }
+  }
+  if (targetFbs != 1) {
+    ALOGW("Saw %zu layers, posted=%d", num_layers, targetFbs);
+  }
+  frame_buffer_.Broadcast(buffer_idx);
+  return 0;
+}
+
+uint8_t* VSoCComposer::RotateTmpBuffer(unsigned int order) {
+  return &tmp_buffer_[(order % kNumTmpBufferPieces) * tmp_buffer_.size() /
+                      kNumTmpBufferPieces];
+}
+
+uint8_t* VSoCComposer::GetSpecialTmpBuffer(size_t needed_size) {
+  special_tmp_buffer_.resize(needed_size);
+  return &special_tmp_buffer_[0];
+}
+
+}  // namespace cvd
diff --git a/guest/hals/hwcomposer/cutf_cvm/vsoc_composer.h b/guest/hals/hwcomposer/cutf_cvm/vsoc_composer.h
new file mode 100644
index 0000000..7007931
--- /dev/null
+++ b/guest/hals/hwcomposer/cutf_cvm/vsoc_composer.h
@@ -0,0 +1,48 @@
+#pragma once
+/*
+ * Copyright (C) 2016 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 is 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 <vector>
+
+#include <hardware/gralloc.h>
+
+#include "guest/hals/gralloc/legacy/gralloc_vsoc_priv.h"
+
+#include "base_composer.h"
+#include "hwcomposer.h"
+
+namespace cvd {
+
+class VSoCComposer : public BaseComposer {
+ public:
+  VSoCComposer(int64_t vsync_base_timestamp);
+  ~VSoCComposer();
+
+  // override
+  int PrepareLayers(size_t num_layers, vsoc_hwc_layer* layers);
+  // override
+  int SetLayers(size_t num_layers, vsoc_hwc_layer* layers);
+
+ protected:
+  static const int kNumTmpBufferPieces;
+  uint8_t* RotateTmpBuffer(unsigned int order);
+  uint8_t* GetSpecialTmpBuffer(size_t needed_size);
+  void CompositeLayer(vsoc_hwc_layer* src_layer, int32_t fb_offset);
+  std::vector<uint8_t> tmp_buffer_;
+  std::vector<uint8_t> special_tmp_buffer_;
+};
+
+}  // namespace cvd
diff --git a/guest/hals/hwcomposer/vsoc/Android.mk b/guest/hals/hwcomposer/vsoc/Android.mk
index 2d22f2d..b7cb911 100644
--- a/guest/hals/hwcomposer/vsoc/Android.mk
+++ b/guest/hals/hwcomposer/vsoc/Android.mk
@@ -33,7 +33,7 @@
 # New hwcomposer, performs software composition
 include $(CLEAR_VARS)
 include $(LOCAL_PATH)/hwcomposer.mk
-LOCAL_MODULE := hwcomposer.cutf_ivsh
+LOCAL_MODULE := hwcomposer.cutf_ivsh_ashmem
 LOCAL_VENDOR_MODULE := true
 
 # See b/67109557
diff --git a/guest/hals/hwcomposer/vsoc/vsoc_composer.cpp b/guest/hals/hwcomposer/vsoc/vsoc_composer.cpp
index 33b08e1..d77c004 100644
--- a/guest/hals/hwcomposer/vsoc/vsoc_composer.cpp
+++ b/guest/hals/hwcomposer/vsoc/vsoc_composer.cpp
@@ -176,9 +176,9 @@
   uint8_t* src_y = src.buffer;
   int stride_y = stride_in_pixels;
   uint8_t* src_v = src_y + stride_y * src.height;
-  int stride_v = ScreenRegionView::align(stride_y / 2, 16);
+  int stride_v = ScreenRegionView::align(stride_y / 2);
   uint8_t* src_u = src_v + stride_v *  src.height / 2;
-  int stride_u = ScreenRegionView::align(stride_y / 2, 16);
+  int stride_u = ScreenRegionView::align(stride_y / 2);
 
   // Adjust for crop
   src_y += src.crop_y * stride_y + src.crop_x;
@@ -376,12 +376,12 @@
   int y_res = src_layer->displayFrame.bottom - src_layer->displayFrame.top;
   size_t output_frame_size =
       x_res *
-    ScreenRegionView::align(y_res * screen_view->bytes_per_pixel(), 16);
+    ScreenRegionView::align(y_res * screen_view->bytes_per_pixel());
   while (needed_tmp_buffers > 0) {
     BufferSpec tmp(RotateTmpBuffer(needed_tmp_buffers), output_frame_size,
                    x_res, y_res,
                    ScreenRegionView::align(
-                       x_res * screen_view->bytes_per_pixel(), 16));
+                       x_res * screen_view->bytes_per_pixel()));
     dest_buffer_stack.push_back(tmp);
     needed_tmp_buffers--;
   }
@@ -403,7 +403,7 @@
       int src_width = src_layer_spec.crop_width;
       int src_height = src_layer_spec.crop_height;
       int dst_stride = ScreenRegionView::align(
-          src_width * screen_view->bytes_per_pixel(), 16);
+          src_width * screen_view->bytes_per_pixel());
       size_t needed_size = dst_stride * src_height;
       dst_buffer_spec.width = src_width;
       dst_buffer_spec.height = src_height;
diff --git a/guest/hals/power/Android.mk b/guest/hals/power/Android.mk
deleted file mode 100644
index d73bc0f..0000000
--- a/guest/hals/power/Android.mk
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright (C) 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 is 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.
-
-LOCAL_PATH := $(call my-dir)
-
-# HAL module implementation stored in
-# hw/<POWERS_HARDWARE_MODULE_ID>.<ro.hardware>.so
-include $(CLEAR_VARS)
-
-LOCAL_CFLAGS += $(VSOC_VERSION_CFLAGS)
-
-LOCAL_C_INCLUDES := device/google/cuttlefish_common
-
-ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -ge 21; echo $$?))
-LOCAL_MODULE_RELATIVE_PATH := hw
-else
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
-endif
-LOCAL_MULTILIB := first
-
-LOCAL_HEADER_LIBRARIES := libhardware_headers libutils_headers
-LOCAL_SHARED_LIBRARIES := liblog libcutils
-LOCAL_SRC_FILES := power.c
-LOCAL_MODULE := power.cutf
-LOCAL_MODULE_TAGS := optional
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/guest/hals/power/power.c b/guest/hals/power/power.c
deleted file mode 100644
index 5bd3b0a..0000000
--- a/guest/hals/power/power.c
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 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 is 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.
- *
- * Based on the HiKeyPowerHAL
- */
-
-#include <pthread.h>
-#include <semaphore.h>
-#include <cutils/properties.h>
-
-#define LOG_TAG "VSoCPowerHAL"
-#include <utils/Log.h>
-
-#include <hardware/hardware.h>
-#include <hardware/power.h>
-#include "guest/libs/platform_support/api_level_fixes.h"
-
-struct vsoc_power_module {
-    struct power_module base;
-    pthread_mutex_t lock;
-};
-
-
-#if VSOC_PLATFORM_SDK_AFTER(N_MR1)
-
-static void vsoc_power_set_feature(struct power_module __unused *module,
-                                  feature_t __unused hint,
-                                  int __unused state) {
-    return;
-}
-
-#elif VSOC_PLATFORM_SDK_AFTER(L)
-
-static void vsoc_power_set_feature(struct power_module __unused *module,
-                                  power_hint_t __unused hint,
-                                  int __unused state) {
-    return;
-}
-
-#endif
-
-static void vsoc_power_hint(struct power_module __unused *module,
-                           power_hint_t __unused hint,
-                           void __unused *data) {
-    return;
-}
-
-static void vsoc_power_set_interactive(struct power_module __unused *module,
-                                      int __unused on) {
-    return;
-}
-
-static  void vsoc_power_init(struct power_module __unused *module) {
-    return;
-}
-
-
-/*
- * The power module wasn't opened at all in versions prior to 'O'. The module
- * pointer was reinterpretd as a device pointer. 'O' retains this behavior when
- * open is set to NULL. This code is using that mode.
- * For reference,
- * 'O': hardware/interfaces/power/1.0/default/Power.cpp
- * prior: frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
- */
-static struct hw_module_methods_t power_module_methods = {
-    VSOC_STATIC_INITIALIZER(open) NULL
-};
-
-
-struct vsoc_power_module HAL_MODULE_INFO_SYM = {
-  VSOC_STATIC_INITIALIZER(base) {
-    .common = {
-        VSOC_STATIC_INITIALIZER(tag) HARDWARE_MODULE_TAG,
-        VSOC_STATIC_INITIALIZER(module_api_version) POWER_MODULE_API_VERSION_0_2,
-        VSOC_STATIC_INITIALIZER(hal_api_version) HARDWARE_HAL_API_VERSION,
-        VSOC_STATIC_INITIALIZER(id) POWER_HARDWARE_MODULE_ID,
-        VSOC_STATIC_INITIALIZER(name) "VSoC Power HAL",
-        VSOC_STATIC_INITIALIZER(author) "The Android Open Source Project",
-        VSOC_STATIC_INITIALIZER(methods) &power_module_methods,
-    },
-    VSOC_STATIC_INITIALIZER(init) vsoc_power_init,
-    VSOC_STATIC_INITIALIZER(setInteractive) vsoc_power_set_interactive,
-    VSOC_STATIC_INITIALIZER(powerHint) vsoc_power_hint,
-    // Before L_MR1 we don't have setFeature
-#if VSOC_PLATFORM_SDK_AFTER(L)
-    VSOC_STATIC_INITIALIZER(setFeature) vsoc_power_set_feature,
-#endif
-  },
-
-  VSOC_STATIC_INITIALIZER(lock) PTHREAD_MUTEX_INITIALIZER,
-};
-
diff --git a/guest/hals/ril/Android.mk b/guest/hals/ril/Android.mk
index 85503b0..77db038 100644
--- a/guest/hals/ril/Android.mk
+++ b/guest/hals/ril/Android.mk
@@ -23,11 +23,12 @@
   liblog \
   libcutils \
   libutils \
-  libril \
+  ${CUTTLEFISH_LIBRIL_NAME} \
   libcuttlefish_fs \
   cuttlefish_net \
   cuttlefish_auto_resources \
   libbase \
+  libcuttlefish_device_config \
 
 LOCAL_C_INCLUDES := \
     device/google/cuttlefish_common \
@@ -48,3 +49,5 @@
 endif
 
 include $(BUILD_SHARED_LIBRARY)
+
+include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/guest/hals/ril/cuttlefish_ril.cpp b/guest/hals/ril/cuttlefish_ril.cpp
index 929933b..209f3e8 100644
--- a/guest/hals/ril/cuttlefish_ril.cpp
+++ b/guest/hals/ril/cuttlefish_ril.cpp
@@ -27,13 +27,13 @@
 #include <string>
 #include <vector>
 
-#include "common/libs/constants/ril.h"
+#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"
 #include "guest/libs/platform_support/api_level_fixes.h"
 
-#define CUTTLEFISH_RIL_VERSION_STRING "Android Cuttlefish RIL 1.0"
+#define CUTTLEFISH_RIL_VERSION_STRING "Android Cuttlefish RIL 1.4"
 
 /* Modem Technology bits */
 #define MDM_GSM 0x01
@@ -62,48 +62,7 @@
   RUIM_NETWORK_PERSONALIZATION = 11
 } SIM_Status;
 
-class RilConfig {
- public:
-  static void InitRilConfig();
-
-  static char* address_and_prefixlength() {
-    return RilConfig::global_ril_config_.address_and_prefixlength_;
-  }
-
-  static char* dns() {
-    return RilConfig::global_ril_config_.dns_;
-  }
-
-  static char* gateway() {
-    return RilConfig::global_ril_config_.gateway_;
-  }
-
-  static char* ipaddr() {
-    return RilConfig::global_ril_config_.ipaddr_;
-  }
-
-  static int prefixlen() {
-    return RilConfig::global_ril_config_.prefixlen_;
-  }
-
-  static char* broadcast() {
-    return RilConfig::global_ril_config_.broadcast_;
-  }
-
- private:
-  RilConfig() = default;
-  RilConfig(const RilConfig&) = default;
-
-  char ipaddr_[16]; // xxx.xxx.xxx.xxx\0 = 16 bytes
-  char gateway_[16];
-  char dns_[16];
-  char broadcast_[16];
-  char address_and_prefixlength_[19]; // <ipaddr>/dd
-  int prefixlen_;
-
-  static RilConfig global_ril_config_;
-};
-RilConfig RilConfig::global_ril_config_;
+static std::unique_ptr<cvd::DeviceConfig> global_ril_config = nullptr;
 
 static const struct RIL_Env* gce_ril_env;
 
@@ -114,6 +73,7 @@
 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 };
@@ -173,43 +133,6 @@
   return false;
 }
 
-static bool ReadStringProperty(char* dst, const char* key, size_t max_size) {
-  char buffer[PROPERTY_VALUE_MAX];
-  auto res = property_get(key, buffer, NULL);
-  if (res < 0) {
-    ALOGE("Failed to read property %s", key);
-    return false;
-  }
-  if (res > static_cast<int>(max_size - 1)) {
-    ALOGE("Invalid value in property %s: value too long: %s", key, buffer);
-    return false;
-  }
-  snprintf(dst, res + 1, "%s", buffer);
-  return true;
-}
-
-void RilConfig::InitRilConfig() {
-  RilConfig tmp_config;
-  ReadStringProperty(&tmp_config.ipaddr_[0], CUTTLEFISH_RIL_ADDR_PROPERTY,
-                     sizeof(tmp_config.ipaddr_));
-  ReadStringProperty(&tmp_config.gateway_[0],
-                     CUTTLEFISH_RIL_GATEWAY_PROPERTY,
-                     sizeof(tmp_config.gateway_));
-  ReadStringProperty(&tmp_config.dns_[0], CUTTLEFISH_RIL_DNS_PROPERTY,
-                     sizeof(tmp_config.dns_));
-  ReadStringProperty(&tmp_config.broadcast_[0],
-                     CUTTLEFISH_RIL_BROADCAST_PROPERTY,
-                     sizeof(tmp_config.broadcast_));
-  tmp_config.prefixlen_ =
-      property_get_int32(CUTTLEFISH_RIL_PREFIXLEN_PROPERTY, 30);
-
-  snprintf(&tmp_config.address_and_prefixlength_[0],
-           sizeof(tmp_config.address_and_prefixlength_), "%s/%d",
-           tmp_config.ipaddr_, tmp_config.prefixlen_);
-
-  RilConfig::global_ril_config_ = tmp_config;
-}
-
 // TearDownNetworkInterface disables network interface.
 // This call returns true, if operation was successful.
 bool TearDownNetworkInterface() {
@@ -269,9 +192,9 @@
 
     responses[index].ifname = (char*)"rmnet0";
     responses[index].addresses =
-      const_cast<char*>(RilConfig::address_and_prefixlength());
-    responses[index].dnses = RilConfig::dns();
-    responses[index].gateways = RilConfig::gateway();
+      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());
 #if VSOC_PLATFORM_SDK_AFTER(N_MR1)
     responses[index].pcscf = (char*)"";
     responses[index].mtu = 1440;
@@ -338,6 +261,7 @@
     ALOGE("%s returning: called with small datalen %zu", __FUNCTION__, datalen);
     return;
   }
+
   DataCall call;
   int tech = atoi(details[0]);
   switch (tech) {
@@ -382,7 +306,7 @@
 
   if (call.connection_type_ != DataCall::kConnTypeIPv4) {
     ALOGE("Non-IPv4 connections are not supported by Cuttlefish RIL.");
-    gce_ril_env->OnRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
+    gce_ril_env->OnRequestComplete(t, RIL_E_INVALID_ARGUMENTS, NULL, 0);
     return;
   }
 
@@ -393,8 +317,9 @@
   }
 
   if (gDataCalls.empty()) {
-    SetUpNetworkInterface(RilConfig::ipaddr(), RilConfig::prefixlen(),
-                          RilConfig::broadcast());
+    SetUpNetworkInterface(global_ril_config->ril_ipaddr(),
+                          global_ril_config->ril_prefixlen(),
+                          global_ril_config->ril_broadcast());
   }
 
   gDataCalls[gNextDataCallId] = call;
@@ -1453,6 +1378,22 @@
   gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
 }
 
+#if VSOC_PLATFORM_SDK_AFTER(P)
+static void request_set_carrier_restrictions4(void* /*data*/,
+                                              size_t /*datalen*/,
+                                              RIL_Token t) {
+  ALOGV("Set carrier restrictions is not supported");
+  // Carrier restrictions are not supported on cuttlefish, as they are specific for locked devices
+  gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
+}
+
+static void request_get_carrier_restrictions4(RIL_Token t) {
+  ALOGV("Get carrier restrictions is not supported");
+  // Carrier restrictions are not supported on cuttlefish, as they are specific for locked devices
+  gce_ril_env->OnRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
+}
+#endif
+
 static RIL_RadioState gce_ril_current_state() {
   ALOGV("Reporting radio state %d", gRadioPowerState);
   return gRadioPowerState;
@@ -2274,6 +2215,78 @@
   gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply));
 }
 
+// New functions after P.
+#if VSOC_PLATFORM_SDK_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_start_network_scan4(RIL_Token t) {
+  ALOGV("Scanning network 1.4");
+  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;
+}
+
+#endif
+
 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
@@ -2476,6 +2489,9 @@
     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;
 #endif
 #if VSOC_PLATFORM_SDK_AFTER(K)
     case RIL_REQUEST_GET_HARDWARE_CONFIG:
@@ -2505,6 +2521,43 @@
       break;
 
 #endif
+
+// New requests after P.
+#if VSOC_PLATFORM_SDK_AFTER(P)
+    case RIL_REQUEST_START_NETWORK_SCAN:
+      request_start_network_scan(t);
+      break;
+    case RIL_REQUEST_START_NETWORK_SCAN4:
+      request_start_network_scan4(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_SET_CARRIER_RESTRICTIONS_1_4:
+      request_set_carrier_restrictions4(data, datalen, t);
+      break;
+    case RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4:
+      request_get_carrier_restrictions4(t);
+      break;
+#endif
     case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
       gce_ril_env->OnRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
       break;
@@ -2549,7 +2602,11 @@
   time(&gce_ril_start_time);
   gce_ril_env = env;
 
-  RilConfig::InitRilConfig();
+  global_ril_config = cvd::DeviceConfig::Get();
+  if (!global_ril_config) {
+    ALOGE("Failed to open device configuration!!!");
+    return nullptr;
+  }
 
   TearDownNetworkInterface();
 
diff --git a/guest/hals/ril/cuttlefish_ril.h b/guest/hals/ril/cuttlefish_ril.h
index 442c377..10340d8 100644
--- a/guest/hals/ril/cuttlefish_ril.h
+++ b/guest/hals/ril/cuttlefish_ril.h
@@ -24,5 +24,13 @@
 #include <stdint.h>
 #include <stdlib.h>
 #include <sys/time.h>
+
+// Start to use and maintain the local ril.h file from Q.
+#include "guest/libs/platform_support/api_level_fixes.h"
+#if VSOC_PLATFORM_SDK_BEFORE(Q)
 #include <telephony/ril.h>
-#include <telephony/ril_cdma_sms.h>
+#else
+#include <guest/hals/ril/libril/ril.h>
+#endif
+
+#include <telephony/ril_cdma_sms.h>
\ No newline at end of file
diff --git a/guest/hals/ril/libril/Android.mk b/guest/hals/ril/libril/Android.mk
new file mode 100644
index 0000000..ad02bf6
--- /dev/null
+++ b/guest/hals/ril/libril/Android.mk
@@ -0,0 +1,66 @@
+# Copyright (C) 2019 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 is 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.
+
+# We're forced to use Android.mk here because:
+#   This depends on headers in hardware/ril/libril
+#   hardware/ril/libril is still on Android.mk
+
+ifeq (libril-cuttlefish-fork,$(CUTTLEFISH_LIBRIL_NAME))
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_VENDOR_MODULE := true
+LOCAL_MODULE := libril-cuttlefish-fork
+LOCAL_SRC_FILES:= \
+    ril.cpp \
+    ril_service.cpp \
+    ril_event.cpp \
+    RilSapSocket.cpp \
+    sap_service.cpp \
+
+
+LOCAL_SHARED_LIBRARIES := \
+    liblog \
+    libutils \
+    libcutils \
+    libhardware_legacy \
+    libhidlbase \
+    libhidltransport \
+    libhwbinder \
+    librilutils \
+    android.hardware.radio@1.0 \
+    android.hardware.radio@1.1 \
+    android.hardware.radio.deprecated@1.0 \
+    android.hardware.radio@1.2 \
+    android.hardware.radio@1.3 \
+    android.hardware.radio@1.4 \
+
+LOCAL_STATIC_LIBRARIES := \
+    libprotobuf-c-nano-enable_malloc \
+
+LOCAL_C_INCLUDES += \
+    device/google/cuttlefish_common \
+    hardware/include \
+    external/nanopb-c \
+    hardware/ril/include \
+    hardware/ril/libril
+
+LOCAL_CFLAGS += \
+    -Wextra \
+    -Wno-unused-parameter
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := hardware/ril/include
+
+include $(BUILD_SHARED_LIBRARY)
+endif
diff --git a/guest/hals/ril/libril/RilSapSocket.cpp b/guest/hals/ril/libril/RilSapSocket.cpp
new file mode 100644
index 0000000..3465807
--- /dev/null
+++ b/guest/hals/ril/libril/RilSapSocket.cpp
@@ -0,0 +1,295 @@
+/*
+* Copyright (C) 2014 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 is 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.
+*/
+
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
+#define RIL_SHLIB
+#include "RilSapSocket.h"
+#include "pb_decode.h"
+#include "pb_encode.h"
+#undef LOG_TAG
+#define LOG_TAG "RIL_UIM_SOCKET"
+#include <utils/Log.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sap_service.h>
+#include <guest/hals/ril/libril/ril.h>
+
+static RilSapSocket::RilSapSocketList *head = NULL;
+
+extern "C" void
+RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
+        const struct timeval *relativeTime);
+
+struct RIL_Env RilSapSocket::uimRilEnv = {
+        .OnRequestComplete = RilSapSocket::sOnRequestComplete,
+        .OnUnsolicitedResponse = RilSapSocket::sOnUnsolicitedResponse,
+        .RequestTimedCallback = RIL_requestTimedCallback
+};
+
+void RilSapSocket::sOnRequestComplete (RIL_Token t,
+        RIL_Errno e,
+        void *response,
+        size_t responselen) {
+    RilSapSocket *sap_socket;
+    SapSocketRequest *request = (SapSocketRequest*) t;
+
+    RLOGD("Socket id:%d", request->socketId);
+
+    sap_socket = getSocketById(request->socketId);
+
+    if (sap_socket) {
+        sap_socket->onRequestComplete(t,e,response,responselen);
+    } else {
+        RLOGE("Invalid socket id");
+        if (request->curr) {
+            free(request->curr);
+        }
+        free(request);
+    }
+}
+
+#if defined(ANDROID_MULTI_SIM)
+void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
+        const void *data,
+        size_t datalen,
+        RIL_SOCKET_ID socketId) {
+    RilSapSocket *sap_socket = getSocketById(socketId);
+    if (sap_socket) {
+        sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
+    }
+}
+#else
+void RilSapSocket::sOnUnsolicitedResponse(int unsolResponse,
+       const void *data,
+       size_t datalen) {
+    RilSapSocket *sap_socket = getSocketById(RIL_SOCKET_1);
+    if(sap_socket){
+        sap_socket->onUnsolicitedResponse(unsolResponse, (void *)data, datalen);
+    }
+}
+#endif
+
+void RilSapSocket::printList() {
+    RilSapSocketList *current = head;
+    RLOGD("Printing socket list");
+    while(NULL != current) {
+        RLOGD("SocketName:%s",current->socket->name);
+        RLOGD("Socket id:%d",current->socket->id);
+        current = current->next;
+    }
+}
+
+RilSapSocket *RilSapSocket::getSocketById(RIL_SOCKET_ID socketId) {
+    RilSapSocket *sap_socket;
+    RilSapSocketList *current = head;
+
+    RLOGD("Entered getSocketById");
+    printList();
+
+    while(NULL != current) {
+        if(socketId == current->socket->id) {
+            sap_socket = current->socket;
+            return sap_socket;
+        }
+        current = current->next;
+    }
+    return NULL;
+}
+
+void RilSapSocket::initSapSocket(const char *socketName,
+        const RIL_RadioFunctions *uimFuncs) {
+
+    if (strcmp(socketName, RIL1_SERVICE_NAME) == 0) {
+        if(!SocketExists(socketName)) {
+            addSocketToList(socketName, RIL_SOCKET_1, uimFuncs);
+        }
+    }
+
+#if (SIM_COUNT >= 2)
+    if (strcmp(socketName, RIL2_SERVICE_NAME) == 0) {
+        if(!SocketExists(socketName)) {
+            addSocketToList(socketName, RIL_SOCKET_2, uimFuncs);
+        }
+    }
+#endif
+
+#if (SIM_COUNT >= 3)
+    if (strcmp(socketName, RIL3_SERVICE_NAME) == 0) {
+        if(!SocketExists(socketName)) {
+            addSocketToList(socketName, RIL_SOCKET_3, uimFuncs);
+        }
+    }
+#endif
+
+#if (SIM_COUNT >= 4)
+    if (strcmp(socketName, RIL4_SERVICE_NAME) == 0) {
+        if(!SocketExists(socketName)) {
+            addSocketToList(socketName, RIL_SOCKET_4, uimFuncs);
+        }
+    }
+#endif
+}
+
+void RilSapSocket::addSocketToList(const char *socketName, RIL_SOCKET_ID socketid,
+        const RIL_RadioFunctions *uimFuncs) {
+    RilSapSocket* socket = NULL;
+    RilSapSocketList *current;
+
+    if(!SocketExists(socketName)) {
+        socket = new RilSapSocket(socketName, socketid, uimFuncs);
+        RilSapSocketList* listItem = (RilSapSocketList*)malloc(sizeof(RilSapSocketList));
+        if (!listItem) {
+            RLOGE("addSocketToList: OOM");
+            delete socket;
+            return;
+        }
+        listItem->socket = socket;
+        listItem->next = NULL;
+
+        RLOGD("Adding socket with id: %d", socket->id);
+
+        if(NULL == head) {
+            head = listItem;
+            head->next = NULL;
+        }
+        else {
+            current = head;
+            while(NULL != current->next) {
+                current = current->next;
+            }
+            current->next = listItem;
+        }
+    }
+}
+
+bool RilSapSocket::SocketExists(const char *socketName) {
+    RilSapSocketList* current = head;
+
+    while(NULL != current) {
+        if(strcmp(current->socket->name, socketName) == 0) {
+            return true;
+        }
+        current = current->next;
+    }
+    return false;
+}
+
+RilSapSocket::RilSapSocket(const char *socketName,
+        RIL_SOCKET_ID socketId,
+        const RIL_RadioFunctions *inputUimFuncs):
+        RilSocket(socketName, socketId) {
+    if (inputUimFuncs) {
+        uimFuncs = inputUimFuncs;
+    }
+}
+
+void RilSapSocket::dispatchRequest(MsgHeader *req) {
+    // SapSocketRequest will be deallocated in onRequestComplete()
+    SapSocketRequest* currRequest=(SapSocketRequest*)malloc(sizeof(SapSocketRequest));
+    if (!currRequest) {
+        RLOGE("dispatchRequest: OOM");
+        // Free MsgHeader allocated in pushRecord()
+        free(req);
+        return;
+    }
+    currRequest->token = req->token;
+    currRequest->curr = req;
+    currRequest->p_next = NULL;
+    currRequest->socketId = id;
+
+    pendingResponseQueue.enqueue(currRequest);
+
+    if (uimFuncs) {
+        RLOGI("RilSapSocket::dispatchRequest [%d] > SAP REQUEST type: %d. id: %d. error: %d, \
+                token 0x%p",
+                req->token,
+                req->type,
+                req->id,
+                req->error,
+                currRequest );
+
+#if defined(ANDROID_MULTI_SIM)
+        uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest, id);
+#else
+        uimFuncs->onRequest(req->id, req->payload->bytes, req->payload->size, currRequest);
+#endif
+    }
+}
+
+void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response,
+        size_t response_len) {
+    SapSocketRequest* request= (SapSocketRequest*)t;
+
+    if (!request || !request->curr) {
+        RLOGE("RilSapSocket::onRequestComplete: request/request->curr is NULL");
+        return;
+    }
+
+    MsgHeader *hdr = request->curr;
+
+    MsgHeader rsp;
+    rsp.token = request->curr->token;
+    rsp.type = MsgType_RESPONSE;
+    rsp.id = request->curr->id;
+    rsp.error = (Error)e;
+    rsp.payload = (pb_bytes_array_t *)calloc(1, sizeof(pb_bytes_array_t) + response_len);
+    if (!rsp.payload) {
+        RLOGE("onRequestComplete: OOM");
+    } else {
+        if (response && response_len > 0) {
+            memcpy(rsp.payload->bytes, response, response_len);
+            rsp.payload->size = response_len;
+        } else {
+            rsp.payload->size = 0;
+        }
+
+        RLOGE("RilSapSocket::onRequestComplete: Token:%d, MessageId:%d ril token 0x%p",
+                hdr->token, hdr->id, t);
+
+        sap::processResponse(&rsp, this);
+        free(rsp.payload);
+    }
+
+    // Deallocate SapSocketRequest
+    if(!pendingResponseQueue.checkAndDequeue(hdr->id, hdr->token)) {
+        RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id);
+        RLOGE ("RilSapSocket::onRequestComplete: invalid Token or Message Id");
+    }
+
+    // Deallocate MsgHeader
+    free(hdr);
+}
+
+void RilSapSocket::onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen) {
+    if (data && datalen > 0) {
+        pb_bytes_array_t *payload = (pb_bytes_array_t *)calloc(1,
+                sizeof(pb_bytes_array_t) + datalen);
+        if (!payload) {
+            RLOGE("onUnsolicitedResponse: OOM");
+            return;
+        }
+        memcpy(payload->bytes, data, datalen);
+        payload->size = datalen;
+        MsgHeader rsp;
+        rsp.payload = payload;
+        rsp.type = MsgType_UNSOL_RESPONSE;
+        rsp.id = (MsgId)unsolResponse;
+        rsp.error = Error_RIL_E_SUCCESS;
+        sap::processUnsolResponse(&rsp, this);
+        free(payload);
+    }
+}
diff --git a/guest/hals/ril/libril/ril.cpp b/guest/hals/ril/libril/ril.cpp
new file mode 100644
index 0000000..d440232
--- /dev/null
+++ b/guest/hals/ril/libril/ril.cpp
@@ -0,0 +1,1251 @@
+/* //guest/hals/ril/ril.cpp
+**
+** Copyright 2006, 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 is 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.
+*/
+
+#define LOG_TAG "RILC"
+
+#include <hardware_legacy/power.h>
+#include <guest/hals/ril/libril/ril.h>
+#include <telephony/ril_cdma_sms.h>
+#include <cutils/sockets.h>
+#include <cutils/jstring.h>
+#include <telephony/record_stream.h>
+#include <utils/Log.h>
+#include <utils/SystemClock.h>
+#include <pthread.h>
+#include <cutils/jstring.h>
+#include <sys/types.h>
+#include <sys/limits.h>
+#include <sys/system_properties.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+#include <assert.h>
+#include <ctype.h>
+#include <sys/un.h>
+#include <assert.h>
+#include <netinet/in.h>
+#include <cutils/properties.h>
+#include <RilSapSocket.h>
+#include <guest/hals/ril/libril/ril_service.h>
+#include <sap_service.h>
+
+extern "C" void
+RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen);
+
+extern "C" void
+RIL_onRequestAck(RIL_Token t);
+namespace android {
+
+#define PHONE_PROCESS "radio"
+#define BLUETOOTH_PROCESS "bluetooth"
+
+#define ANDROID_WAKE_LOCK_NAME "radio-interface"
+
+#define ANDROID_WAKE_LOCK_SECS 0
+#define ANDROID_WAKE_LOCK_USECS 200000
+
+#define PROPERTY_RIL_IMPL "gsm.version.ril-impl"
+
+// match with constant in RIL.java
+#define MAX_COMMAND_BYTES (8 * 1024)
+
+// Basically: memset buffers that the client library
+// shouldn't be using anymore in an attempt to find
+// memory usage issues sooner.
+#define MEMSET_FREED 1
+
+#define NUM_ELEMS(a)     (sizeof (a) / sizeof (a)[0])
+
+/* Negative values for private RIL errno's */
+#define RIL_ERRNO_INVALID_RESPONSE (-1)
+#define RIL_ERRNO_NO_MEMORY (-12)
+
+// request, response, and unsolicited msg print macro
+#define PRINTBUF_SIZE 8096
+
+enum WakeType {DONT_WAKE, WAKE_PARTIAL};
+
+typedef struct {
+    int requestNumber;
+    int (*responseFunction) (int slotId, int responseType, int token,
+            RIL_Errno e, void *response, size_t responselen);
+    WakeType wakeType;
+} UnsolResponseInfo;
+
+typedef struct UserCallbackInfo {
+    RIL_TimedCallback p_callback;
+    void *userParam;
+    struct ril_event event;
+    struct UserCallbackInfo *p_next;
+} UserCallbackInfo;
+
+extern "C" const char * failCauseToString(RIL_Errno);
+extern "C" const char * callStateToString(RIL_CallState);
+extern "C" const char * radioStateToString(RIL_RadioState);
+extern "C" const char * rilSocketIdToString(RIL_SOCKET_ID socket_id);
+
+extern "C"
+char ril_service_name_base[MAX_SERVICE_NAME_LENGTH] = RIL_SERVICE_NAME_BASE;
+extern "C"
+char ril_service_name[MAX_SERVICE_NAME_LENGTH] = RIL1_SERVICE_NAME;
+/*******************************************************************/
+
+RIL_RadioFunctions s_callbacks = {0, NULL, NULL, NULL, NULL, NULL};
+static int s_registerCalled = 0;
+
+static pthread_t s_tid_dispatch;
+static int s_started = 0;
+
+static int s_fdWakeupRead;
+static int s_fdWakeupWrite;
+
+int s_wakelock_count = 0;
+
+static struct ril_event s_wakeupfd_event;
+
+static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t s_wakeLockCountMutex = PTHREAD_MUTEX_INITIALIZER;
+static RequestInfo *s_pendingRequests = NULL;
+
+#if (SIM_COUNT >= 2)
+static pthread_mutex_t s_pendingRequestsMutex_socket2  = PTHREAD_MUTEX_INITIALIZER;
+static RequestInfo *s_pendingRequests_socket2          = NULL;
+#endif
+
+#if (SIM_COUNT >= 3)
+static pthread_mutex_t s_pendingRequestsMutex_socket3  = PTHREAD_MUTEX_INITIALIZER;
+static RequestInfo *s_pendingRequests_socket3          = NULL;
+#endif
+
+#if (SIM_COUNT >= 4)
+static pthread_mutex_t s_pendingRequestsMutex_socket4  = PTHREAD_MUTEX_INITIALIZER;
+static RequestInfo *s_pendingRequests_socket4          = NULL;
+#endif
+
+static const struct timeval TIMEVAL_WAKE_TIMEOUT = {ANDROID_WAKE_LOCK_SECS,ANDROID_WAKE_LOCK_USECS};
+
+
+static pthread_mutex_t s_startupMutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t s_startupCond = PTHREAD_COND_INITIALIZER;
+
+static UserCallbackInfo *s_last_wake_timeout_info = NULL;
+
+static void *s_lastNITZTimeData = NULL;
+static size_t s_lastNITZTimeDataSize;
+
+#if RILC_LOG
+    static char printBuf[PRINTBUF_SIZE];
+#endif
+
+/*******************************************************************/
+static void grabPartialWakeLock();
+void releaseWakeLock();
+static void wakeTimeoutCallback(void *);
+
+#ifdef RIL_SHLIB
+#if defined(ANDROID_MULTI_SIM)
+extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen, RIL_SOCKET_ID socket_id);
+#else
+extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen);
+#endif
+#endif
+
+#if defined(ANDROID_MULTI_SIM)
+#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c), (d))
+#else
+#define RIL_UNSOL_RESPONSE(a, b, c, d) RIL_onUnsolicitedResponse((a), (b), (c))
+#endif
+
+static UserCallbackInfo * internalRequestTimedCallback
+    (RIL_TimedCallback callback, void *param,
+        const struct timeval *relativeTime);
+
+/** Index == requestNumber */
+static CommandInfo s_commands[] = {
+#include "ril_commands.h"
+};
+
+static UnsolResponseInfo s_unsolResponses[] = {
+#include "ril_unsol_commands.h"
+};
+
+char * RIL_getServiceName() {
+    return ril_service_name;
+}
+
+RequestInfo *
+addRequestToList(int serial, int slotId, int request) {
+    RequestInfo *pRI;
+    int ret;
+    RIL_SOCKET_ID socket_id = (RIL_SOCKET_ID) slotId;
+    /* Hook for current context */
+    /* pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
+    pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
+    /* pendingRequestsHook refer to &s_pendingRequests */
+    RequestInfo**    pendingRequestsHook = &s_pendingRequests;
+
+#if (SIM_COUNT >= 2)
+    if (socket_id == RIL_SOCKET_2) {
+        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
+        pendingRequestsHook = &s_pendingRequests_socket2;
+    }
+#if (SIM_COUNT >= 3)
+    else if (socket_id == RIL_SOCKET_3) {
+        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
+        pendingRequestsHook = &s_pendingRequests_socket3;
+    }
+#endif
+#if (SIM_COUNT >= 4)
+    else if (socket_id == RIL_SOCKET_4) {
+        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
+        pendingRequestsHook = &s_pendingRequests_socket4;
+    }
+#endif
+#endif
+
+    pRI = (RequestInfo *)calloc(1, sizeof(RequestInfo));
+    if (pRI == NULL) {
+        RLOGE("Memory allocation failed for request %s", requestToString(request));
+        return NULL;
+    }
+
+    pRI->token = serial;
+    pRI->pCI = &(s_commands[request]);
+    pRI->socket_id = socket_id;
+
+    ret = pthread_mutex_lock(pendingRequestsMutexHook);
+    assert (ret == 0);
+
+    pRI->p_next = *pendingRequestsHook;
+    *pendingRequestsHook = pRI;
+
+    ret = pthread_mutex_unlock(pendingRequestsMutexHook);
+    assert (ret == 0);
+
+    return pRI;
+}
+
+static void triggerEvLoop() {
+    int ret;
+    if (!pthread_equal(pthread_self(), s_tid_dispatch)) {
+        /* trigger event loop to wakeup. No reason to do this,
+         * if we're in the event loop thread */
+         do {
+            ret = write (s_fdWakeupWrite, " ", 1);
+         } while (ret < 0 && errno == EINTR);
+    }
+}
+
+static void rilEventAddWakeup(struct ril_event *ev) {
+    ril_event_add(ev);
+    triggerEvLoop();
+}
+
+/**
+ * A write on the wakeup fd is done just to pop us out of select()
+ * We empty the buffer here and then ril_event will reset the timers on the
+ * way back down
+ */
+static void processWakeupCallback(int fd, short flags, void *param) {
+    char buff[16];
+    int ret;
+
+    RLOGV("processWakeupCallback");
+
+    /* empty our wakeup socket out */
+    do {
+        ret = read(s_fdWakeupRead, &buff, sizeof(buff));
+    } while (ret > 0 || (ret < 0 && errno == EINTR));
+}
+
+static void resendLastNITZTimeData(RIL_SOCKET_ID socket_id) {
+    if (s_lastNITZTimeData != NULL) {
+        int responseType = (s_callbacks.version >= 13)
+                           ? RESPONSE_UNSOLICITED_ACK_EXP
+                           : RESPONSE_UNSOLICITED;
+        // acquire read lock for the service before calling nitzTimeReceivedInd() since it reads
+        // nitzTimeReceived in ril_service
+        pthread_rwlock_t *radioServiceRwlockPtr = radio_1_4::getRadioServiceRwlock(
+                (int) socket_id);
+        int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr);
+        assert(rwlockRet == 0);
+
+        int ret = radio_1_4::nitzTimeReceivedInd(
+            (int)socket_id, responseType, 0,
+            RIL_E_SUCCESS, s_lastNITZTimeData, s_lastNITZTimeDataSize);
+        if (ret == 0) {
+            free(s_lastNITZTimeData);
+            s_lastNITZTimeData = NULL;
+        }
+
+        rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr);
+        assert(rwlockRet == 0);
+    }
+}
+
+void onNewCommandConnect(RIL_SOCKET_ID socket_id) {
+    // Inform we are connected and the ril version
+    int rilVer = s_callbacks.version;
+    RIL_UNSOL_RESPONSE(RIL_UNSOL_RIL_CONNECTED,
+                                    &rilVer, sizeof(rilVer), socket_id);
+
+    // implicit radio state changed
+    RIL_UNSOL_RESPONSE(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
+                                    NULL, 0, socket_id);
+
+    // Send last NITZ time data, in case it was missed
+    if (s_lastNITZTimeData != NULL) {
+        resendLastNITZTimeData(socket_id);
+    }
+
+    // Get version string
+    if (s_callbacks.getVersion != NULL) {
+        const char *version;
+        version = s_callbacks.getVersion();
+        RLOGI("RIL Daemon version: %s\n", version);
+
+        property_set(PROPERTY_RIL_IMPL, version);
+    } else {
+        RLOGI("RIL Daemon version: unavailable\n");
+        property_set(PROPERTY_RIL_IMPL, "unavailable");
+    }
+
+}
+
+static void userTimerCallback (int fd, short flags, void *param) {
+    UserCallbackInfo *p_info;
+
+    p_info = (UserCallbackInfo *)param;
+
+    p_info->p_callback(p_info->userParam);
+
+
+    // FIXME generalize this...there should be a cancel mechanism
+    if (s_last_wake_timeout_info != NULL && s_last_wake_timeout_info == p_info) {
+        s_last_wake_timeout_info = NULL;
+    }
+
+    free(p_info);
+}
+
+
+static void *
+eventLoop(void *param) {
+    int ret;
+    int filedes[2];
+
+    ril_event_init();
+
+    pthread_mutex_lock(&s_startupMutex);
+
+    s_started = 1;
+    pthread_cond_broadcast(&s_startupCond);
+
+    pthread_mutex_unlock(&s_startupMutex);
+
+    ret = pipe(filedes);
+
+    if (ret < 0) {
+        RLOGE("Error in pipe() errno:%d", errno);
+        return NULL;
+    }
+
+    s_fdWakeupRead = filedes[0];
+    s_fdWakeupWrite = filedes[1];
+
+    fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
+
+    ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
+                processWakeupCallback, NULL);
+
+    rilEventAddWakeup (&s_wakeupfd_event);
+
+    // Only returns on error
+    ril_event_loop();
+    RLOGE ("error in event_loop_base errno:%d", errno);
+    // kill self to restart on error
+    kill(0, SIGKILL);
+
+    return NULL;
+}
+
+extern "C" void
+RIL_startEventLoop(void) {
+    /* spin up eventLoop thread and wait for it to get started */
+    s_started = 0;
+    pthread_mutex_lock(&s_startupMutex);
+
+    pthread_attr_t attr;
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
+    if (result != 0) {
+        RLOGE("Failed to create dispatch thread: %s", strerror(result));
+        goto done;
+    }
+
+    while (s_started == 0) {
+        pthread_cond_wait(&s_startupCond, &s_startupMutex);
+    }
+
+done:
+    pthread_mutex_unlock(&s_startupMutex);
+}
+
+// Used for testing purpose only.
+extern "C" void RIL_setcallbacks (const RIL_RadioFunctions *callbacks) {
+    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
+}
+
+extern "C" void
+RIL_register (const RIL_RadioFunctions *callbacks) {
+    RLOGI("SIM_COUNT: %d", SIM_COUNT);
+
+    if (callbacks == NULL) {
+        RLOGE("RIL_register: RIL_RadioFunctions * null");
+        return;
+    }
+    if (callbacks->version < RIL_VERSION_MIN) {
+        RLOGE("RIL_register: version %d is to old, min version is %d",
+             callbacks->version, RIL_VERSION_MIN);
+        return;
+    }
+
+    RLOGD("RIL_register: Vsoc RIL version %d", callbacks->version);
+
+    if (s_registerCalled > 0) {
+        RLOGE("RIL_register has been called more than once. "
+                "Subsequent call ignored");
+        return;
+    }
+
+    memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
+
+    s_registerCalled = 1;
+
+    RLOGI("s_registerCalled flag set, %d", s_started);
+    // Little self-check
+
+    for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) {
+        assert(i == s_commands[i].requestNumber);
+    }
+
+    for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) {
+        assert(i + RIL_UNSOL_RESPONSE_BASE
+                == s_unsolResponses[i].requestNumber);
+    }
+
+    radio_1_4::registerService(&s_callbacks, s_commands);
+    RLOGI("RILHIDL called registerService");
+
+}
+
+extern "C" void
+RIL_register_socket (const RIL_RadioFunctions *(*Init)(const struct RIL_Env *, int, char **),
+        RIL_SOCKET_TYPE socketType, int argc, char **argv) {
+
+    const RIL_RadioFunctions* UimFuncs = NULL;
+
+    if(Init) {
+        UimFuncs = Init(&RilSapSocket::uimRilEnv, argc, argv);
+
+        switch(socketType) {
+            case RIL_SAP_SOCKET:
+                RilSapSocket::initSapSocket(RIL1_SERVICE_NAME, UimFuncs);
+
+#if (SIM_COUNT >= 2)
+                RilSapSocket::initSapSocket(RIL2_SERVICE_NAME, UimFuncs);
+#endif
+
+#if (SIM_COUNT >= 3)
+                RilSapSocket::initSapSocket(RIL3_SERVICE_NAME, UimFuncs);
+#endif
+
+#if (SIM_COUNT >= 4)
+                RilSapSocket::initSapSocket(RIL4_SERVICE_NAME, UimFuncs);
+#endif
+                break;
+            default:;
+        }
+
+        RLOGI("RIL_register_socket: calling registerService");
+        sap::registerService(UimFuncs);
+    }
+}
+
+// Check and remove RequestInfo if its a response and not just ack sent back
+static int
+checkAndDequeueRequestInfoIfAck(struct RequestInfo *pRI, bool isAck) {
+    int ret = 0;
+    /* Hook for current context
+       pendingRequestsMutextHook refer to &s_pendingRequestsMutex */
+    pthread_mutex_t* pendingRequestsMutexHook = &s_pendingRequestsMutex;
+    /* pendingRequestsHook refer to &s_pendingRequests */
+    RequestInfo ** pendingRequestsHook = &s_pendingRequests;
+
+    if (pRI == NULL) {
+        return 0;
+    }
+
+#if (SIM_COUNT >= 2)
+    if (pRI->socket_id == RIL_SOCKET_2) {
+        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket2;
+        pendingRequestsHook = &s_pendingRequests_socket2;
+    }
+#if (SIM_COUNT >= 3)
+        if (pRI->socket_id == RIL_SOCKET_3) {
+            pendingRequestsMutexHook = &s_pendingRequestsMutex_socket3;
+            pendingRequestsHook = &s_pendingRequests_socket3;
+        }
+#endif
+#if (SIM_COUNT >= 4)
+    if (pRI->socket_id == RIL_SOCKET_4) {
+        pendingRequestsMutexHook = &s_pendingRequestsMutex_socket4;
+        pendingRequestsHook = &s_pendingRequests_socket4;
+    }
+#endif
+#endif
+    pthread_mutex_lock(pendingRequestsMutexHook);
+
+    for(RequestInfo **ppCur = pendingRequestsHook
+        ; *ppCur != NULL
+        ; ppCur = &((*ppCur)->p_next)
+    ) {
+        if (pRI == *ppCur) {
+            ret = 1;
+            if (isAck) { // Async ack
+                if (pRI->wasAckSent == 1) {
+                    RLOGD("Ack was already sent for %s", requestToString(pRI->pCI->requestNumber));
+                } else {
+                    pRI->wasAckSent = 1;
+                }
+            } else {
+                *ppCur = (*ppCur)->p_next;
+            }
+            break;
+        }
+    }
+
+    pthread_mutex_unlock(pendingRequestsMutexHook);
+
+    return ret;
+}
+
+extern "C" void
+RIL_onRequestAck(RIL_Token t) {
+    RequestInfo *pRI;
+
+    RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
+
+    pRI = (RequestInfo *)t;
+
+    if (!checkAndDequeueRequestInfoIfAck(pRI, true)) {
+        RLOGE ("RIL_onRequestAck: invalid RIL_Token");
+        return;
+    }
+
+    socket_id = pRI->socket_id;
+
+#if VDBG
+    RLOGD("Request Ack, %s", rilSocketIdToString(socket_id));
+#endif
+
+    appendPrintBuf("Ack [%04d]< %s", pRI->token, requestToString(pRI->pCI->requestNumber));
+
+    if (pRI->cancelled == 0) {
+        pthread_rwlock_t *radioServiceRwlockPtr = radio_1_4::getRadioServiceRwlock(
+                (int) socket_id);
+        int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr);
+        assert(rwlockRet == 0);
+
+        radio_1_4::acknowledgeRequest((int) socket_id, pRI->token);
+
+        rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr);
+        assert(rwlockRet == 0);
+    }
+}
+extern "C" void
+RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
+    RequestInfo *pRI;
+    int ret;
+    RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
+
+    pRI = (RequestInfo *)t;
+
+    if (!checkAndDequeueRequestInfoIfAck(pRI, false)) {
+        RLOGE ("RIL_onRequestComplete: invalid RIL_Token");
+        return;
+    }
+
+    socket_id = pRI->socket_id;
+
+#if VDBG
+    RLOGD("RequestComplete, %s", rilSocketIdToString(socket_id));
+#endif
+
+    if (pRI->local > 0) {
+        // Locally issued command...void only!
+        // response does not go back up the command socket
+        RLOGD("C[locl]< %s", requestToString(pRI->pCI->requestNumber));
+
+        free(pRI);
+        return;
+    }
+
+    appendPrintBuf("[%04d]< %s",
+        pRI->token, requestToString(pRI->pCI->requestNumber));
+
+    if (pRI->cancelled == 0) {
+        int responseType;
+        if (s_callbacks.version >= 13 && pRI->wasAckSent == 1) {
+            // If ack was already sent, then this call is an asynchronous response. So we need to
+            // send id indicating that we expect an ack from RIL.java as we acquire wakelock here.
+            responseType = RESPONSE_SOLICITED_ACK_EXP;
+            grabPartialWakeLock();
+        } else {
+            responseType = RESPONSE_SOLICITED;
+        }
+
+        // there is a response payload, no matter success or not.
+#if VDBG
+        RLOGE ("Calling responseFunction() for token %d", pRI->token);
+#endif
+
+        pthread_rwlock_t *radioServiceRwlockPtr = radio_1_4::getRadioServiceRwlock((int) socket_id);
+        int rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr);
+        assert(rwlockRet == 0);
+
+        ret = pRI->pCI->responseFunction((int) socket_id,
+                responseType, pRI->token, e, response, responselen);
+
+        rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr);
+        assert(rwlockRet == 0);
+    }
+    free(pRI);
+}
+
+static void
+grabPartialWakeLock() {
+    if (s_callbacks.version >= 13) {
+        int ret;
+        ret = pthread_mutex_lock(&s_wakeLockCountMutex);
+        assert(ret == 0);
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+
+        UserCallbackInfo *p_info =
+                internalRequestTimedCallback(wakeTimeoutCallback, NULL, &TIMEVAL_WAKE_TIMEOUT);
+        if (p_info == NULL) {
+            release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+        } else {
+            s_wakelock_count++;
+            if (s_last_wake_timeout_info != NULL) {
+                s_last_wake_timeout_info->userParam = (void *)1;
+            }
+            s_last_wake_timeout_info = p_info;
+        }
+        ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
+        assert(ret == 0);
+    } else {
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
+    }
+}
+
+void
+releaseWakeLock() {
+    if (s_callbacks.version >= 13) {
+        int ret;
+        ret = pthread_mutex_lock(&s_wakeLockCountMutex);
+        assert(ret == 0);
+
+        if (s_wakelock_count > 1) {
+            s_wakelock_count--;
+        } else {
+            s_wakelock_count = 0;
+            release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+            if (s_last_wake_timeout_info != NULL) {
+                s_last_wake_timeout_info->userParam = (void *)1;
+            }
+        }
+
+        ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
+        assert(ret == 0);
+    } else {
+        release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+    }
+}
+
+/**
+ * Timer callback to put us back to sleep before the default timeout
+ */
+static void
+wakeTimeoutCallback (void *param) {
+    // We're using "param != NULL" as a cancellation mechanism
+    if (s_callbacks.version >= 13) {
+        if (param == NULL) {
+            int ret;
+            ret = pthread_mutex_lock(&s_wakeLockCountMutex);
+            assert(ret == 0);
+            s_wakelock_count = 0;
+            release_wake_lock(ANDROID_WAKE_LOCK_NAME);
+            ret = pthread_mutex_unlock(&s_wakeLockCountMutex);
+            assert(ret == 0);
+        }
+    } else {
+        if (param == NULL) {
+            releaseWakeLock();
+        }
+    }
+}
+
+#if defined(ANDROID_MULTI_SIM)
+extern "C"
+void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen, RIL_SOCKET_ID socket_id)
+#else
+extern "C"
+void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen)
+#endif
+{
+    int unsolResponseIndex;
+    int ret;
+    bool shouldScheduleTimeout = false;
+    RIL_SOCKET_ID soc_id = RIL_SOCKET_1;
+
+#if defined(ANDROID_MULTI_SIM)
+    soc_id = socket_id;
+#endif
+
+
+    if (s_registerCalled == 0) {
+        // Ignore RIL_onUnsolicitedResponse before RIL_register
+        RLOGW("RIL_onUnsolicitedResponse called before RIL_register");
+        return;
+    }
+
+    unsolResponseIndex = unsolResponse - RIL_UNSOL_RESPONSE_BASE;
+
+    if ((unsolResponseIndex < 0)
+        || (unsolResponseIndex >= (int32_t)NUM_ELEMS(s_unsolResponses))) {
+        RLOGE("unsupported unsolicited response code %d", unsolResponse);
+        return;
+    }
+
+    // Grab a wake lock if needed for this reponse,
+    // as we exit we'll either release it immediately
+    // or set a timer to release it later.
+    switch (s_unsolResponses[unsolResponseIndex].wakeType) {
+        case WAKE_PARTIAL:
+            grabPartialWakeLock();
+            shouldScheduleTimeout = true;
+        break;
+
+        case DONT_WAKE:
+        default:
+            // No wake lock is grabed so don't set timeout
+            shouldScheduleTimeout = false;
+            break;
+    }
+
+    appendPrintBuf("[UNSL]< %s", requestToString(unsolResponse));
+
+    int responseType;
+    if (s_callbacks.version >= 13
+                && s_unsolResponses[unsolResponseIndex].wakeType == WAKE_PARTIAL) {
+        responseType = RESPONSE_UNSOLICITED_ACK_EXP;
+    } else {
+        responseType = RESPONSE_UNSOLICITED;
+    }
+
+    pthread_rwlock_t *radioServiceRwlockPtr = radio_1_4::getRadioServiceRwlock((int) soc_id);
+    int rwlockRet;
+
+    if (unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
+        // get a write lock in caes of NITZ since setNitzTimeReceived() is called
+        rwlockRet = pthread_rwlock_wrlock(radioServiceRwlockPtr);
+        assert(rwlockRet == 0);
+        radio_1_4::setNitzTimeReceived((int) soc_id, android::elapsedRealtime());
+    } else {
+        rwlockRet = pthread_rwlock_rdlock(radioServiceRwlockPtr);
+        assert(rwlockRet == 0);
+    }
+
+    if (s_unsolResponses[unsolResponseIndex].responseFunction) {
+        RLOGD("calling UNSOLICITED responseFunction for index %d", unsolResponseIndex);
+        ret = s_unsolResponses[unsolResponseIndex].responseFunction(
+                (int) soc_id, responseType, 0, RIL_E_SUCCESS, const_cast<void*>(data),
+                datalen);
+    } else {
+        RLOGW("No call responseFunction defined for UNSOLICITED");
+    }
+
+    rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr);
+    assert(rwlockRet == 0);
+
+    if (s_callbacks.version < 13) {
+        if (shouldScheduleTimeout) {
+            UserCallbackInfo *p_info = internalRequestTimedCallback(wakeTimeoutCallback, NULL,
+                    &TIMEVAL_WAKE_TIMEOUT);
+
+            if (p_info == NULL) {
+                goto error_exit;
+            } else {
+                // Cancel the previous request
+                if (s_last_wake_timeout_info != NULL) {
+                    s_last_wake_timeout_info->userParam = (void *)1;
+                }
+                s_last_wake_timeout_info = p_info;
+            }
+        }
+    }
+
+#if VDBG
+    RLOGI("%s UNSOLICITED: %s length:%zu", rilSocketIdToString(soc_id),
+            requestToString(unsolResponse), datalen);
+#endif
+
+    if (ret != 0 && unsolResponse == RIL_UNSOL_NITZ_TIME_RECEIVED) {
+        // Unfortunately, NITZ time is not poll/update like everything
+        // else in the system. So, if the upstream client isn't connected,
+        // keep a copy of the last NITZ response (with receive time noted
+        // above) around so we can deliver it when it is connected
+
+        if (s_lastNITZTimeData != NULL) {
+            free(s_lastNITZTimeData);
+            s_lastNITZTimeData = NULL;
+        }
+
+        s_lastNITZTimeData = calloc(datalen, 1);
+        if (s_lastNITZTimeData == NULL) {
+            RLOGE("Memory allocation failed in RIL_onUnsolicitedResponse");
+            goto error_exit;
+        }
+        s_lastNITZTimeDataSize = datalen;
+        memcpy(s_lastNITZTimeData, data, datalen);
+    }
+
+    // Normal exit
+    return;
+
+error_exit:
+    if (shouldScheduleTimeout) {
+        releaseWakeLock();
+    }
+}
+
+/** FIXME generalize this if you track UserCAllbackInfo, clear it
+    when the callback occurs
+*/
+static UserCallbackInfo *
+internalRequestTimedCallback (RIL_TimedCallback callback, void *param,
+                                const struct timeval *relativeTime)
+{
+    struct timeval myRelativeTime;
+    UserCallbackInfo *p_info;
+
+    p_info = (UserCallbackInfo *) calloc(1, sizeof(UserCallbackInfo));
+    if (p_info == NULL) {
+        RLOGE("Memory allocation failed in internalRequestTimedCallback");
+        return p_info;
+
+    }
+
+    p_info->p_callback = callback;
+    p_info->userParam = param;
+
+    if (relativeTime == NULL) {
+        /* treat null parameter as a 0 relative time */
+        memset (&myRelativeTime, 0, sizeof(myRelativeTime));
+    } else {
+        /* FIXME I think event_add's tv param is really const anyway */
+        memcpy (&myRelativeTime, relativeTime, sizeof(myRelativeTime));
+    }
+
+    ril_event_set(&(p_info->event), -1, false, userTimerCallback, p_info);
+
+    ril_timer_add(&(p_info->event), &myRelativeTime);
+
+    triggerEvLoop();
+    return p_info;
+}
+
+
+extern "C" void
+RIL_requestTimedCallback (RIL_TimedCallback callback, void *param,
+                                const struct timeval *relativeTime) {
+    internalRequestTimedCallback (callback, param, relativeTime);
+}
+
+const char *
+failCauseToString(RIL_Errno e) {
+    switch(e) {
+        case RIL_E_SUCCESS: return "E_SUCCESS";
+        case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE";
+        case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE";
+        case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT";
+        case RIL_E_SIM_PIN2: return "E_SIM_PIN2";
+        case RIL_E_SIM_PUK2: return "E_SIM_PUK2";
+        case RIL_E_REQUEST_NOT_SUPPORTED: return "E_REQUEST_NOT_SUPPORTED";
+        case RIL_E_CANCELLED: return "E_CANCELLED";
+        case RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL: return "E_OP_NOT_ALLOWED_DURING_VOICE_CALL";
+        case RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW: return "E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW";
+        case RIL_E_SMS_SEND_FAIL_RETRY: return "E_SMS_SEND_FAIL_RETRY";
+        case RIL_E_SIM_ABSENT:return "E_SIM_ABSENT";
+        case RIL_E_ILLEGAL_SIM_OR_ME:return "E_ILLEGAL_SIM_OR_ME";
+#ifdef FEATURE_MULTIMODE_ANDROID
+        case RIL_E_SUBSCRIPTION_NOT_AVAILABLE:return "E_SUBSCRIPTION_NOT_AVAILABLE";
+        case RIL_E_MODE_NOT_SUPPORTED:return "E_MODE_NOT_SUPPORTED";
+#endif
+        case RIL_E_FDN_CHECK_FAILURE: return "E_FDN_CHECK_FAILURE";
+        case RIL_E_MISSING_RESOURCE: return "E_MISSING_RESOURCE";
+        case RIL_E_NO_SUCH_ELEMENT: return "E_NO_SUCH_ELEMENT";
+        case RIL_E_DIAL_MODIFIED_TO_USSD: return "E_DIAL_MODIFIED_TO_USSD";
+        case RIL_E_DIAL_MODIFIED_TO_SS: return "E_DIAL_MODIFIED_TO_SS";
+        case RIL_E_DIAL_MODIFIED_TO_DIAL: return "E_DIAL_MODIFIED_TO_DIAL";
+        case RIL_E_USSD_MODIFIED_TO_DIAL: return "E_USSD_MODIFIED_TO_DIAL";
+        case RIL_E_USSD_MODIFIED_TO_SS: return "E_USSD_MODIFIED_TO_SS";
+        case RIL_E_USSD_MODIFIED_TO_USSD: return "E_USSD_MODIFIED_TO_USSD";
+        case RIL_E_SS_MODIFIED_TO_DIAL: return "E_SS_MODIFIED_TO_DIAL";
+        case RIL_E_SS_MODIFIED_TO_USSD: return "E_SS_MODIFIED_TO_USSD";
+        case RIL_E_SUBSCRIPTION_NOT_SUPPORTED: return "E_SUBSCRIPTION_NOT_SUPPORTED";
+        case RIL_E_SS_MODIFIED_TO_SS: return "E_SS_MODIFIED_TO_SS";
+        case RIL_E_LCE_NOT_SUPPORTED: return "E_LCE_NOT_SUPPORTED";
+        case RIL_E_NO_MEMORY: return "E_NO_MEMORY";
+        case RIL_E_INTERNAL_ERR: return "E_INTERNAL_ERR";
+        case RIL_E_SYSTEM_ERR: return "E_SYSTEM_ERR";
+        case RIL_E_MODEM_ERR: return "E_MODEM_ERR";
+        case RIL_E_INVALID_STATE: return "E_INVALID_STATE";
+        case RIL_E_NO_RESOURCES: return "E_NO_RESOURCES";
+        case RIL_E_SIM_ERR: return "E_SIM_ERR";
+        case RIL_E_INVALID_ARGUMENTS: return "E_INVALID_ARGUMENTS";
+        case RIL_E_INVALID_SIM_STATE: return "E_INVALID_SIM_STATE";
+        case RIL_E_INVALID_MODEM_STATE: return "E_INVALID_MODEM_STATE";
+        case RIL_E_INVALID_CALL_ID: return "E_INVALID_CALL_ID";
+        case RIL_E_NO_SMS_TO_ACK: return "E_NO_SMS_TO_ACK";
+        case RIL_E_NETWORK_ERR: return "E_NETWORK_ERR";
+        case RIL_E_REQUEST_RATE_LIMITED: return "E_REQUEST_RATE_LIMITED";
+        case RIL_E_SIM_BUSY: return "E_SIM_BUSY";
+        case RIL_E_SIM_FULL: return "E_SIM_FULL";
+        case RIL_E_NETWORK_REJECT: return "E_NETWORK_REJECT";
+        case RIL_E_OPERATION_NOT_ALLOWED: return "E_OPERATION_NOT_ALLOWED";
+        case RIL_E_EMPTY_RECORD: return "E_EMPTY_RECORD";
+        case RIL_E_INVALID_SMS_FORMAT: return "E_INVALID_SMS_FORMAT";
+        case RIL_E_ENCODING_ERR: return "E_ENCODING_ERR";
+        case RIL_E_INVALID_SMSC_ADDRESS: return "E_INVALID_SMSC_ADDRESS";
+        case RIL_E_NO_SUCH_ENTRY: return "E_NO_SUCH_ENTRY";
+        case RIL_E_NETWORK_NOT_READY: return "E_NETWORK_NOT_READY";
+        case RIL_E_NOT_PROVISIONED: return "E_NOT_PROVISIONED";
+        case RIL_E_NO_SUBSCRIPTION: return "E_NO_SUBSCRIPTION";
+        case RIL_E_NO_NETWORK_FOUND: return "E_NO_NETWORK_FOUND";
+        case RIL_E_DEVICE_IN_USE: return "E_DEVICE_IN_USE";
+        case RIL_E_ABORTED: return "E_ABORTED";
+        case RIL_E_INVALID_RESPONSE: return "INVALID_RESPONSE";
+        case RIL_E_OEM_ERROR_1: return "E_OEM_ERROR_1";
+        case RIL_E_OEM_ERROR_2: return "E_OEM_ERROR_2";
+        case RIL_E_OEM_ERROR_3: return "E_OEM_ERROR_3";
+        case RIL_E_OEM_ERROR_4: return "E_OEM_ERROR_4";
+        case RIL_E_OEM_ERROR_5: return "E_OEM_ERROR_5";
+        case RIL_E_OEM_ERROR_6: return "E_OEM_ERROR_6";
+        case RIL_E_OEM_ERROR_7: return "E_OEM_ERROR_7";
+        case RIL_E_OEM_ERROR_8: return "E_OEM_ERROR_8";
+        case RIL_E_OEM_ERROR_9: return "E_OEM_ERROR_9";
+        case RIL_E_OEM_ERROR_10: return "E_OEM_ERROR_10";
+        case RIL_E_OEM_ERROR_11: return "E_OEM_ERROR_11";
+        case RIL_E_OEM_ERROR_12: return "E_OEM_ERROR_12";
+        case RIL_E_OEM_ERROR_13: return "E_OEM_ERROR_13";
+        case RIL_E_OEM_ERROR_14: return "E_OEM_ERROR_14";
+        case RIL_E_OEM_ERROR_15: return "E_OEM_ERROR_15";
+        case RIL_E_OEM_ERROR_16: return "E_OEM_ERROR_16";
+        case RIL_E_OEM_ERROR_17: return "E_OEM_ERROR_17";
+        case RIL_E_OEM_ERROR_18: return "E_OEM_ERROR_18";
+        case RIL_E_OEM_ERROR_19: return "E_OEM_ERROR_19";
+        case RIL_E_OEM_ERROR_20: return "E_OEM_ERROR_20";
+        case RIL_E_OEM_ERROR_21: return "E_OEM_ERROR_21";
+        case RIL_E_OEM_ERROR_22: return "E_OEM_ERROR_22";
+        case RIL_E_OEM_ERROR_23: return "E_OEM_ERROR_23";
+        case RIL_E_OEM_ERROR_24: return "E_OEM_ERROR_24";
+        case RIL_E_OEM_ERROR_25: return "E_OEM_ERROR_25";
+        default: return "<unknown error>";
+    }
+}
+
+const char *
+radioStateToString(RIL_RadioState s) {
+    switch(s) {
+        case RADIO_STATE_OFF: return "RADIO_OFF";
+        case RADIO_STATE_UNAVAILABLE: return "RADIO_UNAVAILABLE";
+        case RADIO_STATE_ON:return"RADIO_ON";
+        default: return "<unknown state>";
+    }
+}
+
+const char *
+callStateToString(RIL_CallState s) {
+    switch(s) {
+        case RIL_CALL_ACTIVE : return "ACTIVE";
+        case RIL_CALL_HOLDING: return "HOLDING";
+        case RIL_CALL_DIALING: return "DIALING";
+        case RIL_CALL_ALERTING: return "ALERTING";
+        case RIL_CALL_INCOMING: return "INCOMING";
+        case RIL_CALL_WAITING: return "WAITING";
+        default: return "<unknown state>";
+    }
+}
+
+const char *
+requestToString(int request) {
+/*
+ cat guest/hals/ril/libril/ril_commands.h \
+ | egrep "^ *{RIL_" \
+ | sed -re 's/\{RIL_([^,]+),[^,]+,([^}]+).+/case RIL_\1: return "\1";/'
+
+
+ cat guest/hals/ril/libril/ril_unsol_commands.h \
+ | egrep "^ *{RIL_" \
+ | sed -re 's/\{RIL_([^,]+),([^}]+).+/case RIL_\1: return "\1";/'
+
+*/
+    switch(request) {
+        case RIL_REQUEST_GET_SIM_STATUS: return "GET_SIM_STATUS";
+        case RIL_REQUEST_ENTER_SIM_PIN: return "ENTER_SIM_PIN";
+        case RIL_REQUEST_ENTER_SIM_PUK: return "ENTER_SIM_PUK";
+        case RIL_REQUEST_ENTER_SIM_PIN2: return "ENTER_SIM_PIN2";
+        case RIL_REQUEST_ENTER_SIM_PUK2: return "ENTER_SIM_PUK2";
+        case RIL_REQUEST_CHANGE_SIM_PIN: return "CHANGE_SIM_PIN";
+        case RIL_REQUEST_CHANGE_SIM_PIN2: return "CHANGE_SIM_PIN2";
+        case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION: return "ENTER_NETWORK_DEPERSONALIZATION";
+        case RIL_REQUEST_GET_CURRENT_CALLS: return "GET_CURRENT_CALLS";
+        case RIL_REQUEST_DIAL: return "DIAL";
+        case RIL_REQUEST_GET_IMSI: return "GET_IMSI";
+        case RIL_REQUEST_HANGUP: return "HANGUP";
+        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND: return "HANGUP_WAITING_OR_BACKGROUND";
+        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND: return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
+        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE: return "SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
+        case RIL_REQUEST_CONFERENCE: return "CONFERENCE";
+        case RIL_REQUEST_UDUB: return "UDUB";
+        case RIL_REQUEST_LAST_CALL_FAIL_CAUSE: return "LAST_CALL_FAIL_CAUSE";
+        case RIL_REQUEST_SIGNAL_STRENGTH: return "SIGNAL_STRENGTH";
+        case RIL_REQUEST_VOICE_REGISTRATION_STATE: return "VOICE_REGISTRATION_STATE";
+        case RIL_REQUEST_DATA_REGISTRATION_STATE: return "DATA_REGISTRATION_STATE";
+        case RIL_REQUEST_OPERATOR: return "OPERATOR";
+        case RIL_REQUEST_RADIO_POWER: return "RADIO_POWER";
+        case RIL_REQUEST_DTMF: return "DTMF";
+        case RIL_REQUEST_SEND_SMS: return "SEND_SMS";
+        case RIL_REQUEST_SEND_SMS_EXPECT_MORE: return "SEND_SMS_EXPECT_MORE";
+        case RIL_REQUEST_SETUP_DATA_CALL: return "SETUP_DATA_CALL";
+        case RIL_REQUEST_SIM_IO: return "SIM_IO";
+        case RIL_REQUEST_SEND_USSD: return "SEND_USSD";
+        case RIL_REQUEST_CANCEL_USSD: return "CANCEL_USSD";
+        case RIL_REQUEST_GET_CLIR: return "GET_CLIR";
+        case RIL_REQUEST_SET_CLIR: return "SET_CLIR";
+        case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS: return "QUERY_CALL_FORWARD_STATUS";
+        case RIL_REQUEST_SET_CALL_FORWARD: return "SET_CALL_FORWARD";
+        case RIL_REQUEST_QUERY_CALL_WAITING: return "QUERY_CALL_WAITING";
+        case RIL_REQUEST_SET_CALL_WAITING: return "SET_CALL_WAITING";
+        case RIL_REQUEST_SMS_ACKNOWLEDGE: return "SMS_ACKNOWLEDGE";
+        case RIL_REQUEST_GET_IMEI: return "GET_IMEI";
+        case RIL_REQUEST_GET_IMEISV: return "GET_IMEISV";
+        case RIL_REQUEST_ANSWER: return "ANSWER";
+        case RIL_REQUEST_DEACTIVATE_DATA_CALL: return "DEACTIVATE_DATA_CALL";
+        case RIL_REQUEST_QUERY_FACILITY_LOCK: return "QUERY_FACILITY_LOCK";
+        case RIL_REQUEST_SET_FACILITY_LOCK: return "SET_FACILITY_LOCK";
+        case RIL_REQUEST_CHANGE_BARRING_PASSWORD: return "CHANGE_BARRING_PASSWORD";
+        case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE: return "QUERY_NETWORK_SELECTION_MODE";
+        case RIL_REQUEST_START_NETWORK_SCAN: return "RIL_REQUEST_START_NETWORK_SCAN";
+        case RIL_REQUEST_START_NETWORK_SCAN4: return "RIL_REQUEST_START_NETWORK_SCAN4";
+        case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC: return "SET_NETWORK_SELECTION_AUTOMATIC";
+        case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL: return "SET_NETWORK_SELECTION_MANUAL";
+        case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS: return "QUERY_AVAILABLE_NETWORKS";
+        case RIL_REQUEST_DTMF_START: return "DTMF_START";
+        case RIL_REQUEST_DTMF_STOP: return "DTMF_STOP";
+        case RIL_REQUEST_BASEBAND_VERSION: return "BASEBAND_VERSION";
+        case RIL_REQUEST_SEPARATE_CONNECTION: return "SEPARATE_CONNECTION";
+        case RIL_REQUEST_SET_MUTE: return "SET_MUTE";
+        case RIL_REQUEST_GET_MUTE: return "GET_MUTE";
+        case RIL_REQUEST_QUERY_CLIP: return "QUERY_CLIP";
+        case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE: return "LAST_DATA_CALL_FAIL_CAUSE";
+        case RIL_REQUEST_DATA_CALL_LIST: return "DATA_CALL_LIST";
+        case RIL_REQUEST_RESET_RADIO: return "RESET_RADIO";
+        case RIL_REQUEST_OEM_HOOK_RAW: return "OEM_HOOK_RAW";
+        case RIL_REQUEST_OEM_HOOK_STRINGS: return "OEM_HOOK_STRINGS";
+        case RIL_REQUEST_SCREEN_STATE: return "SCREEN_STATE";
+        case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION: return "SET_SUPP_SVC_NOTIFICATION";
+        case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
+        case RIL_REQUEST_DELETE_SMS_ON_SIM: return "DELETE_SMS_ON_SIM";
+        case RIL_REQUEST_SET_BAND_MODE: return "SET_BAND_MODE";
+        case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE: return "QUERY_AVAILABLE_BAND_MODE";
+        case RIL_REQUEST_STK_GET_PROFILE: return "STK_GET_PROFILE";
+        case RIL_REQUEST_STK_SET_PROFILE: return "STK_SET_PROFILE";
+        case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND: return "STK_SEND_ENVELOPE_COMMAND";
+        case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE: return "STK_SEND_TERMINAL_RESPONSE";
+        case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM: return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
+        case RIL_REQUEST_EXPLICIT_CALL_TRANSFER: return "EXPLICIT_CALL_TRANSFER";
+        case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE: return "SET_PREFERRED_NETWORK_TYPE";
+        case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE: return "GET_PREFERRED_NETWORK_TYPE";
+        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS: return "GET_NEIGHBORING_CELL_IDS";
+        case RIL_REQUEST_SET_LOCATION_UPDATES: return "SET_LOCATION_UPDATES";
+        case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE: return "CDMA_SET_SUBSCRIPTION_SOURCE";
+        case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE: return "CDMA_SET_ROAMING_PREFERENCE";
+        case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE: return "CDMA_QUERY_ROAMING_PREFERENCE";
+        case RIL_REQUEST_SET_TTY_MODE: return "SET_TTY_MODE";
+        case RIL_REQUEST_QUERY_TTY_MODE: return "QUERY_TTY_MODE";
+        case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE: return "CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
+        case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE: return "CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
+        case RIL_REQUEST_CDMA_FLASH: return "CDMA_FLASH";
+        case RIL_REQUEST_CDMA_BURST_DTMF: return "CDMA_BURST_DTMF";
+        case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY: return "CDMA_VALIDATE_AND_WRITE_AKEY";
+        case RIL_REQUEST_CDMA_SEND_SMS: return "CDMA_SEND_SMS";
+        case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE: return "CDMA_SMS_ACKNOWLEDGE";
+        case RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG: return "GSM_GET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG: return "GSM_SET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION: return "GSM_SMS_BROADCAST_ACTIVATION";
+        case RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG: return "CDMA_GET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG: return "CDMA_SET_BROADCAST_SMS_CONFIG";
+        case RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION: return "CDMA_SMS_BROADCAST_ACTIVATION";
+        case RIL_REQUEST_CDMA_SUBSCRIPTION: return "CDMA_SUBSCRIPTION";
+        case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM: return "CDMA_WRITE_SMS_TO_RUIM";
+        case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM: return "CDMA_DELETE_SMS_ON_RUIM";
+        case RIL_REQUEST_DEVICE_IDENTITY: return "DEVICE_IDENTITY";
+        case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: return "EXIT_EMERGENCY_CALLBACK_MODE";
+        case RIL_REQUEST_GET_SMSC_ADDRESS: return "GET_SMSC_ADDRESS";
+        case RIL_REQUEST_SET_SMSC_ADDRESS: return "SET_SMSC_ADDRESS";
+        case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: return "REPORT_SMS_MEMORY_STATUS";
+        case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: return "REPORT_STK_SERVICE_IS_RUNNING";
+        case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE: return "CDMA_GET_SUBSCRIPTION_SOURCE";
+        case RIL_REQUEST_ISIM_AUTHENTICATION: return "ISIM_AUTHENTICATION";
+        case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
+        case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "STK_SEND_ENVELOPE_WITH_STATUS";
+        case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
+        case RIL_REQUEST_GET_CELL_INFO_LIST: return "GET_CELL_INFO_LIST";
+        case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return "SET_UNSOL_CELL_INFO_LIST_RATE";
+        case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "SET_INITIAL_ATTACH_APN";
+        case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE";
+        case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS";
+        case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC: return "SIM_TRANSMIT_APDU_BASIC";
+        case RIL_REQUEST_SIM_OPEN_CHANNEL: return "SIM_OPEN_CHANNEL";
+        case RIL_REQUEST_SIM_CLOSE_CHANNEL: return "SIM_CLOSE_CHANNEL";
+        case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL: return "SIM_TRANSMIT_APDU_CHANNEL";
+        case RIL_REQUEST_NV_READ_ITEM: return "NV_READ_ITEM";
+        case RIL_REQUEST_NV_WRITE_ITEM: return "NV_WRITE_ITEM";
+        case RIL_REQUEST_NV_WRITE_CDMA_PRL: return "NV_WRITE_CDMA_PRL";
+        case RIL_REQUEST_NV_RESET_CONFIG: return "NV_RESET_CONFIG";
+        case RIL_REQUEST_SET_UICC_SUBSCRIPTION: return "SET_UICC_SUBSCRIPTION";
+        case RIL_REQUEST_ALLOW_DATA: return "ALLOW_DATA";
+        case RIL_REQUEST_GET_HARDWARE_CONFIG: return "GET_HARDWARE_CONFIG";
+        case RIL_REQUEST_SIM_AUTHENTICATION: return "SIM_AUTHENTICATION";
+        case RIL_REQUEST_GET_DC_RT_INFO: return "GET_DC_RT_INFO";
+        case RIL_REQUEST_SET_DC_RT_INFO_RATE: return "SET_DC_RT_INFO_RATE";
+        case RIL_REQUEST_SET_DATA_PROFILE: return "SET_DATA_PROFILE";
+        case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
+        case RIL_REQUEST_GET_RADIO_CAPABILITY: return "GET_RADIO_CAPABILITY";
+        case RIL_REQUEST_SET_RADIO_CAPABILITY: return "SET_RADIO_CAPABILITY";
+        case RIL_REQUEST_START_LCE: return "START_LCE";
+        case RIL_REQUEST_STOP_LCE: return "STOP_LCE";
+        case RIL_REQUEST_PULL_LCEDATA: return "PULL_LCEDATA";
+        case RIL_REQUEST_GET_ACTIVITY_INFO: return "GET_ACTIVITY_INFO";
+        case RIL_REQUEST_SET_CARRIER_RESTRICTIONS: return "SET_CARRIER_RESTRICTIONS";
+        case RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4: return "SET_CARRIER_RESTRICTIONS_1_4";
+        case RIL_REQUEST_GET_CARRIER_RESTRICTIONS: return "GET_CARRIER_RESTRICTIONS";
+        case RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4: return "GET_CARRIER_RESTRICTIONS_1_4";
+        case RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION: return "SET_CARRIER_INFO_IMSI_ENCRYPTION";
+        case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RESPONSE_ACKNOWLEDGEMENT";
+        case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
+        case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
+        case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED";
+        case RIL_UNSOL_RESPONSE_NEW_SMS: return "UNSOL_RESPONSE_NEW_SMS";
+        case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT: return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
+        case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM: return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
+        case RIL_UNSOL_ON_USSD: return "UNSOL_ON_USSD";
+        case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST";
+        case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
+        case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
+        case RIL_UNSOL_DATA_CALL_LIST_CHANGED: return "UNSOL_DATA_CALL_LIST_CHANGED";
+        case RIL_UNSOL_SUPP_SVC_NOTIFICATION: return "UNSOL_SUPP_SVC_NOTIFICATION";
+        case RIL_UNSOL_STK_SESSION_END: return "UNSOL_STK_SESSION_END";
+        case RIL_UNSOL_STK_PROACTIVE_COMMAND: return "UNSOL_STK_PROACTIVE_COMMAND";
+        case RIL_UNSOL_STK_EVENT_NOTIFY: return "UNSOL_STK_EVENT_NOTIFY";
+        case RIL_UNSOL_STK_CALL_SETUP: return "UNSOL_STK_CALL_SETUP";
+        case RIL_UNSOL_SIM_SMS_STORAGE_FULL: return "UNSOL_SIM_SMS_STORAGE_FULL";
+        case RIL_UNSOL_SIM_REFRESH: return "UNSOL_SIM_REFRESH";
+        case RIL_UNSOL_CALL_RING: return "UNSOL_CALL_RING";
+        case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED: return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
+        case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS: return "UNSOL_RESPONSE_CDMA_NEW_SMS";
+        case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS: return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
+        case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL: return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
+        case RIL_UNSOL_RESTRICTED_STATE_CHANGED: return "UNSOL_RESTRICTED_STATE_CHANGED";
+        case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE: return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
+        case RIL_UNSOL_CDMA_CALL_WAITING: return "UNSOL_CDMA_CALL_WAITING";
+        case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS: return "UNSOL_CDMA_OTA_PROVISION_STATUS";
+        case RIL_UNSOL_CDMA_INFO_REC: return "UNSOL_CDMA_INFO_REC";
+        case RIL_UNSOL_OEM_HOOK_RAW: return "UNSOL_OEM_HOOK_RAW";
+        case RIL_UNSOL_RINGBACK_TONE: return "UNSOL_RINGBACK_TONE";
+        case RIL_UNSOL_RESEND_INCALL_MUTE: return "UNSOL_RESEND_INCALL_MUTE";
+        case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED: return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
+        case RIL_UNSOL_CDMA_PRL_CHANGED: return "UNSOL_CDMA_PRL_CHANGED";
+        case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE: return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
+        case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED";
+        case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED";
+        case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
+        case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED";
+        case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED: return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
+        case RIL_UNSOL_SRVCC_STATE_NOTIFY: return "UNSOL_SRVCC_STATE_NOTIFY";
+        case RIL_UNSOL_HARDWARE_CONFIG_CHANGED: return "UNSOL_HARDWARE_CONFIG_CHANGED";
+        case RIL_UNSOL_DC_RT_INFO_CHANGED: return "UNSOL_DC_RT_INFO_CHANGED";
+        case RIL_UNSOL_RADIO_CAPABILITY: return "UNSOL_RADIO_CAPABILITY";
+        case RIL_UNSOL_MODEM_RESTART: return "UNSOL_MODEM_RESTART";
+        case RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION: return "UNSOL_CARRIER_INFO_IMSI_ENCRYPTION";
+        case RIL_UNSOL_ON_SS: return "UNSOL_ON_SS";
+        case RIL_UNSOL_STK_CC_ALPHA_NOTIFY: return "UNSOL_STK_CC_ALPHA_NOTIFY";
+        case RIL_UNSOL_LCEDATA_RECV: return "UNSOL_LCEDATA_RECV";
+        case RIL_UNSOL_PCO_DATA: return "UNSOL_PCO_DATA";
+        default: return "<unknown request>";
+    }
+}
+
+const char *
+rilSocketIdToString(RIL_SOCKET_ID socket_id)
+{
+    switch(socket_id) {
+        case RIL_SOCKET_1:
+            return "RIL_SOCKET_1";
+#if (SIM_COUNT >= 2)
+        case RIL_SOCKET_2:
+            return "RIL_SOCKET_2";
+#endif
+#if (SIM_COUNT >= 3)
+        case RIL_SOCKET_3:
+            return "RIL_SOCKET_3";
+#endif
+#if (SIM_COUNT >= 4)
+        case RIL_SOCKET_4:
+            return "RIL_SOCKET_4";
+#endif
+        default:
+            return "not a valid RIL";
+    }
+}
+
+} /* namespace android */
diff --git a/guest/hals/ril/libril/ril.h b/guest/hals/ril/libril/ril.h
new file mode 100644
index 0000000..9b1b0ff
--- /dev/null
+++ b/guest/hals/ril/libril/ril.h
@@ -0,0 +1,7600 @@
+/*
+ * Copyright (C) 2006 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 is 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.
+ */
+
+#ifndef ANDROID_RIL_H
+#define ANDROID_RIL_H 1
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <telephony/ril_cdma_sms.h>
+#include <telephony/ril_nv_items.h>
+#include <telephony/ril_msim.h>
+
+#ifndef FEATURE_UNIT_TEST
+#include <sys/time.h>
+#endif /* !FEATURE_UNIT_TEST */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SIM_COUNT
+#if defined(ANDROID_SIM_COUNT_2)
+#define SIM_COUNT 2
+#elif defined(ANDROID_SIM_COUNT_3)
+#define SIM_COUNT 3
+#elif defined(ANDROID_SIM_COUNT_4)
+#define SIM_COUNT 4
+#else
+#define SIM_COUNT 1
+#endif
+
+#ifndef ANDROID_MULTI_SIM
+#define SIM_COUNT 1
+#endif
+#endif
+
+/*
+ * RIL version.
+ * Value of RIL_VERSION should not be changed in future. Here onwards,
+ * when a new change is supposed to be introduced  which could involve new
+ * schemes added like Wakelocks, data structures added/updated, etc, we would
+ * just document RIL version associated with that change below. When OEM updates its
+ * RIL with those changes, they would return that new RIL version during RIL_REGISTER.
+ * We should make use of the returned version by vendor to identify appropriate scheme
+ * or data structure version to use.
+ *
+ * Documentation of RIL version and associated changes
+ * RIL_VERSION = 12 : This version corresponds to updated data structures namely
+ *                    RIL_Data_Call_Response_v11, RIL_SIM_IO_v6, RIL_CardStatus_v6,
+ *                    RIL_SimRefreshResponse_v7, RIL_CDMA_CallWaiting_v6,
+ *                    RIL_LTE_SignalStrength_v8, RIL_SignalStrength_v10, RIL_CellIdentityGsm_v12
+ *                    RIL_CellIdentityWcdma_v12, RIL_CellIdentityLte_v12,RIL_CellInfoGsm_v12,
+ *                    RIL_CellInfoWcdma_v12, RIL_CellInfoLte_v12, RIL_CellInfo_v12.
+ *
+ * RIL_VERSION = 13 : This version includes new wakelock semantics and as the first
+ *                    strongly versioned version it enforces structure use.
+ *
+ * RIL_VERSION = 14 : New data structures are added, namely RIL_CarrierMatchType,
+ *                    RIL_Carrier, RIL_CarrierRestrictions and RIL_PCO_Data.
+ *                    New commands added: RIL_REQUEST_SET_CARRIER_RESTRICTIONS,
+ *                    RIL_REQUEST_SET_CARRIER_RESTRICTIONS and RIL_UNSOL_PCO_DATA.
+ *
+ * RIL_VERSION = 15 : New commands added:
+ *                    RIL_UNSOL_MODEM_RESTART,
+ *                    RIL_REQUEST_SEND_DEVICE_STATE,
+ *                    RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER,
+ *                    RIL_REQUEST_SET_SIM_CARD_POWER,
+ *                    RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION,
+ *                    RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION
+ *                    The new parameters for RIL_REQUEST_SETUP_DATA_CALL,
+ *                    Updated data structures: RIL_DataProfileInfo_v15, RIL_InitialAttachApn_v15
+ *                    New data structure RIL_DataRegistrationStateResponse,
+ *                    RIL_VoiceRegistrationStateResponse same is
+ *                    used in RIL_REQUEST_DATA_REGISTRATION_STATE and
+ *                    RIL_REQUEST_VOICE_REGISTRATION_STATE respectively.
+ *                    New data structure RIL_OpenChannelParams.
+ *                    RIL_REQUEST_START_NETWORK_SCAN
+ *                    RIL_REQUEST_STOP_NETWORK_SCAN
+ *                    RIL_UNSOL_NETWORK_SCAN_RESULT
+ *                    RIL_REQUEST_GET_MODEM_STACK_STATUS
+ *                    RIL_REQUEST_ENABLE_MODEM
+ *                    RIL_REQUEST_EMERGENCY_DIAL
+ *                    RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS
+ */
+#define RIL_VERSION 12
+#define LAST_IMPRECISE_RIL_VERSION 12 // Better self-documented name
+#define RIL_VERSION_MIN 6 /* Minimum RIL_VERSION supported */
+
+#define CDMA_ALPHA_INFO_BUFFER_LENGTH 64
+#define CDMA_NUMBER_INFO_BUFFER_LENGTH 81
+
+#define MAX_RILDS 3
+#define MAX_SERVICE_NAME_LENGTH 6
+#define MAX_CLIENT_ID_LENGTH 2
+#define MAX_DEBUG_SOCKET_NAME_LENGTH 12
+#define MAX_QEMU_PIPE_NAME_LENGTH  11
+#define MAX_UUID_LENGTH 64
+#define MAX_BANDS 8
+#define MAX_CHANNELS 32
+#define MAX_RADIO_ACCESS_NETWORKS 8
+
+
+typedef void * RIL_Token;
+
+typedef enum {
+    RIL_SOCKET_1,
+#if (SIM_COUNT >= 2)
+    RIL_SOCKET_2,
+#if (SIM_COUNT >= 3)
+    RIL_SOCKET_3,
+#endif
+#if (SIM_COUNT >= 4)
+    RIL_SOCKET_4,
+#endif
+#endif
+    RIL_SOCKET_NUM
+} RIL_SOCKET_ID;
+
+
+typedef enum {
+    RIL_E_SUCCESS = 0,
+    RIL_E_RADIO_NOT_AVAILABLE = 1,     /* If radio did not start or is resetting */
+    RIL_E_GENERIC_FAILURE = 2,
+    RIL_E_PASSWORD_INCORRECT = 3,      /* for PIN/PIN2 methods only! */
+    RIL_E_SIM_PIN2 = 4,                /* Operation requires SIM PIN2 to be entered */
+    RIL_E_SIM_PUK2 = 5,                /* Operation requires SIM PIN2 to be entered */
+    RIL_E_REQUEST_NOT_SUPPORTED = 6,
+    RIL_E_CANCELLED = 7,
+    RIL_E_OP_NOT_ALLOWED_DURING_VOICE_CALL = 8, /* data ops are not allowed during voice
+                                                   call on a Class C GPRS device */
+    RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9,  /* data ops are not allowed before device
+                                                   registers in network */
+    RIL_E_SMS_SEND_FAIL_RETRY = 10,             /* fail to send sms and need retry */
+    RIL_E_SIM_ABSENT = 11,                      /* fail to set the location where CDMA subscription
+                                                   shall be retrieved because of SIM or RUIM
+                                                   card absent */
+    RIL_E_SUBSCRIPTION_NOT_AVAILABLE = 12,      /* fail to find CDMA subscription from specified
+                                                   location */
+    RIL_E_MODE_NOT_SUPPORTED = 13,              /* HW does not support preferred network type */
+    RIL_E_FDN_CHECK_FAILURE = 14,               /* command failed because recipient is not on FDN list */
+    RIL_E_ILLEGAL_SIM_OR_ME = 15,               /* network selection failed due to
+                                                   illegal SIM or ME */
+    RIL_E_MISSING_RESOURCE = 16,                /* no logical channel available */
+    RIL_E_NO_SUCH_ELEMENT = 17,                  /* application not found on SIM */
+    RIL_E_DIAL_MODIFIED_TO_USSD = 18,           /* DIAL request modified to USSD */
+    RIL_E_DIAL_MODIFIED_TO_SS = 19,             /* DIAL request modified to SS */
+    RIL_E_DIAL_MODIFIED_TO_DIAL = 20,           /* DIAL request modified to DIAL with different
+                                                   data */
+    RIL_E_USSD_MODIFIED_TO_DIAL = 21,           /* USSD request modified to DIAL */
+    RIL_E_USSD_MODIFIED_TO_SS = 22,             /* USSD request modified to SS */
+    RIL_E_USSD_MODIFIED_TO_USSD = 23,           /* USSD request modified to different USSD
+                                                   request */
+    RIL_E_SS_MODIFIED_TO_DIAL = 24,             /* SS request modified to DIAL */
+    RIL_E_SS_MODIFIED_TO_USSD = 25,             /* SS request modified to USSD */
+    RIL_E_SUBSCRIPTION_NOT_SUPPORTED = 26,      /* Subscription not supported by RIL */
+    RIL_E_SS_MODIFIED_TO_SS = 27,               /* SS request modified to different SS request */
+    RIL_E_LCE_NOT_SUPPORTED = 36,               /* LCE service not supported(36 in RILConstants.java) */
+    RIL_E_NO_MEMORY = 37,                       /* Not sufficient memory to process the request */
+    RIL_E_INTERNAL_ERR = 38,                    /* Modem hit unexpected error scenario while handling
+                                                   this request */
+    RIL_E_SYSTEM_ERR = 39,                      /* Hit platform or system error */
+    RIL_E_MODEM_ERR = 40,                       /* Vendor RIL got unexpected or incorrect response
+                                                   from modem for this request */
+    RIL_E_INVALID_STATE = 41,                   /* Unexpected request for the current state */
+    RIL_E_NO_RESOURCES = 42,                    /* Not sufficient resource to process the request */
+    RIL_E_SIM_ERR = 43,                         /* Received error from SIM card */
+    RIL_E_INVALID_ARGUMENTS = 44,               /* Received invalid arguments in request */
+    RIL_E_INVALID_SIM_STATE = 45,               /* Can not process the request in current SIM state */
+    RIL_E_INVALID_MODEM_STATE = 46,             /* Can not process the request in current Modem state */
+    RIL_E_INVALID_CALL_ID = 47,                 /* Received invalid call id in request */
+    RIL_E_NO_SMS_TO_ACK = 48,                   /* ACK received when there is no SMS to ack */
+    RIL_E_NETWORK_ERR = 49,                     /* Received error from network */
+    RIL_E_REQUEST_RATE_LIMITED = 50,            /* Operation denied due to overly-frequent requests */
+    RIL_E_SIM_BUSY = 51,                        /* SIM is busy */
+    RIL_E_SIM_FULL = 52,                        /* The target EF is full */
+    RIL_E_NETWORK_REJECT = 53,                  /* Request is rejected by network */
+    RIL_E_OPERATION_NOT_ALLOWED = 54,           /* Not allowed the request now */
+    RIL_E_EMPTY_RECORD = 55,                    /* The request record is empty */
+    RIL_E_INVALID_SMS_FORMAT = 56,              /* Invalid sms format */
+    RIL_E_ENCODING_ERR = 57,                    /* Message not encoded properly */
+    RIL_E_INVALID_SMSC_ADDRESS = 58,            /* SMSC address specified is invalid */
+    RIL_E_NO_SUCH_ENTRY = 59,                   /* No such entry present to perform the request */
+    RIL_E_NETWORK_NOT_READY = 60,               /* Network is not ready to perform the request */
+    RIL_E_NOT_PROVISIONED = 61,                 /* Device doesnot have this value provisioned */
+    RIL_E_NO_SUBSCRIPTION = 62,                 /* Device doesnot have subscription */
+    RIL_E_NO_NETWORK_FOUND = 63,                /* Network cannot be found */
+    RIL_E_DEVICE_IN_USE = 64,                   /* Operation cannot be performed because the device
+                                                   is currently in use */
+    RIL_E_ABORTED = 65,                         /* Operation aborted */
+    RIL_E_INVALID_RESPONSE = 66,                /* Invalid response sent by vendor code */
+    // OEM specific error codes. To be used by OEM when they don't want to reveal
+    // specific error codes which would be replaced by Generic failure.
+    RIL_E_OEM_ERROR_1 = 501,
+    RIL_E_OEM_ERROR_2 = 502,
+    RIL_E_OEM_ERROR_3 = 503,
+    RIL_E_OEM_ERROR_4 = 504,
+    RIL_E_OEM_ERROR_5 = 505,
+    RIL_E_OEM_ERROR_6 = 506,
+    RIL_E_OEM_ERROR_7 = 507,
+    RIL_E_OEM_ERROR_8 = 508,
+    RIL_E_OEM_ERROR_9 = 509,
+    RIL_E_OEM_ERROR_10 = 510,
+    RIL_E_OEM_ERROR_11 = 511,
+    RIL_E_OEM_ERROR_12 = 512,
+    RIL_E_OEM_ERROR_13 = 513,
+    RIL_E_OEM_ERROR_14 = 514,
+    RIL_E_OEM_ERROR_15 = 515,
+    RIL_E_OEM_ERROR_16 = 516,
+    RIL_E_OEM_ERROR_17 = 517,
+    RIL_E_OEM_ERROR_18 = 518,
+    RIL_E_OEM_ERROR_19 = 519,
+    RIL_E_OEM_ERROR_20 = 520,
+    RIL_E_OEM_ERROR_21 = 521,
+    RIL_E_OEM_ERROR_22 = 522,
+    RIL_E_OEM_ERROR_23 = 523,
+    RIL_E_OEM_ERROR_24 = 524,
+    RIL_E_OEM_ERROR_25 = 525
+} RIL_Errno;
+
+typedef enum {
+    RIL_CALL_ACTIVE = 0,
+    RIL_CALL_HOLDING = 1,
+    RIL_CALL_DIALING = 2,    /* MO call only */
+    RIL_CALL_ALERTING = 3,   /* MO call only */
+    RIL_CALL_INCOMING = 4,   /* MT call only */
+    RIL_CALL_WAITING = 5     /* MT call only */
+} RIL_CallState;
+
+typedef enum {
+    RADIO_STATE_OFF = 0,                   /* Radio explictly powered off (eg CFUN=0) */
+    RADIO_STATE_UNAVAILABLE = 1,           /* Radio unavailable (eg, resetting or not booted) */
+    RADIO_STATE_ON = 10                    /* Radio is on */
+} RIL_RadioState;
+
+typedef enum {
+    RADIO_TECH_UNKNOWN = 0,
+    RADIO_TECH_GPRS = 1,
+    RADIO_TECH_EDGE = 2,
+    RADIO_TECH_UMTS = 3,
+    RADIO_TECH_IS95A = 4,
+    RADIO_TECH_IS95B = 5,
+    RADIO_TECH_1xRTT =  6,
+    RADIO_TECH_EVDO_0 = 7,
+    RADIO_TECH_EVDO_A = 8,
+    RADIO_TECH_HSDPA = 9,
+    RADIO_TECH_HSUPA = 10,
+    RADIO_TECH_HSPA = 11,
+    RADIO_TECH_EVDO_B = 12,
+    RADIO_TECH_EHRPD = 13,
+    RADIO_TECH_LTE = 14,
+    RADIO_TECH_HSPAP = 15, // HSPA+
+    RADIO_TECH_GSM = 16, // Only supports voice
+    RADIO_TECH_TD_SCDMA = 17,
+    RADIO_TECH_IWLAN = 18,
+    RADIO_TECH_LTE_CA = 19
+} RIL_RadioTechnology;
+
+typedef enum {
+    RAF_UNKNOWN =  (1 <<  RADIO_TECH_UNKNOWN),
+    RAF_GPRS = (1 << RADIO_TECH_GPRS),
+    RAF_EDGE = (1 << RADIO_TECH_EDGE),
+    RAF_UMTS = (1 << RADIO_TECH_UMTS),
+    RAF_IS95A = (1 << RADIO_TECH_IS95A),
+    RAF_IS95B = (1 << RADIO_TECH_IS95B),
+    RAF_1xRTT = (1 << RADIO_TECH_1xRTT),
+    RAF_EVDO_0 = (1 << RADIO_TECH_EVDO_0),
+    RAF_EVDO_A = (1 << RADIO_TECH_EVDO_A),
+    RAF_HSDPA = (1 << RADIO_TECH_HSDPA),
+    RAF_HSUPA = (1 << RADIO_TECH_HSUPA),
+    RAF_HSPA = (1 << RADIO_TECH_HSPA),
+    RAF_EVDO_B = (1 << RADIO_TECH_EVDO_B),
+    RAF_EHRPD = (1 << RADIO_TECH_EHRPD),
+    RAF_LTE = (1 << RADIO_TECH_LTE),
+    RAF_HSPAP = (1 << RADIO_TECH_HSPAP),
+    RAF_GSM = (1 << RADIO_TECH_GSM),
+    RAF_TD_SCDMA = (1 << RADIO_TECH_TD_SCDMA),
+    RAF_LTE_CA = (1 << RADIO_TECH_LTE_CA)
+} RIL_RadioAccessFamily;
+
+typedef enum {
+    BAND_MODE_UNSPECIFIED = 0,      //"unspecified" (selected by baseband automatically)
+    BAND_MODE_EURO = 1,             //"EURO band" (GSM-900 / DCS-1800 / WCDMA-IMT-2000)
+    BAND_MODE_USA = 2,              //"US band" (GSM-850 / PCS-1900 / WCDMA-850 / WCDMA-PCS-1900)
+    BAND_MODE_JPN = 3,              //"JPN band" (WCDMA-800 / WCDMA-IMT-2000)
+    BAND_MODE_AUS = 4,              //"AUS band" (GSM-900 / DCS-1800 / WCDMA-850 / WCDMA-IMT-2000)
+    BAND_MODE_AUS_2 = 5,            //"AUS band 2" (GSM-900 / DCS-1800 / WCDMA-850)
+    BAND_MODE_CELL_800 = 6,         //"Cellular" (800-MHz Band)
+    BAND_MODE_PCS = 7,              //"PCS" (1900-MHz Band)
+    BAND_MODE_JTACS = 8,            //"Band Class 3" (JTACS Band)
+    BAND_MODE_KOREA_PCS = 9,        //"Band Class 4" (Korean PCS Band)
+    BAND_MODE_5_450M = 10,          //"Band Class 5" (450-MHz Band)
+    BAND_MODE_IMT2000 = 11,         //"Band Class 6" (2-GMHz IMT2000 Band)
+    BAND_MODE_7_700M_2 = 12,        //"Band Class 7" (Upper 700-MHz Band)
+    BAND_MODE_8_1800M = 13,         //"Band Class 8" (1800-MHz Band)
+    BAND_MODE_9_900M = 14,          //"Band Class 9" (900-MHz Band)
+    BAND_MODE_10_800M_2 = 15,       //"Band Class 10" (Secondary 800-MHz Band)
+    BAND_MODE_EURO_PAMR_400M = 16,  //"Band Class 11" (400-MHz European PAMR Band)
+    BAND_MODE_AWS = 17,             //"Band Class 15" (AWS Band)
+    BAND_MODE_USA_2500M = 18        //"Band Class 16" (US 2.5-GHz Band)
+} RIL_RadioBandMode;
+
+typedef enum {
+    RC_PHASE_CONFIGURED = 0,  // LM is configured is initial value and value after FINISH completes
+    RC_PHASE_START      = 1,  // START is sent before Apply and indicates that an APPLY will be
+                              // forthcoming with these same parameters
+    RC_PHASE_APPLY      = 2,  // APPLY is sent after all LM's receive START and returned
+                              // RIL_RadioCapability.status = 0, if any START's fail no
+                              // APPLY will be sent
+    RC_PHASE_UNSOL_RSP  = 3,  // UNSOL_RSP is sent with RIL_UNSOL_RADIO_CAPABILITY
+    RC_PHASE_FINISH     = 4   // FINISH is sent after all commands have completed. If an error
+                              // occurs in any previous command the RIL_RadioAccessesFamily and
+                              // logicalModemUuid fields will be the prior configuration thus
+                              // restoring the configuration to the previous value. An error
+                              // returned by this command will generally be ignored or may
+                              // cause that logical modem to be removed from service.
+} RadioCapabilityPhase;
+
+typedef enum {
+    RC_STATUS_NONE       = 0, // This parameter has no meaning with RC_PHASE_START,
+                              // RC_PHASE_APPLY
+    RC_STATUS_SUCCESS    = 1, // Tell modem the action transaction of set radio
+                              // capability was success with RC_PHASE_FINISH
+    RC_STATUS_FAIL       = 2, // Tell modem the action transaction of set radio
+                              // capability is fail with RC_PHASE_FINISH.
+} RadioCapabilityStatus;
+
+#define RIL_RADIO_CAPABILITY_VERSION 1
+typedef struct {
+    int version;            // Version of structure, RIL_RADIO_CAPABILITY_VERSION
+    int session;            // Unique session value defined by framework returned in all "responses/unsol"
+    int phase;              // CONFIGURED, START, APPLY, FINISH
+    int rat;                // RIL_RadioAccessFamily for the radio
+    char logicalModemUuid[MAX_UUID_LENGTH]; // A UUID typically "com.xxxx.lmX where X is the logical modem.
+    int status;             // Return status and an input parameter for RC_PHASE_FINISH
+} RIL_RadioCapability;
+
+// Do we want to split Data from Voice and the use
+// RIL_RadioTechnology for get/setPreferredVoice/Data ?
+typedef enum {
+    PREF_NET_TYPE_GSM_WCDMA                = 0, /* GSM/WCDMA (WCDMA preferred) */
+    PREF_NET_TYPE_GSM_ONLY                 = 1, /* GSM only */
+    PREF_NET_TYPE_WCDMA                    = 2, /* WCDMA  */
+    PREF_NET_TYPE_GSM_WCDMA_AUTO           = 3, /* GSM/WCDMA (auto mode, according to PRL) */
+    PREF_NET_TYPE_CDMA_EVDO_AUTO           = 4, /* CDMA and EvDo (auto mode, according to PRL) */
+    PREF_NET_TYPE_CDMA_ONLY                = 5, /* CDMA only */
+    PREF_NET_TYPE_EVDO_ONLY                = 6, /* EvDo only */
+    PREF_NET_TYPE_GSM_WCDMA_CDMA_EVDO_AUTO = 7, /* GSM/WCDMA, CDMA, and EvDo (auto mode, according to PRL) */
+    PREF_NET_TYPE_LTE_CDMA_EVDO            = 8, /* LTE, CDMA and EvDo */
+    PREF_NET_TYPE_LTE_GSM_WCDMA            = 9, /* LTE, GSM/WCDMA */
+    PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA  = 10, /* LTE, CDMA, EvDo, GSM/WCDMA */
+    PREF_NET_TYPE_LTE_ONLY                 = 11, /* LTE only */
+    PREF_NET_TYPE_LTE_WCDMA                = 12,  /* LTE/WCDMA */
+    PREF_NET_TYPE_TD_SCDMA_ONLY            = 13, /* TD-SCDMA only */
+    PREF_NET_TYPE_TD_SCDMA_WCDMA           = 14, /* TD-SCDMA and WCDMA */
+    PREF_NET_TYPE_TD_SCDMA_LTE             = 15, /* TD-SCDMA and LTE */
+    PREF_NET_TYPE_TD_SCDMA_GSM             = 16, /* TD-SCDMA and GSM */
+    PREF_NET_TYPE_TD_SCDMA_GSM_LTE         = 17, /* TD-SCDMA,GSM and LTE */
+    PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA       = 18, /* TD-SCDMA, GSM/WCDMA */
+    PREF_NET_TYPE_TD_SCDMA_WCDMA_LTE       = 19, /* TD-SCDMA, WCDMA and LTE */
+    PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_LTE   = 20, /* TD-SCDMA, GSM/WCDMA and LTE */
+    PREF_NET_TYPE_TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO  = 21, /* TD-SCDMA, GSM/WCDMA, CDMA and EvDo */
+    PREF_NET_TYPE_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA   = 22  /* TD-SCDMA, LTE, CDMA, EvDo GSM/WCDMA */
+} RIL_PreferredNetworkType;
+
+/* Source for cdma subscription */
+typedef enum {
+   CDMA_SUBSCRIPTION_SOURCE_RUIM_SIM = 0,
+   CDMA_SUBSCRIPTION_SOURCE_NV = 1
+} RIL_CdmaSubscriptionSource;
+
+/* User-to-User signaling Info activation types derived from 3GPP 23.087 v8.0 */
+typedef enum {
+    RIL_UUS_TYPE1_IMPLICIT = 0,
+    RIL_UUS_TYPE1_REQUIRED = 1,
+    RIL_UUS_TYPE1_NOT_REQUIRED = 2,
+    RIL_UUS_TYPE2_REQUIRED = 3,
+    RIL_UUS_TYPE2_NOT_REQUIRED = 4,
+    RIL_UUS_TYPE3_REQUIRED = 5,
+    RIL_UUS_TYPE3_NOT_REQUIRED = 6
+} RIL_UUS_Type;
+
+/* User-to-User Signaling Information data coding schemes. Possible values for
+ * Octet 3 (Protocol Discriminator field) in the UUIE. The values have been
+ * specified in section 10.5.4.25 of 3GPP TS 24.008 */
+typedef enum {
+    RIL_UUS_DCS_USP = 0,          /* User specified protocol */
+    RIL_UUS_DCS_OSIHLP = 1,       /* OSI higher layer protocol */
+    RIL_UUS_DCS_X244 = 2,         /* X.244 */
+    RIL_UUS_DCS_RMCF = 3,         /* Reserved for system mangement
+                                     convergence function */
+    RIL_UUS_DCS_IA5c = 4          /* IA5 characters */
+} RIL_UUS_DCS;
+
+/* User-to-User Signaling Information defined in 3GPP 23.087 v8.0
+ * This data is passed in RIL_ExtensionRecord and rec contains this
+ * structure when type is RIL_UUS_INFO_EXT_REC */
+typedef struct {
+  RIL_UUS_Type    uusType;    /* UUS Type */
+  RIL_UUS_DCS     uusDcs;     /* UUS Data Coding Scheme */
+  int             uusLength;  /* Length of UUS Data */
+  char *          uusData;    /* UUS Data */
+} RIL_UUS_Info;
+
+/* CDMA Signal Information Record as defined in C.S0005 section 3.7.5.5 */
+typedef struct {
+  char isPresent;    /* non-zero if signal information record is present */
+  char signalType;   /* as defined 3.7.5.5-1 */
+  char alertPitch;   /* as defined 3.7.5.5-2 */
+  char signal;       /* as defined 3.7.5.5-3, 3.7.5.5-4 or 3.7.5.5-5 */
+} RIL_CDMA_SignalInfoRecord;
+
+typedef struct {
+    RIL_CallState   state;
+    int             index;      /* Connection Index for use with, eg, AT+CHLD */
+    int             toa;        /* type of address, eg 145 = intl */
+    char            isMpty;     /* nonzero if is mpty call */
+    char            isMT;       /* nonzero if call is mobile terminated */
+    char            als;        /* ALS line indicator if available
+                                   (0 = line 1) */
+    char            isVoice;    /* nonzero if this is is a voice call */
+    char            isVoicePrivacy;     /* nonzero if CDMA voice privacy mode is active */
+    char *          number;     /* Remote party number */
+    int             numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */
+    char *          name;       /* Remote party name */
+    int             namePresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone */
+    RIL_UUS_Info *  uusInfo;    /* NULL or Pointer to User-User Signaling Information */
+} RIL_Call;
+
+/* Deprecated, use RIL_Data_Call_Response_v6 */
+typedef struct {
+    int             cid;        /* Context ID, uniquely identifies this call */
+    int             active;     /* 0=inactive, 1=active/physical link down, 2=active/physical link up */
+    char *          type;       /* One of the PDP_type values in TS 27.007 section 10.1.1.
+                                   For example, "IP", "IPV6", "IPV4V6", or "PPP". */
+    char *          apn;        /* ignored */
+    char *          address;    /* An address, e.g., "192.0.1.3" or "2001:db8::1". */
+} RIL_Data_Call_Response_v4;
+
+/*
+ * Returned by RIL_REQUEST_SETUP_DATA_CALL, RIL_REQUEST_DATA_CALL_LIST
+ * and RIL_UNSOL_DATA_CALL_LIST_CHANGED, on error status != 0.
+ */
+typedef struct {
+    int             status;     /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */
+    int             suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry
+                                           back-off timer value RIL wants to override the one
+                                           pre-configured in FW.
+                                           The unit is miliseconds.
+                                           The value < 0 means no value is suggested.
+                                           The value 0 means retry should be done ASAP.
+                                           The value of INT_MAX(0x7fffffff) means no retry. */
+    int             cid;        /* Context ID, uniquely identifies this call */
+    int             active;     /* 0=inactive, 1=active/physical link down, 2=active/physical link up */
+    char *          type;       /* One of the PDP_type values in TS 27.007 section 10.1.1.
+                                   For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is
+                                   PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported
+                                   such as "IP" or "IPV6" */
+    char *          ifname;     /* The network interface name */
+    char *          addresses;  /* A space-delimited list of addresses with optional "/" prefix length,
+                                   e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64".
+                                   May not be empty, typically 1 IPv4 or 1 IPv6 or
+                                   one of each. If the prefix length is absent the addresses
+                                   are assumed to be point to point with IPv4 having a prefix
+                                   length of 32 and IPv6 128. */
+    char *          dnses;      /* A space-delimited list of DNS server addresses,
+                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+                                   May be empty. */
+    char *          gateways;   /* A space-delimited list of default gateway addresses,
+                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+                                   May be empty in which case the addresses represent point
+                                   to point connections. */
+} RIL_Data_Call_Response_v6;
+
+typedef struct {
+    int             status;     /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */
+    int             suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry
+                                           back-off timer value RIL wants to override the one
+                                           pre-configured in FW.
+                                           The unit is miliseconds.
+                                           The value < 0 means no value is suggested.
+                                           The value 0 means retry should be done ASAP.
+                                           The value of INT_MAX(0x7fffffff) means no retry. */
+    int             cid;        /* Context ID, uniquely identifies this call */
+    int             active;     /* 0=inactive, 1=active/physical link down, 2=active/physical link up */
+    char *          type;       /* One of the PDP_type values in TS 27.007 section 10.1.1.
+                                   For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is
+                                   PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported
+                                   such as "IP" or "IPV6" */
+    char *          ifname;     /* The network interface name */
+    char *          addresses;  /* A space-delimited list of addresses with optional "/" prefix length,
+                                   e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64".
+                                   May not be empty, typically 1 IPv4 or 1 IPv6 or
+                                   one of each. If the prefix length is absent the addresses
+                                   are assumed to be point to point with IPv4 having a prefix
+                                   length of 32 and IPv6 128. */
+    char *          dnses;      /* A space-delimited list of DNS server addresses,
+                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+                                   May be empty. */
+    char *          gateways;   /* A space-delimited list of default gateway addresses,
+                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+                                   May be empty in which case the addresses represent point
+                                   to point connections. */
+    char *          pcscf;    /* the Proxy Call State Control Function address
+                                 via PCO(Protocol Configuration Option) for IMS client. */
+} RIL_Data_Call_Response_v9;
+
+typedef struct {
+    int             status;     /* A RIL_DataCallFailCause, 0 which is PDP_FAIL_NONE if no error */
+    int             suggestedRetryTime; /* If status != 0, this fields indicates the suggested retry
+                                           back-off timer value RIL wants to override the one
+                                           pre-configured in FW.
+                                           The unit is miliseconds.
+                                           The value < 0 means no value is suggested.
+                                           The value 0 means retry should be done ASAP.
+                                           The value of INT_MAX(0x7fffffff) means no retry. */
+    int             cid;        /* Context ID, uniquely identifies this call */
+    int             active;     /* 0=inactive, 1=active/physical link down, 2=active/physical link up */
+    char *          type;       /* One of the PDP_type values in TS 27.007 section 10.1.1.
+                                   For example, "IP", "IPV6", "IPV4V6", or "PPP". If status is
+                                   PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED this is the type supported
+                                   such as "IP" or "IPV6" */
+    char *          ifname;     /* The network interface name */
+    char *          addresses;  /* A space-delimited list of addresses with optional "/" prefix length,
+                                   e.g., "192.0.1.3" or "192.0.1.11/16 2001:db8::1/64".
+                                   May not be empty, typically 1 IPv4 or 1 IPv6 or
+                                   one of each. If the prefix length is absent the addresses
+                                   are assumed to be point to point with IPv4 having a prefix
+                                   length of 32 and IPv6 128. */
+    char *          dnses;      /* A space-delimited list of DNS server addresses,
+                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+                                   May be empty. */
+    char *          gateways;   /* A space-delimited list of default gateway addresses,
+                                   e.g., "192.0.1.3" or "192.0.1.11 2001:db8::1".
+                                   May be empty in which case the addresses represent point
+                                   to point connections. */
+    char *          pcscf;    /* the Proxy Call State Control Function address
+                                 via PCO(Protocol Configuration Option) for IMS client. */
+    int             mtu;        /* MTU received from network
+                                   Value <= 0 means network has either not sent a value or
+                                   sent an invalid value */
+} RIL_Data_Call_Response_v11;
+
+typedef enum {
+    RADIO_TECH_3GPP = 1, /* 3GPP Technologies - GSM, WCDMA */
+    RADIO_TECH_3GPP2 = 2 /* 3GPP2 Technologies - CDMA */
+} RIL_RadioTechnologyFamily;
+
+typedef struct {
+    RIL_RadioTechnologyFamily tech;
+    unsigned char             retry;       /* 0 == not retry, nonzero == retry */
+    int                       messageRef;  /* Valid field if retry is set to nonzero.
+                                              Contains messageRef from RIL_SMS_Response
+                                              corresponding to failed MO SMS.
+                                            */
+
+    union {
+        /* Valid field if tech is RADIO_TECH_3GPP2. See RIL_REQUEST_CDMA_SEND_SMS */
+        RIL_CDMA_SMS_Message* cdmaMessage;
+
+        /* Valid field if tech is RADIO_TECH_3GPP. See RIL_REQUEST_SEND_SMS */
+        char**                gsmMessage;   /* This is an array of pointers where pointers
+                                               are contiguous but elements pointed by those pointers
+                                               are not contiguous
+                                            */
+    } message;
+} RIL_IMS_SMS_Message;
+
+typedef struct {
+    int messageRef;   /* TP-Message-Reference for GSM,
+                         and BearerData MessageId for CDMA
+                         (See 3GPP2 C.S0015-B, v2.0, table 4.5-1). */
+    char *ackPDU;     /* or NULL if n/a */
+    int errorCode;    /* See 3GPP 27.005, 3.2.5 for GSM/UMTS,
+                         3GPP2 N.S0005 (IS-41C) Table 171 for CDMA,
+                         -1 if unknown or not applicable*/
+} RIL_SMS_Response;
+
+/** Used by RIL_REQUEST_WRITE_SMS_TO_SIM */
+typedef struct {
+    int status;     /* Status of message.  See TS 27.005 3.1, "<stat>": */
+                    /*      0 = "REC UNREAD"    */
+                    /*      1 = "REC READ"      */
+                    /*      2 = "STO UNSENT"    */
+                    /*      3 = "STO SENT"      */
+    char * pdu;     /* PDU of message to write, as an ASCII hex string less the SMSC address,
+                       the TP-layer length is "strlen(pdu)/2". */
+    char * smsc;    /* SMSC address in GSM BCD format prefixed by a length byte
+                       (as expected by TS 27.005) or NULL for default SMSC */
+} RIL_SMS_WriteArgs;
+
+/** Used by RIL_REQUEST_DIAL */
+typedef struct {
+    char * address;
+    int clir;
+            /* (same as 'n' paremeter in TS 27.007 7.7 "+CLIR"
+             * clir == 0 on "use subscription default value"
+             * clir == 1 on "CLIR invocation" (restrict CLI presentation)
+             * clir == 2 on "CLIR suppression" (allow CLI presentation)
+             */
+    RIL_UUS_Info *  uusInfo;    /* NULL or Pointer to User-User Signaling Information */
+} RIL_Dial;
+
+typedef struct {
+    int command;    /* one of the commands listed for TS 27.007 +CRSM*/
+    int fileid;     /* EF id */
+    char *path;     /* "pathid" from TS 27.007 +CRSM command.
+                       Path is in hex asciii format eg "7f205f70"
+                       Path must always be provided.
+                     */
+    int p1;
+    int p2;
+    int p3;
+    char *data;     /* May be NULL*/
+    char *pin2;     /* May be NULL*/
+} RIL_SIM_IO_v5;
+
+typedef struct {
+    int command;    /* one of the commands listed for TS 27.007 +CRSM*/
+    int fileid;     /* EF id */
+    char *path;     /* "pathid" from TS 27.007 +CRSM command.
+                       Path is in hex asciii format eg "7f205f70"
+                       Path must always be provided.
+                     */
+    int p1;
+    int p2;
+    int p3;
+    char *data;     /* May be NULL*/
+    char *pin2;     /* May be NULL*/
+    char *aidPtr;   /* AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value. */
+} RIL_SIM_IO_v6;
+
+/* Used by RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL and
+ * RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC. */
+typedef struct {
+    int sessionid;  /* "sessionid" from TS 27.007 +CGLA command. Should be
+                       ignored for +CSIM command. */
+
+    /* Following fields are used to derive the APDU ("command" and "length"
+       values in TS 27.007 +CSIM and +CGLA commands). */
+    int cla;
+    int instruction;
+    int p1;
+    int p2;
+    int p3;         /* A negative P3 implies a 4 byte APDU. */
+    char *data;     /* May be NULL. In hex string format. */
+} RIL_SIM_APDU;
+
+typedef struct {
+    int sw1;
+    int sw2;
+    char *simResponse;  /* In hex string format ([a-fA-F0-9]*), except for SIM_AUTHENTICATION
+                           response for which it is in Base64 format, see 3GPP TS 31.102 7.1.2 */
+} RIL_SIM_IO_Response;
+
+/* See also com.android.internal.telephony.gsm.CallForwardInfo */
+
+typedef struct {
+    int             status;     /*
+                                 * For RIL_REQUEST_QUERY_CALL_FORWARD_STATUS
+                                 * status 1 = active, 0 = not active
+                                 *
+                                 * For RIL_REQUEST_SET_CALL_FORWARD:
+                                 * status is:
+                                 * 0 = disable
+                                 * 1 = enable
+                                 * 2 = interrogate
+                                 * 3 = registeration
+                                 * 4 = erasure
+                                 */
+
+    int             reason;      /* from TS 27.007 7.11 "reason" */
+    int             serviceClass;/* From 27.007 +CCFC/+CLCK "class"
+                                    See table for Android mapping from
+                                    MMI service code
+                                    0 means user doesn't input class */
+    int             toa;         /* "type" from TS 27.007 7.11 */
+    char *          number;      /* "number" from TS 27.007 7.11. May be NULL */
+    int             timeSeconds; /* for CF no reply only */
+}RIL_CallForwardInfo;
+
+typedef struct {
+   char * cid;         /* Combination of LAC and Cell Id in 32 bits in GSM.
+                        * Upper 16 bits is LAC and lower 16 bits
+                        * is CID (as described in TS 27.005)
+                        * Primary Scrambling Code (as described in TS 25.331)
+                        *         in 9 bits in UMTS
+                        * Valid values are hexadecimal 0x0000 - 0xffffffff.
+                        */
+   int    rssi;        /* Received RSSI in GSM,
+                        * Level index of CPICH Received Signal Code Power in UMTS
+                        */
+} RIL_NeighboringCell;
+
+typedef struct {
+  char lce_status;                 /* LCE service status:
+                                    * -1 = not supported;
+                                    * 0 = stopped;
+                                    * 1 = active.
+                                    */
+  unsigned int actual_interval_ms; /* actual LCE reporting interval,
+                                    * meaningful only if LCEStatus = 1.
+                                    */
+} RIL_LceStatusInfo;
+
+typedef struct {
+  unsigned int last_hop_capacity_kbps; /* last-hop cellular capacity: kilobits/second. */
+  unsigned char confidence_level;      /* capacity estimate confidence: 0-100 */
+  unsigned char lce_suspended;         /* LCE report going to be suspended? (e.g., radio
+                                        * moves to inactive state or network type change)
+                                        * 1 = suspended;
+                                        * 0 = not suspended.
+                                        */
+} RIL_LceDataInfo;
+
+typedef enum {
+    RIL_MATCH_ALL = 0,          /* Apply to all carriers with the same mcc/mnc */
+    RIL_MATCH_SPN = 1,          /* Use SPN and mcc/mnc to identify the carrier */
+    RIL_MATCH_IMSI_PREFIX = 2,  /* Use IMSI prefix and mcc/mnc to identify the carrier */
+    RIL_MATCH_GID1 = 3,         /* Use GID1 and mcc/mnc to identify the carrier */
+    RIL_MATCH_GID2 = 4,         /* Use GID2 and mcc/mnc to identify the carrier */
+} RIL_CarrierMatchType;
+
+typedef struct {
+    const char * mcc;
+    const char * mnc;
+    RIL_CarrierMatchType match_type;   /* Specify match type for the carrier.
+                                        * If it’s RIL_MATCH_ALL, match_data is null;
+                                        * otherwise, match_data is the value for the match type.
+                                        */
+    const char * match_data;
+} RIL_Carrier;
+
+typedef struct {
+  int32_t len_allowed_carriers;         /* length of array allowed_carriers */
+  int32_t len_excluded_carriers;        /* length of array excluded_carriers */
+  RIL_Carrier * allowed_carriers;       /* whitelist for allowed carriers */
+  RIL_Carrier * excluded_carriers;      /* blacklist for explicitly excluded carriers
+                                         * which match allowed_carriers. Eg. allowed_carriers match
+                                         * mcc/mnc, excluded_carriers has same mcc/mnc and gid1
+                                         * is ABCD. It means except the carrier whose gid1 is ABCD,
+                                         * all carriers with the same mcc/mnc are allowed.
+                                         */
+} RIL_CarrierRestrictions;
+
+typedef enum {
+    NO_MULTISIM_POLICY = 0,             /* configuration applies to each slot independently. */
+    ONE_VALID_SIM_MUST_BE_PRESENT = 1,  /* Any SIM card can be used as far as one valid card is
+                                         * present in the device.
+                                         */
+} RIL_SimLockMultiSimPolicy;
+
+typedef struct {
+  int32_t len_allowed_carriers;         /* length of array allowed_carriers */
+  int32_t len_excluded_carriers;        /* length of array excluded_carriers */
+  RIL_Carrier * allowed_carriers;       /* whitelist for allowed carriers */
+  RIL_Carrier * excluded_carriers;      /* blacklist for explicitly excluded carriers
+                                         * which match allowed_carriers. Eg. allowed_carriers match
+                                         * mcc/mnc, excluded_carriers has same mcc/mnc and gid1
+                                         * is ABCD. It means except the carrier whose gid1 is ABCD,
+                                         * all carriers with the same mcc/mnc are allowed.
+                                         */
+  int allowedCarriersPrioritized;       /* allowed list prioritized */
+  RIL_SimLockMultiSimPolicy multiSimPolicy; /* multisim policy */
+} RIL_CarrierRestrictionsWithPriority;
+
+typedef struct {
+  char * mcc;                         /* MCC of the Carrier. */
+  char * mnc ;                        /* MNC of the Carrier. */
+  uint8_t * carrierKey;               /* Public Key from the Carrier used to encrypt the
+                                       * IMSI/IMPI.
+                                       */
+  int32_t carrierKeyLength;            /* Length of the Public Key. */
+  char * keyIdentifier;               /* The keyIdentifier Attribute value pair that helps
+                                       * a server locate the private key to decrypt the
+                                       * permanent identity.
+                                       */
+  int64_t expirationTime;             /* Date-Time (in UTC) when the key will expire. */
+
+} RIL_CarrierInfoForImsiEncryption;
+
+/* See RIL_REQUEST_LAST_CALL_FAIL_CAUSE */
+typedef enum {
+    CALL_FAIL_UNOBTAINABLE_NUMBER = 1,
+    CALL_FAIL_NO_ROUTE_TO_DESTINATION = 3,
+    CALL_FAIL_CHANNEL_UNACCEPTABLE = 6,
+    CALL_FAIL_OPERATOR_DETERMINED_BARRING = 8,
+    CALL_FAIL_NORMAL = 16,
+    CALL_FAIL_BUSY = 17,
+    CALL_FAIL_NO_USER_RESPONDING = 18,
+    CALL_FAIL_NO_ANSWER_FROM_USER = 19,
+    CALL_FAIL_CALL_REJECTED = 21,
+    CALL_FAIL_NUMBER_CHANGED = 22,
+    CALL_FAIL_PREEMPTION = 25,
+    CALL_FAIL_DESTINATION_OUT_OF_ORDER = 27,
+    CALL_FAIL_INVALID_NUMBER_FORMAT = 28,
+    CALL_FAIL_FACILITY_REJECTED = 29,
+    CALL_FAIL_RESP_TO_STATUS_ENQUIRY = 30,
+    CALL_FAIL_NORMAL_UNSPECIFIED = 31,
+    CALL_FAIL_CONGESTION = 34,
+    CALL_FAIL_NETWORK_OUT_OF_ORDER = 38,
+    CALL_FAIL_TEMPORARY_FAILURE = 41,
+    CALL_FAIL_SWITCHING_EQUIPMENT_CONGESTION = 42,
+    CALL_FAIL_ACCESS_INFORMATION_DISCARDED = 43,
+    CALL_FAIL_REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE = 44,
+    CALL_FAIL_RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47,
+    CALL_FAIL_QOS_UNAVAILABLE = 49,
+    CALL_FAIL_REQUESTED_FACILITY_NOT_SUBSCRIBED = 50,
+    CALL_FAIL_INCOMING_CALLS_BARRED_WITHIN_CUG = 55,
+    CALL_FAIL_BEARER_CAPABILITY_NOT_AUTHORIZED = 57,
+    CALL_FAIL_BEARER_CAPABILITY_UNAVAILABLE = 58,
+    CALL_FAIL_SERVICE_OPTION_NOT_AVAILABLE = 63,
+    CALL_FAIL_BEARER_SERVICE_NOT_IMPLEMENTED = 65,
+    CALL_FAIL_ACM_LIMIT_EXCEEDED = 68,
+    CALL_FAIL_REQUESTED_FACILITY_NOT_IMPLEMENTED = 69,
+    CALL_FAIL_ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70,
+    CALL_FAIL_SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79,
+    CALL_FAIL_INVALID_TRANSACTION_IDENTIFIER = 81,
+    CALL_FAIL_USER_NOT_MEMBER_OF_CUG = 87,
+    CALL_FAIL_INCOMPATIBLE_DESTINATION = 88,
+    CALL_FAIL_INVALID_TRANSIT_NW_SELECTION = 91,
+    CALL_FAIL_SEMANTICALLY_INCORRECT_MESSAGE = 95,
+    CALL_FAIL_INVALID_MANDATORY_INFORMATION = 96,
+    CALL_FAIL_MESSAGE_TYPE_NON_IMPLEMENTED = 97,
+    CALL_FAIL_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98,
+    CALL_FAIL_INFORMATION_ELEMENT_NON_EXISTENT = 99,
+    CALL_FAIL_CONDITIONAL_IE_ERROR = 100,
+    CALL_FAIL_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101,
+    CALL_FAIL_RECOVERY_ON_TIMER_EXPIRED = 102,
+    CALL_FAIL_PROTOCOL_ERROR_UNSPECIFIED = 111,
+    CALL_FAIL_INTERWORKING_UNSPECIFIED = 127,
+    CALL_FAIL_CALL_BARRED = 240,
+    CALL_FAIL_FDN_BLOCKED = 241,
+    CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242,
+    CALL_FAIL_IMEI_NOT_ACCEPTED = 243,
+    CALL_FAIL_DIAL_MODIFIED_TO_USSD = 244, /* STK Call Control */
+    CALL_FAIL_DIAL_MODIFIED_TO_SS = 245,
+    CALL_FAIL_DIAL_MODIFIED_TO_DIAL = 246,
+    CALL_FAIL_RADIO_OFF = 247, /* Radio is OFF */
+    CALL_FAIL_OUT_OF_SERVICE = 248, /* No cellular coverage */
+    CALL_FAIL_NO_VALID_SIM = 249, /* No valid SIM is present */
+    CALL_FAIL_RADIO_INTERNAL_ERROR = 250, /* Internal error at Modem */
+    CALL_FAIL_NETWORK_RESP_TIMEOUT = 251, /* No response from network */
+    CALL_FAIL_NETWORK_REJECT = 252, /* Explicit network reject */
+    CALL_FAIL_RADIO_ACCESS_FAILURE = 253, /* RRC connection failure. Eg.RACH */
+    CALL_FAIL_RADIO_LINK_FAILURE = 254, /* Radio Link Failure */
+    CALL_FAIL_RADIO_LINK_LOST = 255, /* Radio link lost due to poor coverage */
+    CALL_FAIL_RADIO_UPLINK_FAILURE = 256, /* Radio uplink failure */
+    CALL_FAIL_RADIO_SETUP_FAILURE = 257, /* RRC connection setup failure */
+    CALL_FAIL_RADIO_RELEASE_NORMAL = 258, /* RRC connection release, normal */
+    CALL_FAIL_RADIO_RELEASE_ABNORMAL = 259, /* RRC connection release, abnormal */
+    CALL_FAIL_ACCESS_CLASS_BLOCKED = 260, /* Access class barring */
+    CALL_FAIL_NETWORK_DETACH = 261, /* Explicit network detach */
+    CALL_FAIL_CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000,
+    CALL_FAIL_CDMA_DROP = 1001,
+    CALL_FAIL_CDMA_INTERCEPT = 1002,
+    CALL_FAIL_CDMA_REORDER = 1003,
+    CALL_FAIL_CDMA_SO_REJECT = 1004,
+    CALL_FAIL_CDMA_RETRY_ORDER = 1005,
+    CALL_FAIL_CDMA_ACCESS_FAILURE = 1006,
+    CALL_FAIL_CDMA_PREEMPTED = 1007,
+    CALL_FAIL_CDMA_NOT_EMERGENCY = 1008, /* For non-emergency number dialed
+                                            during emergency callback mode */
+    CALL_FAIL_CDMA_ACCESS_BLOCKED = 1009, /* CDMA network access probes blocked */
+
+    /* OEM specific error codes. Used to distinguish error from
+     * CALL_FAIL_ERROR_UNSPECIFIED and help assist debugging */
+    CALL_FAIL_OEM_CAUSE_1 = 0xf001,
+    CALL_FAIL_OEM_CAUSE_2 = 0xf002,
+    CALL_FAIL_OEM_CAUSE_3 = 0xf003,
+    CALL_FAIL_OEM_CAUSE_4 = 0xf004,
+    CALL_FAIL_OEM_CAUSE_5 = 0xf005,
+    CALL_FAIL_OEM_CAUSE_6 = 0xf006,
+    CALL_FAIL_OEM_CAUSE_7 = 0xf007,
+    CALL_FAIL_OEM_CAUSE_8 = 0xf008,
+    CALL_FAIL_OEM_CAUSE_9 = 0xf009,
+    CALL_FAIL_OEM_CAUSE_10 = 0xf00a,
+    CALL_FAIL_OEM_CAUSE_11 = 0xf00b,
+    CALL_FAIL_OEM_CAUSE_12 = 0xf00c,
+    CALL_FAIL_OEM_CAUSE_13 = 0xf00d,
+    CALL_FAIL_OEM_CAUSE_14 = 0xf00e,
+    CALL_FAIL_OEM_CAUSE_15 = 0xf00f,
+
+    CALL_FAIL_ERROR_UNSPECIFIED = 0xffff /* This error will be deprecated soon,
+                                            vendor code should make sure to map error
+                                            code to specific error */
+} RIL_LastCallFailCause;
+
+typedef struct {
+  RIL_LastCallFailCause cause_code;
+  char *                vendor_cause;
+} RIL_LastCallFailCauseInfo;
+
+/* See RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE */
+typedef enum {
+    PDP_FAIL_NONE = 0, /* No error, connection ok */
+
+    /* an integer cause code defined in TS 24.008
+       section 6.1.3.1.3 or TS 24.301 Release 8+ Annex B.
+       If the implementation does not have access to the exact cause codes,
+       then it should return one of the following values,
+       as the UI layer needs to distinguish these
+       cases for error notification and potential retries. */
+    PDP_FAIL_OPERATOR_BARRED = 0x08,               /* no retry */
+    PDP_FAIL_NAS_SIGNALLING = 0x0E,
+    PDP_FAIL_LLC_SNDCP = 0x19,
+    PDP_FAIL_INSUFFICIENT_RESOURCES = 0x1A,
+    PDP_FAIL_MISSING_UKNOWN_APN = 0x1B,            /* no retry */
+    PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C,      /* no retry */
+    PDP_FAIL_USER_AUTHENTICATION = 0x1D,           /* no retry */
+    PDP_FAIL_ACTIVATION_REJECT_GGSN = 0x1E,        /* no retry */
+    PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F,
+    PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20,  /* no retry */
+    PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21, /* no retry */
+    PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22,
+    PDP_FAIL_NSAPI_IN_USE = 0x23,                  /* no retry */
+    PDP_FAIL_REGULAR_DEACTIVATION = 0x24,          /* possibly restart radio,
+                                                      based on framework config */
+    PDP_FAIL_QOS_NOT_ACCEPTED = 0x25,
+    PDP_FAIL_NETWORK_FAILURE = 0x26,
+    PDP_FAIL_UMTS_REACTIVATION_REQ = 0x27,
+    PDP_FAIL_FEATURE_NOT_SUPP = 0x28,
+    PDP_FAIL_TFT_SEMANTIC_ERROR = 0x29,
+    PDP_FAIL_TFT_SYTAX_ERROR = 0x2A,
+    PDP_FAIL_UNKNOWN_PDP_CONTEXT = 0x2B,
+    PDP_FAIL_FILTER_SEMANTIC_ERROR = 0x2C,
+    PDP_FAIL_FILTER_SYTAX_ERROR = 0x2D,
+    PDP_FAIL_PDP_WITHOUT_ACTIVE_TFT = 0x2E,
+    PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32,             /* no retry */
+    PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33,             /* no retry */
+    PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34,
+    PDP_FAIL_ESM_INFO_NOT_RECEIVED = 0x35,
+    PDP_FAIL_PDN_CONN_DOES_NOT_EXIST = 0x36,
+    PDP_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37,
+    PDP_FAIL_MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41,
+    PDP_FAIL_UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42,
+    PDP_FAIL_INVALID_TRANSACTION_ID = 0x51,
+    PDP_FAIL_MESSAGE_INCORRECT_SEMANTIC = 0x5F,
+    PDP_FAIL_INVALID_MANDATORY_INFO = 0x60,
+    PDP_FAIL_MESSAGE_TYPE_UNSUPPORTED = 0x61,
+    PDP_FAIL_MSG_TYPE_NONCOMPATIBLE_STATE = 0x62,
+    PDP_FAIL_UNKNOWN_INFO_ELEMENT = 0x63,
+    PDP_FAIL_CONDITIONAL_IE_ERROR = 0x64,
+    PDP_FAIL_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65,
+    PDP_FAIL_PROTOCOL_ERRORS = 0x6F,             /* no retry */
+    PDP_FAIL_APN_TYPE_CONFLICT = 0x70,
+    PDP_FAIL_INVALID_PCSCF_ADDR = 0x71,
+    PDP_FAIL_INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72,
+    PDP_FAIL_EMM_ACCESS_BARRED = 0x73,
+    PDP_FAIL_EMERGENCY_IFACE_ONLY = 0x74,
+    PDP_FAIL_IFACE_MISMATCH = 0x75,
+    PDP_FAIL_COMPANION_IFACE_IN_USE = 0x76,
+    PDP_FAIL_IP_ADDRESS_MISMATCH = 0x77,
+    PDP_FAIL_IFACE_AND_POL_FAMILY_MISMATCH = 0x78,
+    PDP_FAIL_EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79,
+    PDP_FAIL_AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A,
+
+    // OEM specific error codes. To be used by OEMs when they don't want to
+    // reveal error code which would be replaced by PDP_FAIL_ERROR_UNSPECIFIED
+    PDP_FAIL_OEM_DCFAILCAUSE_1 = 0x1001,
+    PDP_FAIL_OEM_DCFAILCAUSE_2 = 0x1002,
+    PDP_FAIL_OEM_DCFAILCAUSE_3 = 0x1003,
+    PDP_FAIL_OEM_DCFAILCAUSE_4 = 0x1004,
+    PDP_FAIL_OEM_DCFAILCAUSE_5 = 0x1005,
+    PDP_FAIL_OEM_DCFAILCAUSE_6 = 0x1006,
+    PDP_FAIL_OEM_DCFAILCAUSE_7 = 0x1007,
+    PDP_FAIL_OEM_DCFAILCAUSE_8 = 0x1008,
+    PDP_FAIL_OEM_DCFAILCAUSE_9 = 0x1009,
+    PDP_FAIL_OEM_DCFAILCAUSE_10 = 0x100A,
+    PDP_FAIL_OEM_DCFAILCAUSE_11 = 0x100B,
+    PDP_FAIL_OEM_DCFAILCAUSE_12 = 0x100C,
+    PDP_FAIL_OEM_DCFAILCAUSE_13 = 0x100D,
+    PDP_FAIL_OEM_DCFAILCAUSE_14 = 0x100E,
+    PDP_FAIL_OEM_DCFAILCAUSE_15 = 0x100F,
+
+    /* Not mentioned in the specification */
+    PDP_FAIL_VOICE_REGISTRATION_FAIL = -1,
+    PDP_FAIL_DATA_REGISTRATION_FAIL = -2,
+
+   /* reasons for data call drop - network/modem disconnect */
+    PDP_FAIL_SIGNAL_LOST = -3,
+    PDP_FAIL_PREF_RADIO_TECH_CHANGED = -4,/* preferred technology has changed, should retry
+                                             with parameters appropriate for new technology */
+    PDP_FAIL_RADIO_POWER_OFF = -5,        /* data call was disconnected because radio was resetting,
+                                             powered off - no retry */
+    PDP_FAIL_TETHERED_CALL_ACTIVE = -6,   /* data call was disconnected by modem because tethered
+                                             mode was up on same APN/data profile - no retry until
+                                             tethered call is off */
+
+    PDP_FAIL_ERROR_UNSPECIFIED = 0xffff,  /* retry silently. Will be deprecated soon as
+                                             new error codes are added making this unnecessary */
+} RIL_DataCallFailCause;
+
+/* See RIL_REQUEST_SETUP_DATA_CALL */
+typedef enum {
+    RIL_DATA_PROFILE_DEFAULT    = 0,
+    RIL_DATA_PROFILE_TETHERED   = 1,
+    RIL_DATA_PROFILE_IMS        = 2,
+    RIL_DATA_PROFILE_FOTA       = 3,
+    RIL_DATA_PROFILE_CBS        = 4,
+    RIL_DATA_PROFILE_OEM_BASE   = 1000,    /* Start of OEM-specific profiles */
+    RIL_DATA_PROFILE_INVALID    = 0xFFFFFFFF
+} RIL_DataProfile;
+
+/* Used by RIL_UNSOL_SUPP_SVC_NOTIFICATION */
+typedef struct {
+    int     notificationType;   /*
+                                 * 0 = MO intermediate result code
+                                 * 1 = MT unsolicited result code
+                                 */
+    int     code;               /* See 27.007 7.17
+                                   "code1" for MO
+                                   "code2" for MT. */
+    int     index;              /* CUG index. See 27.007 7.17. */
+    int     type;               /* "type" from 27.007 7.17 (MT only). */
+    char *  number;             /* "number" from 27.007 7.17
+                                   (MT only, may be NULL). */
+} RIL_SuppSvcNotification;
+
+#define RIL_CARD_MAX_APPS     8
+
+typedef enum {
+    RIL_CARDSTATE_ABSENT     = 0,
+    RIL_CARDSTATE_PRESENT    = 1,
+    RIL_CARDSTATE_ERROR      = 2,
+    RIL_CARDSTATE_RESTRICTED = 3  /* card is present but not usable due to carrier restrictions.*/
+} RIL_CardState;
+
+typedef enum {
+    RIL_PERSOSUBSTATE_UNKNOWN                   = 0, /* initial state */
+    RIL_PERSOSUBSTATE_IN_PROGRESS               = 1, /* in between each lock transition */
+    RIL_PERSOSUBSTATE_READY                     = 2, /* when either SIM or RUIM Perso is finished
+                                                        since each app can only have 1 active perso
+                                                        involved */
+    RIL_PERSOSUBSTATE_SIM_NETWORK               = 3,
+    RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET        = 4,
+    RIL_PERSOSUBSTATE_SIM_CORPORATE             = 5,
+    RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER      = 6,
+    RIL_PERSOSUBSTATE_SIM_SIM                   = 7,
+    RIL_PERSOSUBSTATE_SIM_NETWORK_PUK           = 8, /* The corresponding perso lock is blocked */
+    RIL_PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK    = 9,
+    RIL_PERSOSUBSTATE_SIM_CORPORATE_PUK         = 10,
+    RIL_PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK  = 11,
+    RIL_PERSOSUBSTATE_SIM_SIM_PUK               = 12,
+    RIL_PERSOSUBSTATE_RUIM_NETWORK1             = 13,
+    RIL_PERSOSUBSTATE_RUIM_NETWORK2             = 14,
+    RIL_PERSOSUBSTATE_RUIM_HRPD                 = 15,
+    RIL_PERSOSUBSTATE_RUIM_CORPORATE            = 16,
+    RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER     = 17,
+    RIL_PERSOSUBSTATE_RUIM_RUIM                 = 18,
+    RIL_PERSOSUBSTATE_RUIM_NETWORK1_PUK         = 19, /* The corresponding perso lock is blocked */
+    RIL_PERSOSUBSTATE_RUIM_NETWORK2_PUK         = 20,
+    RIL_PERSOSUBSTATE_RUIM_HRPD_PUK             = 21,
+    RIL_PERSOSUBSTATE_RUIM_CORPORATE_PUK        = 22,
+    RIL_PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK = 23,
+    RIL_PERSOSUBSTATE_RUIM_RUIM_PUK             = 24
+} RIL_PersoSubstate;
+
+typedef enum {
+    RIL_APPSTATE_UNKNOWN               = 0,
+    RIL_APPSTATE_DETECTED              = 1,
+    RIL_APPSTATE_PIN                   = 2, /* If PIN1 or UPin is required */
+    RIL_APPSTATE_PUK                   = 3, /* If PUK1 or Puk for UPin is required */
+    RIL_APPSTATE_SUBSCRIPTION_PERSO    = 4, /* perso_substate should be look at
+                                               when app_state is assigned to this value */
+    RIL_APPSTATE_READY                 = 5
+} RIL_AppState;
+
+typedef enum {
+    RIL_PINSTATE_UNKNOWN              = 0,
+    RIL_PINSTATE_ENABLED_NOT_VERIFIED = 1,
+    RIL_PINSTATE_ENABLED_VERIFIED     = 2,
+    RIL_PINSTATE_DISABLED             = 3,
+    RIL_PINSTATE_ENABLED_BLOCKED      = 4,
+    RIL_PINSTATE_ENABLED_PERM_BLOCKED = 5
+} RIL_PinState;
+
+typedef enum {
+  RIL_APPTYPE_UNKNOWN = 0,
+  RIL_APPTYPE_SIM     = 1,
+  RIL_APPTYPE_USIM    = 2,
+  RIL_APPTYPE_RUIM    = 3,
+  RIL_APPTYPE_CSIM    = 4,
+  RIL_APPTYPE_ISIM    = 5
+} RIL_AppType;
+
+/*
+ * Please note that registration state UNKNOWN is
+ * treated as "out of service" in the Android telephony.
+ * Registration state REG_DENIED must be returned if Location Update
+ * Reject (with cause 17 - Network Failure) is received
+ * repeatedly from the network, to facilitate
+ * "managed roaming"
+ */
+typedef enum {
+    RIL_NOT_REG_AND_NOT_SEARCHING = 0,           // Not registered, MT is not currently searching
+                                                 // a new operator to register
+    RIL_REG_HOME = 1,                            // Registered, home network
+    RIL_NOT_REG_AND_SEARCHING = 2,               // Not registered, but MT is currently searching
+                                                 // a new operator to register
+    RIL_REG_DENIED = 3,                          // Registration denied
+    RIL_UNKNOWN = 4,                             // Unknown
+    RIL_REG_ROAMING = 5,                         // Registered, roaming
+    RIL_NOT_REG_AND_EMERGENCY_AVAILABLE_AND_NOT_SEARCHING = 10,   // Same as
+                                                 // RIL_NOT_REG_AND_NOT_SEARCHING but indicates that
+                                                 // emergency calls are enabled.
+    RIL_NOT_REG_AND_EMERGENCY_AVAILABLE_AND_SEARCHING = 12,  // Same as RIL_NOT_REG_AND_SEARCHING
+                                                 // but indicates that
+                                                 // emergency calls are enabled.
+    RIL_REG_DENIED_AND_EMERGENCY_AVAILABLE = 13, // Same as REG_DENIED but indicates that
+                                                 // emergency calls are enabled.
+    RIL_UNKNOWN_AND_EMERGENCY_AVAILABLE = 14,    // Same as UNKNOWN but indicates that
+                                                 // emergency calls are enabled.
+} RIL_RegState;
+
+typedef struct
+{
+  RIL_AppType      app_type;
+  RIL_AppState     app_state;
+  RIL_PersoSubstate perso_substate; /* applicable only if app_state ==
+                                       RIL_APPSTATE_SUBSCRIPTION_PERSO */
+  char             *aid_ptr;        /* null terminated string, e.g., from 0xA0, 0x00 -> 0x41,
+                                       0x30, 0x30, 0x30 */
+  char             *app_label_ptr;  /* null terminated string */
+  int              pin1_replaced;   /* applicable to USIM, CSIM & ISIM */
+  RIL_PinState     pin1;
+  RIL_PinState     pin2;
+} RIL_AppStatus;
+
+/* Deprecated, use RIL_CardStatus_v6 */
+typedef struct
+{
+  RIL_CardState card_state;
+  RIL_PinState  universal_pin_state;             /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */
+  int           gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */
+  int           cdma_subscription_app_index;     /* value < RIL_CARD_MAX_APPS, -1 if none */
+  int           num_applications;                /* value <= RIL_CARD_MAX_APPS */
+  RIL_AppStatus applications[RIL_CARD_MAX_APPS];
+} RIL_CardStatus_v5;
+
+typedef struct
+{
+  RIL_CardState card_state;
+  RIL_PinState  universal_pin_state;             /* applicable to USIM and CSIM: RIL_PINSTATE_xxx */
+  int           gsm_umts_subscription_app_index; /* value < RIL_CARD_MAX_APPS, -1 if none */
+  int           cdma_subscription_app_index;     /* value < RIL_CARD_MAX_APPS, -1 if none */
+  int           ims_subscription_app_index;      /* value < RIL_CARD_MAX_APPS, -1 if none */
+  int           num_applications;                /* value <= RIL_CARD_MAX_APPS */
+  RIL_AppStatus applications[RIL_CARD_MAX_APPS];
+} RIL_CardStatus_v6;
+
+/** The result of a SIM refresh, returned in data[0] of RIL_UNSOL_SIM_REFRESH
+ *      or as part of RIL_SimRefreshResponse_v7
+ */
+typedef enum {
+    /* A file on SIM has been updated.  data[1] contains the EFID. */
+    SIM_FILE_UPDATE = 0,
+    /* SIM initialized.  All files should be re-read. */
+    SIM_INIT = 1,
+    /* SIM reset.  SIM power required, SIM may be locked and all files should be re-read. */
+    SIM_RESET = 2
+} RIL_SimRefreshResult;
+
+typedef struct {
+    RIL_SimRefreshResult result;
+    int                  ef_id; /* is the EFID of the updated file if the result is */
+                                /* SIM_FILE_UPDATE or 0 for any other result. */
+    char *               aid;   /* is AID(application ID) of the card application */
+                                /* See ETSI 102.221 8.1 and 101.220 4 */
+                                /*     For SIM_FILE_UPDATE result it can be set to AID of */
+                                /*         application in which updated EF resides or it can be */
+                                /*         NULL if EF is outside of an application. */
+                                /*     For SIM_INIT result this field is set to AID of */
+                                /*         application that caused REFRESH */
+                                /*     For SIM_RESET result it is NULL. */
+} RIL_SimRefreshResponse_v7;
+
+/* Deprecated, use RIL_CDMA_CallWaiting_v6 */
+typedef struct {
+    char *          number;             /* Remote party number */
+    int             numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */
+    char *          name;               /* Remote party name */
+    RIL_CDMA_SignalInfoRecord signalInfoRecord;
+} RIL_CDMA_CallWaiting_v5;
+
+typedef struct {
+    char *          number;             /* Remote party number */
+    int             numberPresentation; /* 0=Allowed, 1=Restricted, 2=Not Specified/Unknown */
+    char *          name;               /* Remote party name */
+    RIL_CDMA_SignalInfoRecord signalInfoRecord;
+    /* Number type/Number plan required to support International Call Waiting */
+    int             number_type;        /* 0=Unknown, 1=International, 2=National,
+                                           3=Network specific, 4=subscriber */
+    int             number_plan;        /* 0=Unknown, 1=ISDN, 3=Data, 4=Telex, 8=Nat'l, 9=Private */
+} RIL_CDMA_CallWaiting_v6;
+
+/**
+ * Which types of Cell Broadcast Message (CBM) are to be received by the ME
+ *
+ * uFromServiceID - uToServiceID defines a range of CBM message identifiers
+ * whose value is 0x0000 - 0xFFFF as defined in TS 23.041 9.4.1.2.2 for GMS
+ * and 9.4.4.2.2 for UMTS. All other values can be treated as empty
+ * CBM message ID.
+ *
+ * uFromCodeScheme - uToCodeScheme defines a range of CBM data coding schemes
+ * whose value is 0x00 - 0xFF as defined in TS 23.041 9.4.1.2.3 for GMS
+ * and 9.4.4.2.3 for UMTS.
+ * All other values can be treated as empty CBM data coding scheme.
+ *
+ * selected 0 means message types specified in <fromServiceId, toServiceId>
+ * and <fromCodeScheme, toCodeScheme>are not accepted, while 1 means accepted.
+ *
+ * Used by RIL_REQUEST_GSM_GET_BROADCAST_CONFIG and
+ * RIL_REQUEST_GSM_SET_BROADCAST_CONFIG.
+ */
+typedef struct {
+    int fromServiceId;
+    int toServiceId;
+    int fromCodeScheme;
+    int toCodeScheme;
+    unsigned char selected;
+} RIL_GSM_BroadcastSmsConfigInfo;
+
+/* No restriction at all including voice/SMS/USSD/SS/AV64 and packet data. */
+#define RIL_RESTRICTED_STATE_NONE           0x00
+/* Block emergency call due to restriction. But allow all normal voice/SMS/USSD/SS/AV64. */
+#define RIL_RESTRICTED_STATE_CS_EMERGENCY   0x01
+/* Block all normal voice/SMS/USSD/SS/AV64 due to restriction. Only Emergency call allowed. */
+#define RIL_RESTRICTED_STATE_CS_NORMAL      0x02
+/* Block all voice/SMS/USSD/SS/AV64 including emergency call due to restriction.*/
+#define RIL_RESTRICTED_STATE_CS_ALL         0x04
+/* Block packet data access due to restriction. */
+#define RIL_RESTRICTED_STATE_PS_ALL         0x10
+
+/* The status for an OTASP/OTAPA session */
+typedef enum {
+    CDMA_OTA_PROVISION_STATUS_SPL_UNLOCKED,
+    CDMA_OTA_PROVISION_STATUS_SPC_RETRIES_EXCEEDED,
+    CDMA_OTA_PROVISION_STATUS_A_KEY_EXCHANGED,
+    CDMA_OTA_PROVISION_STATUS_SSD_UPDATED,
+    CDMA_OTA_PROVISION_STATUS_NAM_DOWNLOADED,
+    CDMA_OTA_PROVISION_STATUS_MDN_DOWNLOADED,
+    CDMA_OTA_PROVISION_STATUS_IMSI_DOWNLOADED,
+    CDMA_OTA_PROVISION_STATUS_PRL_DOWNLOADED,
+    CDMA_OTA_PROVISION_STATUS_COMMITTED,
+    CDMA_OTA_PROVISION_STATUS_OTAPA_STARTED,
+    CDMA_OTA_PROVISION_STATUS_OTAPA_STOPPED,
+    CDMA_OTA_PROVISION_STATUS_OTAPA_ABORTED
+} RIL_CDMA_OTA_ProvisionStatus;
+
+typedef struct {
+    int signalStrength;  /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
+    int bitErrorRate;    /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */
+} RIL_GW_SignalStrength;
+
+typedef struct {
+    int signalStrength;  /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
+    int bitErrorRate;    /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */
+    int timingAdvance;   /* Timing Advance in bit periods. 1 bit period = 48/13 us.
+                          * INT_MAX denotes invalid value */
+} RIL_GSM_SignalStrength_v12;
+
+typedef struct {
+    int signalStrength;  /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
+    int bitErrorRate;    /* bit error rate (0-7, 99) as defined in TS 27.007 8.5 */
+} RIL_SignalStrengthWcdma;
+
+typedef struct {
+    int dbm;  /* Valid values are positive integers.  This value is the actual RSSI value
+               * multiplied by -1.  Example: If the actual RSSI is -75, then this response
+               * value will be 75.
+               */
+    int ecio; /* Valid values are positive integers.  This value is the actual Ec/Io multiplied
+               * by -10.  Example: If the actual Ec/Io is -12.5 dB, then this response value
+               * will be 125.
+               */
+} RIL_CDMA_SignalStrength;
+
+
+typedef struct {
+    int dbm;  /* Valid values are positive integers.  This value is the actual RSSI value
+               * multiplied by -1.  Example: If the actual RSSI is -75, then this response
+               * value will be 75.
+               */
+    int ecio; /* Valid values are positive integers.  This value is the actual Ec/Io multiplied
+               * by -10.  Example: If the actual Ec/Io is -12.5 dB, then this response value
+               * will be 125.
+               */
+    int signalNoiseRatio; /* Valid values are 0-8.  8 is the highest signal to noise ratio. */
+} RIL_EVDO_SignalStrength;
+
+typedef struct {
+    int signalStrength;  /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
+    int rsrp;            /* The current Reference Signal Receive Power in dBm multipled by -1.
+                          * Range: 44 to 140 dBm
+                          * INT_MAX: 0x7FFFFFFF denotes invalid value.
+                          * Reference: 3GPP TS 36.133 9.1.4 */
+    int rsrq;            /* The current Reference Signal Receive Quality in dB multiplied by -1.
+                          * Range: 20 to 3 dB.
+                          * INT_MAX: 0x7FFFFFFF denotes invalid value.
+                          * Reference: 3GPP TS 36.133 9.1.7 */
+    int rssnr;           /* The current reference signal signal-to-noise ratio in 0.1 dB units.
+                          * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB).
+                          * INT_MAX : 0x7FFFFFFF denotes invalid value.
+                          * Reference: 3GPP TS 36.101 8.1.1 */
+    int cqi;             /* The current Channel Quality Indicator.
+                          * Range: 0 to 15.
+                          * INT_MAX : 0x7FFFFFFF denotes invalid value.
+                          * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */
+} RIL_LTE_SignalStrength;
+
+typedef struct {
+    int signalStrength;  /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
+    int rsrp;            /* The current Reference Signal Receive Power in dBm multipled by -1.
+                          * Range: 44 to 140 dBm
+                          * INT_MAX: 0x7FFFFFFF denotes invalid value.
+                          * Reference: 3GPP TS 36.133 9.1.4 */
+    int rsrq;            /* The current Reference Signal Receive Quality in dB multiplied by -1.
+                          * Range: 20 to 3 dB.
+                          * INT_MAX: 0x7FFFFFFF denotes invalid value.
+                          * Reference: 3GPP TS 36.133 9.1.7 */
+    int rssnr;           /* The current reference signal signal-to-noise ratio in 0.1 dB units.
+                          * Range: -200 to +300 (-200 = -20.0 dB, +300 = 30dB).
+                          * INT_MAX : 0x7FFFFFFF denotes invalid value.
+                          * Reference: 3GPP TS 36.101 8.1.1 */
+    int cqi;             /* The current Channel Quality Indicator.
+                          * Range: 0 to 15.
+                          * INT_MAX : 0x7FFFFFFF denotes invalid value.
+                          * Reference: 3GPP TS 36.101 9.2, 9.3, A.4 */
+    int timingAdvance;   /* timing advance in micro seconds for a one way trip from cell to device.
+                          * Approximate distance can be calculated using 300m/us * timingAdvance.
+                          * Range: 0 to 0x7FFFFFFE
+                          * INT_MAX : 0x7FFFFFFF denotes invalid value.
+                          * Reference: 3GPP 36.321 section 6.1.3.5
+                          * also: http://www.cellular-planningoptimization.com/2010/02/timing-advance-with-calculation.html */
+} RIL_LTE_SignalStrength_v8;
+
+typedef struct {
+    int rscp;    /* The Received Signal Code Power in dBm multipled by -1.
+                  * Range : 25 to 120
+                  * INT_MAX: 0x7FFFFFFF denotes invalid value.
+                  * Reference: 3GPP TS 25.123, section 9.1.1.1 */
+} RIL_TD_SCDMA_SignalStrength;
+
+/* Deprecated, use RIL_SignalStrength_v6 */
+typedef struct {
+    RIL_GW_SignalStrength   GW_SignalStrength;
+    RIL_CDMA_SignalStrength CDMA_SignalStrength;
+    RIL_EVDO_SignalStrength EVDO_SignalStrength;
+} RIL_SignalStrength_v5;
+
+typedef struct {
+    RIL_GW_SignalStrength   GW_SignalStrength;
+    RIL_CDMA_SignalStrength CDMA_SignalStrength;
+    RIL_EVDO_SignalStrength EVDO_SignalStrength;
+    RIL_LTE_SignalStrength  LTE_SignalStrength;
+} RIL_SignalStrength_v6;
+
+typedef struct {
+    RIL_GW_SignalStrength       GW_SignalStrength;
+    RIL_CDMA_SignalStrength     CDMA_SignalStrength;
+    RIL_EVDO_SignalStrength     EVDO_SignalStrength;
+    RIL_LTE_SignalStrength_v8   LTE_SignalStrength;
+} RIL_SignalStrength_v8;
+
+typedef struct {
+    RIL_GW_SignalStrength       GW_SignalStrength;
+    RIL_CDMA_SignalStrength     CDMA_SignalStrength;
+    RIL_EVDO_SignalStrength     EVDO_SignalStrength;
+    RIL_LTE_SignalStrength_v8   LTE_SignalStrength;
+    RIL_TD_SCDMA_SignalStrength TD_SCDMA_SignalStrength;
+} RIL_SignalStrength_v10;
+
+typedef struct {
+    int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
+    int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
+    int cid;    /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown  */
+} RIL_CellIdentityGsm;
+
+typedef struct {
+    int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
+    int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
+    int cid;    /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown  */
+    int arfcn;  /* 16-bit GSM Absolute RF channel number; this value must be reported */
+    uint8_t bsic; /* 6-bit Base Station Identity Code; 0xFF if unknown */
+} RIL_CellIdentityGsm_v12;
+
+typedef struct {
+    int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
+    int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
+    int cid;    /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown  */
+    int psc;    /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511, INT_MAX if unknown */
+} RIL_CellIdentityWcdma;
+
+typedef struct {
+    int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
+    int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
+    int cid;    /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown  */
+    int psc;    /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511; this value must be reported */
+    int uarfcn; /* 16-bit UMTS Absolute RF Channel Number; this value must be reported */
+} RIL_CellIdentityWcdma_v12;
+
+typedef struct {
+    int networkId;      /* Network Id 0..65535, INT_MAX if unknown */
+    int systemId;       /* CDMA System Id 0..32767, INT_MAX if unknown  */
+    int basestationId;  /* Base Station Id 0..65535, INT_MAX if unknown  */
+    int longitude;      /* Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+                         * It is represented in units of 0.25 seconds and ranges from -2592000
+                         * to 2592000, both values inclusive (corresponding to a range of -180
+                         * to +180 degrees). INT_MAX if unknown */
+
+    int latitude;       /* Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
+                         * It is represented in units of 0.25 seconds and ranges from -1296000
+                         * to 1296000, both values inclusive (corresponding to a range of -90
+                         * to +90 degrees). INT_MAX if unknown */
+} RIL_CellIdentityCdma;
+
+typedef struct {
+    int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
+    int ci;     /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */
+    int pci;    /* physical cell id 0..503, INT_MAX if unknown  */
+    int tac;    /* 16-bit tracking area code, INT_MAX if unknown  */
+} RIL_CellIdentityLte;
+
+typedef struct {
+    int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
+    int ci;     /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */
+    int pci;    /* physical cell id 0..503; this value must be reported */
+    int tac;    /* 16-bit tracking area code, INT_MAX if unknown  */
+    int earfcn; /* 18-bit LTE Absolute RF Channel Number; this value must be reported */
+} RIL_CellIdentityLte_v12;
+
+typedef struct {
+    int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
+    int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
+    int cid;    /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown  */
+    int cpid;    /* 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown */
+} RIL_CellIdentityTdscdma;
+
+typedef struct {
+  RIL_CellIdentityGsm   cellIdentityGsm;
+  RIL_GW_SignalStrength signalStrengthGsm;
+} RIL_CellInfoGsm;
+
+typedef struct {
+  RIL_CellIdentityGsm_v12   cellIdentityGsm;
+  RIL_GSM_SignalStrength_v12 signalStrengthGsm;
+} RIL_CellInfoGsm_v12;
+
+typedef struct {
+  RIL_CellIdentityWcdma cellIdentityWcdma;
+  RIL_SignalStrengthWcdma signalStrengthWcdma;
+} RIL_CellInfoWcdma;
+
+typedef struct {
+  RIL_CellIdentityWcdma_v12 cellIdentityWcdma;
+  RIL_SignalStrengthWcdma signalStrengthWcdma;
+} RIL_CellInfoWcdma_v12;
+
+typedef struct {
+  RIL_CellIdentityCdma      cellIdentityCdma;
+  RIL_CDMA_SignalStrength   signalStrengthCdma;
+  RIL_EVDO_SignalStrength   signalStrengthEvdo;
+} RIL_CellInfoCdma;
+
+typedef struct {
+  RIL_CellIdentityLte        cellIdentityLte;
+  RIL_LTE_SignalStrength_v8  signalStrengthLte;
+} RIL_CellInfoLte;
+
+typedef struct {
+  RIL_CellIdentityLte_v12    cellIdentityLte;
+  RIL_LTE_SignalStrength_v8  signalStrengthLte;
+} RIL_CellInfoLte_v12;
+
+typedef struct {
+  RIL_CellIdentityTdscdma cellIdentityTdscdma;
+  RIL_TD_SCDMA_SignalStrength signalStrengthTdscdma;
+} RIL_CellInfoTdscdma;
+
+// Must be the same as CellInfo.TYPE_XXX
+typedef enum {
+  RIL_CELL_INFO_TYPE_NONE   = 0, /* indicates no cell information */
+  RIL_CELL_INFO_TYPE_GSM    = 1,
+  RIL_CELL_INFO_TYPE_CDMA   = 2,
+  RIL_CELL_INFO_TYPE_LTE    = 3,
+  RIL_CELL_INFO_TYPE_WCDMA  = 4,
+  RIL_CELL_INFO_TYPE_TD_SCDMA  = 5
+} RIL_CellInfoType;
+
+// Must be the same as CellInfo.TIMESTAMP_TYPE_XXX
+typedef enum {
+    RIL_TIMESTAMP_TYPE_UNKNOWN = 0,
+    RIL_TIMESTAMP_TYPE_ANTENNA = 1,
+    RIL_TIMESTAMP_TYPE_MODEM = 2,
+    RIL_TIMESTAMP_TYPE_OEM_RIL = 3,
+    RIL_TIMESTAMP_TYPE_JAVA_RIL = 4,
+} RIL_TimeStampType;
+
+typedef struct {
+  RIL_CellInfoType  cellInfoType;   /* cell type for selecting from union CellInfo */
+  int               registered;     /* !0 if this cell is registered 0 if not registered */
+  RIL_TimeStampType timeStampType;  /* type of time stamp represented by timeStamp */
+  uint64_t          timeStamp;      /* Time in nanos as returned by ril_nano_time */
+  union {
+    RIL_CellInfoGsm     gsm;
+    RIL_CellInfoCdma    cdma;
+    RIL_CellInfoLte     lte;
+    RIL_CellInfoWcdma   wcdma;
+    RIL_CellInfoTdscdma tdscdma;
+  } CellInfo;
+} RIL_CellInfo;
+
+typedef struct {
+  RIL_CellInfoType  cellInfoType;   /* cell type for selecting from union CellInfo */
+  int               registered;     /* !0 if this cell is registered 0 if not registered */
+  RIL_TimeStampType timeStampType;  /* type of time stamp represented by timeStamp */
+  uint64_t          timeStamp;      /* Time in nanos as returned by ril_nano_time */
+  union {
+    RIL_CellInfoGsm_v12     gsm;
+    RIL_CellInfoCdma        cdma;
+    RIL_CellInfoLte_v12     lte;
+    RIL_CellInfoWcdma_v12   wcdma;
+    RIL_CellInfoTdscdma     tdscdma;
+  } CellInfo;
+} RIL_CellInfo_v12;
+
+typedef struct {
+  RIL_CellInfoType  cellInfoType;   /* cell type for selecting from union CellInfo */
+  union {
+    RIL_CellIdentityGsm_v12 cellIdentityGsm;
+    RIL_CellIdentityWcdma_v12 cellIdentityWcdma;
+    RIL_CellIdentityLte_v12 cellIdentityLte;
+    RIL_CellIdentityTdscdma cellIdentityTdscdma;
+    RIL_CellIdentityCdma cellIdentityCdma;
+  };
+}RIL_CellIdentity_v16;
+
+typedef struct {
+    RIL_RegState regState;                // Valid reg states are RIL_NOT_REG_AND_NOT_SEARCHING,
+                                          // REG_HOME, RIL_NOT_REG_AND_SEARCHING, REG_DENIED,
+                                          // UNKNOWN, REG_ROAMING defined in RegState
+    RIL_RadioTechnology rat;              // indicates the available voice radio technology,
+                                          // valid values as defined by RadioTechnology.
+    int32_t cssSupported;                 // concurrent services support indicator. if
+                                          // registered on a CDMA system.
+                                          // 0 - Concurrent services not supported,
+                                          // 1 - Concurrent services supported
+    int32_t roamingIndicator;             // TSB-58 Roaming Indicator if registered
+                                          // on a CDMA or EVDO system or -1 if not.
+                                          // Valid values are 0-255.
+    int32_t systemIsInPrl;                // indicates whether the current system is in the
+                                          // PRL if registered on a CDMA or EVDO system or -1 if
+                                          // not. 0=not in the PRL, 1=in the PRL
+    int32_t defaultRoamingIndicator;      // default Roaming Indicator from the PRL,
+                                          // if registered on a CDMA or EVDO system or -1 if not.
+                                          // Valid values are 0-255.
+    int32_t reasonForDenial;              // reasonForDenial if registration state is 3
+                                          // (Registration denied) this is an enumerated reason why
+                                          // registration was denied. See 3GPP TS 24.008,
+                                          // 10.5.3.6 and Annex G.
+                                          // 0 - General
+                                          // 1 - Authentication Failure
+                                          // 2 - IMSI unknown in HLR
+                                          // 3 - Illegal MS
+                                          // 4 - Illegal ME
+                                          // 5 - PLMN not allowed
+                                          // 6 - Location area not allowed
+                                          // 7 - Roaming not allowed
+                                          // 8 - No Suitable Cells in this Location Area
+                                          // 9 - Network failure
+                                          // 10 - Persistent location update reject
+                                          // 11 - PLMN not allowed
+                                          // 12 - Location area not allowed
+                                          // 13 - Roaming not allowed in this Location Area
+                                          // 15 - No Suitable Cells in this Location Area
+                                          // 17 - Network Failure
+                                          // 20 - MAC Failure
+                                          // 21 - Sync Failure
+                                          // 22 - Congestion
+                                          // 23 - GSM Authentication unacceptable
+                                          // 25 - Not Authorized for this CSG
+                                          // 32 - Service option not supported
+                                          // 33 - Requested service option not subscribed
+                                          // 34 - Service option temporarily out of order
+                                          // 38 - Call cannot be identified
+                                          // 48-63 - Retry upon entry into a new cell
+                                          // 95 - Semantically incorrect message
+                                          // 96 - Invalid mandatory information
+                                          // 97 - Message type non-existent or not implemented
+                                          // 98 - Message type not compatible with protocol state
+                                          // 99 - Information element non-existent or
+                                          //      not implemented
+                                          // 100 - Conditional IE error
+                                          // 101 - Message not compatible with protocol state;
+    RIL_CellIdentity_v16 cellIdentity;    // current cell information
+}RIL_VoiceRegistrationStateResponse;
+
+
+typedef struct {
+    RIL_RegState regState;                // Valid reg states are RIL_NOT_REG_AND_NOT_SEARCHING,
+                                          // REG_HOME, RIL_NOT_REG_AND_SEARCHING, REG_DENIED,
+                                          // UNKNOWN, REG_ROAMING defined in RegState
+    RIL_RadioTechnology rat;              // indicates the available data radio technology,
+                                          // valid values as defined by RadioTechnology.
+    int32_t reasonDataDenied;             // if registration state is 3 (Registration
+                                          // denied) this is an enumerated reason why
+                                          // registration was denied. See 3GPP TS 24.008,
+                                          // Annex G.6 "Additional cause codes for GMM".
+                                          // 7 == GPRS services not allowed
+                                          // 8 == GPRS services and non-GPRS services not allowed
+                                          // 9 == MS identity cannot be derived by the network
+                                          // 10 == Implicitly detached
+                                          // 14 == GPRS services not allowed in this PLMN
+                                          // 16 == MSC temporarily not reachable
+                                          // 40 == No PDP context activated
+    int32_t maxDataCalls;                 // The maximum number of simultaneous Data Calls that
+                                          // must be established using setupDataCall().
+    RIL_CellIdentity_v16 cellIdentity;    // Current cell information
+}RIL_DataRegistrationStateResponse;
+
+/* Names of the CDMA info records (C.S0005 section 3.7.5) */
+typedef enum {
+  RIL_CDMA_DISPLAY_INFO_REC,
+  RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC,
+  RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC,
+  RIL_CDMA_CONNECTED_NUMBER_INFO_REC,
+  RIL_CDMA_SIGNAL_INFO_REC,
+  RIL_CDMA_REDIRECTING_NUMBER_INFO_REC,
+  RIL_CDMA_LINE_CONTROL_INFO_REC,
+  RIL_CDMA_EXTENDED_DISPLAY_INFO_REC,
+  RIL_CDMA_T53_CLIR_INFO_REC,
+  RIL_CDMA_T53_RELEASE_INFO_REC,
+  RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC
+} RIL_CDMA_InfoRecName;
+
+/* Display Info Rec as defined in C.S0005 section 3.7.5.1
+   Extended Display Info Rec as defined in C.S0005 section 3.7.5.16
+   Note: the Extended Display info rec contains multiple records of the
+   form: display_tag, display_len, and display_len occurrences of the
+   chari field if the display_tag is not 10000000 or 10000001.
+   To save space, the records are stored consecutively in a byte buffer.
+   The display_tag, display_len and chari fields are all 1 byte.
+*/
+
+typedef struct {
+  char alpha_len;
+  char alpha_buf[CDMA_ALPHA_INFO_BUFFER_LENGTH];
+} RIL_CDMA_DisplayInfoRecord;
+
+/* Called Party Number Info Rec as defined in C.S0005 section 3.7.5.2
+   Calling Party Number Info Rec as defined in C.S0005 section 3.7.5.3
+   Connected Number Info Rec as defined in C.S0005 section 3.7.5.4
+*/
+
+typedef struct {
+  char len;
+  char buf[CDMA_NUMBER_INFO_BUFFER_LENGTH];
+  char number_type;
+  char number_plan;
+  char pi;
+  char si;
+} RIL_CDMA_NumberInfoRecord;
+
+/* Redirecting Number Information Record as defined in C.S0005 section 3.7.5.11 */
+typedef enum {
+  RIL_REDIRECTING_REASON_UNKNOWN = 0,
+  RIL_REDIRECTING_REASON_CALL_FORWARDING_BUSY = 1,
+  RIL_REDIRECTING_REASON_CALL_FORWARDING_NO_REPLY = 2,
+  RIL_REDIRECTING_REASON_CALLED_DTE_OUT_OF_ORDER = 9,
+  RIL_REDIRECTING_REASON_CALL_FORWARDING_BY_THE_CALLED_DTE = 10,
+  RIL_REDIRECTING_REASON_CALL_FORWARDING_UNCONDITIONAL = 15,
+  RIL_REDIRECTING_REASON_RESERVED
+} RIL_CDMA_RedirectingReason;
+
+typedef struct {
+  RIL_CDMA_NumberInfoRecord redirectingNumber;
+  /* redirectingReason is set to RIL_REDIRECTING_REASON_UNKNOWN if not included */
+  RIL_CDMA_RedirectingReason redirectingReason;
+} RIL_CDMA_RedirectingNumberInfoRecord;
+
+/* Line Control Information Record as defined in C.S0005 section 3.7.5.15 */
+typedef struct {
+  char lineCtrlPolarityIncluded;
+  char lineCtrlToggle;
+  char lineCtrlReverse;
+  char lineCtrlPowerDenial;
+} RIL_CDMA_LineControlInfoRecord;
+
+/* T53 CLIR Information Record */
+typedef struct {
+  char cause;
+} RIL_CDMA_T53_CLIRInfoRecord;
+
+/* T53 Audio Control Information Record */
+typedef struct {
+  char upLink;
+  char downLink;
+} RIL_CDMA_T53_AudioControlInfoRecord;
+
+typedef struct {
+
+  RIL_CDMA_InfoRecName name;
+
+  union {
+    /* Display and Extended Display Info Rec */
+    RIL_CDMA_DisplayInfoRecord           display;
+
+    /* Called Party Number, Calling Party Number, Connected Number Info Rec */
+    RIL_CDMA_NumberInfoRecord            number;
+
+    /* Signal Info Rec */
+    RIL_CDMA_SignalInfoRecord            signal;
+
+    /* Redirecting Number Info Rec */
+    RIL_CDMA_RedirectingNumberInfoRecord redir;
+
+    /* Line Control Info Rec */
+    RIL_CDMA_LineControlInfoRecord       lineCtrl;
+
+    /* T53 CLIR Info Rec */
+    RIL_CDMA_T53_CLIRInfoRecord          clir;
+
+    /* T53 Audio Control Info Rec */
+    RIL_CDMA_T53_AudioControlInfoRecord  audioCtrl;
+  } rec;
+} RIL_CDMA_InformationRecord;
+
+#define RIL_CDMA_MAX_NUMBER_OF_INFO_RECS 10
+
+typedef struct {
+  char numberOfInfoRecs;
+  RIL_CDMA_InformationRecord infoRec[RIL_CDMA_MAX_NUMBER_OF_INFO_RECS];
+} RIL_CDMA_InformationRecords;
+
+/* See RIL_REQUEST_NV_READ_ITEM */
+typedef struct {
+  RIL_NV_Item itemID;
+} RIL_NV_ReadItem;
+
+/* See RIL_REQUEST_NV_WRITE_ITEM */
+typedef struct {
+  RIL_NV_Item   itemID;
+  char *        value;
+} RIL_NV_WriteItem;
+
+typedef enum {
+    HANDOVER_STARTED = 0,
+    HANDOVER_COMPLETED = 1,
+    HANDOVER_FAILED = 2,
+    HANDOVER_CANCELED = 3
+} RIL_SrvccState;
+
+/* hardware configuration reported to RILJ. */
+typedef enum {
+   RIL_HARDWARE_CONFIG_MODEM = 0,
+   RIL_HARDWARE_CONFIG_SIM = 1,
+} RIL_HardwareConfig_Type;
+
+typedef enum {
+   RIL_HARDWARE_CONFIG_STATE_ENABLED = 0,
+   RIL_HARDWARE_CONFIG_STATE_STANDBY = 1,
+   RIL_HARDWARE_CONFIG_STATE_DISABLED = 2,
+} RIL_HardwareConfig_State;
+
+typedef struct {
+   int rilModel;
+   uint32_t rat; /* bitset - ref. RIL_RadioTechnology. */
+   int maxVoice;
+   int maxData;
+   int maxStandby;
+} RIL_HardwareConfig_Modem;
+
+typedef struct {
+   char modemUuid[MAX_UUID_LENGTH];
+} RIL_HardwareConfig_Sim;
+
+typedef struct {
+  RIL_HardwareConfig_Type type;
+  char uuid[MAX_UUID_LENGTH];
+  RIL_HardwareConfig_State state;
+  union {
+     RIL_HardwareConfig_Modem modem;
+     RIL_HardwareConfig_Sim sim;
+  } cfg;
+} RIL_HardwareConfig;
+
+typedef enum {
+  SS_CFU,
+  SS_CF_BUSY,
+  SS_CF_NO_REPLY,
+  SS_CF_NOT_REACHABLE,
+  SS_CF_ALL,
+  SS_CF_ALL_CONDITIONAL,
+  SS_CLIP,
+  SS_CLIR,
+  SS_COLP,
+  SS_COLR,
+  SS_WAIT,
+  SS_BAOC,
+  SS_BAOIC,
+  SS_BAOIC_EXC_HOME,
+  SS_BAIC,
+  SS_BAIC_ROAMING,
+  SS_ALL_BARRING,
+  SS_OUTGOING_BARRING,
+  SS_INCOMING_BARRING
+} RIL_SsServiceType;
+
+typedef enum {
+  SS_ACTIVATION,
+  SS_DEACTIVATION,
+  SS_INTERROGATION,
+  SS_REGISTRATION,
+  SS_ERASURE
+} RIL_SsRequestType;
+
+typedef enum {
+  SS_ALL_TELE_AND_BEARER_SERVICES,
+  SS_ALL_TELESEVICES,
+  SS_TELEPHONY,
+  SS_ALL_DATA_TELESERVICES,
+  SS_SMS_SERVICES,
+  SS_ALL_TELESERVICES_EXCEPT_SMS
+} RIL_SsTeleserviceType;
+
+#define SS_INFO_MAX 4
+#define NUM_SERVICE_CLASSES 7
+
+typedef struct {
+  int numValidIndexes; /* This gives the number of valid values in cfInfo.
+                       For example if voice is forwarded to one number and data
+                       is forwarded to a different one then numValidIndexes will be
+                       2 indicating total number of valid values in cfInfo.
+                       Similarly if all the services are forwarded to the same
+                       number then the value of numValidIndexes will be 1. */
+
+  RIL_CallForwardInfo cfInfo[NUM_SERVICE_CLASSES]; /* This is the response data
+                                                      for SS request to query call
+                                                      forward status. see
+                                                      RIL_REQUEST_QUERY_CALL_FORWARD_STATUS */
+} RIL_CfData;
+
+typedef struct {
+  RIL_SsServiceType serviceType;
+  RIL_SsRequestType requestType;
+  RIL_SsTeleserviceType teleserviceType;
+  int serviceClass;
+  RIL_Errno result;
+
+  union {
+    int ssInfo[SS_INFO_MAX]; /* This is the response data for most of the SS GET/SET
+                                RIL requests. E.g. RIL_REQUSET_GET_CLIR returns
+                                two ints, so first two values of ssInfo[] will be
+                                used for response if serviceType is SS_CLIR and
+                                requestType is SS_INTERROGATION */
+
+    RIL_CfData cfData;
+  };
+} RIL_StkCcUnsolSsResponse;
+
+/**
+ * Data connection power state
+ */
+typedef enum {
+    RIL_DC_POWER_STATE_LOW      = 1,        // Low power state
+    RIL_DC_POWER_STATE_MEDIUM   = 2,        // Medium power state
+    RIL_DC_POWER_STATE_HIGH     = 3,        // High power state
+    RIL_DC_POWER_STATE_UNKNOWN  = INT32_MAX // Unknown state
+} RIL_DcPowerStates;
+
+/**
+ * Data connection real time info
+ */
+typedef struct {
+    uint64_t                    time;       // Time in nanos as returned by ril_nano_time
+    RIL_DcPowerStates           powerState; // Current power state
+} RIL_DcRtInfo;
+
+/**
+ * Data profile to modem
+ */
+typedef struct {
+    /* id of the data profile */
+    int profileId;
+    /* the APN to connect to */
+    char* apn;
+    /** one of the PDP_type values in TS 27.007 section 10.1.1.
+     * For example, "IP", "IPV6", "IPV4V6", or "PPP".
+     */
+    char* protocol;
+    /** authentication protocol used for this PDP context
+     * (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3)
+     */
+    int authType;
+    /* the username for APN, or NULL */
+    char* user;
+    /* the password for APN, or NULL */
+    char* password;
+    /* the profile type, TYPE_COMMON-0, TYPE_3GPP-1, TYPE_3GPP2-2 */
+    int type;
+    /* the period in seconds to limit the maximum connections */
+    int maxConnsTime;
+    /* the maximum connections during maxConnsTime */
+    int maxConns;
+    /** the required wait time in seconds after a successful UE initiated
+     * disconnect of a given PDN connection before the device can send
+     * a new PDN connection request for that given PDN
+     */
+    int waitTime;
+    /* true to enable the profile, 0 to disable, 1 to enable */
+    int enabled;
+} RIL_DataProfileInfo;
+
+typedef struct {
+    /* id of the data profile */
+    int profileId;
+    /* the APN to connect to */
+    char* apn;
+    /** one of the PDP_type values in TS 27.007 section 10.1.1.
+     * For example, "IP", "IPV6", "IPV4V6", or "PPP".
+     */
+    char* protocol;
+    /** one of the PDP_type values in TS 27.007 section 10.1.1 used on roaming network.
+     * For example, "IP", "IPV6", "IPV4V6", or "PPP".
+     */
+    char *roamingProtocol;
+    /** authentication protocol used for this PDP context
+     * (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3)
+     */
+    int authType;
+    /* the username for APN, or NULL */
+    char* user;
+    /* the password for APN, or NULL */
+    char* password;
+    /* the profile type, TYPE_COMMON-0, TYPE_3GPP-1, TYPE_3GPP2-2 */
+    int type;
+    /* the period in seconds to limit the maximum connections */
+    int maxConnsTime;
+    /* the maximum connections during maxConnsTime */
+    int maxConns;
+    /** the required wait time in seconds after a successful UE initiated
+     * disconnect of a given PDN connection before the device can send
+     * a new PDN connection request for that given PDN
+     */
+    int waitTime;
+    /* true to enable the profile, 0 to disable, 1 to enable */
+    int enabled;
+    /* supported APN types bitmask. See RIL_ApnTypes for the value of each bit. */
+    int supportedTypesBitmask;
+    /** the bearer bitmask. See RIL_RadioAccessFamily for the value of each bit. */
+    int bearerBitmask;
+    /** maximum transmission unit (MTU) size in bytes */
+    int mtu;
+    /** the MVNO type: possible values are "imsi", "gid", "spn" */
+    char *mvnoType;
+    /** MVNO match data. Can be anything defined by the carrier. For example,
+     *        SPN like: "A MOBILE", "BEN NL", etc...
+     *        IMSI like: "302720x94", "2060188", etc...
+     *        GID like: "4E", "33", etc...
+     */
+    char *mvnoMatchData;
+} RIL_DataProfileInfo_v15;
+
+/* Tx Power Levels */
+#define RIL_NUM_TX_POWER_LEVELS     5
+
+/**
+ * Aggregate modem activity information
+ */
+typedef struct {
+
+  /* total time (in ms) when modem is in a low power or
+   * sleep state
+   */
+  uint32_t sleep_mode_time_ms;
+
+  /* total time (in ms) when modem is awake but neither
+   * the transmitter nor receiver are active/awake */
+  uint32_t idle_mode_time_ms;
+
+  /* total time (in ms) during which the transmitter is active/awake,
+   * subdivided by manufacturer-defined device-specific
+   * contiguous increasing ranges of transmit power between
+   * 0 and the transmitter's maximum transmit power.
+   */
+  uint32_t tx_mode_time_ms[RIL_NUM_TX_POWER_LEVELS];
+
+  /* total time (in ms) for which receiver is active/awake and
+   * the transmitter is inactive */
+  uint32_t rx_mode_time_ms;
+} RIL_ActivityStatsInfo;
+
+typedef enum {
+    RIL_APN_TYPE_UNKNOWN      = 0x0,          // Unknown
+    RIL_APN_TYPE_DEFAULT      = 0x1,          // APN type for default data traffic
+    RIL_APN_TYPE_MMS          = 0x2,          // APN type for MMS traffic
+    RIL_APN_TYPE_SUPL         = 0x4,          // APN type for SUPL assisted GPS
+    RIL_APN_TYPE_DUN          = 0x8,          // APN type for DUN traffic
+    RIL_APN_TYPE_HIPRI        = 0x10,         // APN type for HiPri traffic
+    RIL_APN_TYPE_FOTA         = 0x20,         // APN type for FOTA
+    RIL_APN_TYPE_IMS          = 0x40,         // APN type for IMS
+    RIL_APN_TYPE_CBS          = 0x80,         // APN type for CBS
+    RIL_APN_TYPE_IA           = 0x100,        // APN type for IA Initial Attach APN
+    RIL_APN_TYPE_EMERGENCY    = 0x200,        // APN type for Emergency PDN. This is not an IA apn,
+                                              // but is used for access to carrier services in an
+                                              // emergency call situation.
+    RIL_APN_TYPE_ALL          = 0xFFFFFFFF    // All APN types
+} RIL_ApnTypes;
+
+typedef enum {
+    RIL_DST_POWER_SAVE_MODE,        // Device power save mode (provided by PowerManager)
+                                    // True indicates the device is in power save mode.
+    RIL_DST_CHARGING_STATE,         // Device charging state (provided by BatteryManager)
+                                    // True indicates the device is charging.
+    RIL_DST_LOW_DATA_EXPECTED       // Low data expected mode. True indicates low data traffic
+                                    // is expected, for example, when the device is idle
+                                    // (e.g. not doing tethering in the background). Note
+                                    // this doesn't mean no data is expected.
+} RIL_DeviceStateType;
+
+typedef enum {
+    RIL_UR_SIGNAL_STRENGTH            = 0x01, // When this bit is set, modem should always send the
+                                              // signal strength update through
+                                              // RIL_UNSOL_SIGNAL_STRENGTH, otherwise suppress it.
+    RIL_UR_FULL_NETWORK_STATE         = 0x02, // When this bit is set, modem should always send
+                                              // RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED
+                                              // when any field in
+                                              // RIL_REQUEST_VOICE_REGISTRATION_STATE or
+                                              // RIL_REQUEST_DATA_REGISTRATION_STATE changes. When
+                                              // this bit is not set, modem should suppress
+                                              // RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED
+                                              // only when insignificant fields change
+                                              // (e.g. cell info).
+                                              // Modem should continue sending
+                                              // RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED
+                                              // when significant fields are updated even when this
+                                              // bit is not set. The following fields are
+                                              // considered significant, registration state and
+                                              // radio technology.
+    RIL_UR_DATA_CALL_DORMANCY_CHANGED = 0x04  // When this bit is set, modem should send the data
+                                              // call list changed unsolicited response
+                                              // RIL_UNSOL_DATA_CALL_LIST_CHANGED whenever any
+                                              // field in RIL_Data_Call_Response changes.
+                                              // Otherwise modem should suppress the unsolicited
+                                              // response when the only changed field is 'active'
+                                              // (for data dormancy). For all other fields change,
+                                              // modem should continue sending
+                                              // RIL_UNSOL_DATA_CALL_LIST_CHANGED regardless this
+                                              // bit is set or not.
+} RIL_UnsolicitedResponseFilter;
+
+typedef struct {
+    char * aidPtr; /* AID value, See ETSI 102.221 and 101.220*/
+    int p2;        /* P2 parameter (described in ISO 7816-4)
+                      P2Constants:NO_P2 if to be ignored */
+} RIL_OpenChannelParams;
+
+typedef enum {
+    RIL_ONE_SHOT = 0x01, // Performs the scan only once
+    RIL_PERIODIC = 0x02  // Performs the scan periodically until cancelled
+} RIL_ScanType;
+
+typedef enum {
+    GERAN = 0x01,   // GSM EDGE Radio Access Network
+    UTRAN = 0x02,   // Universal Terrestrial Radio Access Network
+    EUTRAN = 0x03,  // Evolved Universal Terrestrial Radio Access Network
+} RIL_RadioAccessNetworks;
+
+typedef enum {
+    GERAN_BAND_T380 = 1,
+    GERAN_BAND_T410 = 2,
+    GERAN_BAND_450 = 3,
+    GERAN_BAND_480 = 4,
+    GERAN_BAND_710 = 5,
+    GERAN_BAND_750 = 6,
+    GERAN_BAND_T810 = 7,
+    GERAN_BAND_850 = 8,
+    GERAN_BAND_P900 = 9,
+    GERAN_BAND_E900 = 10,
+    GERAN_BAND_R900 = 11,
+    GERAN_BAND_DCS1800 = 12,
+    GERAN_BAND_PCS1900 = 13,
+    GERAN_BAND_ER900 = 14,
+} RIL_GeranBands;
+
+typedef enum {
+    UTRAN_BAND_1 = 1,
+    UTRAN_BAND_2 = 2,
+    UTRAN_BAND_3 = 3,
+    UTRAN_BAND_4 = 4,
+    UTRAN_BAND_5 = 5,
+    UTRAN_BAND_6 = 6,
+    UTRAN_BAND_7 = 7,
+    UTRAN_BAND_8 = 8,
+    UTRAN_BAND_9 = 9,
+    UTRAN_BAND_10 = 10,
+    UTRAN_BAND_11 = 11,
+    UTRAN_BAND_12 = 12,
+    UTRAN_BAND_13 = 13,
+    UTRAN_BAND_14 = 14,
+    UTRAN_BAND_19 = 19,
+    UTRAN_BAND_20 = 20,
+    UTRAN_BAND_21 = 21,
+    UTRAN_BAND_22 = 22,
+    UTRAN_BAND_25 = 25,
+    UTRAN_BAND_26 = 26,
+} RIL_UtranBands;
+
+typedef enum {
+    EUTRAN_BAND_1 = 1,
+    EUTRAN_BAND_2 = 2,
+    EUTRAN_BAND_3 = 3,
+    EUTRAN_BAND_4 = 4,
+    EUTRAN_BAND_5 = 5,
+    EUTRAN_BAND_6 = 6,
+    EUTRAN_BAND_7 = 7,
+    EUTRAN_BAND_8 = 8,
+    EUTRAN_BAND_9 = 9,
+    EUTRAN_BAND_10 = 10,
+    EUTRAN_BAND_11 = 11,
+    EUTRAN_BAND_12 = 12,
+    EUTRAN_BAND_13 = 13,
+    EUTRAN_BAND_14 = 14,
+    EUTRAN_BAND_17 = 17,
+    EUTRAN_BAND_18 = 18,
+    EUTRAN_BAND_19 = 19,
+    EUTRAN_BAND_20 = 20,
+    EUTRAN_BAND_21 = 21,
+    EUTRAN_BAND_22 = 22,
+    EUTRAN_BAND_23 = 23,
+    EUTRAN_BAND_24 = 24,
+    EUTRAN_BAND_25 = 25,
+    EUTRAN_BAND_26 = 26,
+    EUTRAN_BAND_27 = 27,
+    EUTRAN_BAND_28 = 28,
+    EUTRAN_BAND_30 = 30,
+    EUTRAN_BAND_31 = 31,
+    EUTRAN_BAND_33 = 33,
+    EUTRAN_BAND_34 = 34,
+    EUTRAN_BAND_35 = 35,
+    EUTRAN_BAND_36 = 36,
+    EUTRAN_BAND_37 = 37,
+    EUTRAN_BAND_38 = 38,
+    EUTRAN_BAND_39 = 39,
+    EUTRAN_BAND_40 = 40,
+    EUTRAN_BAND_41 = 41,
+    EUTRAN_BAND_42 = 42,
+    EUTRAN_BAND_43 = 43,
+    EUTRAN_BAND_44 = 44,
+    EUTRAN_BAND_45 = 45,
+    EUTRAN_BAND_46 = 46,
+    EUTRAN_BAND_47 = 47,
+    EUTRAN_BAND_48 = 48,
+    EUTRAN_BAND_65 = 65,
+    EUTRAN_BAND_66 = 66,
+    EUTRAN_BAND_68 = 68,
+    EUTRAN_BAND_70 = 70,
+} RIL_EutranBands;
+
+typedef struct {
+    RIL_RadioAccessNetworks radio_access_network; // The type of network to scan.
+    uint32_t bands_length;                        // Length of bands
+    union {
+        RIL_GeranBands geran_bands[MAX_BANDS];
+        RIL_UtranBands utran_bands[MAX_BANDS];
+        RIL_EutranBands eutran_bands[MAX_BANDS];
+    } bands;
+    uint32_t channels_length;                     // Length of channels
+    uint32_t channels[MAX_CHANNELS];              // Frequency channels to scan
+} RIL_RadioAccessSpecifier;
+
+typedef struct {
+    RIL_ScanType type;                                              // Type of the scan
+    int32_t interval;                                               // Time interval in seconds
+                                                                    // between periodic scans, only
+                                                                    // valid when type=RIL_PERIODIC
+    uint32_t specifiers_length;                                     // Length of specifiers
+    RIL_RadioAccessSpecifier specifiers[MAX_RADIO_ACCESS_NETWORKS]; // Radio access networks
+                                                                    // with bands/channels.
+} RIL_NetworkScanRequest;
+
+typedef enum {
+    PARTIAL = 0x01,   // The result contains a part of the scan results
+    COMPLETE = 0x02,  // The result contains the last part of the scan results
+} RIL_ScanStatus;
+
+typedef struct {
+    RIL_ScanStatus status;              // The status of the scan
+    uint32_t network_infos_length;      // Total length of RIL_CellInfo
+    RIL_CellInfo_v12* network_infos;    // List of network information
+    RIL_Errno error;
+} RIL_NetworkScanResult;
+
+/**
+ * RIL_REQUEST_GET_SIM_STATUS
+ *
+ * Requests status of the SIM interface and the SIM card
+ *
+ * "data" is NULL
+ *
+ * "response" is const RIL_CardStatus_v6 *
+ *
+ * Valid errors:
+ *
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_GET_SIM_STATUS 1
+
+/**
+ * RIL_REQUEST_ENTER_SIM_PIN
+ *
+ * Supplies SIM PIN. Only called if RIL_CardStatus has RIL_APPSTATE_PIN state
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is PIN value
+ * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ *
+ * "response" is int *
+ * ((int *)response)[0] is the number of retries remaining, or -1 if unknown
+ *
+ * Valid errors:
+ *
+ * SUCCESS
+ * RADIO_NOT_AVAILABLE (radio resetting)
+ * PASSWORD_INCORRECT
+ * INTERNAL_ERR
+ * NO_MEMORY
+ * NO_RESOURCES
+ * CANCELLED
+ * INVALID_ARGUMENTS
+ * INVALID_SIM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_ENTER_SIM_PIN 2
+
+/**
+ * RIL_REQUEST_ENTER_SIM_PUK
+ *
+ * Supplies SIM PUK and new PIN.
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is PUK value
+ * ((const char **)data)[1] is new PIN value
+ * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ *
+ * "response" is int *
+ * ((int *)response)[0] is the number of retries remaining, or -1 if unknown
+ *
+ * Valid errors:
+ *
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  PASSWORD_INCORRECT
+ *     (PUK is invalid)
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_ARGUMENTS
+ *  INVALID_SIM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_ENTER_SIM_PUK 3
+
+/**
+ * RIL_REQUEST_ENTER_SIM_PIN2
+ *
+ * Supplies SIM PIN2. Only called following operation where SIM_PIN2 was
+ * returned as a a failure from a previous operation.
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is PIN2 value
+ * ((const char **)data)[1] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ *
+ * "response" is int *
+ * ((int *)response)[0] is the number of retries remaining, or -1 if unknown
+ *
+ * Valid errors:
+ *
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  PASSWORD_INCORRECT
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_ARGUMENTS
+ *  INVALID_SIM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_ENTER_SIM_PIN2 4
+
+/**
+ * RIL_REQUEST_ENTER_SIM_PUK2
+ *
+ * Supplies SIM PUK2 and new PIN2.
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is PUK2 value
+ * ((const char **)data)[1] is new PIN2 value
+ * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ *
+ * "response" is int *
+ * ((int *)response)[0] is the number of retries remaining, or -1 if unknown
+ *
+ * Valid errors:
+ *
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  PASSWORD_INCORRECT
+ *     (PUK2 is invalid)
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_ARGUMENTS
+ *  INVALID_SIM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_ENTER_SIM_PUK2 5
+
+/**
+ * RIL_REQUEST_CHANGE_SIM_PIN
+ *
+ * Supplies old SIM PIN and new PIN.
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is old PIN value
+ * ((const char **)data)[1] is new PIN value
+ * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ *
+ * "response" is int *
+ * ((int *)response)[0] is the number of retries remaining, or -1 if unknown
+ *
+ * Valid errors:
+ *
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  PASSWORD_INCORRECT
+ *     (old PIN is invalid)
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_ARGUMENTS
+ *  INVALID_SIM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_CHANGE_SIM_PIN 6
+
+
+/**
+ * RIL_REQUEST_CHANGE_SIM_PIN2
+ *
+ * Supplies old SIM PIN2 and new PIN2.
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is old PIN2 value
+ * ((const char **)data)[1] is new PIN2 value
+ * ((const char **)data)[2] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ *
+ * "response" is int *
+ * ((int *)response)[0] is the number of retries remaining, or -1 if unknown
+ *
+ * Valid errors:
+ *
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  PASSWORD_INCORRECT
+ *     (old PIN2 is invalid)
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_ARGUMENTS
+ *  INVALID_SIM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+
+#define RIL_REQUEST_CHANGE_SIM_PIN2 7
+
+/**
+ * RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION
+ *
+ * Requests that network personlization be deactivated
+ *
+ * "data" is const char **
+ * ((const char **)(data))[0]] is network depersonlization code
+ *
+ * "response" is int *
+ * ((int *)response)[0] is the number of retries remaining, or -1 if unknown
+ *
+ * Valid errors:
+ *
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  PASSWORD_INCORRECT
+ *  SIM_ABSENT
+ *     (code is invalid)
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION 8
+
+/**
+ * RIL_REQUEST_GET_CURRENT_CALLS
+ *
+ * Requests current call list
+ *
+ * "data" is NULL
+ *
+ * "response" must be a "const RIL_Call **"
+ *
+ * Valid errors:
+ *
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  NO_MEMORY
+ *      (request will be made again in a few hundred msec)
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_GET_CURRENT_CALLS 9
+
+
+/**
+ * RIL_REQUEST_DIAL
+ *
+ * Initiate voice call
+ *
+ * "data" is const RIL_Dial *
+ * "response" is NULL
+ *
+ * This method is never used for supplementary service codes
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  DIAL_MODIFIED_TO_USSD
+ *  DIAL_MODIFIED_TO_SS
+ *  DIAL_MODIFIED_TO_DIAL
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  INVALID_STATE
+ *  NO_RESOURCES
+ *  INTERNAL_ERR
+ *  FDN_CHECK_FAILURE
+ *  MODEM_ERR
+ *  NO_SUBSCRIPTION
+ *  NO_NETWORK_FOUND
+ *  INVALID_CALL_ID
+ *  DEVICE_IN_USE
+ *  OPERATION_NOT_ALLOWED
+ *  ABORTED
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_DIAL 10
+
+/**
+ * RIL_REQUEST_GET_IMSI
+ *
+ * Get the SIM IMSI
+ *
+ * Only valid when radio state is "RADIO_STATE_ON"
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ * "response" is a const char * containing the IMSI
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_SIM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_GET_IMSI 11
+
+/**
+ * RIL_REQUEST_HANGUP
+ *
+ * Hang up a specific line (like AT+CHLD=1x)
+ *
+ * After this HANGUP request returns, RIL should show the connection is NOT
+ * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query.
+ *
+ * "data" is an int *
+ * (int *)data)[0] contains Connection index (value of 'x' in CHLD above)
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  INVALID_STATE
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  INVALID_CALL_ID
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_HANGUP 12
+
+/**
+ * RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND
+ *
+ * Hang up waiting or held (like AT+CHLD=0)
+ *
+ * After this HANGUP request returns, RIL should show the connection is NOT
+ * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query.
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  INVALID_CALL_ID
+ *  NO_RESOURCES
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND 13
+
+/**
+ * RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND
+ *
+ * Hang up waiting or held (like AT+CHLD=1)
+ *
+ * After this HANGUP request returns, RIL should show the connection is NOT
+ * active anymore in next RIL_REQUEST_GET_CURRENT_CALLS query.
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND 14
+
+/**
+ * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE
+ *
+ * Switch waiting or holding call and active call (like AT+CHLD=2)
+ *
+ * State transitions should be is follows:
+ *
+ * If call 1 is waiting and call 2 is active, then if this re
+ *
+ *   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
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_STATE
+ *  INVALID_ARGUMENTS
+ *  INVALID_CALL_ID
+ *  OPERATION_NOT_ALLOWED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE 15
+#define RIL_REQUEST_SWITCH_HOLDING_AND_ACTIVE 15
+
+/**
+ * RIL_REQUEST_CONFERENCE
+ *
+ * Conference holding and active (like AT+CHLD=3)
+
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_STATE
+ *  INVALID_CALL_ID
+ *  INVALID_ARGUMENTS
+ *  OPERATION_NOT_ALLOWED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_CONFERENCE 16
+
+/**
+ * RIL_REQUEST_UDUB
+ *
+ * Send UDUB (user determined used busy) to ringing or
+ * waiting call answer)(RIL_BasicRequest r);
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INVALID_STATE
+ *  NO_RESOURCES
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_ARGUMENTS
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_UDUB 17
+
+/**
+ * RIL_REQUEST_LAST_CALL_FAIL_CAUSE
+ *
+ * Requests the failure cause code for the most recently terminated call
+ *
+ * "data" is NULL
+ * "response" is a const RIL_LastCallFailCauseInfo *
+ * RIL_LastCallFailCauseInfo contains LastCallFailCause and vendor cause.
+ * The vendor cause code must be used for debugging purpose only.
+ * The implementation must return one of the values of LastCallFailCause
+ * as mentioned below.
+ *
+ * GSM failure reasons codes for the cause codes defined in TS 24.008 Annex H
+ * where possible.
+ * CDMA failure reasons codes for the possible call failure scenarios
+ * described in the "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard.
+ * Any of the following reason codes if the call is failed or dropped due to reason
+ * mentioned with in the braces.
+ *
+ *      CALL_FAIL_RADIO_OFF (Radio is OFF)
+ *      CALL_FAIL_OUT_OF_SERVICE (No cell coverage)
+ *      CALL_FAIL_NO_VALID_SIM (No valid SIM)
+ *      CALL_FAIL_RADIO_INTERNAL_ERROR (Modem hit unexpected error scenario)
+ *      CALL_FAIL_NETWORK_RESP_TIMEOUT (No response from network)
+ *      CALL_FAIL_NETWORK_REJECT (Explicit network reject)
+ *      CALL_FAIL_RADIO_ACCESS_FAILURE (RRC connection failure. Eg.RACH)
+ *      CALL_FAIL_RADIO_LINK_FAILURE (Radio Link Failure)
+ *      CALL_FAIL_RADIO_LINK_LOST (Radio link lost due to poor coverage)
+ *      CALL_FAIL_RADIO_UPLINK_FAILURE (Radio uplink failure)
+ *      CALL_FAIL_RADIO_SETUP_FAILURE (RRC connection setup failure)
+ *      CALL_FAIL_RADIO_RELEASE_NORMAL (RRC connection release, normal)
+ *      CALL_FAIL_RADIO_RELEASE_ABNORMAL (RRC connection release, abnormal)
+ *      CALL_FAIL_ACCESS_CLASS_BLOCKED (Access class barring)
+ *      CALL_FAIL_NETWORK_DETACH (Explicit network detach)
+ *
+ * OEM causes (CALL_FAIL_OEM_CAUSE_XX) must be used for debug purpose only
+ *
+ * If the implementation does not have access to the exact cause codes,
+ * then it should return one of the values listed in RIL_LastCallFailCause,
+ * as the UI layer needs to distinguish these cases for tone generation or
+ * error notification.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ * See also: RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE
+ */
+#define RIL_REQUEST_LAST_CALL_FAIL_CAUSE 18
+
+/**
+ * RIL_REQUEST_SIGNAL_STRENGTH
+ *
+ * Requests current signal strength and associated information
+ *
+ * Must succeed if radio is on.
+ *
+ * "data" is NULL
+ *
+ * "response" is a const RIL_SignalStrength *
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  NOT_PROVISIONED
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SIGNAL_STRENGTH 19
+
+/**
+ * RIL_REQUEST_VOICE_REGISTRATION_STATE
+ *
+ * Request current registration state
+ *
+ * "data" is NULL
+ * "response" is a const RIL_VoiceRegistrationStateResponse *
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_VOICE_REGISTRATION_STATE 20
+
+/**
+ * RIL_REQUEST_DATA_REGISTRATION_STATE
+ *
+ * Request current DATA registration state
+ *
+ * "data" is NULL
+ * "response" is a const RIL_DataRegistrationStateResponse *
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  NOT_PROVISIONED
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_DATA_REGISTRATION_STATE 21
+
+/**
+ * RIL_REQUEST_OPERATOR
+ *
+ * Request current operator ONS or EONS
+ *
+ * "data" is NULL
+ * "response" is a "const char **"
+ * ((const char **)response)[0] is long alpha ONS or EONS
+ *                                  or NULL if unregistered
+ *
+ * ((const char **)response)[1] is short alpha ONS or EONS
+ *                                  or NULL if unregistered
+ * ((const char **)response)[2] is 5 or 6 digit numeric code (MCC + MNC)
+ *                                  or NULL if unregistered
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_OPERATOR 22
+
+/**
+ * RIL_REQUEST_RADIO_POWER
+ *
+ * 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.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is > 0 for "Radio On"
+ * ((int *)data)[0] is == 0 for "Radio Off"
+ *
+ * "response" is NULL
+ *
+ * Turn radio on if "on" > 0
+ * Turn radio off if "on" == 0
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  DEVICE_IN_USE
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_RADIO_POWER 23
+
+/**
+ * RIL_REQUEST_DTMF
+ *
+ * Send a DTMF tone
+ *
+ * If the implementation is currently playing a tone requested via
+ * RIL_REQUEST_DTMF_START, that tone should be cancelled and the new tone
+ * should be played instead
+ *
+ * "data" is a char * containing a single character with one of 12 values: 0-9,*,#
+ * "response" is NULL
+ *
+ * FIXME should this block/mute microphone?
+ * How does this interact with local DTMF feedback?
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ * See also: RIL_REQUEST_DTMF_STOP, RIL_REQUEST_DTMF_START
+ *
+ */
+#define RIL_REQUEST_DTMF 24
+
+/**
+ * RIL_REQUEST_SEND_SMS
+ *
+ * Send an SMS message
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed
+ *      by a length byte (as expected by TS 27.005) or NULL for default SMSC
+ * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string
+ *      less the SMSC address
+ *      TP-Layer-Length is be "strlen(((const char **)data)[1])/2"
+ *
+ * "response" is a const RIL_SMS_Response *
+ *
+ * Based on the return error, caller decides to resend if sending sms
+ * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332)
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SMS_SEND_FAIL_RETRY
+ *  FDN_CHECK_FAILURE
+ *  NETWORK_REJECT
+ *  INVALID_STATE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  INVALID_SMS_FORMAT
+ *  SYSTEM_ERR
+ *  ENCODING_ERR
+ *  INVALID_SMSC_ADDRESS
+ *  MODEM_ERR
+ *  NETWORK_ERR
+ *  OPERATION_NOT_ALLOWED
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *  MODE_NOT_SUPPORTED
+ *  SIM_ABSENT
+ *
+ * FIXME how do we specify TP-Message-Reference if we need to resend?
+ */
+#define RIL_REQUEST_SEND_SMS 25
+
+
+/**
+ * RIL_REQUEST_SEND_SMS_EXPECT_MORE
+ *
+ * Send an SMS message. Identical to RIL_REQUEST_SEND_SMS,
+ * except that more messages are expected to be sent soon. If possible,
+ * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command)
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is SMSC address in GSM BCD format prefixed
+ *      by a length byte (as expected by TS 27.005) or NULL for default SMSC
+ * ((const char **)data)[1] is SMS in PDU format as an ASCII hex string
+ *      less the SMSC address
+ *      TP-Layer-Length is be "strlen(((const char **)data)[1])/2"
+ *
+ * "response" is a const RIL_SMS_Response *
+ *
+ * Based on the return error, caller decides to resend if sending sms
+ * fails. SMS_SEND_FAIL_RETRY means retry (i.e. error cause is 332)
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SMS_SEND_FAIL_RETRY
+ *  NETWORK_REJECT
+ *  INVALID_STATE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  INVALID_SMS_FORMAT
+ *  SYSTEM_ERR
+ *  REQUEST_RATE_LIMITED
+ *  FDN_CHECK_FAILURE
+ *  MODEM_ERR
+ *  NETWORK_ERR
+ *  ENCODING_ERR
+ *  INVALID_SMSC_ADDRESS
+ *  OPERATION_NOT_ALLOWED
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *  MODE_NOT_SUPPORTED
+ *  SIM_ABSENT
+ *
+ */
+#define RIL_REQUEST_SEND_SMS_EXPECT_MORE 26
+
+
+/**
+ * RIL_REQUEST_SETUP_DATA_CALL
+ *
+ * Setup a packet data connection. If RIL_Data_Call_Response_v6.status
+ * return success it is added to the list of data calls and a
+ * RIL_UNSOL_DATA_CALL_LIST_CHANGED is sent. The call remains in the
+ * list until RIL_REQUEST_DEACTIVATE_DATA_CALL is issued or the
+ * radio is powered off/on. This list is returned by RIL_REQUEST_DATA_CALL_LIST
+ * and RIL_UNSOL_DATA_CALL_LIST_CHANGED.
+ *
+ * The RIL is expected to:
+ *  - Create one data call context.
+ *  - Create and configure a dedicated interface for the context
+ *  - The interface must be point to point.
+ *  - The interface is configured with one or more addresses and
+ *    is capable of sending and receiving packets. The prefix length
+ *    of the addresses must be /32 for IPv4 and /128 for IPv6.
+ *  - Must NOT change the linux routing table.
+ *  - Support up to RIL_REQUEST_DATA_REGISTRATION_STATE response[5]
+ *    number of simultaneous data call contexts.
+ *
+ * "data" is a const char **
+ * ((const char **)data)[0] Radio technology to use: 0-CDMA, 1-GSM/UMTS, 2...
+ *                          for values above 2 this is RIL_RadioTechnology + 2.
+ * ((const char **)data)[1] is a RIL_DataProfile (support is optional)
+ * ((const char **)data)[2] is the APN to connect to if radio technology is GSM/UMTS. This APN will
+ *                          override the one in the profile. NULL indicates no APN overrride.
+ * ((const char **)data)[3] is the username for APN, or NULL
+ * ((const char **)data)[4] is the password for APN, or NULL
+ * ((const char **)data)[5] is the PAP / CHAP auth type. Values:
+ *                          0 => PAP and CHAP is never performed.
+ *                          1 => PAP may be performed; CHAP is never performed.
+ *                          2 => CHAP may be performed; PAP is never performed.
+ *                          3 => PAP / CHAP may be performed - baseband dependent.
+ * ((const char **)data)[6] is the non-roaming/home connection type to request. Must be one of the
+ *                          PDP_type values in TS 27.007 section 10.1.1.
+ *                          For example, "IP", "IPV6", "IPV4V6", or "PPP".
+ * ((const char **)data)[7] is the roaming connection type to request. Must be one of the
+ *                          PDP_type values in TS 27.007 section 10.1.1.
+ *                          For example, "IP", "IPV6", "IPV4V6", or "PPP".
+ * ((const char **)data)[8] is the bitmask of APN type in decimal string format. The
+ *                          bitmask will encapsulate the following values:
+ *                          ia,mms,agps,supl,hipri,fota,dun,ims,default.
+ * ((const char **)data)[9] is the bearer bitmask in decimal string format. Each bit is a
+ *                          RIL_RadioAccessFamily. "0" or NULL indicates all RATs.
+ * ((const char **)data)[10] is the boolean in string format indicating the APN setting was
+ *                           sent to the modem through RIL_REQUEST_SET_DATA_PROFILE earlier.
+ * ((const char **)data)[11] is the mtu size in bytes of the mobile interface to which
+ *                           the apn is connected.
+ * ((const char **)data)[12] is the MVNO type:
+ *                           possible values are "imsi", "gid", "spn".
+ * ((const char **)data)[13] is MVNO match data in string. Can be anything defined by the carrier.
+ *                           For example,
+ *                           SPN like: "A MOBILE", "BEN NL", etc...
+ *                           IMSI like: "302720x94", "2060188", etc...
+ *                           GID like: "4E", "33", etc...
+ * ((const char **)data)[14] is the boolean string indicating data roaming is allowed or not. "1"
+ *                           indicates data roaming is enabled by the user, "0" indicates disabled.
+ *
+ * "response" is a RIL_Data_Call_Response_v11
+ *
+ * FIXME may need way to configure QoS settings
+ *
+ * Valid errors:
+ *  SUCCESS should be returned on both success and failure of setup with
+ *  the RIL_Data_Call_Response_v6.status containing the actual status.
+ *  For all other errors the RIL_Data_Call_Resonse_v6 is ignored.
+ *
+ *  Other errors could include:
+ *    RADIO_NOT_AVAILABLE, OP_NOT_ALLOWED_BEFORE_REG_TO_NW,
+ *    OP_NOT_ALLOWED_DURING_VOICE_CALL, REQUEST_NOT_SUPPORTED,
+ *    INVALID_ARGUMENTS, INTERNAL_ERR, NO_MEMORY, NO_RESOURCES,
+ *    CANCELLED and SIM_ABSENT
+ *
+ * See also: RIL_REQUEST_DEACTIVATE_DATA_CALL
+ */
+#define RIL_REQUEST_SETUP_DATA_CALL 27
+
+
+/**
+ * RIL_REQUEST_SIM_IO
+ *
+ * Request SIM I/O operation.
+ * This is similar to the TS 27.007 "restricted SIM" operation
+ * where it assumes all of the EF selection will be done by the
+ * callee.
+ *
+ * "data" is a const RIL_SIM_IO_v6 *
+ * Please note that RIL_SIM_IO has a "PIN2" field which may be NULL,
+ * or may specify a PIN2 for operations that require a PIN2 (eg
+ * updating FDN records)
+ *
+ * "response" is a const RIL_SIM_IO_Response *
+ *
+ * Arguments and responses that are unused for certain
+ * values of "command" should be ignored or set to NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SIM_PIN2
+ *  SIM_PUK2
+ *  INVALID_SIM_STATE
+ *  SIM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SIM_IO 28
+
+/**
+ * RIL_REQUEST_SEND_USSD
+ *
+ * Send a USSD message
+ *
+ * If a USSD session already exists, the message should be sent in the
+ * context of that session. Otherwise, a new session should be created.
+ *
+ * The network reply should be reported via RIL_UNSOL_ON_USSD
+ *
+ * Only one USSD session may exist at a time, and the session is assumed
+ * to exist until:
+ *   a) The android system invokes RIL_REQUEST_CANCEL_USSD
+ *   b) The implementation sends a RIL_UNSOL_ON_USSD with a type code
+ *      of "0" (USSD-Notify/no further action) or "2" (session terminated)
+ *
+ * "data" is a const char * containing the USSD request in UTF-8 format
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  FDN_CHECK_FAILURE
+ *  USSD_MODIFIED_TO_DIAL
+ *  USSD_MODIFIED_TO_SS
+ *  USSD_MODIFIED_TO_USSD
+ *  SIM_BUSY
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  ABORTED
+ *  SYSTEM_ERR
+ *  INVALID_STATE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ * See also: RIL_REQUEST_CANCEL_USSD, RIL_UNSOL_ON_USSD
+ */
+
+#define RIL_REQUEST_SEND_USSD 29
+
+/**
+ * RIL_REQUEST_CANCEL_USSD
+ *
+ * Cancel the current USSD session if one exists
+ *
+ * "data" is null
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SIM_BUSY
+ *  OPERATION_NOT_ALLOWED
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  INVALID_STATE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_CANCEL_USSD 30
+
+/**
+ * RIL_REQUEST_GET_CLIR
+ *
+ * Gets current CLIR status
+ * "data" is NULL
+ * "response" is int *
+ * ((int *)data)[0] is "n" parameter from TS 27.007 7.7
+ * ((int *)data)[1] is "m" parameter from TS 27.007 7.7
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  FDN_CHECK_FAILURE
+ *  SYSTEM_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_GET_CLIR 31
+
+/**
+ * RIL_REQUEST_SET_CLIR
+ *
+ * "data" is int *
+ * ((int *)data)[0] is "n" parameter from TS 27.007 7.7
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  INVALID_ARGUMENTS
+ *  SYSTEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SET_CLIR 32
+
+/**
+ * RIL_REQUEST_QUERY_CALL_FORWARD_STATUS
+ *
+ * "data" is const RIL_CallForwardInfo *
+ *
+ * "response" is const RIL_CallForwardInfo **
+ * "response" points to an array of RIL_CallForwardInfo *'s, one for
+ * each distinct registered phone number.
+ *
+ * For example, if data is forwarded to +18005551212 and voice is forwarded
+ * to +18005559999, then two separate RIL_CallForwardInfo's should be returned
+ *
+ * If, however, both data and voice are forwarded to +18005551212, then
+ * a single RIL_CallForwardInfo can be returned with the service class
+ * set to "data + voice = 3")
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  FDN_CHECK_FAILURE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_QUERY_CALL_FORWARD_STATUS 33
+
+
+/**
+ * RIL_REQUEST_SET_CALL_FORWARD
+ *
+ * Configure call forward rule
+ *
+ * "data" is const RIL_CallForwardInfo *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_STATE
+ *  FDN_CHECK_FAILURE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SET_CALL_FORWARD 34
+
+
+/**
+ * RIL_REQUEST_QUERY_CALL_WAITING
+ *
+ * Query current call waiting state
+ *
+ * "data" is const int *
+ * ((const int *)data)[0] is the TS 27.007 service class to query.
+ * "response" is a const int *
+ * ((const int *)response)[0] is 0 for "disabled" and 1 for "enabled"
+ *
+ * If ((const int *)response)[0] is = 1, then ((const int *)response)[1]
+ * must follow, with the TS 27.007 service class bit vector of services
+ * for which call waiting is enabled.
+ *
+ * For example, if ((const int *)response)[0]  is 1 and
+ * ((const int *)response)[1] is 3, then call waiting is enabled for data
+ * and voice and disabled for everything else
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  FDN_CHECK_FAILURE
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_QUERY_CALL_WAITING 35
+
+
+/**
+ * RIL_REQUEST_SET_CALL_WAITING
+ *
+ * Configure current call waiting state
+ *
+ * "data" is const int *
+ * ((const int *)data)[0] is 0 for "disabled" and 1 for "enabled"
+ * ((const int *)data)[1] is the TS 27.007 service class bit vector of
+ *                           services to modify
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_STATE
+ *  FDN_CHECK_FAILURE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SET_CALL_WAITING 36
+
+/**
+ * RIL_REQUEST_SMS_ACKNOWLEDGE
+ *
+ * Acknowledge successful or failed receipt of SMS previously indicated
+ * via RIL_UNSOL_RESPONSE_NEW_SMS
+ *
+ * "data" is int *
+ * ((int *)data)[0] is 1 on successful receipt
+ *                  (basically, AT+CNMA=1 from TS 27.005
+ *                  is 0 on failed receipt
+ *                  (basically, AT+CNMA=2 from TS 27.005)
+ * ((int *)data)[1] if data[0] is 0, this contains the failure cause as defined
+ *                  in TS 23.040, 9.2.3.22. Currently only 0xD3 (memory
+ *                  capacity exceeded) and 0xFF (unspecified error) are
+ *                  reported.
+ *
+ * "response" is NULL
+ *
+ * FIXME would like request that specified RP-ACK/RP-ERROR PDU
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SMS_ACKNOWLEDGE  37
+
+/**
+ * RIL_REQUEST_GET_IMEI - DEPRECATED
+ *
+ * Get the device IMEI, including check digit
+ *
+ * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY
+ * Valid when RadioState is not RADIO_STATE_UNAVAILABLE
+ *
+ * "data" is NULL
+ * "response" is a const char * containing the IMEI
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  NOT_PROVISIONED
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+
+#define RIL_REQUEST_GET_IMEI 38
+
+/**
+ * RIL_REQUEST_GET_IMEISV - DEPRECATED
+ *
+ * Get the device IMEISV, which should be two decimal digits
+ *
+ * The request is DEPRECATED, use RIL_REQUEST_DEVICE_IDENTITY
+ * Valid when RadioState is not RADIO_STATE_UNAVAILABLE
+ *
+ * "data" is NULL
+ * "response" is a const char * containing the IMEISV
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  NOT_PROVISIONED
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+
+#define RIL_REQUEST_GET_IMEISV 39
+
+
+/**
+ * RIL_REQUEST_ANSWER
+ *
+ * Answer incoming call
+ *
+ * Will not be called for WAITING calls.
+ * RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE will be used in this case
+ * instead
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_ANSWER 40
+
+/**
+ * RIL_REQUEST_DEACTIVATE_DATA_CALL
+ *
+ * Deactivate packet data connection and remove from the
+ * data call list if SUCCESS is returned. Any other return
+ * values should also try to remove the call from the list,
+ * but that may not be possible. In any event a
+ * RIL_REQUEST_RADIO_POWER off/on must clear the list. An
+ * RIL_UNSOL_DATA_CALL_LIST_CHANGED is not expected to be
+ * issued because of an RIL_REQUEST_DEACTIVATE_DATA_CALL.
+ *
+ * "data" is const char **
+ * ((char**)data)[0] indicating CID
+ * ((char**)data)[1] indicating Disconnect Reason
+ *                   0 => No specific reason specified
+ *                   1 => Radio shutdown requested
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_CALL_ID
+ *  INVALID_STATE
+ *  INVALID_ARGUMENTS
+ *  REQUEST_NOT_SUPPORTED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  SIM_ABSENT
+ *
+ * See also: RIL_REQUEST_SETUP_DATA_CALL
+ */
+#define RIL_REQUEST_DEACTIVATE_DATA_CALL 41
+
+/**
+ * RIL_REQUEST_QUERY_FACILITY_LOCK
+ *
+ * Query the status of a facility lock state
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is the facility string code from TS 27.007 7.4
+ *                      (eg "AO" for BAOC, "SC" for SIM lock)
+ * ((const char **)data)[1] is the password, or "" if not required
+ * ((const char **)data)[2] is the TS 27.007 service class bit vector of
+ *                           services to query
+ * ((const char **)data)[3] is AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ *                            This is only applicable in the case of Fixed Dialing Numbers
+ *                            (FDN) requests.
+ *
+ * "response" is an int *
+ * ((const int *)response) 0 is the TS 27.007 service class bit vector of
+ *                           services for which the specified barring facility
+ *                           is active. "0" means "disabled for all"
+ *
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  FDN_CHECK_FAILURE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_QUERY_FACILITY_LOCK 42
+
+/**
+ * RIL_REQUEST_SET_FACILITY_LOCK
+ *
+ * Enable/disable one facility lock
+ *
+ * "data" is const char **
+ *
+ * ((const char **)data)[0] = facility string code from TS 27.007 7.4
+ * (eg "AO" for BAOC)
+ * ((const char **)data)[1] = "0" for "unlock" and "1" for "lock"
+ * ((const char **)data)[2] = password
+ * ((const char **)data)[3] = string representation of decimal TS 27.007
+ *                            service class bit vector. Eg, the string
+ *                            "1" means "set this facility for voice services"
+ * ((const char **)data)[4] = AID value, See ETSI 102.221 8.1 and 101.220 4, NULL if no value.
+ *                            This is only applicable in the case of Fixed Dialing Numbers
+ *                            (FDN) requests.
+ *
+ * "response" is int *
+ * ((int *)response)[0] is the number of retries remaining, or -1 if unknown
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  INVALID_ARGUMENTS
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INVALID_STATE
+ *  FDN_CHECK_FAILURE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_SET_FACILITY_LOCK 43
+
+/**
+ * RIL_REQUEST_CHANGE_BARRING_PASSWORD
+ *
+ * Change call barring facility password
+ *
+ * "data" is const char **
+ *
+ * ((const char **)data)[0] = facility string code from TS 27.007 7.4
+ * (eg "AO" for BAOC)
+ * ((const char **)data)[1] = old password
+ * ((const char **)data)[2] = new password
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  FDN_CHECK_FAILURE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_CHANGE_BARRING_PASSWORD 44
+
+/**
+ * RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE
+ *
+ * Query current network selectin mode
+ *
+ * "data" is NULL
+ *
+ * "response" is int *
+ * ((const int *)response)[0] is
+ *     0 for automatic selection
+ *     1 for manual selection
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE 45
+
+/**
+ * RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC
+ *
+ * Specify that the network should be selected automatically
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * This request must not respond until the new operator is selected
+ * and registered
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  ILLEGAL_SIM_OR_ME
+ *  OPERATION_NOT_ALLOWED
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and
+ *       no retries needed, such as illegal SIM or ME.
+ *
+ */
+#define RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC 46
+
+/**
+ * RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL
+ *
+ * Manually select a specified network.
+ *
+ * "data" is const char * specifying MCCMNC of network to select (eg "310170")
+ * "response" is NULL
+ *
+ * This request must not respond until the new operator is selected
+ * and registered
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  ILLEGAL_SIM_OR_ME
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ * Note: Returns ILLEGAL_SIM_OR_ME when the failure is permanent and
+ *       no retries needed, such as illegal SIM or ME.
+ *
+ */
+#define RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL 47
+
+/**
+ * RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
+ *
+ * Scans for available networks
+ *
+ * "data" is NULL
+ * "response" is const char ** that should be an array of n*4 strings, where
+ *    n is the number of available networks
+ * For each available network:
+ *
+ * ((const char **)response)[n+0] is long alpha ONS or EONS
+ * ((const char **)response)[n+1] is short alpha ONS or EONS
+ * ((const char **)response)[n+2] is 5 or 6 digit numeric code (MCC + MNC)
+ * ((const char **)response)[n+3] is a string value of the status:
+ *           "unknown"
+ *           "available"
+ *           "current"
+ *           "forbidden"
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  OPERATION_NOT_ALLOWED
+ *  ABORTED
+ *  DEVICE_IN_USE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  CANCELLED
+ *  OPERATION_NOT_ALLOWED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_QUERY_AVAILABLE_NETWORKS 48
+
+/**
+ * RIL_REQUEST_DTMF_START
+ *
+ * Start playing a DTMF tone. Continue playing DTMF tone until
+ * RIL_REQUEST_DTMF_STOP is received
+ *
+ * If a RIL_REQUEST_DTMF_START is received while a tone is currently playing,
+ * it should cancel the previous tone and play the new one.
+ *
+ * "data" is a char *
+ * ((char *)data)[0] is a single character with one of 12 values: 0-9,*,#
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_STOP
+ */
+#define RIL_REQUEST_DTMF_START 49
+
+/**
+ * RIL_REQUEST_DTMF_STOP
+ *
+ * Stop playing a currently playing DTMF tone.
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  OPERATION_NOT_ALLOWED
+ *  NO_RESOURCES
+ *  NO_MEMORY
+ *  INVALID_ARGUMENTS
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ * See also: RIL_REQUEST_DTMF, RIL_REQUEST_DTMF_START
+ */
+#define RIL_REQUEST_DTMF_STOP 50
+
+/**
+ * RIL_REQUEST_BASEBAND_VERSION
+ *
+ * Return string value indicating baseband version, eg
+ * response from AT+CGMR
+ *
+ * "data" is NULL
+ * "response" is const char * containing version string for log reporting
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  EMPTY_RECORD
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  NOT_PROVISIONED
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_BASEBAND_VERSION 51
+
+/**
+ * RIL_REQUEST_SEPARATE_CONNECTION
+ *
+ * Separate a party from a multiparty call placing the multiparty call
+ * (less the specified party) on hold and leaving the specified party
+ * as the only other member of the current (active) call
+ *
+ * Like AT+CHLD=2x
+ *
+ * See TS 22.084 1.3.8.2 (iii)
+ * TS 22.030 6.5.5 "Entering "2X followed by send"
+ * TS 27.007 "AT+CHLD=2x"
+ *
+ * "data" is an int *
+ * (int *)data)[0] contains Connection index (value of 'x' in CHLD above) "response" is NULL
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INVALID_ARGUMENTS
+ *  INVALID_STATE
+ *  NO_RESOURCES
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  INVALID_STATE
+ *  OPERATION_NOT_ALLOWED
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SEPARATE_CONNECTION 52
+
+
+/**
+ * RIL_REQUEST_SET_MUTE
+ *
+ * Turn on or off uplink (microphone) mute.
+ *
+ * Will only be sent while voice call is active.
+ * Will always be reset to "disable mute" when a new voice call is initiated
+ *
+ * "data" is an int *
+ * (int *)data)[0] is 1 for "enable mute" and 0 for "disable mute"
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_SET_MUTE 53
+
+/**
+ * RIL_REQUEST_GET_MUTE
+ *
+ * Queries the current state of the uplink mute setting
+ *
+ * "data" is NULL
+ * "response" is an int *
+ * (int *)response)[0] is 1 for "mute enabled" and 0 for "mute disabled"
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  SS_MODIFIED_TO_DIAL
+ *  SS_MODIFIED_TO_USSD
+ *  SS_MODIFIED_TO_SS
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_GET_MUTE 54
+
+/**
+ * RIL_REQUEST_QUERY_CLIP
+ *
+ * Queries the status of the CLIP supplementary service
+ *
+ * (for MMI code "*#30#")
+ *
+ * "data" is NULL
+ * "response" is an int *
+ * (int *)response)[0] is 1 for "CLIP provisioned"
+ *                           and 0 for "CLIP not provisioned"
+ *                           and 2 for "unknown, e.g. no network etc"
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  FDN_CHECK_FAILURE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_QUERY_CLIP 55
+
+/**
+ * RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE - Deprecated use the status
+ * field in RIL_Data_Call_Response_v6.
+ *
+ * Requests the failure cause code for the most recently failed PDP
+ * context or CDMA data connection active
+ * replaces RIL_REQUEST_LAST_PDP_FAIL_CAUSE
+ *
+ * "data" is NULL
+ *
+ * "response" is a "int *"
+ * ((int *)response)[0] is an integer cause code defined in TS 24.008
+ *   section 6.1.3.1.3 or close approximation
+ *
+ * If the implementation does not have access to the exact cause codes,
+ * then it should return one of the values listed in
+ * RIL_DataCallFailCause, as the UI layer needs to distinguish these
+ * cases for error notification
+ * and potential retries.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ * See also: RIL_REQUEST_LAST_CALL_FAIL_CAUSE
+ *
+ * Deprecated use the status field in RIL_Data_Call_Response_v6.
+ */
+
+#define RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE 56
+
+/**
+ * RIL_REQUEST_DATA_CALL_LIST
+ *
+ * Returns the data call list. An entry is added when a
+ * RIL_REQUEST_SETUP_DATA_CALL is issued and removed on a
+ * RIL_REQUEST_DEACTIVATE_DATA_CALL. The list is emptied
+ * when RIL_REQUEST_RADIO_POWER off/on is issued.
+ *
+ * "data" is NULL
+ * "response" is an array of RIL_Data_Call_Response_v6
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ *
+ * See also: RIL_UNSOL_DATA_CALL_LIST_CHANGED
+ */
+
+#define RIL_REQUEST_DATA_CALL_LIST 57
+
+/**
+ * RIL_REQUEST_RESET_RADIO - DEPRECATED
+ *
+ * Request a radio reset. The RIL implementation may postpone
+ * the reset until after this request is responded to if the baseband
+ * is presently busy.
+ *
+ * The request is DEPRECATED, use RIL_REQUEST_RADIO_POWER
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  REQUEST_NOT_SUPPORTED
+ */
+
+#define RIL_REQUEST_RESET_RADIO 58
+
+/**
+ * RIL_REQUEST_OEM_HOOK_RAW
+ *
+ * This request reserved for OEM-specific uses. It passes raw byte arrays
+ * back and forth.
+ *
+ * It can be invoked on the Java side from
+ * com.android.internal.telephony.Phone.invokeOemRilRequestRaw()
+ *
+ * "data" is a char * of bytes copied from the byte[] data argument in java
+ * "response" is a char * of bytes that will returned via the
+ * caller's "response" Message here:
+ * (byte[])(((AsyncResult)response.obj).result)
+ *
+ * An error response here will result in
+ * (((AsyncResult)response.obj).result) == null and
+ * (((AsyncResult)response.obj).exception) being an instance of
+ * com.android.internal.telephony.gsm.CommandException
+ *
+ * Valid errors:
+ *  All
+ */
+
+#define RIL_REQUEST_OEM_HOOK_RAW 59
+
+/**
+ * RIL_REQUEST_OEM_HOOK_STRINGS
+ *
+ * This request reserved for OEM-specific uses. It passes strings
+ * back and forth.
+ *
+ * It can be invoked on the Java side from
+ * com.android.internal.telephony.Phone.invokeOemRilRequestStrings()
+ *
+ * "data" is a const char **, representing an array of null-terminated UTF-8
+ * strings copied from the "String[] strings" argument to
+ * invokeOemRilRequestStrings()
+ *
+ * "response" is a const char **, representing an array of null-terminated UTF-8
+ * stings that will be returned via the caller's response message here:
+ *
+ * (String[])(((AsyncResult)response.obj).result)
+ *
+ * An error response here will result in
+ * (((AsyncResult)response.obj).result) == null and
+ * (((AsyncResult)response.obj).exception) being an instance of
+ * com.android.internal.telephony.gsm.CommandException
+ *
+ * Valid errors:
+ *  All
+ */
+
+#define RIL_REQUEST_OEM_HOOK_STRINGS 60
+
+/**
+ * RIL_REQUEST_SCREEN_STATE - DEPRECATED
+ *
+ * Indicates the current state of the screen.  When the screen is off, the
+ * RIL should notify the baseband to suppress certain notifications (eg,
+ * signal strength and changes in LAC/CID or BID/SID/NID/latitude/longitude)
+ * in an effort to conserve power.  These notifications should resume when the
+ * screen is on.
+ *
+ * Note this request is deprecated. Use RIL_REQUEST_SEND_DEVICE_STATE to report the device state
+ * to the modem and use RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER to turn on/off unsolicited
+ * response from the modem in different scenarios.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is == 1 for "Screen On"
+ * ((int *)data)[0] is == 0 for "Screen Off"
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SCREEN_STATE 61
+
+
+/**
+ * RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION
+ *
+ * Enables/disables supplementary service related notifications
+ * from the network.
+ *
+ * Notifications are reported via RIL_UNSOL_SUPP_SVC_NOTIFICATION.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is == 1 for notifications enabled
+ * ((int *)data)[0] is == 0 for notifications disabled
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SIM_BUSY
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ * See also: RIL_UNSOL_SUPP_SVC_NOTIFICATION.
+ */
+#define RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION 62
+
+/**
+ * RIL_REQUEST_WRITE_SMS_TO_SIM
+ *
+ * Stores a SMS message to SIM memory.
+ *
+ * "data" is RIL_SMS_WriteArgs *
+ *
+ * "response" is int *
+ * ((const int *)response)[0] is the record index where the message is stored.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  SIM_FULL
+ *  INVALID_ARGUMENTS
+ *  INVALID_SMS_FORMAT
+ *  INTERNAL_ERR
+ *  MODEM_ERR
+ *  ENCODING_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  INVALID_MODEM_STATE
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_SMSC_ADDRESS
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ *
+ */
+#define RIL_REQUEST_WRITE_SMS_TO_SIM 63
+
+/**
+ * RIL_REQUEST_DELETE_SMS_ON_SIM
+ *
+ * Deletes a SMS message from SIM memory.
+ *
+ * "data" is int  *
+ * ((int *)data)[0] is the record index of the message to delete.
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  SIM_FULL
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  NO_SUCH_ENTRY
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ *
+ */
+#define RIL_REQUEST_DELETE_SMS_ON_SIM 64
+
+/**
+ * RIL_REQUEST_SET_BAND_MODE
+ *
+ * Assign a specified band for RF configuration.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is a RIL_RadioBandMode
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  OPERATION_NOT_ALLOWED
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ * See also: RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE
+ */
+#define RIL_REQUEST_SET_BAND_MODE 65
+
+/**
+ * RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE
+ *
+ * Query the list of band mode supported by RF.
+ *
+ * "data" is NULL
+ *
+ * "response" is int *
+ * "response" points to an array of int's, the int[0] is the size of array;
+ * subsequent values are a list of RIL_RadioBandMode listing supported modes.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ * See also: RIL_REQUEST_SET_BAND_MODE
+ */
+#define RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE 66
+
+/**
+ * RIL_REQUEST_STK_GET_PROFILE
+ *
+ * Requests the profile of SIM tool kit.
+ * The profile indicates the SAT/USAT features supported by ME.
+ * The SAT/USAT features refer to 3GPP TS 11.14 and 3GPP TS 31.111
+ *
+ * "data" is NULL
+ *
+ * "response" is a const char * containing SAT/USAT profile
+ * in hexadecimal format string starting with first byte of terminal profile
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE (radio resetting)
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_STK_GET_PROFILE 67
+
+/**
+ * RIL_REQUEST_STK_SET_PROFILE
+ *
+ * Download the STK terminal profile as part of SIM initialization
+ * procedure
+ *
+ * "data" is a const char * containing SAT/USAT profile
+ * in hexadecimal format string starting with first byte of terminal profile
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE (radio resetting)
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_STK_SET_PROFILE 68
+
+/**
+ * RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND
+ *
+ * Requests to send a SAT/USAT envelope command to SIM.
+ * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111
+ *
+ * "data" is a const char * containing SAT/USAT command
+ * in hexadecimal format string starting with command tag
+ *
+ * "response" is a const char * containing SAT/USAT response
+ * in hexadecimal format string starting with first byte of response
+ * (May be NULL)
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE (radio resetting)
+ *  SIM_BUSY
+ *  OPERATION_NOT_ALLOWED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND 69
+
+/**
+ * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE
+ *
+ * Requests to send a terminal response to SIM for a received
+ * proactive command
+ *
+ * "data" is a const char * containing SAT/USAT response
+ * in hexadecimal format string starting with first byte of response data
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE (radio resetting)
+ *  RIL_E_OPERATION_NOT_ALLOWED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE 70
+
+/**
+ * RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM
+ *
+ * When STK application gets RIL_UNSOL_STK_CALL_SETUP, the call actually has
+ * been initialized by ME already. (We could see the call has been in the 'call
+ * list') So, STK application needs to accept/reject the call according as user
+ * operations.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is > 0 for "accept" the call setup
+ * ((int *)data)[0] is == 0 for "reject" the call setup
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE (radio resetting)
+ *  RIL_E_OPERATION_NOT_ALLOWED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM 71
+
+/**
+ * RIL_REQUEST_EXPLICIT_CALL_TRANSFER
+ *
+ * Connects the two calls and disconnects the subscriber from both calls.
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  INVALID_STATE
+ *  NO_RESOURCES
+ *  NO_MEMORY
+ *  INVALID_ARGUMENTS
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  INVALID_STATE
+ *  OPERATION_NOT_ALLOWED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_EXPLICIT_CALL_TRANSFER 72
+
+/**
+ * RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE
+ *
+ * Requests to set the preferred network type for searching and registering
+ * (CS/PS domain, RAT, and operation mode)
+ *
+ * "data" is int * which is RIL_PreferredNetworkType
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  OPERATION_NOT_ALLOWED
+ *  MODE_NOT_SUPPORTED
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE 73
+
+/**
+ * RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE
+ *
+ * Query the preferred network type (CS/PS domain, RAT, and operation mode)
+ * for searching and registering
+ *
+ * "data" is NULL
+ *
+ * "response" is int *
+ * ((int *)reponse)[0] is == RIL_PreferredNetworkType
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ * See also: RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE
+ */
+#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE 74
+
+/**
+ * RIL_REQUEST_NEIGHBORING_CELL_IDS
+ *
+ * Request neighboring cell id in GSM network
+ *
+ * "data" is NULL
+ * "response" must be a " const RIL_NeighboringCell** "
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  NO_NETWORK_FOUND
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_GET_NEIGHBORING_CELL_IDS 75
+
+/**
+ * RIL_REQUEST_SET_LOCATION_UPDATES
+ *
+ * Enables/disables network state change notifications due to changes in
+ * LAC and/or CID (for GSM) or BID/SID/NID/latitude/longitude (for CDMA).
+ * Basically +CREG=2 vs. +CREG=1 (TS 27.007).
+ *
+ * Note:  The RIL implementation should default to "updates enabled"
+ * when the screen is on and "updates disabled" when the screen is off.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is == 1 for updates enabled (+CREG=2)
+ * ((int *)data)[0] is == 0 for updates disabled (+CREG=1)
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ * See also: RIL_REQUEST_SCREEN_STATE, RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED
+ */
+#define RIL_REQUEST_SET_LOCATION_UPDATES 76
+
+/**
+ * RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE
+ *
+ * Request to set the location where the CDMA subscription shall
+ * be retrieved
+ *
+ * "data" is int *
+ * ((int *)data)[0] is == RIL_CdmaSubscriptionSource
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SIM_ABSENT
+ *  SUBSCRIPTION_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ * See also: RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE
+ */
+#define RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE 77
+
+/**
+ * RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE
+ *
+ * Request to set the roaming preferences in CDMA
+ *
+ * "data" is int *
+ * ((int *)data)[0] is == 0 for Home Networks only, as defined in PRL
+ * ((int *)data)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL
+ * ((int *)data)[0] is == 2 for Roaming on Any Network, as defined in the PRL
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  OPERATION_NOT_ALLOWED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE 78
+
+/**
+ * RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE
+ *
+ * Request the actual setting of the roaming preferences in CDMA in the modem
+ *
+ * "data" is NULL
+ *
+ * "response" is int *
+ * ((int *)response)[0] is == 0 for Home Networks only, as defined in PRL
+ * ((int *)response)[0] is == 1 for Roaming on Affiliated networks, as defined in PRL
+ * ((int *)response)[0] is == 2 for Roaming on Any Network, as defined in the PRL
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE 79
+
+/**
+ * RIL_REQUEST_SET_TTY_MODE
+ *
+ * Request to set the TTY mode
+ *
+ * "data" is int *
+ * ((int *)data)[0] is == 0 for TTY off
+ * ((int *)data)[0] is == 1 for TTY Full
+ * ((int *)data)[0] is == 2 for TTY HCO (hearing carryover)
+ * ((int *)data)[0] is == 3 for TTY VCO (voice carryover)
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SET_TTY_MODE 80
+
+/**
+ * RIL_REQUEST_QUERY_TTY_MODE
+ *
+ * Request the setting of TTY mode
+ *
+ * "data" is NULL
+ *
+ * "response" is int *
+ * ((int *)response)[0] is == 0 for TTY off
+ * ((int *)response)[0] is == 1 for TTY Full
+ * ((int *)response)[0] is == 2 for TTY HCO (hearing carryover)
+ * ((int *)response)[0] is == 3 for TTY VCO (voice carryover)
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_QUERY_TTY_MODE 81
+
+/**
+ * RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE
+ *
+ * Request to set the preferred voice privacy mode used in voice
+ * scrambling
+ *
+ * "data" is int *
+ * ((int *)data)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask)
+ * ((int *)data)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask)
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  INVALID_CALL_ID
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE 82
+
+/**
+ * RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE
+ *
+ * Request the setting of preferred voice privacy mode
+ *
+ * "data" is NULL
+ *
+ * "response" is int *
+ * ((int *)response)[0] is == 0 for Standard Privacy Mode (Public Long Code Mask)
+ * ((int *)response)[0] is == 1 for Enhanced Privacy Mode (Private Long Code Mask)
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE 83
+
+/**
+ * RIL_REQUEST_CDMA_FLASH
+ *
+ * Send FLASH
+ *
+ * "data" is const char *
+ * ((const char *)data)[0] is a FLASH string
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  INVALID_STATE
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_CDMA_FLASH 84
+
+/**
+ * RIL_REQUEST_CDMA_BURST_DTMF
+ *
+ * Send DTMF string
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is a DTMF string
+ * ((const char **)data)[1] is the DTMF ON length in milliseconds, or 0 to use
+ *                          default
+ * ((const char **)data)[2] is the DTMF OFF length in milliseconds, or 0 to use
+ *                          default
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  INVALID_CALL_ID
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  OPERATION_NOT_ALLOWED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_CDMA_BURST_DTMF 85
+
+/**
+ * RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY
+ *
+ * Takes a 26 digit string (20 digit AKEY + 6 digit checksum).
+ * If the checksum is valid the 20 digit AKEY is written to NV,
+ * replacing the existing AKEY no matter what it was before.
+ *
+ * "data" is const char *
+ * ((const char *)data)[0] is a 26 digit string (ASCII digits '0'-'9')
+ *                         where the last 6 digits are a checksum of the
+ *                         first 20, as specified in TR45.AHAG
+ *                         "Common Cryptographic Algorithms, Revision D.1
+ *                         Section 2.2"
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY 86
+
+/**
+ * RIL_REQUEST_CDMA_SEND_SMS
+ *
+ * Send a CDMA SMS message
+ *
+ * "data" is const RIL_CDMA_SMS_Message *
+ *
+ * "response" is a const RIL_SMS_Response *
+ *
+ * Based on the return error, caller decides to resend if sending sms
+ * fails. The CDMA error class is derived as follows,
+ * SUCCESS is error class 0 (no error)
+ * SMS_SEND_FAIL_RETRY is error class 2 (temporary failure)
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SMS_SEND_FAIL_RETRY
+ *  NETWORK_REJECT
+ *  INVALID_STATE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  INVALID_SMS_FORMAT
+ *  SYSTEM_ERR
+ *  FDN_CHECK_FAILURE
+ *  MODEM_ERR
+ *  NETWORK_ERR
+ *  ENCODING_ERR
+ *  INVALID_SMSC_ADDRESS
+ *  OPERATION_NOT_ALLOWED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *  MODE_NOT_SUPPORTED
+ *  SIM_ABSENT
+ *
+ */
+#define RIL_REQUEST_CDMA_SEND_SMS 87
+
+/**
+ * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE
+ *
+ * Acknowledge the success or failure in the receipt of SMS
+ * previously indicated via RIL_UNSOL_RESPONSE_CDMA_NEW_SMS
+ *
+ * "data" is const RIL_CDMA_SMS_Ack *
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  NO_SMS_TO_ACK
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INVALID_STATE
+ *  OPERATION_NOT_ALLOWED
+ *  NETWORK_NOT_READY
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE 88
+
+/**
+ * RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG
+ *
+ * Request the setting of GSM/WCDMA Cell Broadcast SMS config.
+ *
+ * "data" is NULL
+ *
+ * "response" is a const RIL_GSM_BroadcastSmsConfigInfo **
+ * "responselen" is count * sizeof (RIL_GSM_BroadcastSmsConfigInfo *)
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  SYSTEM_ERR
+ *  NO_RESOURCES
+ *  MODEM_ERR
+ *  SYSTEM_ERR
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG 89
+
+/**
+ * RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG
+ *
+ * Set GSM/WCDMA Cell Broadcast SMS config
+ *
+ * "data" is a const RIL_GSM_BroadcastSmsConfigInfo **
+ * "datalen" is count * sizeof(RIL_GSM_BroadcastSmsConfigInfo *)
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_STATE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  REQUEST_RATE_LIMITED
+ *  MODEM_ERR
+ *  SYSTEM_ERR
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG 90
+
+/**
+ * RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION
+ *
+* Enable or disable the reception of GSM/WCDMA Cell Broadcast SMS
+ *
+ * "data" is const int *
+ * (const int *)data[0] indicates to activate or turn off the
+ * reception of GSM/WCDMA Cell Broadcast SMS, 0-1,
+ *                       0 - Activate, 1 - Turn off
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_STATE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  REQUEST_RATE_LIMITED
+*   MODEM_ERR
+*   INTERNAL_ERR
+*   NO_RESOURCES
+*   CANCELLED
+*   INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION 91
+
+/**
+ * RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG
+ *
+ * Request the setting of CDMA Broadcast SMS config
+ *
+ * "data" is NULL
+ *
+ * "response" is a const RIL_CDMA_BroadcastSmsConfigInfo **
+ * "responselen" is count * sizeof (RIL_CDMA_BroadcastSmsConfigInfo *)
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  SYSTEM_ERR
+ *  NO_RESOURCES
+ *  MODEM_ERR
+ *  SYSTEM_ERR
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG 92
+
+/**
+ * RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG
+ *
+ * Set CDMA Broadcast SMS config
+ *
+ * "data" is a const RIL_CDMA_BroadcastSmsConfigInfo **
+ * "datalen" is count * sizeof(const RIL_CDMA_BroadcastSmsConfigInfo *)
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_STATE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  REQUEST_RATE_LIMITED
+ *  MODEM_ERR
+ *  SYSTEM_ERR
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG 93
+
+/**
+ * RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION
+ *
+ * Enable or disable the reception of CDMA Broadcast SMS
+ *
+ * "data" is const int *
+ * (const int *)data[0] indicates to activate or turn off the
+ * reception of CDMA Broadcast SMS, 0-1,
+ *                       0 - Activate, 1 - Turn off
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_STATE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  REQUEST_RATE_LIMITED
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION 94
+
+/**
+ * RIL_REQUEST_CDMA_SUBSCRIPTION
+ *
+ * Request the device MDN / H_SID / H_NID.
+ *
+ * The request is only allowed when CDMA subscription is available.  When CDMA
+ * subscription is changed, application layer should re-issue the request to
+ * update the subscription information.
+ *
+ * If a NULL value is returned for any of the device id, it means that error
+ * accessing the device.
+ *
+ * "response" is const char **
+ * ((const char **)response)[0] is MDN if CDMA subscription is available
+ * ((const char **)response)[1] is a comma separated list of H_SID (Home SID) if
+ *                              CDMA subscription is available, in decimal format
+ * ((const char **)response)[2] is a comma separated list of H_NID (Home NID) if
+ *                              CDMA subscription is available, in decimal format
+ * ((const char **)response)[3] is MIN (10 digits, MIN2+MIN1) if CDMA subscription is available
+ * ((const char **)response)[4] is PRL version if CDMA subscription is available
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RIL_E_SUBSCRIPTION_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  NOT_PROVISIONED
+ *  REQUEST_NOT_SUPPORTED
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+
+#define RIL_REQUEST_CDMA_SUBSCRIPTION 95
+
+/**
+ * RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM
+ *
+ * Stores a CDMA SMS message to RUIM memory.
+ *
+ * "data" is RIL_CDMA_SMS_WriteArgs *
+ *
+ * "response" is int *
+ * ((const int *)response)[0] is the record index where the message is stored.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SIM_FULL
+ *  INVALID_ARGUMENTS
+ *  INVALID_SMS_FORMAT
+ *  INTERNAL_ERR
+ *  MODEM_ERR
+ *  ENCODING_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  INVALID_MODEM_STATE
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_SMSC_ADDRESS
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ *
+ */
+#define RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM 96
+
+/**
+ * RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM
+ *
+ * Deletes a CDMA SMS message from RUIM memory.
+ *
+ * "data" is int  *
+ * ((int *)data)[0] is the record index of the message to delete.
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  NO_SUCH_ENTRY
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ */
+#define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97
+
+/**
+ * RIL_REQUEST_DEVICE_IDENTITY
+ *
+ * Request the device ESN / MEID / IMEI / IMEISV.
+ *
+ * The request is always allowed and contains GSM and CDMA device identity;
+ * it substitutes the deprecated requests RIL_REQUEST_GET_IMEI and
+ * RIL_REQUEST_GET_IMEISV.
+ *
+ * If a NULL value is returned for any of the device id, it means that error
+ * accessing the device.
+ *
+ * When CDMA subscription is changed the ESN/MEID may change.  The application
+ * layer should re-issue the request to update the device identity in this case.
+ *
+ * "response" is const char **
+ * ((const char **)response)[0] is IMEI if GSM subscription is available
+ * ((const char **)response)[1] is IMEISV if GSM subscription is available
+ * ((const char **)response)[2] is ESN if CDMA subscription is available
+ * ((const char **)response)[3] is MEID if CDMA subscription is available
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  NOT_PROVISIONED
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_DEVICE_IDENTITY 98
+
+/**
+ * RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE
+ *
+ * Request the radio's system selection module to exit emergency
+ * callback mode.  RIL will not respond with SUCCESS until the modem has
+ * completely exited from Emergency Callback Mode.
+ *
+ * "data" is NULL
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  OPERATION_NOT_ALLOWED
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE 99
+
+/**
+ * RIL_REQUEST_GET_SMSC_ADDRESS
+ *
+ * Queries the default Short Message Service Center address on the device.
+ *
+ * "data" is NULL
+ *
+ * "response" is const char * containing the SMSC address.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  REQUEST_RATE_LIMITED
+ *  SYSTEM_ERR
+ *  INTERNAL_ERR
+ *  MODEM_ERR
+ *  INVALID_ARGUMENTS
+ *  INVALID_MODEM_STATE
+ *  NOT_PROVISIONED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ *
+ */
+#define RIL_REQUEST_GET_SMSC_ADDRESS 100
+
+/**
+ * RIL_REQUEST_SET_SMSC_ADDRESS
+ *
+ * Sets the default Short Message Service Center address on the device.
+ *
+ * "data" is const char * containing the SMSC address.
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  INVALID_SMS_FORMAT
+ *  NO_MEMORY
+ *  SYSTEM_ERR
+ *  REQUEST_RATE_LIMITED
+ *  MODEM_ERR
+ *  NO_RESOURCES
+ *  INTERNAL_ERR
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ */
+#define RIL_REQUEST_SET_SMSC_ADDRESS 101
+
+/**
+ * RIL_REQUEST_REPORT_SMS_MEMORY_STATUS
+ *
+ * Indicates whether there is storage available for new SMS messages.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is 1 if memory is available for storing new messages
+ *                  is 0 if memory capacity is exceeded
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INVALID_ARGUMENTS
+ *  NO_MEMORY
+ *  INVALID_STATE
+ *  SYSTEM_ERR
+ *  REQUEST_RATE_LIMITED
+ *  MODEM_ERR
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_REPORT_SMS_MEMORY_STATUS 102
+
+/**
+ * RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING
+ *
+ * Indicates that the StkSerivce is running and is
+ * ready to receive RIL_UNSOL_STK_XXXXX commands.
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING 103
+
+/**
+ * RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE
+ *
+ * Request to query the location where the CDMA subscription shall
+ * be retrieved
+ *
+ * "data" is NULL
+ *
+ * "response" is int *
+ * ((int *)data)[0] is == RIL_CdmaSubscriptionSource
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SUBSCRIPTION_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ * See also: RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE
+ */
+#define RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE 104
+
+/**
+ * RIL_REQUEST_ISIM_AUTHENTICATION
+ *
+ * Request the ISIM application on the UICC to perform AKA
+ * challenge/response algorithm for IMS authentication
+ *
+ * "data" is a const char * containing the challenge string in Base64 format
+ * "response" is a const char * containing the response in Base64 format
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_ISIM_AUTHENTICATION 105
+
+/**
+ * RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU
+ *
+ * Acknowledge successful or failed receipt of SMS previously indicated
+ * via RIL_UNSOL_RESPONSE_NEW_SMS, including acknowledgement TPDU to send
+ * as the RP-User-Data element of the RP-ACK or RP-ERROR PDU.
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] is "1" on successful receipt (send RP-ACK)
+ *                          is "0" on failed receipt (send RP-ERROR)
+ * ((const char **)data)[1] is the acknowledgement TPDU in hexadecimal format
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU 106
+
+/**
+ * RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS
+ *
+ * Requests to send a SAT/USAT envelope command to SIM.
+ * The SAT/USAT envelope command refers to 3GPP TS 11.14 and 3GPP TS 31.111.
+ *
+ * This request has one difference from RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
+ * the SW1 and SW2 status bytes from the UICC response are returned along with
+ * the response data, using the same structure as RIL_REQUEST_SIM_IO.
+ *
+ * The RIL implementation shall perform the normal processing of a '91XX'
+ * response in SW1/SW2 to retrieve the pending proactive command and send it
+ * as an unsolicited response, as RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND does.
+ *
+ * "data" is a const char * containing the SAT/USAT command
+ * in hexadecimal format starting with command tag
+ *
+ * "response" is a const RIL_SIM_IO_Response *
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE (radio resetting)
+ *  SIM_BUSY
+ *  OPERATION_NOT_ALLOWED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ */
+#define RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS 107
+
+/**
+ * RIL_REQUEST_VOICE_RADIO_TECH
+ *
+ * Query the radio technology type (3GPP/3GPP2) used for voice. Query is valid only
+ * when radio state is not RADIO_STATE_UNAVAILABLE
+ *
+ * "data" is NULL
+ * "response" is int *
+ * ((int *) response)[0] is of type const RIL_RadioTechnology
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_VOICE_RADIO_TECH 108
+
+/**
+ * RIL_REQUEST_GET_CELL_INFO_LIST
+ *
+ * Request all of the current cell information known to the radio. The radio
+ * must a list of all current cells, including the neighboring cells. If for a particular
+ * cell information isn't known then the appropriate unknown value will be returned.
+ * This does not cause or change the rate of RIL_UNSOL_CELL_INFO_LIST.
+ *
+ * "data" is NULL
+ *
+ * "response" is an array of  RIL_CellInfo_v12.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  NO_NETWORK_FOUND
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_GET_CELL_INFO_LIST 109
+
+/**
+ * RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE
+ *
+ * Sets the minimum time between when RIL_UNSOL_CELL_INFO_LIST should be invoked.
+ * A value of 0, means invoke RIL_UNSOL_CELL_INFO_LIST when any of the reported
+ * information changes. Setting the value to INT_MAX(0x7fffffff) means never issue
+ * a RIL_UNSOL_CELL_INFO_LIST.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is minimum time in milliseconds
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110
+
+/**
+ * RIL_REQUEST_SET_INITIAL_ATTACH_APN
+ *
+ * Set an apn to initial attach network
+ *
+ * "data" is a const char **
+ * ((const char **)data)[0] is the APN to connect if radio technology is LTE
+ * ((const char **)data)[1] is the connection type to request must be one of the
+ *                          PDP_type values in TS 27.007 section 10.1.1.
+ *                          For example, "IP", "IPV6", "IPV4V6", or "PPP".
+ * ((const char **)data)[2] is the PAP / CHAP auth type. Values:
+ *                          0 => PAP and CHAP is never performed.
+ *                          1 => PAP may be performed; CHAP is never performed.
+ *                          2 => CHAP may be performed; PAP is never performed.
+ *                          3 => PAP / CHAP may be performed - baseband dependent.
+ * ((const char **)data)[3] is the username for APN, or NULL
+ * ((const char **)data)[4] is the password for APN, or NULL
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  SUBSCRIPTION_NOT_AVAILABLE
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  NOT_PROVISIONED
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111
+
+/**
+ * RIL_REQUEST_IMS_REGISTRATION_STATE
+ *
+ * This message is DEPRECATED and shall be removed in a future release (target: 2018);
+ * instead, provide IMS registration status via an IMS Service.
+ *
+ * Request current IMS registration state
+ *
+ * "data" is NULL
+ *
+ * "response" is int *
+ * ((int *)response)[0] is registration state:
+ *              0 - Not registered
+ *              1 - Registered
+ *
+ * If ((int*)response)[0] is = 1, then ((int *) response)[1]
+ * must follow with IMS SMS format:
+ *
+ * ((int *) response)[1] is of type RIL_RadioTechnologyFamily
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_IMS_REGISTRATION_STATE 112
+
+/**
+ * RIL_REQUEST_IMS_SEND_SMS
+ *
+ * Send a SMS message over IMS
+ *
+ * "data" is const RIL_IMS_SMS_Message *
+ *
+ * "response" is a const RIL_SMS_Response *
+ *
+ * Based on the return error, caller decides to resend if sending sms
+ * fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry.
+ * In case of retry, data is encoded based on Voice Technology available.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  SMS_SEND_FAIL_RETRY
+ *  FDN_CHECK_FAILURE
+ *  NETWORK_REJECT
+ *  INVALID_ARGUMENTS
+ *  INVALID_STATE
+ *  NO_MEMORY
+ *  INVALID_SMS_FORMAT
+ *  SYSTEM_ERR
+ *  REQUEST_RATE_LIMITED
+ *  MODEM_ERR
+ *  NETWORK_ERR
+ *  ENCODING_ERR
+ *  INVALID_SMSC_ADDRESS
+ *  OPERATION_NOT_ALLOWED
+ *  INTERNAL_ERR
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_IMS_SEND_SMS 113
+
+/**
+ * RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC
+ *
+ * Request APDU exchange on the basic channel. This command reflects TS 27.007
+ * "generic SIM access" operation (+CSIM). The modem must ensure proper function
+ * of GSM/CDMA, and filter commands appropriately. It should filter
+ * channel management and SELECT by DF name commands.
+ *
+ * "data" is a const RIL_SIM_APDU *
+ * "sessionid" field should be ignored.
+ *
+ * "response" is a const RIL_SIM_IO_Response *
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC 114
+
+/**
+ * RIL_REQUEST_SIM_OPEN_CHANNEL
+ *
+ * Open a new logical channel and select the given application. This command
+ * reflects TS 27.007 "open logical channel" operation (+CCHO). This request
+ * also specifies the P2 parameter (described in ISO 7816-4).
+ *
+ * "data" is a const RIL_OpenChannelParam *
+ *
+ * "response" is int *
+ * ((int *)data)[0] contains the session id of the logical channel.
+ * ((int *)data)[1] onwards may optionally contain the select response for the
+ *     open channel command with one byte per integer.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  MISSING_RESOURCE
+ *  NO_SUCH_ELEMENT
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  SIM_ERR
+ *  INVALID_SIM_STATE
+ *  MISSING_RESOURCE
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SIM_OPEN_CHANNEL 115
+
+/**
+ * RIL_REQUEST_SIM_CLOSE_CHANNEL
+ *
+ * Close a previously opened logical channel. This command reflects TS 27.007
+ * "close logical channel" operation (+CCHC).
+ *
+ * "data" is int *
+ * ((int *)data)[0] is the session id of logical the channel to close.
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SIM_CLOSE_CHANNEL 116
+
+/**
+ * RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL
+ *
+ * Exchange APDUs with a UICC over a previously opened logical channel. This
+ * command reflects TS 27.007 "generic logical channel access" operation
+ * (+CGLA). The modem should filter channel management and SELECT by DF name
+ * commands.
+ *
+ * "data" is a const RIL_SIM_APDU*
+ *
+ * "response" is a const RIL_SIM_IO_Response *
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL 117
+
+/**
+ * RIL_REQUEST_NV_READ_ITEM
+ *
+ * Read one of the radio NV items defined in RadioNVItems.java / ril_nv_items.h.
+ * This is used for device configuration by some CDMA operators.
+ *
+ * "data" is a const RIL_NV_ReadItem *
+ *
+ * "response" is const char * containing the contents of the NV item
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_NV_READ_ITEM 118
+
+/**
+ * RIL_REQUEST_NV_WRITE_ITEM
+ *
+ * Write one of the radio NV items defined in RadioNVItems.java / ril_nv_items.h.
+ * This is used for device configuration by some CDMA operators.
+ *
+ * "data" is a const RIL_NV_WriteItem *
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_NV_WRITE_ITEM 119
+
+/**
+ * RIL_REQUEST_NV_WRITE_CDMA_PRL
+ *
+ * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
+ * This is used for device configuration by some CDMA operators.
+ *
+ * "data" is a const char * containing the PRL as a byte array
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_NV_WRITE_CDMA_PRL 120
+
+/**
+ * RIL_REQUEST_NV_RESET_CONFIG
+ *
+ * Reset the radio NV configuration to the factory state.
+ * This is used for device configuration by some CDMA operators.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is 1 to reload all NV items
+ * ((int *)data)[0] is 2 for erase NV reset (SCRTN)
+ * ((int *)data)[0] is 3 for factory reset (RTN)
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_NV_RESET_CONFIG 121
+
+ /** RIL_REQUEST_SET_UICC_SUBSCRIPTION
+ * FIXME This API needs to have more documentation.
+ *
+ * Selection/de-selection of a subscription from a SIM card
+ * "data" is const  RIL_SelectUiccSub*
+
+ *
+ * "response" is NULL
+ *
+ *  Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  SUBSCRIPTION_NOT_SUPPORTED
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_SET_UICC_SUBSCRIPTION  122
+
+/**
+ *  RIL_REQUEST_ALLOW_DATA
+ *
+ *  Tells the modem whether data calls are allowed or not
+ *
+ * "data" is int *
+ * FIXME slotId and aid will be added.
+ * ((int *)data)[0] is == 0 to allow data calls
+ * ((int *)data)[0] is == 1 to disallow data calls
+ *
+ * "response" is NULL
+ *
+ *  Valid errors:
+ *
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  MODEM_ERR
+ *  INVALID_ARGUMENTS
+ *  DEVICE_IN_USE
+ *  INVALID_MODEM_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_ALLOW_DATA  123
+
+/**
+ * RIL_REQUEST_GET_HARDWARE_CONFIG
+ *
+ * Request all of the current hardware (modem and sim) associated
+ * with the RIL.
+ *
+ * "data" is NULL
+ *
+ * "response" is an array of  RIL_HardwareConfig.
+ *
+ * Valid errors:
+ * RADIO_NOT_AVAILABLE
+ * REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_GET_HARDWARE_CONFIG 124
+
+/**
+ * RIL_REQUEST_SIM_AUTHENTICATION
+ *
+ * Returns the response of SIM Authentication through RIL to a
+ * challenge request.
+ *
+ * "data" Base64 encoded string containing challenge:
+ *      int   authContext;          P2 value of authentication command, see P2 parameter in
+ *                                  3GPP TS 31.102 7.1.2
+ *      char *authData;             the challenge string in Base64 format, see 3GPP
+ *                                  TS 31.102 7.1.2
+ *      char *aid;                  AID value, See ETSI 102.221 8.1 and 101.220 4,
+ *                                  NULL if no value
+ *
+ * "response" Base64 encoded strings containing response:
+ *      int   sw1;                  Status bytes per 3GPP TS 31.102 section 7.3
+ *      int   sw2;
+ *      char *simResponse;          Response in Base64 format, see 3GPP TS 31.102 7.1.2
+ *
+ *  Valid errors:
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  INVALID_MODEM_STATE
+ *  INVALID_ARGUMENTS
+ *  SIM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ */
+#define RIL_REQUEST_SIM_AUTHENTICATION 125
+
+/**
+ * RIL_REQUEST_GET_DC_RT_INFO
+ *
+ * The request is DEPRECATED, use RIL_REQUEST_GET_ACTIVITY_INFO
+ * Requests the Data Connection Real Time Info
+ *
+ * "data" is NULL
+ *
+ * "response" is the most recent RIL_DcRtInfo
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  REQUEST_NOT_SUPPORTED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ * See also: RIL_UNSOL_DC_RT_INFO_CHANGED
+ */
+#define RIL_REQUEST_GET_DC_RT_INFO 126
+
+/**
+ * RIL_REQUEST_SET_DC_RT_INFO_RATE
+ *
+ * The request is DEPRECATED
+ * This is the minimum number of milliseconds between successive
+ * RIL_UNSOL_DC_RT_INFO_CHANGED messages and defines the highest rate
+ * at which RIL_UNSOL_DC_RT_INFO_CHANGED's will be sent. A value of
+ * 0 means send as fast as possible.
+ *
+ * "data" The number of milliseconds as an int
+ *
+ * "response" is null
+ *
+ * Valid errors:
+ *  SUCCESS must not fail
+ */
+#define RIL_REQUEST_SET_DC_RT_INFO_RATE 127
+
+/**
+ * RIL_REQUEST_SET_DATA_PROFILE
+ *
+ * Set data profile in modem
+ * Modem should erase existed profiles from framework, and apply new profiles
+ * "data" is a const RIL_DataProfileInfo **
+ * "datalen" is count * sizeof(const RIL_DataProfileInfo *)
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  SUBSCRIPTION_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ */
+#define RIL_REQUEST_SET_DATA_PROFILE 128
+
+/**
+ * RIL_REQUEST_SHUTDOWN
+ *
+ * Device is shutting down. All further commands are ignored
+ * and RADIO_NOT_AVAILABLE must be returned.
+ *
+ * "data" is null
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  OPERATION_NOT_ALLOWED
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SHUTDOWN 129
+
+/**
+ * RIL_REQUEST_GET_RADIO_CAPABILITY
+ *
+ * Used to get phone radio capablility.
+ *
+ * "data" is the RIL_RadioCapability structure
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  OPERATION_NOT_ALLOWED
+ *  INVALID_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_GET_RADIO_CAPABILITY 130
+
+/**
+ * RIL_REQUEST_SET_RADIO_CAPABILITY
+ *
+ * Used to set the phones radio capability. Be VERY careful
+ * using this request as it may cause some vendor modems to reset. Because
+ * of the possible modem reset any RIL commands after this one may not be
+ * processed.
+ *
+ * "data" is the RIL_RadioCapability structure
+ *
+ * "response" is the RIL_RadioCapability structure, used to feedback return status
+ *
+ * Valid errors:
+ *  SUCCESS means a RIL_UNSOL_RADIO_CAPABILITY will be sent within 30 seconds.
+ *  RADIO_NOT_AVAILABLE
+ *  OPERATION_NOT_ALLOWED
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  MODEM_ERR
+ *  INVALID_STATE
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SET_RADIO_CAPABILITY 131
+
+/**
+ * RIL_REQUEST_START_LCE
+ *
+ * Start Link Capacity Estimate (LCE) service if supported by the radio.
+ *
+ * "data" is const int *
+ * ((const int*)data)[0] specifies the desired reporting interval (ms).
+ * ((const int*)data)[1] specifies the LCE service mode. 1: PULL; 0: PUSH.
+ *
+ * "response" is the RIL_LceStatusInfo.
+ *
+ * Valid errors:
+ * SUCCESS
+ * RADIO_NOT_AVAILABLE
+ * LCE_NOT_SUPPORTED
+ * INTERNAL_ERR
+ * REQUEST_NOT_SUPPORTED
+ * NO_MEMORY
+ * NO_RESOURCES
+ * CANCELLED
+ * SIM_ABSENT
+ */
+#define RIL_REQUEST_START_LCE 132
+
+/**
+ * RIL_REQUEST_STOP_LCE
+ *
+ * Stop Link Capacity Estimate (LCE) service, the STOP operation should be
+ * idempotent for the radio modem.
+ *
+ * "response" is the RIL_LceStatusInfo.
+ *
+ * Valid errors:
+ * SUCCESS
+ * RADIO_NOT_AVAILABLE
+ * LCE_NOT_SUPPORTED
+ * INTERNAL_ERR
+ * NO_MEMORY
+ * NO_RESOURCES
+ * CANCELLED
+ * REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ */
+#define RIL_REQUEST_STOP_LCE 133
+
+/**
+ * RIL_REQUEST_PULL_LCEDATA
+ *
+ * Pull LCE service for capacity information.
+ *
+ * "response" is the RIL_LceDataInfo.
+ *
+ * Valid errors:
+ * SUCCESS
+ * RADIO_NOT_AVAILABLE
+ * LCE_NOT_SUPPORTED
+ * INTERNAL_ERR
+ * NO_MEMORY
+ * NO_RESOURCES
+ * CANCELLED
+ * REQUEST_NOT_SUPPORTED
+ *  SIM_ABSENT
+ */
+#define RIL_REQUEST_PULL_LCEDATA 134
+
+/**
+ * RIL_REQUEST_GET_ACTIVITY_INFO
+ *
+ * Get modem activity information for power consumption estimation.
+ *
+ * Request clear-on-read statistics information that is used for
+ * estimating the per-millisecond power consumption of the cellular
+ * modem.
+ *
+ * "data" is null
+ * "response" is const RIL_ActivityStatsInfo *
+ *
+ * Valid errors:
+ *
+ * SUCCESS
+ * RADIO_NOT_AVAILABLE (radio resetting)
+ * NO_MEMORY
+ * INTERNAL_ERR
+ * SYSTEM_ERR
+ * MODEM_ERR
+ * NOT_PROVISIONED
+ * REQUEST_NOT_SUPPORTED
+ * NO_RESOURCES CANCELLED
+ */
+#define RIL_REQUEST_GET_ACTIVITY_INFO 135
+
+/**
+ * RIL_REQUEST_SET_CARRIER_RESTRICTIONS
+ *
+ * Set carrier restrictions for this sim slot. Expected modem behavior:
+ *  If never receives this command
+ *  - Must allow all carriers
+ *  Receives this command with data being NULL
+ *  - Must allow all carriers. If a previously allowed SIM is present, modem must not reload
+ *    the SIM. If a previously disallowed SIM is present, reload the SIM and notify Android.
+ *  Receives this command with a list of carriers
+ *  - Only allow specified carriers, persist across power cycles and FDR. If a present SIM
+ *    is in the allowed list, modem must not reload the SIM. If a present SIM is *not* in
+ *    the allowed list, modem must detach from the registered network and only keep emergency
+ *    service, and notify Android SIM refresh reset with new SIM state being
+ *    RIL_CARDSTATE_RESTRICTED. Emergency service must be enabled.
+ *
+ * "data" is const RIL_CarrierRestrictions *
+ * A list of allowed carriers and possibly a list of excluded carriers.
+ * If data is NULL, means to clear previous carrier restrictions and allow all carriers
+ *
+ * "response" is int *
+ * ((int *)data)[0] contains the number of allowed carriers which have been set correctly.
+ * On success, it should match the length of list data->allowed_carriers.
+ * If data is NULL, the value must be 0.
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_INVALID_ARGUMENTS
+ *  RIL_E_RADIO_NOT_AVAILABLE
+ *  RIL_E_REQUEST_NOT_SUPPORTED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SET_CARRIER_RESTRICTIONS 136
+
+/**
+ * RIL_REQUEST_GET_CARRIER_RESTRICTIONS
+ *
+ * Get carrier restrictions for this sim slot. Expected modem behavior:
+ *  Return list of allowed carriers, or null if all carriers are allowed.
+ *
+ * "data" is NULL
+ *
+ * "response" is const RIL_CarrierRestrictions *.
+ * If response is NULL, it means all carriers are allowed.
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE
+ *  RIL_E_REQUEST_NOT_SUPPORTED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_GET_CARRIER_RESTRICTIONS 137
+
+/**
+ * RIL_REQUEST_SEND_DEVICE_STATE
+ *
+ * Send the updated device state.
+ * Modem can perform power saving based on the provided device state.
+ * "data" is const int *
+ * ((const int*)data)[0] A RIL_DeviceStateType that specifies the device state type.
+ * ((const int*)data)[1] Specifies the state. See RIL_DeviceStateType for the definition of each
+ *                       type.
+ *
+ * "datalen" is count * sizeof(const RIL_DeviceState *)
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  INVALID_ARGUMENTS
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SEND_DEVICE_STATE 138
+
+/**
+ * RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER
+ *
+ * Set the unsolicited response filter
+ * This is used to prevent unnecessary application processor
+ * wake up for power saving purposes by suppressing the
+ * unsolicited responses in certain scenarios.
+ *
+ * "data" is an int *
+ *
+ * ((int *)data)[0] is a 32-bit bitmask of RIL_UnsolicitedResponseFilter
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  INVALID_ARGUMENTS (e.g. the requested filter doesn't exist)
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  NO_MEMORY
+ *  INTERNAL_ERR
+ *  SYSTEM_ERR
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER 139
+
+ /**
+  * RIL_REQUEST_SET_SIM_CARD_POWER
+  *
+  * Set SIM card power up or down
+  *
+  * Request is equivalent to inserting and removing the card, with
+  * an additional effect where the ability to detect card removal/insertion
+  * is disabled when the SIM card is powered down.
+  *
+  * This will generate RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED
+  * as if the SIM had been inserted or removed.
+  *
+  * "data" is int *
+  * ((int *)data)[0] is 1 for "SIM POWER UP"
+  * ((int *)data)[0] is 0 for "SIM POWER DOWN"
+  *
+  * "response" is NULL
+  *
+  * Valid errors:
+  *  SUCCESS
+  *  RADIO_NOT_AVAILABLE
+  *  REQUEST_NOT_SUPPORTED
+  *  SIM_ABSENT
+  *  INVALID_ARGUMENTS
+  *  INTERNAL_ERR
+  *  NO_MEMORY
+  *  NO_RESOURCES
+  *  CANCELLED
+  */
+#define RIL_REQUEST_SET_SIM_CARD_POWER 140
+
+/**
+ * RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION
+ *
+ * Provide Carrier specific information to the modem that will be used to
+ * encrypt the IMSI and IMPI. Sent by the framework during boot, carrier
+ * switch and everytime we receive a new certificate.
+ *
+ * "data" is the RIL_CarrierInfoForImsiEncryption * structure.
+ *
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE
+ *  SIM_ABSENT
+ *  RIL_E_REQUEST_NOT_SUPPORTED
+ *  INVALID_ARGUMENTS
+ *  MODEM_INTERNAL_FAILURE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION 141
+
+/**
+ * RIL_REQUEST_START_NETWORK_SCAN
+ *
+ * Starts a new network scan
+ *
+ * Request to start a network scan with specified radio access networks with frequency bands and/or
+ * channels.
+ *
+ * "data" is a const RIL_NetworkScanRequest *.
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  OPERATION_NOT_ALLOWED
+ *  DEVICE_IN_USE
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  MODEM_ERR
+ *  INVALID_ARGUMENTS
+ *  REQUEST_NOT_SUPPORTED
+ *  NO_RESOURCES
+ *  CANCELLED
+ *
+ */
+#define RIL_REQUEST_START_NETWORK_SCAN 142
+
+/**
+ * RIL_REQUEST_STOP_NETWORK_SCAN
+ *
+ * Stops an ongoing network scan
+ *
+ * Request to stop the ongoing network scan. Since the modem can only perform one scan at a time,
+ * there is no parameter for this request.
+ *
+ * "data" is NULL
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  INTERNAL_ERR
+ *  MODEM_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ *  REQUEST_NOT_SUPPORTED
+ *
+ */
+#define RIL_REQUEST_STOP_NETWORK_SCAN 143
+
+/**
+ * RIL_REQUEST_START_KEEPALIVE
+ *
+ * Start a keepalive session
+ *
+ * Request that the modem begin sending keepalive packets on a particular
+ * data call, with a specified source, destination, and format.
+ *
+ * "data" is a const RIL_RequestKeepalive
+ * "response" is RIL_KeepaliveStatus with a valid "handle"
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  NO_RESOURCES
+ *  INVALID_ARGUMENTS
+ *
+ */
+#define RIL_REQUEST_START_KEEPALIVE 144
+
+/**
+ * RIL_REQUEST_STOP_KEEPALIVE
+ *
+ * Stops an ongoing keepalive session
+ *
+ * Requests that a keepalive session with the given handle be stopped.
+ * there is no parameter for this request.
+ *
+ * "data" is an integer handle
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  INVALID_ARGUMENTS
+ *
+ */
+#define RIL_REQUEST_STOP_KEEPALIVE 145
+
+/**
+ * RIL_REQUEST_START_NETWORK_SCAN4
+ *
+ * Starts a new network scan
+ *
+ * Request to start a network scan with specified radio access networks with frequency bands and/or
+ * channels.
+ *
+ * "data" is a const RIL_NetworkScanRequest *.
+ * "response" is NULL
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  DEVICE_IN_USE
+ *  INTERNAL_ERR
+ *  MODEM_ERR
+ *  INVALID_ARGUMENTS
+ *
+ */
+#define RIL_REQUEST_START_NETWORK_SCAN4 146
+
+/**
+ * RIL_REQUEST_GET_MODEM_STACK_STATUS
+ *
+ * Request status of a logical modem
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  MODEM_ERR
+ *
+ */
+#define RIL_REQUEST_GET_MODEM_STACK_STATUS 147
+
+/**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param networkTypeBitmap a 32-bit bitmap of RadioAccessFamily.
+ *
+ * Valid errors returned:
+ *   RadioError:NONE
+ *   RadioError:RADIO_NOT_AVAILABLE
+ *   RadioError:INTERNAL_ERR
+ *   RadioError:INVALID_ARGUMENTS
+ *   RadioError:MODEM_ERR
+ *   RadioError:REQUEST_NOT_SUPPORTED
+ *   RadioError:NO_RESOURCES
+ */
+#define RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP 148
+
+/**
+ * Callback of IRadio.setPreferredNetworkTypeBitmap(int, bitfield<RadioAccessFamily>)
+ *
+ * @param info Response info struct containing response type, serial no. and error
+ *
+ * Valid errors returned:
+ *   RadioError:NONE
+ *   RadioError:RADIO_NOT_AVAILABLE
+ *   RadioError:OPERATION_NOT_ALLOWED
+ *   RadioError:MODE_NOT_SUPPORTED
+ *   RadioError:INTERNAL_ERR
+ *   RadioError:INVALID_ARGUMENTS
+ *   RadioError:MODEM_ERR
+ *   RadioError:REQUEST_NOT_SUPPORTED
+ *   RadioError:NO_RESOURCES
+ */
+#define RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP 149
+
+/**
+ * RIL_REQUEST_EMERGENCY_DIAL
+ *
+ * Initiate emergency voice call, with zero or more emergency service category(s), zero or
+ * more emergency Uniform Resource Names (URN), and routing information for handling the call.
+ * Android uses this request to make its emergency call instead of using @1.0::IRadio.dial
+ * if the 'address' in the 'dialInfo' field is identified as an emergency number by Android.
+ *
+ * In multi-sim scenario, if the emergency number is from a specific subscription, this radio
+ * request is sent through the IRadio service that serves the subscription, no matter of the
+ * PUK/PIN state of the subscription and the service state of the radio.
+ *
+ * Some countries or carriers require some emergency numbers that must be handled with normal
+ * call routing or emergency routing. If the 'routing' field is specified as
+ * @1.4::EmergencyNumberRouting#NORMAL, the implementation must use normal call routing to
+ * handle the call; if it is specified as @1.4::EmergencyNumberRouting#EMERGENCY, the
+ * implementation must use emergency routing to handle the call; if it is
+ * @1.4::EmergencyNumberRouting#UNKNOWN, Android does not know how to handle the call.
+ *
+ * If the dialed emergency number does not have a specified emergency service category, the
+ * 'categories' field is set to @1.4::EmergencyServiceCategory#UNSPECIFIED; if the dialed
+ * emergency number does not have specified emergency Uniform Resource Names, the 'urns' field
+ * is set to an empty list. If the underlying technology used to request emergency services
+ * does not support the emergency service category or emergency uniform resource names, the
+ * field 'categories' or 'urns' may be ignored.
+ *
+ * 'fromEmergencyDialer' indicates if this request originated from emergency dialer/shortcut,
+ * which means an explicit intent from the user to dial an emergency number. The modem must
+ * treat this as an actual emergency dial and not try to disambiguate.
+ *
+ * If 'isTesting' is true, this request is for testing purpose, and must not be sent to a real
+ * emergency service; otherwise it's for a real emergency call request.
+ * Valid errors:
+ *  NONE
+ *  RADIO_NOT_AVAILABLE (radio resetting)
+ *  DIAL_MODIFIED_TO_USSD
+ *  DIAL_MODIFIED_TO_SS
+ *  DIAL_MODIFIED_TO_DIAL
+ *  INVALID_ARGUMENTS
+ *  NO_RESOURCES
+ *  INTERNAL_ERR
+ *  FDN_CHECK_FAILURE
+ *  MODEM_ERR
+ *  NO_SUBSCRIPTION
+ *  NO_NETWORK_FOUND
+ *  INVALID_CALL_ID
+ *  DEVICE_IN_USE
+ *  ABORTED
+ *  INVALID_MODEM_STATE
+ */
+#define RIL_REQUEST_EMERGENCY_DIAL 150
+
+/**
+ * Specify which bands modem's background scan must act on.
+ * If specifyChannels is true, it only scans bands specified in specifiers.
+ * If specifyChannels is false, it scans all bands.
+ *
+ * For example, CBRS is only on LTE band 48. By specifying this band,
+ * modem saves more power.
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  INTERNAL_ERR
+ *
+ */
+#define RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS 151
+
+/**
+ * RIL_REQUEST_ENABLE_MODEM
+ *
+ * Enable a logical modem
+ *
+ * Valid errors:
+ *  SUCCESS
+ *  RADIO_NOT_AVAILABLE
+ *  MODEM_ERR
+ *
+ */
+#define RIL_REQUEST_ENABLE_MODEM 152
+
+/**
+ * RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4
+ *
+ * Set carrier restrictions. Expected modem behavior:
+ *  If never receives this command:
+ *  - Must allow all carriers
+ *  Receives this command:
+ *  - Only allow carriers specified in carriers. The restriction persists across power cycles
+ *    and FDR. If a present SIM is allowed, modem must not reload the SIM. If a present SIM is
+ *    *not* allowed, modem must detach from the registered network and only keep emergency
+ *    service, and notify Android SIM refresh reset with new SIM state being
+ *    CardState:RESTRICTED. Emergency service must be enabled.
+ *
+ * "data" is const RIL_CarrierRestrictionsWithPriority *
+ * A list of allowed carriers and possibly a list of excluded carriers with the priority and
+ * multisim policy.
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_INVALID_ARGUMENTS
+ *  RIL_E_RADIO_NOT_AVAILABLE
+ *  RIL_E_REQUEST_NOT_SUPPORTED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4 153
+
+/**
+ * RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4
+ *
+ * Gets the carrier restrictions.
+ *
+ * "data" is NULL
+ *
+ * "response" is const RIL_CarrierRestrictionsWithPriority *.
+ *
+ * Valid errors:
+ *  RIL_E_SUCCESS
+ *  RIL_E_RADIO_NOT_AVAILABLE
+ *  RIL_E_REQUEST_NOT_SUPPORTED
+ *  INTERNAL_ERR
+ *  NO_MEMORY
+ *  NO_RESOURCES
+ *  CANCELLED
+ */
+#define RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4 154
+
+/***********************************************************************/
+
+/**
+ * RIL_RESPONSE_ACKNOWLEDGEMENT
+ *
+ * This is used by Asynchronous solicited messages and Unsolicited messages
+ * to acknowledge the receipt of those messages in RIL.java so that the ack
+ * can be used to let ril.cpp to release wakelock.
+ *
+ * Valid errors
+ * SUCCESS
+ * RADIO_NOT_AVAILABLE
+ */
+
+#define RIL_RESPONSE_ACKNOWLEDGEMENT 800
+
+/***********************************************************************/
+
+
+#define RIL_UNSOL_RESPONSE_BASE 1000
+
+/**
+ * RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
+ *
+ * Indicate when value of RIL_RadioState has changed.
+ *
+ * Callee will invoke RIL_RadioStateRequest method on main thread
+ *
+ * "data" is NULL
+ */
+
+#define RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED 1000
+
+
+/**
+ * RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
+ *
+ * Indicate when call state has changed
+ *
+ * Callee will invoke RIL_REQUEST_GET_CURRENT_CALLS on main thread
+ *
+ * "data" is NULL
+ *
+ * Response should be invoked on, for example,
+ * "RING", "BUSY", "NO CARRIER", and also call state
+ * transitions (DIALING->ALERTING ALERTING->ACTIVE)
+ *
+ * Redundent or extraneous invocations are tolerated
+ */
+#define RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED 1001
+
+
+/**
+ * RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED
+ *
+ * Called when the voice network state changed
+ *
+ * Callee will invoke the following requests on main thread:
+ *
+ * RIL_REQUEST_VOICE_REGISTRATION_STATE
+ * RIL_REQUEST_OPERATOR
+ *
+ * "data" is NULL
+ *
+ * FIXME should this happen when SIM records are loaded? (eg, for
+ * EONS)
+ */
+#define RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED 1002
+
+/**
+ * RIL_UNSOL_RESPONSE_NEW_SMS
+ *
+ * Called when new SMS is received.
+ *
+ * "data" is const char *
+ * This is a pointer to a string containing the PDU of an SMS-DELIVER
+ * as an ascii string of hex digits. The PDU starts with the SMSC address
+ * per TS 27.005 (+CMT:)
+ *
+ * Callee will subsequently confirm the receipt of thei SMS with a
+ * RIL_REQUEST_SMS_ACKNOWLEDGE
+ *
+ * No new RIL_UNSOL_RESPONSE_NEW_SMS
+ * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a
+ * RIL_REQUEST_SMS_ACKNOWLEDGE has been received
+ */
+
+#define RIL_UNSOL_RESPONSE_NEW_SMS 1003
+
+/**
+ * RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT
+ *
+ * Called when new SMS Status Report is received.
+ *
+ * "data" is const char *
+ * This is a pointer to a string containing the PDU of an SMS-STATUS-REPORT
+ * as an ascii string of hex digits. The PDU starts with the SMSC address
+ * per TS 27.005 (+CDS:).
+ *
+ * Callee will subsequently confirm the receipt of the SMS with a
+ * RIL_REQUEST_SMS_ACKNOWLEDGE
+ *
+ * No new RIL_UNSOL_RESPONSE_NEW_SMS
+ * or RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT messages should be sent until a
+ * RIL_REQUEST_SMS_ACKNOWLEDGE has been received
+ */
+
+#define RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT 1004
+
+/**
+ * RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM
+ *
+ * Called when new SMS has been stored on SIM card
+ *
+ * "data" is const int *
+ * ((const int *)data)[0] contains the slot index on the SIM that contains
+ * the new message
+ */
+
+#define RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM 1005
+
+/**
+ * RIL_UNSOL_ON_USSD
+ *
+ * Called when a new USSD message is received.
+ *
+ * "data" is const char **
+ * ((const char **)data)[0] points to a type code, which is
+ *  one of these string values:
+ *      "0"   USSD-Notify -- text in ((const char **)data)[1]
+ *      "1"   USSD-Request -- text in ((const char **)data)[1]
+ *      "2"   Session terminated by network
+ *      "3"   other local client (eg, SIM Toolkit) has responded
+ *      "4"   Operation not supported
+ *      "5"   Network timeout
+ *
+ * The USSD session is assumed to persist if the type code is "1", otherwise
+ * the current session (if any) is assumed to have terminated.
+ *
+ * ((const char **)data)[1] points to a message string if applicable, which
+ * should always be in UTF-8.
+ */
+#define RIL_UNSOL_ON_USSD 1006
+/* Previously #define RIL_UNSOL_ON_USSD_NOTIFY 1006   */
+
+/**
+ * RIL_UNSOL_ON_USSD_REQUEST
+ *
+ * Obsolete. Send via RIL_UNSOL_ON_USSD
+ */
+#define RIL_UNSOL_ON_USSD_REQUEST 1007
+
+/**
+ * RIL_UNSOL_NITZ_TIME_RECEIVED
+ *
+ * Called when radio has received a NITZ time message
+ *
+ * "data" is const char * pointing to NITZ time string
+ * in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt"
+ */
+#define RIL_UNSOL_NITZ_TIME_RECEIVED  1008
+
+/**
+ * RIL_UNSOL_SIGNAL_STRENGTH
+ *
+ * Radio may report signal strength rather han have it polled.
+ *
+ * "data" is a const RIL_SignalStrength *
+ */
+#define RIL_UNSOL_SIGNAL_STRENGTH  1009
+
+
+/**
+ * RIL_UNSOL_DATA_CALL_LIST_CHANGED
+ *
+ * "data" is an array of RIL_Data_Call_Response_v6 identical to that
+ * returned by RIL_REQUEST_DATA_CALL_LIST. It is the complete list
+ * of current data contexts including new contexts that have been
+ * activated. A data call is only removed from this list when the
+ * framework sends a RIL_REQUEST_DEACTIVATE_DATA_CALL or the radio
+ * is powered off/on.
+ *
+ * See also: RIL_REQUEST_DATA_CALL_LIST
+ */
+
+#define RIL_UNSOL_DATA_CALL_LIST_CHANGED 1010
+
+/**
+ * RIL_UNSOL_SUPP_SVC_NOTIFICATION
+ *
+ * Reports supplementary service related notification from the network.
+ *
+ * "data" is a const RIL_SuppSvcNotification *
+ *
+ */
+
+#define RIL_UNSOL_SUPP_SVC_NOTIFICATION 1011
+
+/**
+ * RIL_UNSOL_STK_SESSION_END
+ *
+ * Indicate when STK session is terminated by SIM.
+ *
+ * "data" is NULL
+ */
+#define RIL_UNSOL_STK_SESSION_END 1012
+
+/**
+ * RIL_UNSOL_STK_PROACTIVE_COMMAND
+ *
+ * Indicate when SIM issue a STK proactive command to applications
+ *
+ * "data" is a const char * containing SAT/USAT proactive command
+ * in hexadecimal format string starting with command tag
+ *
+ */
+#define RIL_UNSOL_STK_PROACTIVE_COMMAND 1013
+
+/**
+ * RIL_UNSOL_STK_EVENT_NOTIFY
+ *
+ * Indicate when SIM notifies applcations some event happens.
+ * Generally, application does not need to have any feedback to
+ * SIM but shall be able to indicate appropriate messages to users.
+ *
+ * "data" is a const char * containing SAT/USAT commands or responses
+ * sent by ME to SIM or commands handled by ME, in hexadecimal format string
+ * starting with first byte of response data or command tag
+ *
+ */
+#define RIL_UNSOL_STK_EVENT_NOTIFY 1014
+
+/**
+ * RIL_UNSOL_STK_CALL_SETUP
+ *
+ * Indicate when SIM wants application to setup a voice call.
+ *
+ * "data" is const int *
+ * ((const int *)data)[0] contains timeout value (in milliseconds)
+ */
+#define RIL_UNSOL_STK_CALL_SETUP 1015
+
+/**
+ * RIL_UNSOL_SIM_SMS_STORAGE_FULL
+ *
+ * Indicates that SMS storage on the SIM is full.  Sent when the network
+ * attempts to deliver a new SMS message.  Messages cannot be saved on the
+ * SIM until space is freed.  In particular, incoming Class 2 messages
+ * cannot be stored.
+ *
+ * "data" is null
+ *
+ */
+#define RIL_UNSOL_SIM_SMS_STORAGE_FULL 1016
+
+/**
+ * RIL_UNSOL_SIM_REFRESH
+ *
+ * Indicates that file(s) on the SIM have been updated, or the SIM
+ * has been reinitialized.
+ *
+ * In the case where RIL is version 6 or older:
+ * "data" is an int *
+ * ((int *)data)[0] is a RIL_SimRefreshResult.
+ * ((int *)data)[1] is the EFID of the updated file if the result is
+ * SIM_FILE_UPDATE or NULL for any other result.
+ *
+ * In the case where RIL is version 7:
+ * "data" is a RIL_SimRefreshResponse_v7 *
+ *
+ * Note: If the SIM state changes as a result of the SIM refresh (eg,
+ * SIM_READY -> SIM_LOCKED_OR_ABSENT), RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED
+ * should be sent.
+ */
+#define RIL_UNSOL_SIM_REFRESH 1017
+
+/**
+ * RIL_UNSOL_CALL_RING
+ *
+ * Ring indication for an incoming call (eg, RING or CRING event).
+ * There must be at least one RIL_UNSOL_CALL_RING at the beginning
+ * of a call and sending multiple is optional. If the system property
+ * ro.telephony.call_ring.multiple is false then the upper layers
+ * will generate the multiple events internally. Otherwise the vendor
+ * ril must generate multiple RIL_UNSOL_CALL_RING if
+ * ro.telephony.call_ring.multiple is true or if it is absent.
+ *
+ * The rate of these events is controlled by ro.telephony.call_ring.delay
+ * and has a default value of 3000 (3 seconds) if absent.
+ *
+ * "data" is null for GSM
+ * "data" is const RIL_CDMA_SignalInfoRecord * if CDMA
+ */
+#define RIL_UNSOL_CALL_RING 1018
+
+/**
+ * RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED
+ *
+ * Indicates that SIM state changes.
+ *
+ * Callee will invoke RIL_REQUEST_GET_SIM_STATUS on main thread
+
+ * "data" is null
+ */
+#define RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED 1019
+
+/**
+ * RIL_UNSOL_RESPONSE_CDMA_NEW_SMS
+ *
+ * Called when new CDMA SMS is received
+ *
+ * "data" is const RIL_CDMA_SMS_Message *
+ *
+ * Callee will subsequently confirm the receipt of the SMS with
+ * a RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE
+ *
+ * No new RIL_UNSOL_RESPONSE_CDMA_NEW_SMS should be sent until
+ * RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE has been received
+ *
+ */
+#define RIL_UNSOL_RESPONSE_CDMA_NEW_SMS 1020
+
+/**
+ * RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS
+ *
+ * Called when new Broadcast SMS is received
+ *
+ * "data" can be one of the following:
+ * If received from GSM network, "data" is const char of 88 bytes
+ * which indicates each page of a CBS Message sent to the MS by the
+ * BTS as coded in 3GPP 23.041 Section 9.4.1.2.
+ * If received from UMTS network, "data" is const char of 90 up to 1252
+ * bytes which contain between 1 and 15 CBS Message pages sent as one
+ * packet to the MS by the BTS as coded in 3GPP 23.041 Section 9.4.2.2.
+ *
+ */
+#define RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS 1021
+
+/**
+ * RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL
+ *
+ * Indicates that SMS storage on the RUIM is full.  Messages
+ * cannot be saved on the RUIM until space is freed.
+ *
+ * "data" is null
+ *
+ */
+#define RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL 1022
+
+/**
+ * RIL_UNSOL_RESTRICTED_STATE_CHANGED
+ *
+ * Indicates a restricted state change (eg, for Domain Specific Access Control).
+ *
+ * Radio need send this msg after radio off/on cycle no matter it is changed or not.
+ *
+ * "data" is an int *
+ * ((int *)data)[0] contains a bitmask of RIL_RESTRICTED_STATE_* values.
+ */
+#define RIL_UNSOL_RESTRICTED_STATE_CHANGED 1023
+
+/**
+ * RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE
+ *
+ * Indicates that the radio system selection module has
+ * autonomously entered emergency callback mode.
+ *
+ * "data" is null
+ *
+ */
+#define RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE 1024
+
+/**
+ * RIL_UNSOL_CDMA_CALL_WAITING
+ *
+ * Called when CDMA radio receives a call waiting indication.
+ *
+ * "data" is const RIL_CDMA_CallWaiting *
+ *
+ */
+#define RIL_UNSOL_CDMA_CALL_WAITING 1025
+
+/**
+ * RIL_UNSOL_CDMA_OTA_PROVISION_STATUS
+ *
+ * Called when CDMA radio receives an update of the progress of an
+ * OTASP/OTAPA call.
+ *
+ * "data" is const int *
+ *  For CDMA this is an integer OTASP/OTAPA status listed in
+ *  RIL_CDMA_OTA_ProvisionStatus.
+ *
+ */
+#define RIL_UNSOL_CDMA_OTA_PROVISION_STATUS 1026
+
+/**
+ * RIL_UNSOL_CDMA_INFO_REC
+ *
+ * Called when CDMA radio receives one or more info recs.
+ *
+ * "data" is const RIL_CDMA_InformationRecords *
+ *
+ */
+#define RIL_UNSOL_CDMA_INFO_REC 1027
+
+/**
+ * RIL_UNSOL_OEM_HOOK_RAW
+ *
+ * This is for OEM specific use.
+ *
+ * "data" is a byte[]
+ */
+#define RIL_UNSOL_OEM_HOOK_RAW 1028
+
+/**
+ * RIL_UNSOL_RINGBACK_TONE
+ *
+ * Indicates that nework doesn't have in-band information,  need to
+ * play out-band tone.
+ *
+ * "data" is an int *
+ * ((int *)data)[0] == 0 for stop play ringback tone.
+ * ((int *)data)[0] == 1 for start play ringback tone.
+ */
+#define RIL_UNSOL_RINGBACK_TONE 1029
+
+/**
+ * RIL_UNSOL_RESEND_INCALL_MUTE
+ *
+ * Indicates that framework/application need reset the uplink mute state.
+ *
+ * There may be situations where the mute state becomes out of sync
+ * between the application and device in some GSM infrastructures.
+ *
+ * "data" is null
+ */
+#define RIL_UNSOL_RESEND_INCALL_MUTE 1030
+
+/**
+ * RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED
+ *
+ * Called when CDMA subscription source changed.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is == RIL_CdmaSubscriptionSource
+ */
+#define RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED 1031
+
+/**
+ * RIL_UNSOL_CDMA_PRL_CHANGED
+ *
+ * Called when PRL (preferred roaming list) changes.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is PRL_VERSION as would be returned by RIL_REQUEST_CDMA_SUBSCRIPTION
+ */
+#define RIL_UNSOL_CDMA_PRL_CHANGED 1032
+
+/**
+ * RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE
+ *
+ * Called when Emergency Callback Mode Ends
+ *
+ * Indicates that the radio system selection module has
+ * proactively exited emergency callback mode.
+ *
+ * "data" is NULL
+ *
+ */
+#define RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE 1033
+
+/**
+ * RIL_UNSOL_RIL_CONNECTED
+ *
+ * Called the ril connects and returns the version
+ *
+ * "data" is int *
+ * ((int *)data)[0] is RIL_VERSION
+ */
+#define RIL_UNSOL_RIL_CONNECTED 1034
+
+/**
+ * RIL_UNSOL_VOICE_RADIO_TECH_CHANGED
+ *
+ * Indicates that voice technology has changed. Contains new radio technology
+ * as a data in the message.
+ *
+ * "data" is int *
+ * ((int *)data)[0] is of type const RIL_RadioTechnology
+ *
+ */
+#define RIL_UNSOL_VOICE_RADIO_TECH_CHANGED 1035
+
+/**
+ * RIL_UNSOL_CELL_INFO_LIST
+ *
+ * Same information as returned by RIL_REQUEST_GET_CELL_INFO_LIST, but returned
+ * at the rate no greater than specified by RIL_REQUEST_SET_UNSOL_CELL_INFO_RATE.
+ *
+ * "data" is NULL
+ *
+ * "response" is an array of RIL_CellInfo_v12.
+ */
+#define RIL_UNSOL_CELL_INFO_LIST 1036
+
+/**
+ * RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED
+ *
+ * This message is DEPRECATED and shall be removed in a future release (target: 2018);
+ * instead, provide IMS registration status via an IMS Service.
+ *
+ * Called when IMS registration state has changed
+ *
+ * To get IMS registration state and IMS SMS format, callee needs to invoke the
+ * following request on main thread:
+ *
+ * RIL_REQUEST_IMS_REGISTRATION_STATE
+ *
+ * "data" is NULL
+ *
+ */
+#define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037
+
+/**
+ * RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED
+ *
+ * Indicated when there is a change in subscription status.
+ * This event will be sent in the following scenarios
+ *  - subscription readiness at modem, which was selected by telephony layer
+ *  - when subscription is deactivated by modem due to UICC card removal
+ *  - When network invalidates the subscription i.e. attach reject due to authentication reject
+ *
+ * "data" is const int *
+ * ((const int *)data)[0] == 0 for Subscription Deactivated
+ * ((const int *)data)[0] == 1 for Subscription Activated
+ *
+ */
+#define RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED 1038
+
+/**
+ * RIL_UNSOL_SRVCC_STATE_NOTIFY
+ *
+ * Called when Single Radio Voice Call Continuity(SRVCC)
+ * progress state has changed
+ *
+ * "data" is int *
+ * ((int *)data)[0] is of type const RIL_SrvccState
+ *
+ */
+
+#define RIL_UNSOL_SRVCC_STATE_NOTIFY 1039
+
+/**
+ * RIL_UNSOL_HARDWARE_CONFIG_CHANGED
+ *
+ * Called when the hardware configuration associated with the RILd changes
+ *
+ * "data" is an array of RIL_HardwareConfig
+ *
+ */
+#define RIL_UNSOL_HARDWARE_CONFIG_CHANGED 1040
+
+/**
+ * RIL_UNSOL_DC_RT_INFO_CHANGED
+ *
+ * The message is DEPRECATED, use RIL_REQUEST_GET_ACTIVITY_INFO
+ * Sent when the DC_RT_STATE changes but the time
+ * between these messages must not be less than the
+ * value set by RIL_REQUEST_SET_DC_RT_RATE.
+ *
+ * "data" is the most recent RIL_DcRtInfo
+ *
+ */
+#define RIL_UNSOL_DC_RT_INFO_CHANGED 1041
+
+/**
+ * RIL_UNSOL_RADIO_CAPABILITY
+ *
+ * Sent when RIL_REQUEST_SET_RADIO_CAPABILITY completes.
+ * Returns the phone radio capability exactly as
+ * RIL_REQUEST_GET_RADIO_CAPABILITY and should be the
+ * same set as sent by RIL_REQUEST_SET_RADIO_CAPABILITY.
+ *
+ * "data" is the RIL_RadioCapability structure
+ */
+#define RIL_UNSOL_RADIO_CAPABILITY 1042
+
+/*
+ * RIL_UNSOL_ON_SS
+ *
+ * Called when SS response is received when DIAL/USSD/SS is changed to SS by
+ * call control.
+ *
+ * "data" is const RIL_StkCcUnsolSsResponse *
+ *
+ */
+#define RIL_UNSOL_ON_SS 1043
+
+/**
+ * RIL_UNSOL_STK_CC_ALPHA_NOTIFY
+ *
+ * Called when there is an ALPHA from UICC during Call Control.
+ *
+ * "data" is const char * containing ALPHA string from UICC in UTF-8 format.
+ *
+ */
+#define RIL_UNSOL_STK_CC_ALPHA_NOTIFY 1044
+
+/**
+ * RIL_UNSOL_LCEDATA_RECV
+ *
+ * Called when there is an incoming Link Capacity Estimate (LCE) info report.
+ *
+ * "data" is the RIL_LceDataInfo structure.
+ *
+ */
+#define RIL_UNSOL_LCEDATA_RECV 1045
+
+ /**
+  * RIL_UNSOL_PCO_DATA
+  *
+  * Called when there is new Carrier PCO data received for a data call.  Ideally
+  * only new data will be forwarded, though this is not required.  Multiple
+  * boxes of carrier PCO data for a given call should result in a series of
+  * RIL_UNSOL_PCO_DATA calls.
+  *
+  * "data" is the RIL_PCO_Data structure.
+  *
+  */
+#define RIL_UNSOL_PCO_DATA 1046
+
+ /**
+  * RIL_UNSOL_MODEM_RESTART
+  *
+  * Called when there is a modem reset.
+  *
+  * "reason" is "const char *" containing the reason for the reset. It
+  * could be a crash signature if the restart was due to a crash or some
+  * string such as "user-initiated restart" or "AT command initiated
+  * restart" that explains the cause of the modem restart.
+  *
+  * When modem restarts, one of the following radio state transitions will happen
+  * 1) RADIO_STATE_ON->RADIO_STATE_UNAVAILABLE->RADIO_STATE_ON or
+  * 2) RADIO_STATE_OFF->RADIO_STATE_UNAVAILABLE->RADIO_STATE_OFF
+  * This message can be sent either just before the RADIO_STATE changes to RADIO_STATE_UNAVAILABLE
+  * or just after but should never be sent after the RADIO_STATE changes from UNAVAILABLE to
+  * AVAILABLE(RADIO_STATE_ON/RADIO_STATE_OFF) again.
+  *
+  * It should NOT be sent after the RADIO_STATE changes to AVAILABLE after the
+  * modem restart as that could be interpreted as a second modem reset by the
+  * framework.
+  */
+#define RIL_UNSOL_MODEM_RESTART 1047
+
+/**
+ * RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION
+ *
+ * Called when the modem needs Carrier specific information that will
+ * be used to encrypt IMSI and IMPI.
+ *
+ * "data" is NULL
+ *
+ */
+#define RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION 1048
+
+/**
+ * RIL_UNSOL_NETWORK_SCAN_RESULT
+ *
+ * Returns incremental result for the network scan which is started by
+ * RIL_REQUEST_START_NETWORK_SCAN, sent to report results, status, or errors.
+ *
+ * "data" is NULL
+ * "response" is a const RIL_NetworkScanResult *
+ */
+#define RIL_UNSOL_NETWORK_SCAN_RESULT 1049
+
+/**
+ * RIL_UNSOL_KEEPALIVE_STATUS
+ *
+ * "data" is NULL
+ * "response" is a const RIL_KeepaliveStatus *
+ */
+#define RIL_UNSOL_KEEPALIVE_STATUS 1050
+
+/***********************************************************************/
+
+
+#if defined(ANDROID_MULTI_SIM)
+/**
+ * RIL_Request Function pointer
+ *
+ * @param request is one of RIL_REQUEST_*
+ * @param data is pointer to data defined for that RIL_REQUEST_*
+ *        data is owned by caller, and should not be modified or freed by callee
+ *        structures passed as data may contain pointers to non-contiguous memory
+ * @param t should be used in subsequent call to RIL_onResponse
+ * @param datalen is the length of "data" which is defined as other argument. It may or may
+ *        not be equal to sizeof(data). Refer to the documentation of individual structures
+ *        to find if pointers listed in the structure are contiguous and counted in the datalen
+ *        length or not.
+ *        (Eg: RIL_IMS_SMS_Message where we don't have datalen equal to sizeof(data))
+ *
+ */
+typedef void (*RIL_RequestFunc) (int request, void *data,
+                                    size_t datalen, RIL_Token t, RIL_SOCKET_ID socket_id);
+
+/**
+ * This function should return the current radio state synchronously
+ */
+typedef RIL_RadioState (*RIL_RadioStateRequest)(RIL_SOCKET_ID socket_id);
+
+#else
+/* Backward compatible */
+
+/**
+ * RIL_Request Function pointer
+ *
+ * @param request is one of RIL_REQUEST_*
+ * @param data is pointer to data defined for that RIL_REQUEST_*
+ *        data is owned by caller, and should not be modified or freed by callee
+ *        structures passed as data may contain pointers to non-contiguous memory
+ * @param t should be used in subsequent call to RIL_onResponse
+ * @param datalen is the length of "data" which is defined as other argument. It may or may
+ *        not be equal to sizeof(data). Refer to the documentation of individual structures
+ *        to find if pointers listed in the structure are contiguous and counted in the datalen
+ *        length or not.
+ *        (Eg: RIL_IMS_SMS_Message where we don't have datalen equal to sizeof(data))
+ *
+ */
+typedef void (*RIL_RequestFunc) (int request, void *data,
+                                    size_t datalen, RIL_Token t);
+
+/**
+ * This function should return the current radio state synchronously
+ */
+typedef RIL_RadioState (*RIL_RadioStateRequest)();
+
+#endif
+
+
+/**
+ * This function returns "1" if the specified RIL_REQUEST code is
+ * supported and 0 if it is not
+ *
+ * @param requestCode is one of RIL_REQUEST codes
+ */
+
+typedef int (*RIL_Supports)(int requestCode);
+
+/**
+ * This function is called from a separate thread--not the
+ * thread that calls RIL_RequestFunc--and indicates that a pending
+ * request should be cancelled.
+ *
+ * On cancel, the callee should do its best to abandon the request and
+ * call RIL_onRequestComplete with RIL_Errno CANCELLED at some later point.
+ *
+ * Subsequent calls to  RIL_onRequestComplete for this request with
+ * other results will be tolerated but ignored. (That is, it is valid
+ * to ignore the cancellation request)
+ *
+ * RIL_Cancel calls should return immediately, and not wait for cancellation
+ *
+ * Please see ITU v.250 5.6.1 for how one might implement this on a TS 27.007
+ * interface
+ *
+ * @param t token wants to be canceled
+ */
+
+typedef void (*RIL_Cancel)(RIL_Token t);
+
+typedef void (*RIL_TimedCallback) (void *param);
+
+/**
+ * Return a version string for your RIL implementation
+ */
+typedef const char * (*RIL_GetVersion) (void);
+
+typedef struct {
+    int version;        /* set to RIL_VERSION */
+    RIL_RequestFunc onRequest;
+    RIL_RadioStateRequest onStateRequest;
+    RIL_Supports supports;
+    RIL_Cancel onCancel;
+    RIL_GetVersion getVersion;
+} RIL_RadioFunctions;
+
+typedef struct {
+    char *apn;                  /* the APN to connect to */
+    char *protocol;             /* one of the PDP_type values in TS 27.007 section 10.1.1 used on
+                                   roaming network. For example, "IP", "IPV6", "IPV4V6", or "PPP".*/
+    int authtype;               /* authentication protocol used for this PDP context
+                                   (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) */
+    char *username;             /* the username for APN, or NULL */
+    char *password;             /* the password for APN, or NULL */
+} RIL_InitialAttachApn;
+
+typedef struct {
+    char *apn;                  /* the APN to connect to */
+    char *protocol;             /* one of the PDP_type values in TS 27.007 section 10.1.1 used on
+                                   home network. For example, "IP", "IPV6", "IPV4V6", or "PPP". */
+    char *roamingProtocol;      /* one of the PDP_type values in TS 27.007 section 10.1.1 used on
+                                   roaming network. For example, "IP", "IPV6", "IPV4V6", or "PPP".*/
+    int authtype;               /* authentication protocol used for this PDP context
+                                   (None: 0, PAP: 1, CHAP: 2, PAP&CHAP: 3) */
+    char *username;             /* the username for APN, or NULL */
+    char *password;             /* the password for APN, or NULL */
+    int supportedTypesBitmask;  /* supported APN types bitmask. See RIL_ApnTypes for the value of
+                                   each bit. */
+    int bearerBitmask;          /* the bearer bitmask. See RIL_RadioAccessFamily for the value of
+                                   each bit. */
+    int modemCognitive;         /* indicating the APN setting was sent to the modem through
+                                   setDataProfile earlier. */
+    int mtu;                    /* maximum transmission unit (MTU) size in bytes */
+    char *mvnoType;             /* the MVNO type: possible values are "imsi", "gid", "spn" */
+    char *mvnoMatchData;        /* MVNO match data. Can be anything defined by the carrier.
+                                   For example,
+                                     SPN like: "A MOBILE", "BEN NL", etc...
+                                     IMSI like: "302720x94", "2060188", etc...
+                                     GID like: "4E", "33", etc... */
+} RIL_InitialAttachApn_v15;
+
+typedef struct {
+    int authContext;            /* P2 value of authentication command, see P2 parameter in
+                                   3GPP TS 31.102 7.1.2 */
+    char *authData;             /* the challenge string in Base64 format, see 3GPP
+                                   TS 31.102 7.1.2 */
+    char *aid;                  /* AID value, See ETSI 102.221 8.1 and 101.220 4,
+                                   NULL if no value. */
+} RIL_SimAuthentication;
+
+typedef struct {
+    int cid;                    /* Context ID, uniquely identifies this call */
+    char *bearer_proto;         /* One of the PDP_type values in TS 27.007 section 10.1.1.
+                                   For example, "IP", "IPV6", "IPV4V6". */
+    int pco_id;                 /* The protocol ID for this box.  Note that only IDs from
+                                   FF00H - FFFFH are accepted.  If more than one is included
+                                   from the network, multiple calls should be made to send all
+                                   of them. */
+    int contents_length;        /* The number of octets in the contents. */
+    char *contents;             /* Carrier-defined content.  It is binary, opaque and
+                                   loosely defined in LTE Layer 3 spec 24.008 */
+} RIL_PCO_Data;
+
+typedef enum {
+    NATT_IPV4 = 0,              /* Keepalive specified by RFC 3948 Sec. 2.3 using IPv4 */
+    NATT_IPV6 = 1               /* Keepalive specified by RFC 3948 Sec. 2.3 using IPv6 */
+} RIL_KeepaliveType;
+
+#define MAX_INADDR_LEN 16
+typedef struct {
+    RIL_KeepaliveType type;                  /* Type of keepalive packet */
+    char sourceAddress[MAX_INADDR_LEN];      /* Source address in network-byte order */
+    int sourcePort;                          /* Source port if applicable, or 0x7FFFFFFF;
+                                                the maximum value is 65535 */
+    char destinationAddress[MAX_INADDR_LEN]; /* Destination address in network-byte order */
+    int destinationPort;                     /* Destination port if applicable or 0x7FFFFFFF;
+                                                the maximum value is 65535 */
+    int maxKeepaliveIntervalMillis;          /* Maximum milliseconds between two packets */
+    int cid;                                 /* Context ID, uniquely identifies this call */
+} RIL_KeepaliveRequest;
+
+typedef enum {
+    KEEPALIVE_ACTIVE,                       /* Keepalive session is active */
+    KEEPALIVE_INACTIVE,                     /* Keepalive session is inactive */
+    KEEPALIVE_PENDING                       /* Keepalive session status not available */
+} RIL_KeepaliveStatusCode;
+
+typedef struct {
+    uint32_t sessionHandle;
+    RIL_KeepaliveStatusCode code;
+} RIL_KeepaliveStatus;
+
+#ifdef RIL_SHLIB
+struct RIL_Env {
+    /**
+     * "t" is parameter passed in on previous call to RIL_Notification
+     * routine.
+     *
+     * If "e" != SUCCESS, then response can be null/is ignored
+     *
+     * "response" is owned by caller, and should not be modified or
+     * freed by callee
+     *
+     * RIL_onRequestComplete will return as soon as possible
+     */
+    void (*OnRequestComplete)(RIL_Token t, RIL_Errno e,
+                           void *response, size_t responselen);
+
+#if defined(ANDROID_MULTI_SIM)
+    /**
+     * "unsolResponse" is one of RIL_UNSOL_RESPONSE_*
+     * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_*
+     *
+     * "data" is owned by caller, and should not be modified or freed by callee
+     */
+    void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen, RIL_SOCKET_ID socket_id);
+#else
+    /**
+     * "unsolResponse" is one of RIL_UNSOL_RESPONSE_*
+     * "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_*
+     *
+     * "data" is owned by caller, and should not be modified or freed by callee
+     */
+    void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen);
+#endif
+    /**
+     * Call user-specifed "callback" function on on the same thread that
+     * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies
+     * a relative time value at which the callback is invoked. If relativeTime is
+     * NULL or points to a 0-filled structure, the callback will be invoked as
+     * soon as possible
+     */
+
+    void (*RequestTimedCallback) (RIL_TimedCallback callback,
+                                   void *param, const struct timeval *relativeTime);
+   /**
+    * "t" is parameter passed in on previous call RIL_Notification routine
+    *
+    * RIL_onRequestAck will be called by vendor when an Async RIL request was received
+    * by them and an ack needs to be sent back to java ril.
+    */
+    void (*OnRequestAck) (RIL_Token t);
+};
+
+
+/**
+ *  RIL implementations must defined RIL_Init
+ *  argc and argv will be command line arguments intended for the RIL implementation
+ *  Return NULL on error
+ *
+ * @param env is environment point defined as RIL_Env
+ * @param argc number of arguments
+ * @param argv list fo arguments
+ *
+ */
+const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv);
+
+/**
+ *  If BT SAP(SIM Access Profile) is supported, then RIL implementations must define RIL_SAP_Init
+ *  for initializing RIL_RadioFunctions used for BT SAP communcations. It is called whenever RILD
+ *  starts or modem restarts. Returns handlers for SAP related request that are made on SAP
+ *  sepecific socket, analogous to the RIL_RadioFunctions returned by the call to RIL_Init
+ *  and used on the general RIL socket.
+ *  argc and argv will be command line arguments intended for the RIL implementation
+ *  Return NULL on error.
+ *
+ * @param env is environment point defined as RIL_Env
+ * @param argc number of arguments
+ * @param argv list fo arguments
+ *
+ */
+const RIL_RadioFunctions *RIL_SAP_Init(const struct RIL_Env *env, int argc, char **argv);
+
+#else /* RIL_SHLIB */
+
+/**
+ * Call this once at startup to register notification routine
+ *
+ * @param callbacks user-specifed callback function
+ */
+void RIL_register (const RIL_RadioFunctions *callbacks);
+
+void rilc_thread_pool();
+
+
+/**
+ *
+ * RIL_onRequestComplete will return as soon as possible
+ *
+ * @param t is parameter passed in on previous call to RIL_Notification
+ *          routine.
+ * @param e error code
+ *          if "e" != SUCCESS, then response can be null/is ignored
+ * @param response is owned by caller, and should not be modified or
+ *                 freed by callee
+ * @param responselen the length of response in byte
+ */
+void RIL_onRequestComplete(RIL_Token t, RIL_Errno e,
+                           void *response, size_t responselen);
+
+/**
+ * RIL_onRequestAck will be called by vendor when an Async RIL request was received by them and
+ * an ack needs to be sent back to java ril. This doesn't mark the end of the command or it's
+ * results, just that the command was received and will take a while. After sending this Ack
+ * its vendor's responsibility to make sure that AP is up whenever needed while command is
+ * being processed.
+ *
+ * @param t is parameter passed in on previous call to RIL_Notification
+ *          routine.
+ */
+void RIL_onRequestAck(RIL_Token t);
+
+#if defined(ANDROID_MULTI_SIM)
+/**
+ * @param unsolResponse is one of RIL_UNSOL_RESPONSE_*
+ * @param data is pointer to data defined for that RIL_UNSOL_RESPONSE_*
+ *     "data" is owned by caller, and should not be modified or freed by callee
+ * @param datalen the length of data in byte
+ */
+
+void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen, RIL_SOCKET_ID socket_id);
+#else
+/**
+ * @param unsolResponse is one of RIL_UNSOL_RESPONSE_*
+ * @param data is pointer to data defined for that RIL_UNSOL_RESPONSE_*
+ *     "data" is owned by caller, and should not be modified or freed by callee
+ * @param datalen the length of data in byte
+ */
+
+void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+                                size_t datalen);
+#endif
+
+/**
+ * Call user-specifed "callback" function on on the same thread that
+ * RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies
+ * a relative time value at which the callback is invoked. If relativeTime is
+ * NULL or points to a 0-filled structure, the callback will be invoked as
+ * soon as possible
+ *
+ * @param callback user-specifed callback function
+ * @param param parameter list
+ * @param relativeTime a relative time value at which the callback is invoked
+ */
+
+void RIL_requestTimedCallback (RIL_TimedCallback callback,
+                               void *param, const struct timeval *relativeTime);
+
+#endif /* RIL_SHLIB */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*ANDROID_RIL_H*/
diff --git a/guest/hals/ril/libril/ril_commands.h b/guest/hals/ril/libril/ril_commands.h
new file mode 100644
index 0000000..d9a0db7
--- /dev/null
+++ b/guest/hals/ril/libril/ril_commands.h
@@ -0,0 +1,171 @@
+/* //guest/hals/ril/libril/ril_commands.h
+**
+** Copyright 2006, 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 is 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.
+*/
+    {0, NULL},                   //none
+    {RIL_REQUEST_GET_SIM_STATUS, radio_1_4::getIccCardStatusResponse},
+    {RIL_REQUEST_ENTER_SIM_PIN, radio_1_4::supplyIccPinForAppResponse},
+    {RIL_REQUEST_ENTER_SIM_PUK, radio_1_4::supplyIccPukForAppResponse},
+    {RIL_REQUEST_ENTER_SIM_PIN2, radio_1_4::supplyIccPin2ForAppResponse},
+    {RIL_REQUEST_ENTER_SIM_PUK2, radio_1_4::supplyIccPuk2ForAppResponse},
+    {RIL_REQUEST_CHANGE_SIM_PIN, radio_1_4::changeIccPinForAppResponse},
+    {RIL_REQUEST_CHANGE_SIM_PIN2, radio_1_4::changeIccPin2ForAppResponse},
+    {RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, radio_1_4::supplyNetworkDepersonalizationResponse},
+    {RIL_REQUEST_GET_CURRENT_CALLS, radio_1_4::getCurrentCallsResponse},
+    {RIL_REQUEST_DIAL, radio_1_4::dialResponse},
+    {RIL_REQUEST_GET_IMSI, radio_1_4::getIMSIForAppResponse},
+    {RIL_REQUEST_HANGUP, radio_1_4::hangupConnectionResponse},
+    {RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, radio_1_4::hangupWaitingOrBackgroundResponse},
+    {RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, radio_1_4::hangupForegroundResumeBackgroundResponse},
+    {RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, radio_1_4::switchWaitingOrHoldingAndActiveResponse},
+    {RIL_REQUEST_CONFERENCE, radio_1_4::conferenceResponse},
+    {RIL_REQUEST_UDUB, radio_1_4::rejectCallResponse},
+    {RIL_REQUEST_LAST_CALL_FAIL_CAUSE, radio_1_4::getLastCallFailCauseResponse},
+    {RIL_REQUEST_SIGNAL_STRENGTH, radio_1_4::getSignalStrengthResponse},
+    {RIL_REQUEST_VOICE_REGISTRATION_STATE, radio_1_4::getVoiceRegistrationStateResponse},
+    {RIL_REQUEST_DATA_REGISTRATION_STATE, radio_1_4::getDataRegistrationStateResponse},
+    {RIL_REQUEST_OPERATOR, radio_1_4::getOperatorResponse},
+    {RIL_REQUEST_RADIO_POWER, radio_1_4::setRadioPowerResponse},
+    {RIL_REQUEST_DTMF, radio_1_4::sendDtmfResponse},
+    {RIL_REQUEST_SEND_SMS, radio_1_4::sendSmsResponse},
+    {RIL_REQUEST_SEND_SMS_EXPECT_MORE, radio_1_4::sendSMSExpectMoreResponse},
+    {RIL_REQUEST_SETUP_DATA_CALL, radio_1_4::setupDataCallResponse},
+    {RIL_REQUEST_SIM_IO, radio_1_4::iccIOForAppResponse},
+    {RIL_REQUEST_SEND_USSD, radio_1_4::sendUssdResponse},
+    {RIL_REQUEST_CANCEL_USSD, radio_1_4::cancelPendingUssdResponse},
+    {RIL_REQUEST_GET_CLIR, radio_1_4::getClirResponse},
+    {RIL_REQUEST_SET_CLIR, radio_1_4::setClirResponse},
+    {RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, radio_1_4::getCallForwardStatusResponse},
+    {RIL_REQUEST_SET_CALL_FORWARD, radio_1_4::setCallForwardResponse},
+    {RIL_REQUEST_QUERY_CALL_WAITING, radio_1_4::getCallWaitingResponse},
+    {RIL_REQUEST_SET_CALL_WAITING, radio_1_4::setCallWaitingResponse},
+    {RIL_REQUEST_SMS_ACKNOWLEDGE, radio_1_4::acknowledgeLastIncomingGsmSmsResponse},
+    {RIL_REQUEST_GET_IMEI, NULL},
+    {RIL_REQUEST_GET_IMEISV, NULL},
+    {RIL_REQUEST_ANSWER, radio_1_4::acceptCallResponse},
+    {RIL_REQUEST_DEACTIVATE_DATA_CALL, radio_1_4::deactivateDataCallResponse},
+    {RIL_REQUEST_QUERY_FACILITY_LOCK, radio_1_4::getFacilityLockForAppResponse},
+    {RIL_REQUEST_SET_FACILITY_LOCK, radio_1_4::setFacilityLockForAppResponse},
+    {RIL_REQUEST_CHANGE_BARRING_PASSWORD, radio_1_4::setBarringPasswordResponse},
+    {RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, radio_1_4::getNetworkSelectionModeResponse},
+    {RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, radio_1_4::setNetworkSelectionModeAutomaticResponse},
+    {RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, radio_1_4::setNetworkSelectionModeManualResponse},
+    {RIL_REQUEST_QUERY_AVAILABLE_NETWORKS , radio_1_4::getAvailableNetworksResponse},
+    {RIL_REQUEST_DTMF_START, radio_1_4::startDtmfResponse},
+    {RIL_REQUEST_DTMF_STOP, radio_1_4::stopDtmfResponse},
+    {RIL_REQUEST_BASEBAND_VERSION, radio_1_4::getBasebandVersionResponse},
+    {RIL_REQUEST_SEPARATE_CONNECTION, radio_1_4::separateConnectionResponse},
+    {RIL_REQUEST_SET_MUTE, radio_1_4::setMuteResponse},
+    {RIL_REQUEST_GET_MUTE, radio_1_4::getMuteResponse},
+    {RIL_REQUEST_QUERY_CLIP, radio_1_4::getClipResponse},
+    {RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE, NULL},
+    {RIL_REQUEST_DATA_CALL_LIST, radio_1_4::getDataCallListResponse},
+    {RIL_REQUEST_RESET_RADIO, NULL},
+    {RIL_REQUEST_OEM_HOOK_RAW, radio_1_4::sendRequestRawResponse},
+    {RIL_REQUEST_OEM_HOOK_STRINGS, radio_1_4::sendRequestStringsResponse},
+    {RIL_REQUEST_SCREEN_STATE, radio_1_4::sendDeviceStateResponse},   // Note the response function is different.
+    {RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, radio_1_4::setSuppServiceNotificationsResponse},
+    {RIL_REQUEST_WRITE_SMS_TO_SIM, radio_1_4::writeSmsToSimResponse},
+    {RIL_REQUEST_DELETE_SMS_ON_SIM, radio_1_4::deleteSmsOnSimResponse},
+    {RIL_REQUEST_SET_BAND_MODE, radio_1_4::setBandModeResponse},
+    {RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, radio_1_4::getAvailableBandModesResponse},
+    {RIL_REQUEST_STK_GET_PROFILE, NULL},
+    {RIL_REQUEST_STK_SET_PROFILE, NULL},
+    {RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, radio_1_4::sendEnvelopeResponse},
+    {RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, radio_1_4::sendTerminalResponseToSimResponse},
+    {RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM, radio_1_4::handleStkCallSetupRequestFromSimResponse},
+    {RIL_REQUEST_EXPLICIT_CALL_TRANSFER, radio_1_4::explicitCallTransferResponse},
+    {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, radio_1_4::setPreferredNetworkTypeResponse},
+    {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, radio_1_4::getPreferredNetworkTypeResponse},
+    {RIL_REQUEST_GET_NEIGHBORING_CELL_IDS, radio_1_4::getNeighboringCidsResponse},
+    {RIL_REQUEST_SET_LOCATION_UPDATES, radio_1_4::setLocationUpdatesResponse},
+    {RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, radio_1_4::setCdmaSubscriptionSourceResponse},
+    {RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, radio_1_4::setCdmaRoamingPreferenceResponse},
+    {RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, radio_1_4::getCdmaRoamingPreferenceResponse},
+    {RIL_REQUEST_SET_TTY_MODE, radio_1_4::setTTYModeResponse},
+    {RIL_REQUEST_QUERY_TTY_MODE, radio_1_4::getTTYModeResponse},
+    {RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, radio_1_4::setPreferredVoicePrivacyResponse},
+    {RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE, radio_1_4::getPreferredVoicePrivacyResponse},
+    {RIL_REQUEST_CDMA_FLASH, radio_1_4::sendCDMAFeatureCodeResponse},
+    {RIL_REQUEST_CDMA_BURST_DTMF, radio_1_4::sendBurstDtmfResponse},
+    {RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY, NULL},
+    {RIL_REQUEST_CDMA_SEND_SMS, radio_1_4::sendCdmaSmsResponse},
+    {RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, radio_1_4::acknowledgeLastIncomingCdmaSmsResponse},
+    {RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG, radio_1_4::getGsmBroadcastConfigResponse},
+    {RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG, radio_1_4::setGsmBroadcastConfigResponse},
+    {RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION, radio_1_4::setGsmBroadcastActivationResponse},
+    {RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG, radio_1_4::getCdmaBroadcastConfigResponse},
+    {RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG, radio_1_4::setCdmaBroadcastConfigResponse},
+    {RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION, radio_1_4::setCdmaBroadcastActivationResponse},
+    {RIL_REQUEST_CDMA_SUBSCRIPTION, radio_1_4::getCDMASubscriptionResponse},
+    {RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, radio_1_4::writeSmsToRuimResponse},
+    {RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, radio_1_4::deleteSmsOnRuimResponse},
+    {RIL_REQUEST_DEVICE_IDENTITY, radio_1_4::getDeviceIdentityResponse},
+    {RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, radio_1_4::exitEmergencyCallbackModeResponse},
+    {RIL_REQUEST_GET_SMSC_ADDRESS, radio_1_4::getSmscAddressResponse},
+    {RIL_REQUEST_SET_SMSC_ADDRESS, radio_1_4::setSmscAddressResponse},
+    {RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, radio_1_4::reportSmsMemoryStatusResponse},
+    {RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, radio_1_4::reportStkServiceIsRunningResponse},
+    {RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, radio_1_4::getCdmaSubscriptionSourceResponse},
+    {RIL_REQUEST_ISIM_AUTHENTICATION, radio_1_4::requestIsimAuthenticationResponse},
+    {RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, radio_1_4::acknowledgeIncomingGsmSmsWithPduResponse},
+    {RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, radio_1_4::sendEnvelopeWithStatusResponse},
+    {RIL_REQUEST_VOICE_RADIO_TECH, radio_1_4::getVoiceRadioTechnologyResponse},
+    {RIL_REQUEST_GET_CELL_INFO_LIST, radio_1_4::getCellInfoListResponse},
+    {RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, radio_1_4::setCellInfoListRateResponse},
+    {RIL_REQUEST_SET_INITIAL_ATTACH_APN, radio_1_4::setInitialAttachApnResponse},
+    {RIL_REQUEST_IMS_REGISTRATION_STATE, radio_1_4::getImsRegistrationStateResponse},
+    {RIL_REQUEST_IMS_SEND_SMS, radio_1_4::sendImsSmsResponse},
+    {RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, radio_1_4::iccTransmitApduBasicChannelResponse},
+    {RIL_REQUEST_SIM_OPEN_CHANNEL, radio_1_4::iccOpenLogicalChannelResponse},
+    {RIL_REQUEST_SIM_CLOSE_CHANNEL, radio_1_4::iccCloseLogicalChannelResponse},
+    {RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, radio_1_4::iccTransmitApduLogicalChannelResponse},
+    {RIL_REQUEST_NV_READ_ITEM, radio_1_4::nvReadItemResponse},
+    {RIL_REQUEST_NV_WRITE_ITEM, radio_1_4::nvWriteItemResponse},
+    {RIL_REQUEST_NV_WRITE_CDMA_PRL, radio_1_4::nvWriteCdmaPrlResponse},
+    {RIL_REQUEST_NV_RESET_CONFIG, radio_1_4::nvResetConfigResponse},
+    {RIL_REQUEST_SET_UICC_SUBSCRIPTION, radio_1_4::setUiccSubscriptionResponse},
+    {RIL_REQUEST_ALLOW_DATA, radio_1_4::setDataAllowedResponse},
+    {RIL_REQUEST_GET_HARDWARE_CONFIG, radio_1_4::getHardwareConfigResponse},
+    {RIL_REQUEST_SIM_AUTHENTICATION, radio_1_4::requestIccSimAuthenticationResponse},
+    {RIL_REQUEST_GET_DC_RT_INFO, NULL},
+    {RIL_REQUEST_SET_DC_RT_INFO_RATE, NULL},
+    {RIL_REQUEST_SET_DATA_PROFILE, radio_1_4::setDataProfileResponse},
+    {RIL_REQUEST_SHUTDOWN, radio_1_4::requestShutdownResponse},
+    {RIL_REQUEST_GET_RADIO_CAPABILITY, radio_1_4::getRadioCapabilityResponse},
+    {RIL_REQUEST_SET_RADIO_CAPABILITY, radio_1_4::setRadioCapabilityResponse},
+    {RIL_REQUEST_START_LCE, radio_1_4::startLceServiceResponse},
+    {RIL_REQUEST_STOP_LCE, radio_1_4::stopLceServiceResponse},
+    {RIL_REQUEST_PULL_LCEDATA, radio_1_4::pullLceDataResponse},
+    {RIL_REQUEST_GET_ACTIVITY_INFO, radio_1_4::getModemActivityInfoResponse},
+    {RIL_REQUEST_SET_CARRIER_RESTRICTIONS, radio_1_4::setAllowedCarriersResponse},
+    {RIL_REQUEST_GET_CARRIER_RESTRICTIONS, radio_1_4::getAllowedCarriersResponse},
+    {RIL_REQUEST_SEND_DEVICE_STATE, radio_1_4::sendDeviceStateResponse},
+    {RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, radio_1_4::setIndicationFilterResponse},
+    {RIL_REQUEST_SET_SIM_CARD_POWER, radio_1_4::setSimCardPowerResponse},
+    {RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, radio_1_4::setCarrierInfoForImsiEncryptionResponse},
+    {RIL_REQUEST_START_NETWORK_SCAN, radio_1_4::startNetworkScanResponse},
+    {RIL_REQUEST_STOP_NETWORK_SCAN, radio_1_4::stopNetworkScanResponse},
+    {RIL_REQUEST_START_KEEPALIVE, radio_1_4::startKeepaliveResponse},
+    {RIL_REQUEST_STOP_KEEPALIVE, radio_1_4::stopKeepaliveResponse},
+    {RIL_REQUEST_START_NETWORK_SCAN4, radio_1_4::startNetworkScanResponse4},
+    {RIL_REQUEST_GET_MODEM_STACK_STATUS, radio_1_4::getModemStackStatusResponse},
+    {RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP, radio_1_4::getPreferredNetworkTypeBitmapResponse},
+    {RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP, radio_1_4::setPreferredNetworkTypeBitmapResponse},
+    {RIL_REQUEST_EMERGENCY_DIAL, radio_1_4::emergencyDialResponse},
+    {RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS, radio_1_4::setSystemSelectionChannelsResponse},
+    {RIL_REQUEST_ENABLE_MODEM, radio_1_4::enableModemResponse},
+    {RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4, radio_1_4::setAllowedCarriersResponse4},
+    {RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4, radio_1_4::getAllowedCarriersResponse4},
diff --git a/guest/hals/ril/libril/ril_event.cpp b/guest/hals/ril/libril/ril_event.cpp
new file mode 100644
index 0000000..84b8b72
--- /dev/null
+++ b/guest/hals/ril/libril/ril_event.cpp
@@ -0,0 +1,384 @@
+/* //device/libs/telephony/ril_event.cpp
+**
+** Copyright 2008, 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 is 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.
+*/
+
+#define LOG_TAG "RILC"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <utils/Log.h>
+#include <ril_event.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include <pthread.h>
+static pthread_mutex_t listMutex;
+#define MUTEX_ACQUIRE() pthread_mutex_lock(&listMutex)
+#define MUTEX_RELEASE() pthread_mutex_unlock(&listMutex)
+#define MUTEX_INIT() pthread_mutex_init(&listMutex, NULL)
+#define MUTEX_DESTROY() pthread_mutex_destroy(&listMutex)
+
+#ifndef timeradd
+#define timeradd(tvp, uvp, vvp)						\
+	do {								\
+		(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec;		\
+		(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec;       \
+		if ((vvp)->tv_usec >= 1000000) {			\
+			(vvp)->tv_sec++;				\
+			(vvp)->tv_usec -= 1000000;			\
+		}							\
+	} while (0)
+#endif
+
+#ifndef timercmp
+#define timercmp(a, b, op)               \
+        ((a)->tv_sec == (b)->tv_sec      \
+        ? (a)->tv_usec op (b)->tv_usec   \
+        : (a)->tv_sec op (b)->tv_sec)
+#endif
+
+#ifndef timersub
+#define timersub(a, b, res)                           \
+    do {                                              \
+        (res)->tv_sec = (a)->tv_sec - (b)->tv_sec;    \
+        (res)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+        if ((res)->tv_usec < 0) {                     \
+            (res)->tv_usec += 1000000;                \
+            (res)->tv_sec -= 1;                       \
+        }                                             \
+    } while(0);
+#endif
+
+static fd_set readFds;
+static int nfds = 0;
+
+static struct ril_event * watch_table[MAX_FD_EVENTS];
+static struct ril_event timer_list;
+static struct ril_event pending_list;
+
+#define DEBUG 0
+
+#if DEBUG
+#define dlog(x...) RLOGD( x )
+static void dump_event(struct ril_event * ev)
+{
+    dlog("~~~~ Event %x ~~~~", (unsigned int)ev);
+    dlog("     next    = %x", (unsigned int)ev->next);
+    dlog("     prev    = %x", (unsigned int)ev->prev);
+    dlog("     fd      = %d", ev->fd);
+    dlog("     pers    = %d", ev->persist);
+    dlog("     timeout = %ds + %dus", (int)ev->timeout.tv_sec, (int)ev->timeout.tv_usec);
+    dlog("     func    = %x", (unsigned int)ev->func);
+    dlog("     param   = %x", (unsigned int)ev->param);
+    dlog("~~~~~~~~~~~~~~~~~~");
+}
+#else
+#define dlog(x...) do {} while(0)
+#define dump_event(x) do {} while(0)
+#endif
+
+static void getNow(struct timeval * tv)
+{
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    tv->tv_sec = ts.tv_sec;
+    tv->tv_usec = ts.tv_nsec/1000;
+}
+
+static void init_list(struct ril_event * list)
+{
+    memset(list, 0, sizeof(struct ril_event));
+    list->next = list;
+    list->prev = list;
+    list->fd = -1;
+}
+
+static void addToList(struct ril_event * ev, struct ril_event * list)
+{
+    ev->next = list;
+    ev->prev = list->prev;
+    ev->prev->next = ev;
+    list->prev = ev;
+    dump_event(ev);
+}
+
+static void removeFromList(struct ril_event * ev)
+{
+    dlog("~~~~ +removeFromList ~~~~");
+    dump_event(ev);
+
+    ev->next->prev = ev->prev;
+    ev->prev->next = ev->next;
+    ev->next = NULL;
+    ev->prev = NULL;
+    dlog("~~~~ -removeFromList ~~~~");
+}
+
+
+static void removeWatch(struct ril_event * ev, int index)
+{
+    dlog("~~~~ +removeWatch ~~~~");
+    watch_table[index] = NULL;
+    ev->index = -1;
+
+    FD_CLR(ev->fd, &readFds);
+
+    if (ev->fd+1 == nfds) {
+        int n = 0;
+
+        for (int i = 0; i < MAX_FD_EVENTS; i++) {
+            struct ril_event * rev = watch_table[i];
+
+            if ((rev != NULL) && (rev->fd > n)) {
+                n = rev->fd;
+            }
+        }
+        nfds = n + 1;
+        dlog("~~~~ nfds = %d ~~~~", nfds);
+    }
+    dlog("~~~~ -removeWatch ~~~~");
+}
+
+static void processTimeouts()
+{
+    dlog("~~~~ +processTimeouts ~~~~");
+    MUTEX_ACQUIRE();
+    struct timeval now;
+    struct ril_event * tev = timer_list.next;
+    struct ril_event * next;
+
+    getNow(&now);
+    // walk list, see if now >= ev->timeout for any events
+
+    dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec);
+    while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) {
+        // Timer expired
+        dlog("~~~~ firing timer ~~~~");
+        next = tev->next;
+        removeFromList(tev);
+        addToList(tev, &pending_list);
+        tev = next;
+    }
+    MUTEX_RELEASE();
+    dlog("~~~~ -processTimeouts ~~~~");
+}
+
+static void processReadReadies(fd_set * rfds, int n)
+{
+    dlog("~~~~ +processReadReadies (%d) ~~~~", n);
+    MUTEX_ACQUIRE();
+
+    for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) {
+        struct ril_event * rev = watch_table[i];
+        if (rev != NULL && FD_ISSET(rev->fd, rfds)) {
+            addToList(rev, &pending_list);
+            if (rev->persist == false) {
+                removeWatch(rev, i);
+            }
+            n--;
+        }
+    }
+
+    MUTEX_RELEASE();
+    dlog("~~~~ -processReadReadies (%d) ~~~~", n);
+}
+
+static void firePending()
+{
+    dlog("~~~~ +firePending ~~~~");
+    struct ril_event * ev = pending_list.next;
+    while (ev != &pending_list) {
+        struct ril_event * next = ev->next;
+        removeFromList(ev);
+        ev->func(ev->fd, 0, ev->param);
+        ev = next;
+    }
+    dlog("~~~~ -firePending ~~~~");
+}
+
+static int calcNextTimeout(struct timeval * tv)
+{
+    struct ril_event * tev = timer_list.next;
+    struct timeval now;
+
+    getNow(&now);
+
+    // Sorted list, so calc based on first node
+    if (tev == &timer_list) {
+        // no pending timers
+        return -1;
+    }
+
+    dlog("~~~~ now = %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec);
+    dlog("~~~~ next = %ds + %dus ~~~~",
+            (int)tev->timeout.tv_sec, (int)tev->timeout.tv_usec);
+    if (timercmp(&tev->timeout, &now, >)) {
+        timersub(&tev->timeout, &now, tv);
+    } else {
+        // timer already expired.
+        tv->tv_sec = tv->tv_usec = 0;
+    }
+    return 0;
+}
+
+// Initialize internal data structs
+void ril_event_init()
+{
+    MUTEX_INIT();
+
+    FD_ZERO(&readFds);
+    init_list(&timer_list);
+    init_list(&pending_list);
+    memset(watch_table, 0, sizeof(watch_table));
+}
+
+// Initialize an event
+void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param)
+{
+    dlog("~~~~ ril_event_set %x ~~~~", (unsigned int)ev);
+    memset(ev, 0, sizeof(struct ril_event));
+    ev->fd = fd;
+    ev->index = -1;
+    ev->persist = persist;
+    ev->func = func;
+    ev->param = param;
+    fcntl(fd, F_SETFL, O_NONBLOCK);
+}
+
+// Add event to watch list
+void ril_event_add(struct ril_event * ev)
+{
+    dlog("~~~~ +ril_event_add ~~~~");
+    MUTEX_ACQUIRE();
+    for (int i = 0; i < MAX_FD_EVENTS; i++) {
+        if (watch_table[i] == NULL) {
+            watch_table[i] = ev;
+            ev->index = i;
+            dlog("~~~~ added at %d ~~~~", i);
+            dump_event(ev);
+            FD_SET(ev->fd, &readFds);
+            if (ev->fd >= nfds) nfds = ev->fd+1;
+            dlog("~~~~ nfds = %d ~~~~", nfds);
+            break;
+        }
+    }
+    MUTEX_RELEASE();
+    dlog("~~~~ -ril_event_add ~~~~");
+}
+
+// Add timer event
+void ril_timer_add(struct ril_event * ev, struct timeval * tv)
+{
+    dlog("~~~~ +ril_timer_add ~~~~");
+    MUTEX_ACQUIRE();
+
+    struct ril_event * list;
+    if (tv != NULL) {
+        // add to timer list
+        list = timer_list.next;
+        ev->fd = -1; // make sure fd is invalid
+
+        struct timeval now;
+        getNow(&now);
+        timeradd(&now, tv, &ev->timeout);
+
+        // keep list sorted
+        while (timercmp(&list->timeout, &ev->timeout, < )
+                && (list != &timer_list)) {
+            list = list->next;
+        }
+        // list now points to the first event older than ev
+        addToList(ev, list);
+    }
+
+    MUTEX_RELEASE();
+    dlog("~~~~ -ril_timer_add ~~~~");
+}
+
+// Remove event from watch or timer list
+void ril_event_del(struct ril_event * ev)
+{
+    dlog("~~~~ +ril_event_del ~~~~");
+    MUTEX_ACQUIRE();
+
+    if (ev->index < 0 || ev->index >= MAX_FD_EVENTS) {
+        MUTEX_RELEASE();
+        return;
+    }
+
+    removeWatch(ev, ev->index);
+
+    MUTEX_RELEASE();
+    dlog("~~~~ -ril_event_del ~~~~");
+}
+
+#if DEBUG
+static void printReadies(fd_set * rfds)
+{
+    for (int i = 0; (i < MAX_FD_EVENTS); i++) {
+        struct ril_event * rev = watch_table[i];
+        if (rev != NULL && FD_ISSET(rev->fd, rfds)) {
+          dlog("DON: fd=%d is ready", rev->fd);
+        }
+    }
+}
+#else
+#define printReadies(rfds) do {} while(0)
+#endif
+
+void ril_event_loop()
+{
+    int n;
+    fd_set rfds;
+    struct timeval tv;
+    struct timeval * ptv;
+
+
+    for (;;) {
+
+        // make local copy of read fd_set
+        memcpy(&rfds, &readFds, sizeof(fd_set));
+        if (-1 == calcNextTimeout(&tv)) {
+            // no pending timers; block indefinitely
+            dlog("~~~~ no timers; blocking indefinitely ~~~~");
+            ptv = NULL;
+        } else {
+            dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);
+            ptv = &tv;
+        }
+        printReadies(&rfds);
+        n = select(nfds, &rfds, NULL, NULL, ptv);
+        printReadies(&rfds);
+        dlog("~~~~ %d events fired ~~~~", n);
+        if (n < 0) {
+            if (errno == EINTR) continue;
+
+            RLOGE("ril_event: select error (%d)", errno);
+            // bail?
+            return;
+        }
+
+        // Check for timeouts
+        processTimeouts();
+        // Check for read-ready
+        processReadReadies(&rfds, n);
+        // Fire away
+        firePending();
+    }
+}
diff --git a/guest/hals/ril/libril/ril_ex.h b/guest/hals/ril/libril/ril_ex.h
new file mode 100644
index 0000000..e0fcd7b
--- /dev/null
+++ b/guest/hals/ril/libril/ril_ex.h
@@ -0,0 +1,49 @@
+/*
+* Copyright (C) 2014 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 is 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.
+*/
+
+#ifndef RIL_EX_H_INCLUDED
+#define RIL_EX_H_INCLUDED
+
+#include <guest/hals/ril/libril/ril.h>
+#include <telephony/record_stream.h>
+
+#define NUM_ELEMS_SOCKET(a)     (sizeof (a) / sizeof (a)[0])
+
+struct ril_event;
+
+void rilEventAddWakeup_helper(struct ril_event *ev);
+int blockingWrite_helper(int fd, void* data, size_t len);
+
+enum SocketWakeType {DONT_WAKE, WAKE_PARTIAL};
+
+typedef enum {
+    RIL_TELEPHONY_SOCKET,
+    RIL_SAP_SOCKET
+} RIL_SOCKET_TYPE;
+
+typedef struct SocketListenParam {
+    RIL_SOCKET_ID socket_id;
+    int fdListen;
+    int fdCommand;
+    const char* processName;
+    struct ril_event* commands_event;
+    struct ril_event* listen_event;
+    void (*processCommandsCallback)(int fd, short flags, void *param);
+    RecordStream *p_rs;
+    RIL_SOCKET_TYPE type;
+} SocketListenParam;
+
+#endif
diff --git a/guest/hals/ril/libril/ril_service.cpp b/guest/hals/ril/libril/ril_service.cpp
new file mode 100755
index 0000000..ab3c33b
--- /dev/null
+++ b/guest/hals/ril/libril/ril_service.cpp
@@ -0,0 +1,9479 @@
+/*
+ * Copyright (c) 2016 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 is 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.
+ */
+
+#define LOG_TAG "RILC"
+
+#include <android/hardware/radio/1.4/IRadio.h>
+#include <android/hardware/radio/1.4/IRadioResponse.h>
+#include <android/hardware/radio/1.4/IRadioIndication.h>
+#include <android/hardware/radio/1.4/types.h>
+
+#include <android/hardware/radio/deprecated/1.0/IOemHook.h>
+
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
+#include <guest/hals/ril/libril/ril.h>
+#include <telephony/ril_mnc.h>
+#include <guest/hals/ril/libril/ril_service.h>
+#include <hidl/HidlTransportSupport.h>
+#include <utils/SystemClock.h>
+#include <inttypes.h>
+
+#define INVALID_HEX_CHAR 16
+
+using namespace android::hardware::radio;
+using namespace android::hardware::radio::V1_0;
+using namespace android::hardware::radio::deprecated::V1_0;
+using ::android::hardware::configureRpcThreadpool;
+using ::android::hardware::joinRpcThreadpool;
+using ::android::hardware::Return;
+using ::android::hardware::hidl_bitfield;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_array;
+using ::android::hardware::Void;
+using android::CommandInfo;
+using android::RequestInfo;
+using android::requestToString;
+using android::sp;
+
+#define BOOL_TO_INT(x) (x ? 1 : 0)
+#define ATOI_NULL_HANDLED(x) (x ? atoi(x) : -1)
+#define ATOI_NULL_HANDLED_DEF(x, defaultVal) (x ? atoi(x) : defaultVal)
+
+#if defined(ANDROID_MULTI_SIM)
+#define CALL_ONREQUEST(a, b, c, d, e) \
+        s_vendorFunctions->onRequest((a), (b), (c), (d), ((RIL_SOCKET_ID)(e)))
+#define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest((RIL_SOCKET_ID)(a))
+#else
+#define CALL_ONREQUEST(a, b, c, d, e) s_vendorFunctions->onRequest((a), (b), (c), (d))
+#define CALL_ONSTATEREQUEST(a) s_vendorFunctions->onStateRequest()
+#endif
+
+#ifdef OEM_HOOK_DISABLED
+constexpr bool kOemHookEnabled = false;
+#else
+constexpr bool kOemHookEnabled = true;
+#endif
+
+RIL_RadioFunctions *s_vendorFunctions = NULL;
+static CommandInfo *s_commands;
+
+struct RadioImpl_1_4;
+struct OemHookImpl;
+
+#if (SIM_COUNT >= 2)
+sp<RadioImpl_1_4> radioService[SIM_COUNT];
+sp<OemHookImpl> oemHookService[SIM_COUNT];
+int64_t nitzTimeReceived[SIM_COUNT];
+// counter used for synchronization. It is incremented every time response callbacks are updated.
+volatile int32_t mCounterRadio[SIM_COUNT];
+volatile int32_t mCounterOemHook[SIM_COUNT];
+#else
+sp<RadioImpl_1_4> radioService[1];
+sp<OemHookImpl> oemHookService[1];
+int64_t nitzTimeReceived[1];
+// counter used for synchronization. It is incremented every time response callbacks are updated.
+volatile int32_t mCounterRadio[1];
+volatile int32_t mCounterOemHook[1];
+#endif
+
+static pthread_rwlock_t radioServiceRwlock = PTHREAD_RWLOCK_INITIALIZER;
+
+#if (SIM_COUNT >= 2)
+static pthread_rwlock_t radioServiceRwlock2 = PTHREAD_RWLOCK_INITIALIZER;
+#if (SIM_COUNT >= 3)
+static pthread_rwlock_t radioServiceRwlock3 = PTHREAD_RWLOCK_INITIALIZER;
+#if (SIM_COUNT >= 4)
+static pthread_rwlock_t radioServiceRwlock4 = PTHREAD_RWLOCK_INITIALIZER;
+#endif
+#endif
+#endif
+
+void convertRilHardwareConfigListToHal(void *response, size_t responseLen,
+        hidl_vec<HardwareConfig>& records);
+
+void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc);
+
+void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce);
+
+void convertRilSignalStrengthToHal(void *response, size_t responseLen,
+        SignalStrength& signalStrength);
+
+void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse,
+        SetupDataCallResult& dcResult);
+
+void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse,
+        ::android::hardware::radio::V1_4::SetupDataCallResult& dcResult);
+
+void convertRilDataCallListToHal(void *response, size_t responseLen,
+        hidl_vec<SetupDataCallResult>& dcResultList);
+
+void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<CellInfo>& records);
+
+void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType,
+                         RIL_Errno e);
+
+struct RadioImpl_1_4 : public V1_4::IRadio {
+    int32_t mSlotId;
+    sp<IRadioResponse> mRadioResponse;
+    sp<IRadioIndication> mRadioIndication;
+    sp<V1_2::IRadioResponse> mRadioResponseV1_2;
+    sp<V1_2::IRadioIndication> mRadioIndicationV1_2;
+    sp<V1_3::IRadioResponse> mRadioResponseV1_3;
+    sp<V1_3::IRadioIndication> mRadioIndicationV1_3;
+    sp<V1_4::IRadioResponse> mRadioResponseV1_4;
+    sp<V1_4::IRadioIndication> mRadioIndicationV1_4;
+
+    Return<void> setResponseFunctions(
+            const ::android::sp<IRadioResponse>& radioResponse,
+            const ::android::sp<IRadioIndication>& radioIndication);
+
+    Return<void> getIccCardStatus(int32_t serial);
+
+    Return<void> supplyIccPinForApp(int32_t serial, const hidl_string& pin,
+            const hidl_string& aid);
+
+    Return<void> supplyIccPukForApp(int32_t serial, const hidl_string& puk,
+            const hidl_string& pin, const hidl_string& aid);
+
+    Return<void> supplyIccPin2ForApp(int32_t serial,
+            const hidl_string& pin2,
+            const hidl_string& aid);
+
+    Return<void> supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2,
+            const hidl_string& pin2, const hidl_string& aid);
+
+    Return<void> changeIccPinForApp(int32_t serial, const hidl_string& oldPin,
+            const hidl_string& newPin, const hidl_string& aid);
+
+    Return<void> changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2,
+            const hidl_string& newPin2, const hidl_string& aid);
+
+    Return<void> supplyNetworkDepersonalization(int32_t serial, const hidl_string& netPin);
+
+    Return<void> getCurrentCalls(int32_t serial);
+
+    Return<void> dial(int32_t serial, const Dial& dialInfo);
+
+    Return<void> getImsiForApp(int32_t serial,
+            const ::android::hardware::hidl_string& aid);
+
+    Return<void> hangup(int32_t serial, int32_t gsmIndex);
+
+    Return<void> hangupWaitingOrBackground(int32_t serial);
+
+    Return<void> hangupForegroundResumeBackground(int32_t serial);
+
+    Return<void> switchWaitingOrHoldingAndActive(int32_t serial);
+
+    Return<void> conference(int32_t serial);
+
+    Return<void> rejectCall(int32_t serial);
+
+    Return<void> getLastCallFailCause(int32_t serial);
+
+    Return<void> getSignalStrength(int32_t serial);
+
+    Return<void> getVoiceRegistrationState(int32_t serial);
+
+    Return<void> getDataRegistrationState(int32_t serial);
+
+    Return<void> getOperator(int32_t serial);
+
+    Return<void> setRadioPower(int32_t serial, bool on);
+
+    Return<void> sendDtmf(int32_t serial,
+            const ::android::hardware::hidl_string& s);
+
+    Return<void> sendSms(int32_t serial, const GsmSmsMessage& message);
+
+    Return<void> sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message);
+
+    Return<void> setupDataCall(int32_t serial,
+            RadioTechnology radioTechnology,
+            const DataProfileInfo& profileInfo,
+            bool modemCognitive,
+            bool roamingAllowed,
+            bool isRoaming);
+
+    Return<void> iccIOForApp(int32_t serial,
+            const IccIo& iccIo);
+
+    Return<void> sendUssd(int32_t serial,
+            const ::android::hardware::hidl_string& ussd);
+
+    Return<void> cancelPendingUssd(int32_t serial);
+
+    Return<void> getClir(int32_t serial);
+
+    Return<void> setClir(int32_t serial, int32_t status);
+
+    Return<void> getCallForwardStatus(int32_t serial,
+            const CallForwardInfo& callInfo);
+
+    Return<void> setCallForward(int32_t serial,
+            const CallForwardInfo& callInfo);
+
+    Return<void> getCallWaiting(int32_t serial, int32_t serviceClass);
+
+    Return<void> setCallWaiting(int32_t serial, bool enable, int32_t serviceClass);
+
+    Return<void> acknowledgeLastIncomingGsmSms(int32_t serial,
+            bool success, SmsAcknowledgeFailCause cause);
+
+    Return<void> acceptCall(int32_t serial);
+
+    Return<void> deactivateDataCall(int32_t serial,
+            int32_t cid, bool reasonRadioShutDown);
+
+    Return<void> getFacilityLockForApp(int32_t serial,
+            const ::android::hardware::hidl_string& facility,
+            const ::android::hardware::hidl_string& password,
+            int32_t serviceClass,
+            const ::android::hardware::hidl_string& appId);
+
+    Return<void> setFacilityLockForApp(int32_t serial,
+            const ::android::hardware::hidl_string& facility,
+            bool lockState,
+            const ::android::hardware::hidl_string& password,
+            int32_t serviceClass,
+            const ::android::hardware::hidl_string& appId);
+
+    Return<void> setBarringPassword(int32_t serial,
+            const ::android::hardware::hidl_string& facility,
+            const ::android::hardware::hidl_string& oldPassword,
+            const ::android::hardware::hidl_string& newPassword);
+
+    Return<void> getNetworkSelectionMode(int32_t serial);
+
+    Return<void> setNetworkSelectionModeAutomatic(int32_t serial);
+
+    Return<void> setNetworkSelectionModeManual(int32_t serial,
+            const ::android::hardware::hidl_string& operatorNumeric);
+
+    Return<void> getAvailableNetworks(int32_t serial);
+
+    Return<void> startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request);
+
+    Return<void> stopNetworkScan(int32_t serial);
+
+    Return<void> startDtmf(int32_t serial,
+            const ::android::hardware::hidl_string& s);
+
+    Return<void> stopDtmf(int32_t serial);
+
+    Return<void> getBasebandVersion(int32_t serial);
+
+    Return<void> separateConnection(int32_t serial, int32_t gsmIndex);
+
+    Return<void> setMute(int32_t serial, bool enable);
+
+    Return<void> getMute(int32_t serial);
+
+    Return<void> getClip(int32_t serial);
+
+    Return<void> getDataCallList(int32_t serial);
+
+    Return<void> setSuppServiceNotifications(int32_t serial, bool enable);
+
+    Return<void> writeSmsToSim(int32_t serial,
+            const SmsWriteArgs& smsWriteArgs);
+
+    Return<void> deleteSmsOnSim(int32_t serial, int32_t index);
+
+    Return<void> setBandMode(int32_t serial, RadioBandMode mode);
+
+    Return<void> getAvailableBandModes(int32_t serial);
+
+    Return<void> sendEnvelope(int32_t serial,
+            const ::android::hardware::hidl_string& command);
+
+    Return<void> sendTerminalResponseToSim(int32_t serial,
+            const ::android::hardware::hidl_string& commandResponse);
+
+    Return<void> handleStkCallSetupRequestFromSim(int32_t serial, bool accept);
+
+    Return<void> explicitCallTransfer(int32_t serial);
+
+    Return<void> setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType);
+
+    Return<void> getPreferredNetworkType(int32_t serial);
+
+    Return<void> getNeighboringCids(int32_t serial);
+
+    Return<void> setLocationUpdates(int32_t serial, bool enable);
+
+    Return<void> setCdmaSubscriptionSource(int32_t serial,
+            CdmaSubscriptionSource cdmaSub);
+
+    Return<void> setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type);
+
+    Return<void> getCdmaRoamingPreference(int32_t serial);
+
+    Return<void> setTTYMode(int32_t serial, TtyMode mode);
+
+    Return<void> getTTYMode(int32_t serial);
+
+    Return<void> setPreferredVoicePrivacy(int32_t serial, bool enable);
+
+    Return<void> getPreferredVoicePrivacy(int32_t serial);
+
+    Return<void> sendCDMAFeatureCode(int32_t serial,
+            const ::android::hardware::hidl_string& featureCode);
+
+    Return<void> sendBurstDtmf(int32_t serial,
+            const ::android::hardware::hidl_string& dtmf,
+            int32_t on,
+            int32_t off);
+
+    Return<void> sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms);
+
+    Return<void> acknowledgeLastIncomingCdmaSms(int32_t serial,
+            const CdmaSmsAck& smsAck);
+
+    Return<void> getGsmBroadcastConfig(int32_t serial);
+
+    Return<void> setGsmBroadcastConfig(int32_t serial,
+            const hidl_vec<GsmBroadcastSmsConfigInfo>& configInfo);
+
+    Return<void> setGsmBroadcastActivation(int32_t serial, bool activate);
+
+    Return<void> getCdmaBroadcastConfig(int32_t serial);
+
+    Return<void> setCdmaBroadcastConfig(int32_t serial,
+            const hidl_vec<CdmaBroadcastSmsConfigInfo>& configInfo);
+
+    Return<void> setCdmaBroadcastActivation(int32_t serial, bool activate);
+
+    Return<void> getCDMASubscription(int32_t serial);
+
+    Return<void> writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms);
+
+    Return<void> deleteSmsOnRuim(int32_t serial, int32_t index);
+
+    Return<void> getDeviceIdentity(int32_t serial);
+
+    Return<void> exitEmergencyCallbackMode(int32_t serial);
+
+    Return<void> getSmscAddress(int32_t serial);
+
+    Return<void> setSmscAddress(int32_t serial,
+            const ::android::hardware::hidl_string& smsc);
+
+    Return<void> reportSmsMemoryStatus(int32_t serial, bool available);
+
+    Return<void> reportStkServiceIsRunning(int32_t serial);
+
+    Return<void> getCdmaSubscriptionSource(int32_t serial);
+
+    Return<void> requestIsimAuthentication(int32_t serial,
+            const ::android::hardware::hidl_string& challenge);
+
+    Return<void> acknowledgeIncomingGsmSmsWithPdu(int32_t serial,
+            bool success,
+            const ::android::hardware::hidl_string& ackPdu);
+
+    Return<void> sendEnvelopeWithStatus(int32_t serial,
+            const ::android::hardware::hidl_string& contents);
+
+    Return<void> getVoiceRadioTechnology(int32_t serial);
+
+    Return<void> getCellInfoList(int32_t serial);
+
+    Return<void> setCellInfoListRate(int32_t serial, int32_t rate);
+
+    Return<void> setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo,
+            bool modemCognitive, bool isRoaming);
+
+    Return<void> getImsRegistrationState(int32_t serial);
+
+    Return<void> sendImsSms(int32_t serial, const ImsSmsMessage& message);
+
+    Return<void> iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message);
+
+    Return<void> iccOpenLogicalChannel(int32_t serial,
+            const ::android::hardware::hidl_string& aid, int32_t p2);
+
+    Return<void> iccCloseLogicalChannel(int32_t serial, int32_t channelId);
+
+    Return<void> iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message);
+
+    Return<void> nvReadItem(int32_t serial, NvItem itemId);
+
+    Return<void> nvWriteItem(int32_t serial, const NvWriteItem& item);
+
+    Return<void> nvWriteCdmaPrl(int32_t serial,
+            const ::android::hardware::hidl_vec<uint8_t>& prl);
+
+    Return<void> nvResetConfig(int32_t serial, ResetNvType resetType);
+
+    Return<void> setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub);
+
+    Return<void> setDataAllowed(int32_t serial, bool allow);
+
+    Return<void> getHardwareConfig(int32_t serial);
+
+    Return<void> requestIccSimAuthentication(int32_t serial,
+            int32_t authContext,
+            const ::android::hardware::hidl_string& authData,
+            const ::android::hardware::hidl_string& aid);
+
+    Return<void> setDataProfile(int32_t serial,
+            const ::android::hardware::hidl_vec<DataProfileInfo>& profiles, bool isRoaming);
+
+    Return<void> requestShutdown(int32_t serial);
+
+    Return<void> getRadioCapability(int32_t serial);
+
+    Return<void> setRadioCapability(int32_t serial, const RadioCapability& rc);
+
+    Return<void> startLceService(int32_t serial, int32_t reportInterval, bool pullMode);
+
+    Return<void> stopLceService(int32_t serial);
+
+    Return<void> pullLceData(int32_t serial);
+
+    Return<void> getModemActivityInfo(int32_t serial);
+
+    Return<void> setAllowedCarriers(int32_t serial,
+            bool allAllowed,
+            const CarrierRestrictions& carriers);
+
+    Return<void> getAllowedCarriers(int32_t serial);
+
+    Return<void> sendDeviceState(int32_t serial, DeviceStateType deviceStateType, bool state);
+
+    Return<void> setIndicationFilter(int32_t serial, int32_t indicationFilter);
+
+    Return<void> startKeepalive(int32_t serial, const V1_1::KeepaliveRequest& keepalive);
+
+    Return<void> stopKeepalive(int32_t serial, int32_t sessionHandle);
+
+    Return<void> setSimCardPower(int32_t serial, bool powerUp);
+    Return<void> setSimCardPower_1_1(int32_t serial,
+            const V1_1::CardPowerState state);
+
+    Return<void> responseAcknowledgement();
+
+    Return<void> setCarrierInfoForImsiEncryption(int32_t serial,
+            const V1_1::ImsiEncryptionInfo& message);
+
+    void checkReturnStatus(Return<void>& ret);
+
+    // Methods from ::android::hardware::radio::V1_2::IRadio follow.
+    Return<void> startNetworkScan_1_2(int32_t serial,
+            const ::android::hardware::radio::V1_2::NetworkScanRequest& request);
+    Return<void> setIndicationFilter_1_2(int32_t serial,
+            hidl_bitfield<::android::hardware::radio::V1_2::IndicationFilter> indicationFilter);
+    Return<void> setSignalStrengthReportingCriteria(int32_t serial, int32_t hysteresisMs,
+            int32_t hysteresisDb, const hidl_vec<int32_t>& thresholdsDbm,
+            ::android::hardware::radio::V1_2::AccessNetwork accessNetwork);
+    Return<void> setLinkCapacityReportingCriteria(int32_t serial, int32_t hysteresisMs,
+            int32_t hysteresisDlKbps, int32_t hysteresisUlKbps,
+            const hidl_vec<int32_t>& thresholdsDownlinkKbps,
+            const hidl_vec<int32_t>& thresholdsUplinkKbps,
+            ::android::hardware::radio::V1_2::AccessNetwork accessNetwork);
+    Return<void> setupDataCall_1_2(int32_t serial,
+            ::android::hardware::radio::V1_2::AccessNetwork accessNetwork,
+            const ::android::hardware::radio::V1_0::DataProfileInfo& dataProfileInfo,
+            bool modemCognitive, bool roamingAllowed, bool isRoaming,
+            ::android::hardware::radio::V1_2::DataRequestReason reason,
+            const hidl_vec<hidl_string>& addresses, const hidl_vec<hidl_string>& dnses);
+    Return<void> deactivateDataCall_1_2(int32_t serial, int32_t cid,
+            ::android::hardware::radio::V1_2::DataRequestReason reason);
+
+    // Methods from ::android::hardware::radio::V1_3::IRadio follow.
+    Return<void> setSystemSelectionChannels(int32_t serial, bool specifyChannels,
+            const hidl_vec<::android::hardware::radio::V1_1::RadioAccessSpecifier>& specifiers)
+           ;
+    Return<void> enableModem(int32_t serial, bool on);
+    Return<void> getModemStackStatus(int32_t serial);
+
+    // Methods from ::android::hardware::radio::V1_4::IRadio follow.
+    Return<void> setupDataCall_1_4(int32_t serial,
+            ::android::hardware::radio::V1_4::AccessNetwork accessNetwork,
+            const ::android::hardware::radio::V1_4::DataProfileInfo& dataProfileInfo,
+            bool roamingAllowed, ::android::hardware::radio::V1_2::DataRequestReason reason,
+            const hidl_vec<hidl_string>& addresses, const hidl_vec<hidl_string>& dnses);
+    Return<void> setInitialAttachApn_1_4(int32_t serial,
+            const ::android::hardware::radio::V1_4::DataProfileInfo& dataProfileInfo);
+    Return<void> setDataProfile_1_4(int32_t serial,
+            const hidl_vec<::android::hardware::radio::V1_4::DataProfileInfo>& profiles);
+    Return<void> emergencyDial(int32_t serial,
+            const ::android::hardware::radio::V1_0::Dial& dialInfo,
+            hidl_bitfield<android::hardware::radio::V1_4::EmergencyServiceCategory> categories,
+            const hidl_vec<hidl_string>& urns,
+            ::android::hardware::radio::V1_4::EmergencyCallRouting routing,
+            bool fromEmergencyDialer, bool isTesting);
+    Return<void> startNetworkScan_1_4(int32_t serial,
+            const ::android::hardware::radio::V1_2::NetworkScanRequest& request);
+    Return<void> getPreferredNetworkTypeBitmap(int32_t serial);
+    Return<void> setPreferredNetworkTypeBitmap(
+            int32_t serial, hidl_bitfield<RadioAccessFamily> networkTypeBitmap);
+    Return<void> setAllowedCarriers_1_4(int32_t serial,
+            const ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority& carriers,
+            ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicy);
+    Return<void> getAllowedCarriers_1_4(int32_t serial);
+    Return<void> getSignalStrength_1_4(int32_t serial);
+};
+
+struct OemHookImpl : public IOemHook {
+    int32_t mSlotId;
+    sp<IOemHookResponse> mOemHookResponse;
+    sp<IOemHookIndication> mOemHookIndication;
+
+    Return<void> setResponseFunctions(
+            const ::android::sp<IOemHookResponse>& oemHookResponse,
+            const ::android::sp<IOemHookIndication>& oemHookIndication);
+
+    Return<void> sendRequestRaw(int32_t serial,
+            const ::android::hardware::hidl_vec<uint8_t>& data);
+
+    Return<void> sendRequestStrings(int32_t serial,
+            const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& data);
+};
+
+void memsetAndFreeStrings(int numPointers, ...) {
+    va_list ap;
+    va_start(ap, numPointers);
+    for (int i = 0; i < numPointers; i++) {
+        char *ptr = va_arg(ap, char *);
+        if (ptr) {
+#ifdef MEMSET_FREED
+#define MAX_STRING_LENGTH 4096
+            memset(ptr, 0, strnlen(ptr, MAX_STRING_LENGTH));
+#endif
+            free(ptr);
+        }
+    }
+    va_end(ap);
+}
+
+void sendErrorResponse(RequestInfo *pRI, RIL_Errno err) {
+    pRI->pCI->responseFunction((int) pRI->socket_id,
+            (int) RadioResponseType::SOLICITED, pRI->token, err, NULL, 0);
+}
+
+/**
+ * Copies over src to dest. If memory allocation fails, responseFunction() is called for the
+ * request with error RIL_E_NO_MEMORY. The size() method is used to determine the size of the
+ * destination buffer into which the HIDL string is copied. If there is a discrepancy between
+ * the string length reported by the size() method, and the length of the string returned by
+ * the c_str() method, the function will return false indicating a failure.
+ *
+ * Returns true on success, and false on failure.
+ */
+bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI, bool allowEmpty) {
+    size_t len = src.size();
+    if (len == 0 && !allowEmpty) {
+        *dest = NULL;
+        return true;
+    }
+    *dest = (char *) calloc(len + 1, sizeof(char));
+    if (*dest == NULL) {
+        RLOGE("Memory allocation failed for request %s", requestToString(pRI->pCI->requestNumber));
+        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+        return false;
+    }
+    if (strlcpy(*dest, src.c_str(), len + 1) >= (len + 1)) {
+        RLOGE("Copy of the HIDL string has been truncated, as "
+              "the string length reported by size() does not "
+              "match the length of string returned by c_str().");
+        free(*dest);
+        *dest = NULL;
+        sendErrorResponse(pRI, RIL_E_INTERNAL_ERR);
+        return false;
+    }
+    return true;
+}
+
+bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI) {
+    return copyHidlStringToRil(dest, src, pRI, false);
+}
+
+hidl_string convertCharPtrToHidlString(const char *ptr) {
+    hidl_string ret;
+    if (ptr != NULL) {
+        // TODO: replace this with strnlen
+        ret.setToExternal(ptr, strlen(ptr));
+    }
+    return ret;
+}
+
+bool dispatchVoid(int serial, int slotId, int request) {
+    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
+    if (pRI == NULL) {
+        return false;
+    }
+    CALL_ONREQUEST(request, NULL, 0, pRI, slotId);
+    return true;
+}
+
+bool dispatchString(int serial, int slotId, int request, const char * str) {
+    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
+    if (pRI == NULL) {
+        return false;
+    }
+
+    char *pString;
+    if (!copyHidlStringToRil(&pString, str, pRI)) {
+        return false;
+    }
+
+    CALL_ONREQUEST(request, pString, sizeof(char *), pRI, slotId);
+
+    memsetAndFreeStrings(1, pString);
+    return true;
+}
+
+bool dispatchStrings(int serial, int slotId, int request, bool allowEmpty, int countStrings, ...) {
+    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
+    if (pRI == NULL) {
+        return false;
+    }
+
+    char **pStrings;
+    pStrings = (char **)calloc(countStrings, sizeof(char *));
+    if (pStrings == NULL) {
+        RLOGE("Memory allocation failed for request %s", requestToString(request));
+        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+        return false;
+    }
+    va_list ap;
+    va_start(ap, countStrings);
+    for (int i = 0; i < countStrings; i++) {
+        const char* str = va_arg(ap, const char *);
+        if (!copyHidlStringToRil(&pStrings[i], hidl_string(str), pRI, allowEmpty)) {
+            va_end(ap);
+            for (int j = 0; j < i; j++) {
+                memsetAndFreeStrings(1, pStrings[j]);
+            }
+            free(pStrings);
+            return false;
+        }
+    }
+    va_end(ap);
+
+    CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId);
+
+    if (pStrings != NULL) {
+        for (int i = 0 ; i < countStrings ; i++) {
+            memsetAndFreeStrings(1, pStrings[i]);
+        }
+
+#ifdef MEMSET_FREED
+        memset(pStrings, 0, countStrings * sizeof(char *));
+#endif
+        free(pStrings);
+    }
+    return true;
+}
+
+bool dispatchStrings(int serial, int slotId, int request, const hidl_vec<hidl_string>& data) {
+    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
+    if (pRI == NULL) {
+        return false;
+    }
+
+    int countStrings = data.size();
+    char **pStrings;
+    pStrings = (char **)calloc(countStrings, sizeof(char *));
+    if (pStrings == NULL) {
+        RLOGE("Memory allocation failed for request %s", requestToString(request));
+        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+        return false;
+    }
+
+    for (int i = 0; i < countStrings; i++) {
+        if (!copyHidlStringToRil(&pStrings[i], data[i], pRI)) {
+            for (int j = 0; j < i; j++) {
+                memsetAndFreeStrings(1, pStrings[j]);
+            }
+            free(pStrings);
+            return false;
+        }
+    }
+
+    CALL_ONREQUEST(request, pStrings, countStrings * sizeof(char *), pRI, slotId);
+
+    if (pStrings != NULL) {
+        for (int i = 0 ; i < countStrings ; i++) {
+            memsetAndFreeStrings(1, pStrings[i]);
+        }
+
+#ifdef MEMSET_FREED
+        memset(pStrings, 0, countStrings * sizeof(char *));
+#endif
+        free(pStrings);
+    }
+    return true;
+}
+
+bool dispatchInts(int serial, int slotId, int request, int countInts, ...) {
+    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
+    if (pRI == NULL) {
+        return false;
+    }
+
+    int *pInts = (int *)calloc(countInts, sizeof(int));
+
+    if (pInts == NULL) {
+        RLOGE("Memory allocation failed for request %s", requestToString(request));
+        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+        return false;
+    }
+    va_list ap;
+    va_start(ap, countInts);
+    for (int i = 0; i < countInts; i++) {
+        pInts[i] = va_arg(ap, int);
+    }
+    va_end(ap);
+
+    CALL_ONREQUEST(request, pInts, countInts * sizeof(int), pRI, slotId);
+
+    if (pInts != NULL) {
+#ifdef MEMSET_FREED
+        memset(pInts, 0, countInts * sizeof(int));
+#endif
+        free(pInts);
+    }
+    return true;
+}
+
+bool dispatchCallForwardStatus(int serial, int slotId, int request,
+                              const CallForwardInfo& callInfo) {
+    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
+    if (pRI == NULL) {
+        return false;
+    }
+
+    RIL_CallForwardInfo cf;
+    cf.status = (int) callInfo.status;
+    cf.reason = callInfo.reason;
+    cf.serviceClass = callInfo.serviceClass;
+    cf.toa = callInfo.toa;
+    cf.timeSeconds = callInfo.timeSeconds;
+
+    if (!copyHidlStringToRil(&cf.number, callInfo.number, pRI)) {
+        return false;
+    }
+
+    CALL_ONREQUEST(request, &cf, sizeof(cf), pRI, slotId);
+
+    memsetAndFreeStrings(1, cf.number);
+
+    return true;
+}
+
+bool dispatchRaw(int serial, int slotId, int request, const hidl_vec<uint8_t>& rawBytes) {
+    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
+    if (pRI == NULL) {
+        return false;
+    }
+
+    const uint8_t *uData = rawBytes.data();
+
+    CALL_ONREQUEST(request, (void *) uData, rawBytes.size(), pRI, slotId);
+
+    return true;
+}
+
+bool dispatchIccApdu(int serial, int slotId, int request, const SimApdu& message) {
+    RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
+    if (pRI == NULL) {
+        return false;
+    }
+
+    RIL_SIM_APDU apdu = {};
+
+    apdu.sessionid = message.sessionId;
+    apdu.cla = message.cla;
+    apdu.instruction = message.instruction;
+    apdu.p1 = message.p1;
+    apdu.p2 = message.p2;
+    apdu.p3 = message.p3;
+
+    if (!copyHidlStringToRil(&apdu.data, message.data, pRI)) {
+        return false;
+    }
+
+    CALL_ONREQUEST(request, &apdu, sizeof(apdu), pRI, slotId);
+
+    memsetAndFreeStrings(1, apdu.data);
+
+    return true;
+}
+
+void checkReturnStatus(int32_t slotId, Return<void>& ret, bool isRadioService) {
+    if (ret.isOk() == false) {
+        RLOGE("checkReturnStatus: unable to call response/indication callback");
+        // Remote process hosting the callbacks must be dead. Reset the callback objects;
+        // there's no other recovery to be done here. When the client process is back up, it will
+        // call setResponseFunctions()
+
+        // Caller should already hold rdlock, release that first
+        // note the current counter to avoid overwriting updates made by another thread before
+        // write lock is acquired.
+        int counter = isRadioService ? mCounterRadio[slotId] : mCounterOemHook[slotId];
+        pthread_rwlock_t *radioServiceRwlockPtr = radio_1_4::getRadioServiceRwlock(slotId);
+        int ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
+        assert(ret == 0);
+
+        // acquire wrlock
+        ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
+        assert(ret == 0);
+
+        // make sure the counter value has not changed
+        if (counter == (isRadioService ? mCounterRadio[slotId] : mCounterOemHook[slotId])) {
+            if (isRadioService) {
+                radioService[slotId]->mRadioResponse = NULL;
+                radioService[slotId]->mRadioIndication = NULL;
+                radioService[slotId]->mRadioResponseV1_2 = NULL;
+                radioService[slotId]->mRadioIndicationV1_2 = NULL;
+                radioService[slotId]->mRadioResponseV1_3 = NULL;
+                radioService[slotId]->mRadioIndicationV1_3 = NULL;
+                radioService[slotId]->mRadioResponseV1_4 = NULL;
+                radioService[slotId]->mRadioIndicationV1_4 = NULL;
+            } else {
+                oemHookService[slotId]->mOemHookResponse = NULL;
+                oemHookService[slotId]->mOemHookIndication = NULL;
+            }
+            isRadioService ? mCounterRadio[slotId]++ : mCounterOemHook[slotId]++;
+        } else {
+            RLOGE("checkReturnStatus: not resetting responseFunctions as they likely "
+                    "got updated on another thread");
+        }
+
+        // release wrlock
+        ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
+        assert(ret == 0);
+
+        // Reacquire rdlock
+        ret = pthread_rwlock_rdlock(radioServiceRwlockPtr);
+        assert(ret == 0);
+    }
+}
+
+void RadioImpl_1_4::checkReturnStatus(Return<void>& ret) {
+    ::checkReturnStatus(mSlotId, ret, true);
+}
+
+Return<void> RadioImpl_1_4::setResponseFunctions(
+        const ::android::sp<IRadioResponse>& radioResponseParam,
+        const ::android::sp<IRadioIndication>& radioIndicationParam) {
+    RLOGD("setResponseFunctions");
+
+    pthread_rwlock_t *radioServiceRwlockPtr = radio_1_4::getRadioServiceRwlock(mSlotId);
+    int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
+    assert(ret == 0);
+
+    mRadioResponse = radioResponseParam;
+    mRadioIndication = radioIndicationParam;
+    mRadioResponseV1_4 = V1_4::IRadioResponse::castFrom(mRadioResponse).withDefault(nullptr);
+    mRadioIndicationV1_4 = V1_4::IRadioIndication::castFrom(mRadioIndication).withDefault(nullptr);
+    if (mRadioResponseV1_4 == nullptr || mRadioIndicationV1_4 == nullptr) {
+        mRadioResponseV1_4 = nullptr;
+        mRadioIndicationV1_4 = nullptr;
+    }
+
+    mRadioResponseV1_3 = V1_3::IRadioResponse::castFrom(mRadioResponse).withDefault(nullptr);
+    mRadioIndicationV1_3 = V1_3::IRadioIndication::castFrom(mRadioIndication).withDefault(nullptr);
+    if (mRadioResponseV1_3 == nullptr || mRadioIndicationV1_3 == nullptr) {
+        mRadioResponseV1_3 = nullptr;
+        mRadioIndicationV1_3 = nullptr;
+    }
+
+    mRadioResponseV1_2 = V1_2::IRadioResponse::castFrom(mRadioResponse).withDefault(nullptr);
+    mRadioIndicationV1_2 = V1_2::IRadioIndication::castFrom(mRadioIndication).withDefault(nullptr);
+    if (mRadioResponseV1_2 == nullptr || mRadioIndicationV1_2 == nullptr) {
+        mRadioResponseV1_2 = nullptr;
+        mRadioIndicationV1_2 = nullptr;
+    }
+
+    mCounterRadio[mSlotId]++;
+
+    ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
+    assert(ret == 0);
+
+    // client is connected. Send initial indications.
+    android::onNewCommandConnect((RIL_SOCKET_ID) mSlotId);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getIccCardStatus(int32_t serial) {
+#if VDBG
+    RLOGD("getIccCardStatus: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SIM_STATUS);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::supplyIccPinForApp(int32_t serial, const hidl_string& pin,
+        const hidl_string& aid) {
+#if VDBG
+    RLOGD("supplyIccPinForApp: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN, true,
+            2, pin.c_str(), aid.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::supplyIccPukForApp(int32_t serial, const hidl_string& puk,
+                                           const hidl_string& pin, const hidl_string& aid) {
+#if VDBG
+    RLOGD("supplyIccPukForApp: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK, true,
+            3, puk.c_str(), pin.c_str(), aid.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::supplyIccPin2ForApp(int32_t serial, const hidl_string& pin2,
+                                            const hidl_string& aid) {
+#if VDBG
+    RLOGD("supplyIccPin2ForApp: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN2, true,
+            2, pin2.c_str(), aid.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::supplyIccPuk2ForApp(int32_t serial, const hidl_string& puk2,
+                                            const hidl_string& pin2, const hidl_string& aid) {
+#if VDBG
+    RLOGD("supplyIccPuk2ForApp: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK2, true,
+            3, puk2.c_str(), pin2.c_str(), aid.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::changeIccPinForApp(int32_t serial, const hidl_string& oldPin,
+                                           const hidl_string& newPin, const hidl_string& aid) {
+#if VDBG
+    RLOGD("changeIccPinForApp: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN, true,
+            3, oldPin.c_str(), newPin.c_str(), aid.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::changeIccPin2ForApp(int32_t serial, const hidl_string& oldPin2,
+                                            const hidl_string& newPin2, const hidl_string& aid) {
+#if VDBG
+    RLOGD("changeIccPin2ForApp: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN2, true,
+            3, oldPin2.c_str(), newPin2.c_str(), aid.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::supplyNetworkDepersonalization(int32_t serial,
+                                                       const hidl_string& netPin) {
+#if VDBG
+    RLOGD("supplyNetworkDepersonalization: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, true,
+            1, netPin.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getCurrentCalls(int32_t serial) {
+#if VDBG
+    RLOGD("getCurrentCalls: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CURRENT_CALLS);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::dial(int32_t serial, const Dial& dialInfo) {
+#if VDBG
+    RLOGD("dial: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_DIAL);
+    if (pRI == NULL) {
+        return Void();
+    }
+    RIL_Dial dial = {};
+    RIL_UUS_Info uusInfo = {};
+    int32_t sizeOfDial = sizeof(dial);
+
+    if (!copyHidlStringToRil(&dial.address, dialInfo.address, pRI)) {
+        return Void();
+    }
+    dial.clir = (int) dialInfo.clir;
+
+    if (dialInfo.uusInfo.size() != 0) {
+        uusInfo.uusType = (RIL_UUS_Type) dialInfo.uusInfo[0].uusType;
+        uusInfo.uusDcs = (RIL_UUS_DCS) dialInfo.uusInfo[0].uusDcs;
+
+        if (dialInfo.uusInfo[0].uusData.size() == 0) {
+            uusInfo.uusData = NULL;
+            uusInfo.uusLength = 0;
+        } else {
+            if (!copyHidlStringToRil(&uusInfo.uusData, dialInfo.uusInfo[0].uusData, pRI)) {
+                memsetAndFreeStrings(1, dial.address);
+                return Void();
+            }
+            uusInfo.uusLength = dialInfo.uusInfo[0].uusData.size();
+        }
+
+        dial.uusInfo = &uusInfo;
+    }
+
+    CALL_ONREQUEST(RIL_REQUEST_DIAL, &dial, sizeOfDial, pRI, mSlotId);
+
+    memsetAndFreeStrings(2, dial.address, uusInfo.uusData);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getImsiForApp(int32_t serial, const hidl_string& aid) {
+#if VDBG
+    RLOGD("getImsiForApp: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_GET_IMSI, false,
+            1, aid.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::hangup(int32_t serial, int32_t gsmIndex) {
+#if VDBG
+    RLOGD("hangup: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_HANGUP, 1, gsmIndex);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::hangupWaitingOrBackground(int32_t serial) {
+#if VDBG
+    RLOGD("hangupWaitingOrBackground: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::hangupForegroundResumeBackground(int32_t serial) {
+#if VDBG
+    RLOGD("hangupForegroundResumeBackground: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::switchWaitingOrHoldingAndActive(int32_t serial) {
+#if VDBG
+    RLOGD("switchWaitingOrHoldingAndActive: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::conference(int32_t serial) {
+#if VDBG
+    RLOGD("conference: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_CONFERENCE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::rejectCall(int32_t serial) {
+#if VDBG
+    RLOGD("rejectCall: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_UDUB);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getLastCallFailCause(int32_t serial) {
+#if VDBG
+    RLOGD("getLastCallFailCause: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_LAST_CALL_FAIL_CAUSE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getSignalStrength(int32_t serial) {
+#if VDBG
+    RLOGD("getSignalStrength: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_SIGNAL_STRENGTH);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getVoiceRegistrationState(int32_t serial) {
+#if VDBG
+    RLOGD("getVoiceRegistrationState: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_REGISTRATION_STATE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getDataRegistrationState(int32_t serial) {
+#if VDBG
+    RLOGD("getDataRegistrationState: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_REGISTRATION_STATE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getOperator(int32_t serial) {
+#if VDBG
+    RLOGD("getOperator: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_OPERATOR);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setRadioPower(int32_t serial, bool on) {
+    RLOGD("setRadioPower: serial %d on %d", serial, on);
+    dispatchInts(serial, mSlotId, RIL_REQUEST_RADIO_POWER, 1, BOOL_TO_INT(on));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendDtmf(int32_t serial, const hidl_string& s) {
+#if VDBG
+    RLOGD("sendDtmf: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_DTMF, s.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendSms(int32_t serial, const GsmSmsMessage& message) {
+#if VDBG
+    RLOGD("sendSms: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS, false,
+            2, message.smscPdu.c_str(), message.pdu.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendSMSExpectMore(int32_t serial, const GsmSmsMessage& message) {
+#if VDBG
+    RLOGD("sendSMSExpectMore: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS_EXPECT_MORE, false,
+            2, message.smscPdu.c_str(), message.pdu.c_str());
+    return Void();
+}
+
+static bool convertMvnoTypeToString(MvnoType type, char *&str) {
+    switch (type) {
+        case MvnoType::IMSI:
+            str = (char *)"imsi";
+            return true;
+        case MvnoType::GID:
+            str = (char *)"gid";
+            return true;
+        case MvnoType::SPN:
+            str = (char *)"spn";
+            return true;
+        case MvnoType::NONE:
+            str = (char *)"";
+            return true;
+    }
+    return false;
+}
+
+Return<void> RadioImpl_1_4::setupDataCall(int32_t serial, RadioTechnology radioTechnology,
+                                      const DataProfileInfo& dataProfileInfo, bool modemCognitive,
+                                      bool roamingAllowed, bool isRoaming) {
+
+#if VDBG
+    RLOGD("setupDataCall: serial %d", serial);
+#endif
+
+    if (s_vendorFunctions->version >= 4 && s_vendorFunctions->version <= 14) {
+        const hidl_string &protocol =
+                (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol);
+        dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, true, 7,
+            std::to_string((int) radioTechnology + 2).c_str(),
+            std::to_string((int) dataProfileInfo.profileId).c_str(),
+            dataProfileInfo.apn.c_str(),
+            dataProfileInfo.user.c_str(),
+            dataProfileInfo.password.c_str(),
+            std::to_string((int) dataProfileInfo.authType).c_str(),
+            protocol.c_str());
+    } else if (s_vendorFunctions->version >= 15) {
+        char *mvnoTypeStr = NULL;
+        if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, mvnoTypeStr)) {
+            RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+                    RIL_REQUEST_SETUP_DATA_CALL);
+            if (pRI != NULL) {
+                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+            }
+            return Void();
+        }
+        dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, true, 15,
+            std::to_string((int) radioTechnology + 2).c_str(),
+            std::to_string((int) dataProfileInfo.profileId).c_str(),
+            dataProfileInfo.apn.c_str(),
+            dataProfileInfo.user.c_str(),
+            dataProfileInfo.password.c_str(),
+            std::to_string((int) dataProfileInfo.authType).c_str(),
+            dataProfileInfo.protocol.c_str(),
+            dataProfileInfo.roamingProtocol.c_str(),
+            std::to_string(dataProfileInfo.supportedApnTypesBitmap).c_str(),
+            std::to_string(dataProfileInfo.bearerBitmap).c_str(),
+            modemCognitive ? "1" : "0",
+            std::to_string(dataProfileInfo.mtu).c_str(),
+            mvnoTypeStr,
+            dataProfileInfo.mvnoMatchData.c_str(),
+            roamingAllowed ? "1" : "0");
+    } else {
+        RLOGE("Unsupported RIL version %d, min version expected 4", s_vendorFunctions->version);
+        RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+                RIL_REQUEST_SETUP_DATA_CALL);
+        if (pRI != NULL) {
+            sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED);
+        }
+    }
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::iccIOForApp(int32_t serial, const IccIo& iccIo) {
+#if VDBG
+    RLOGD("iccIOForApp: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_IO);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_SIM_IO_v6 rilIccIo = {};
+    rilIccIo.command = iccIo.command;
+    rilIccIo.fileid = iccIo.fileId;
+    if (!copyHidlStringToRil(&rilIccIo.path, iccIo.path, pRI)) {
+        return Void();
+    }
+
+    rilIccIo.p1 = iccIo.p1;
+    rilIccIo.p2 = iccIo.p2;
+    rilIccIo.p3 = iccIo.p3;
+
+    if (!copyHidlStringToRil(&rilIccIo.data, iccIo.data, pRI)) {
+        memsetAndFreeStrings(1, rilIccIo.path);
+        return Void();
+    }
+
+    if (!copyHidlStringToRil(&rilIccIo.pin2, iccIo.pin2, pRI)) {
+        memsetAndFreeStrings(2, rilIccIo.path, rilIccIo.data);
+        return Void();
+    }
+
+    if (!copyHidlStringToRil(&rilIccIo.aidPtr, iccIo.aid, pRI)) {
+        memsetAndFreeStrings(3, rilIccIo.path, rilIccIo.data, rilIccIo.pin2);
+        return Void();
+    }
+
+    CALL_ONREQUEST(RIL_REQUEST_SIM_IO, &rilIccIo, sizeof(rilIccIo), pRI, mSlotId);
+
+    memsetAndFreeStrings(4, rilIccIo.path, rilIccIo.data, rilIccIo.pin2, rilIccIo.aidPtr);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendUssd(int32_t serial, const hidl_string& ussd) {
+#if VDBG
+    RLOGD("sendUssd: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_SEND_USSD, ussd.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::cancelPendingUssd(int32_t serial) {
+#if VDBG
+    RLOGD("cancelPendingUssd: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_CANCEL_USSD);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getClir(int32_t serial) {
+#if VDBG
+    RLOGD("getClir: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CLIR);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setClir(int32_t serial, int32_t status) {
+#if VDBG
+    RLOGD("setClir: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CLIR, 1, status);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getCallForwardStatus(int32_t serial, const CallForwardInfo& callInfo) {
+#if VDBG
+    RLOGD("getCallForwardStatus: serial %d", serial);
+#endif
+    dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_QUERY_CALL_FORWARD_STATUS,
+            callInfo);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setCallForward(int32_t serial, const CallForwardInfo& callInfo) {
+#if VDBG
+    RLOGD("setCallForward: serial %d", serial);
+#endif
+    dispatchCallForwardStatus(serial, mSlotId, RIL_REQUEST_SET_CALL_FORWARD,
+            callInfo);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getCallWaiting(int32_t serial, int32_t serviceClass) {
+#if VDBG
+    RLOGD("getCallWaiting: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_QUERY_CALL_WAITING, 1, serviceClass);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setCallWaiting(int32_t serial, bool enable, int32_t serviceClass) {
+#if VDBG
+    RLOGD("setCallWaiting: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_CALL_WAITING, 2, BOOL_TO_INT(enable),
+            serviceClass);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::acknowledgeLastIncomingGsmSms(int32_t serial,
+                                                      bool success, SmsAcknowledgeFailCause cause) {
+#if VDBG
+    RLOGD("acknowledgeLastIncomingGsmSms: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SMS_ACKNOWLEDGE, 2, BOOL_TO_INT(success),
+            cause);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::acceptCall(int32_t serial) {
+#if VDBG
+    RLOGD("acceptCall: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_ANSWER);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::deactivateDataCall(int32_t serial,
+                                           int32_t cid, bool reasonRadioShutDown) {
+#if VDBG
+    RLOGD("deactivateDataCall: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_DEACTIVATE_DATA_CALL, false,
+            2, (std::to_string(cid)).c_str(), reasonRadioShutDown ? "1" : "0");
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getFacilityLockForApp(int32_t serial, const hidl_string& facility,
+                                              const hidl_string& password, int32_t serviceClass,
+                                              const hidl_string& appId) {
+#if VDBG
+    RLOGD("getFacilityLockForApp: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_QUERY_FACILITY_LOCK, true,
+            4, facility.c_str(), password.c_str(),
+            (std::to_string(serviceClass)).c_str(), appId.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setFacilityLockForApp(int32_t serial, const hidl_string& facility,
+                                              bool lockState, const hidl_string& password,
+                                              int32_t serviceClass, const hidl_string& appId) {
+#if VDBG
+    RLOGD("setFacilityLockForApp: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_SET_FACILITY_LOCK, true,
+            5, facility.c_str(), lockState ? "1" : "0", password.c_str(),
+            (std::to_string(serviceClass)).c_str(), appId.c_str() );
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setBarringPassword(int32_t serial, const hidl_string& facility,
+                                           const hidl_string& oldPassword,
+                                           const hidl_string& newPassword) {
+#if VDBG
+    RLOGD("setBarringPassword: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_BARRING_PASSWORD, true,
+            3, facility.c_str(), oldPassword.c_str(), newPassword.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getNetworkSelectionMode(int32_t serial) {
+#if VDBG
+    RLOGD("getNetworkSelectionMode: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setNetworkSelectionModeAutomatic(int32_t serial) {
+#if VDBG
+    RLOGD("setNetworkSelectionModeAutomatic: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setNetworkSelectionModeManual(int32_t serial,
+                                                      const hidl_string& operatorNumeric) {
+#if VDBG
+    RLOGD("setNetworkSelectionModeManual: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL,
+            operatorNumeric.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getAvailableNetworks(int32_t serial) {
+#if VDBG
+    RLOGD("getAvailableNetworks: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_NETWORKS);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request) {
+#if VDBG
+    RLOGD("startNetworkScan: serial %d", serial);
+#endif
+
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    if (request.specifiers.size() > MAX_RADIO_ACCESS_NETWORKS) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return Void();
+    }
+
+    RIL_NetworkScanRequest scan_request = {};
+
+    scan_request.type = (RIL_ScanType) request.type;
+    scan_request.interval = request.interval;
+    scan_request.specifiers_length = request.specifiers.size();
+    for (size_t i = 0; i < request.specifiers.size(); ++i) {
+        if (request.specifiers[i].geranBands.size() > MAX_BANDS ||
+            request.specifiers[i].utranBands.size() > MAX_BANDS ||
+            request.specifiers[i].eutranBands.size() > MAX_BANDS ||
+            request.specifiers[i].channels.size() > MAX_CHANNELS) {
+            sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+            return Void();
+        }
+        const V1_1::RadioAccessSpecifier& ras_from =
+                request.specifiers[i];
+        RIL_RadioAccessSpecifier& ras_to = scan_request.specifiers[i];
+
+        ras_to.radio_access_network = (RIL_RadioAccessNetworks) ras_from.radioAccessNetwork;
+        ras_to.channels_length = ras_from.channels.size();
+
+        std::copy(ras_from.channels.begin(), ras_from.channels.end(), ras_to.channels);
+        const std::vector<uint32_t> * bands = nullptr;
+        switch (request.specifiers[i].radioAccessNetwork) {
+            case V1_1::RadioAccessNetworks::GERAN:
+                ras_to.bands_length = ras_from.geranBands.size();
+                bands = (std::vector<uint32_t> *) &ras_from.geranBands;
+                break;
+            case V1_1::RadioAccessNetworks::UTRAN:
+                ras_to.bands_length = ras_from.utranBands.size();
+                bands = (std::vector<uint32_t> *) &ras_from.utranBands;
+                break;
+            case V1_1::RadioAccessNetworks::EUTRAN:
+                ras_to.bands_length = ras_from.eutranBands.size();
+                bands = (std::vector<uint32_t> *) &ras_from.eutranBands;
+                break;
+            default:
+                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+                return Void();
+        }
+        // safe to copy to geran_bands because it's a union member
+        for (size_t idx = 0; idx < ras_to.bands_length; ++idx) {
+            ras_to.bands.geran_bands[idx] = (RIL_GeranBands) (*bands)[idx];
+        }
+    }
+
+    CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI,
+            mSlotId);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::stopNetworkScan(int32_t serial) {
+#if VDBG
+    RLOGD("stopNetworkScan: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_NETWORK_SCAN);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::startDtmf(int32_t serial, const hidl_string& s) {
+#if VDBG
+    RLOGD("startDtmf: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_DTMF_START,
+            s.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::stopDtmf(int32_t serial) {
+#if VDBG
+    RLOGD("stopDtmf: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_DTMF_STOP);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getBasebandVersion(int32_t serial) {
+#if VDBG
+    RLOGD("getBasebandVersion: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_BASEBAND_VERSION);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::separateConnection(int32_t serial, int32_t gsmIndex) {
+#if VDBG
+    RLOGD("separateConnection: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SEPARATE_CONNECTION, 1, gsmIndex);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setMute(int32_t serial, bool enable) {
+#if VDBG
+    RLOGD("setMute: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_MUTE, 1, BOOL_TO_INT(enable));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getMute(int32_t serial) {
+#if VDBG
+    RLOGD("getMute: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_MUTE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getClip(int32_t serial) {
+#if VDBG
+    RLOGD("getClip: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_CLIP);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getDataCallList(int32_t serial) {
+#if VDBG
+    RLOGD("getDataCallList: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_DATA_CALL_LIST);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setSuppServiceNotifications(int32_t serial, bool enable) {
+#if VDBG
+    RLOGD("setSuppServiceNotifications: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, 1,
+            BOOL_TO_INT(enable));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::writeSmsToSim(int32_t serial, const SmsWriteArgs& smsWriteArgs) {
+#if VDBG
+    RLOGD("writeSmsToSim: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_WRITE_SMS_TO_SIM);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_SMS_WriteArgs args;
+    args.status = (int) smsWriteArgs.status;
+
+    if (!copyHidlStringToRil(&args.pdu, smsWriteArgs.pdu, pRI)) {
+        return Void();
+    }
+
+    if (!copyHidlStringToRil(&args.smsc, smsWriteArgs.smsc, pRI)) {
+        memsetAndFreeStrings(1, args.pdu);
+        return Void();
+    }
+
+    CALL_ONREQUEST(RIL_REQUEST_WRITE_SMS_TO_SIM, &args, sizeof(args), pRI, mSlotId);
+
+    memsetAndFreeStrings(2, args.smsc, args.pdu);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::deleteSmsOnSim(int32_t serial, int32_t index) {
+#if VDBG
+    RLOGD("deleteSmsOnSim: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_DELETE_SMS_ON_SIM, 1, index);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setBandMode(int32_t serial, RadioBandMode mode) {
+#if VDBG
+    RLOGD("setBandMode: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_BAND_MODE, 1, mode);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getAvailableBandModes(int32_t serial) {
+#if VDBG
+    RLOGD("getAvailableBandModes: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendEnvelope(int32_t serial, const hidl_string& command) {
+#if VDBG
+    RLOGD("sendEnvelope: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND,
+            command.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendTerminalResponseToSim(int32_t serial,
+                                                  const hidl_string& commandResponse) {
+#if VDBG
+    RLOGD("sendTerminalResponseToSim: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE,
+            commandResponse.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::handleStkCallSetupRequestFromSim(int32_t serial, bool accept) {
+#if VDBG
+    RLOGD("handleStkCallSetupRequestFromSim: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM,
+            1, BOOL_TO_INT(accept));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::explicitCallTransfer(int32_t serial) {
+#if VDBG
+    RLOGD("explicitCallTransfer: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_EXPLICIT_CALL_TRANSFER);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setPreferredNetworkType(int32_t serial, PreferredNetworkType nwType) {
+#if VDBG
+    RLOGD("setPreferredNetworkType: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, 1, nwType);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getPreferredNetworkType(int32_t serial) {
+#if VDBG
+    RLOGD("getPreferredNetworkType: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getNeighboringCids(int32_t serial) {
+#if VDBG
+    RLOGD("getNeighboringCids: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_NEIGHBORING_CELL_IDS);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setLocationUpdates(int32_t serial, bool enable) {
+#if VDBG
+    RLOGD("setLocationUpdates: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_LOCATION_UPDATES, 1, BOOL_TO_INT(enable));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setCdmaSubscriptionSource(int32_t serial, CdmaSubscriptionSource cdmaSub) {
+#if VDBG
+    RLOGD("setCdmaSubscriptionSource: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, 1, cdmaSub);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setCdmaRoamingPreference(int32_t serial, CdmaRoamingType type) {
+#if VDBG
+    RLOGD("setCdmaRoamingPreference: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, 1, type);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getCdmaRoamingPreference(int32_t serial) {
+#if VDBG
+    RLOGD("getCdmaRoamingPreference: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setTTYMode(int32_t serial, TtyMode mode) {
+#if VDBG
+    RLOGD("setTTYMode: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_TTY_MODE, 1, mode);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getTTYMode(int32_t serial) {
+#if VDBG
+    RLOGD("getTTYMode: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_QUERY_TTY_MODE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setPreferredVoicePrivacy(int32_t serial, bool enable) {
+#if VDBG
+    RLOGD("setPreferredVoicePrivacy: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE,
+            1, BOOL_TO_INT(enable));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getPreferredVoicePrivacy(int32_t serial) {
+#if VDBG
+    RLOGD("getPreferredVoicePrivacy: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendCDMAFeatureCode(int32_t serial, const hidl_string& featureCode) {
+#if VDBG
+    RLOGD("sendCDMAFeatureCode: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_CDMA_FLASH,
+            featureCode.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendBurstDtmf(int32_t serial, const hidl_string& dtmf, int32_t on,
+                                      int32_t off) {
+#if VDBG
+    RLOGD("sendBurstDtmf: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_CDMA_BURST_DTMF, false,
+            3, dtmf.c_str(), (std::to_string(on)).c_str(),
+            (std::to_string(off)).c_str());
+    return Void();
+}
+
+void constructCdmaSms(RIL_CDMA_SMS_Message &rcsm, const CdmaSmsMessage& sms) {
+    rcsm.uTeleserviceID = sms.teleserviceId;
+    rcsm.bIsServicePresent = BOOL_TO_INT(sms.isServicePresent);
+    rcsm.uServicecategory = sms.serviceCategory;
+    rcsm.sAddress.digit_mode = (RIL_CDMA_SMS_DigitMode) sms.address.digitMode;
+    rcsm.sAddress.number_mode = (RIL_CDMA_SMS_NumberMode) sms.address.numberMode;
+    rcsm.sAddress.number_type = (RIL_CDMA_SMS_NumberType) sms.address.numberType;
+    rcsm.sAddress.number_plan = (RIL_CDMA_SMS_NumberPlan) sms.address.numberPlan;
+
+    rcsm.sAddress.number_of_digits = sms.address.digits.size();
+    int digitLimit= MIN((rcsm.sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
+    for (int i = 0; i < digitLimit; i++) {
+        rcsm.sAddress.digits[i] = sms.address.digits[i];
+    }
+
+    rcsm.sSubAddress.subaddressType = (RIL_CDMA_SMS_SubaddressType) sms.subAddress.subaddressType;
+    rcsm.sSubAddress.odd = BOOL_TO_INT(sms.subAddress.odd);
+
+    rcsm.sSubAddress.number_of_digits = sms.subAddress.digits.size();
+    digitLimit= MIN((rcsm.sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
+    for (int i = 0; i < digitLimit; i++) {
+        rcsm.sSubAddress.digits[i] = sms.subAddress.digits[i];
+    }
+
+    rcsm.uBearerDataLen = sms.bearerData.size();
+    digitLimit= MIN((rcsm.uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
+    for (int i = 0; i < digitLimit; i++) {
+        rcsm.aBearerData[i] = sms.bearerData[i];
+    }
+}
+
+Return<void> RadioImpl_1_4::sendCdmaSms(int32_t serial, const CdmaSmsMessage& sms) {
+#if VDBG
+    RLOGD("sendCdmaSms: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SEND_SMS);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_CDMA_SMS_Message rcsm = {};
+    constructCdmaSms(rcsm, sms);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::acknowledgeLastIncomingCdmaSms(int32_t serial, const CdmaSmsAck& smsAck) {
+#if VDBG
+    RLOGD("acknowledgeLastIncomingCdmaSms: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_CDMA_SMS_Ack rcsa = {};
+
+    rcsa.uErrorClass = (RIL_CDMA_SMS_ErrorClass) smsAck.errorClass;
+    rcsa.uSMSCauseCode = smsAck.smsCauseCode;
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsa, sizeof(rcsa), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getGsmBroadcastConfig(int32_t serial) {
+#if VDBG
+    RLOGD("getGsmBroadcastConfig: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GSM_GET_BROADCAST_SMS_CONFIG);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setGsmBroadcastConfig(int32_t serial,
+                                              const hidl_vec<GsmBroadcastSmsConfigInfo>&
+                                              configInfo) {
+#if VDBG
+    RLOGD("setGsmBroadcastConfig: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_GSM_SET_BROADCAST_SMS_CONFIG);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    int num = configInfo.size();
+    RIL_GSM_BroadcastSmsConfigInfo gsmBci[num];
+    RIL_GSM_BroadcastSmsConfigInfo *gsmBciPtrs[num];
+
+    for (int i = 0 ; i < num ; i++ ) {
+        gsmBciPtrs[i] = &gsmBci[i];
+        gsmBci[i].fromServiceId = configInfo[i].fromServiceId;
+        gsmBci[i].toServiceId = configInfo[i].toServiceId;
+        gsmBci[i].fromCodeScheme = configInfo[i].fromCodeScheme;
+        gsmBci[i].toCodeScheme = configInfo[i].toCodeScheme;
+        gsmBci[i].selected = BOOL_TO_INT(configInfo[i].selected);
+    }
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, gsmBciPtrs,
+            num * sizeof(RIL_GSM_BroadcastSmsConfigInfo *), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setGsmBroadcastActivation(int32_t serial, bool activate) {
+#if VDBG
+    RLOGD("setGsmBroadcastActivation: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_GSM_SMS_BROADCAST_ACTIVATION,
+            1, BOOL_TO_INT(!activate));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getCdmaBroadcastConfig(int32_t serial) {
+#if VDBG
+    RLOGD("getCdmaBroadcastConfig: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_BROADCAST_SMS_CONFIG);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setCdmaBroadcastConfig(int32_t serial,
+                                               const hidl_vec<CdmaBroadcastSmsConfigInfo>&
+                                               configInfo) {
+#if VDBG
+    RLOGD("setCdmaBroadcastConfig: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_CDMA_SET_BROADCAST_SMS_CONFIG);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    int num = configInfo.size();
+    RIL_CDMA_BroadcastSmsConfigInfo cdmaBci[num];
+    RIL_CDMA_BroadcastSmsConfigInfo *cdmaBciPtrs[num];
+
+    for (int i = 0 ; i < num ; i++ ) {
+        cdmaBciPtrs[i] = &cdmaBci[i];
+        cdmaBci[i].service_category = configInfo[i].serviceCategory;
+        cdmaBci[i].language = configInfo[i].language;
+        cdmaBci[i].selected = BOOL_TO_INT(configInfo[i].selected);
+    }
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, cdmaBciPtrs,
+            num * sizeof(RIL_CDMA_BroadcastSmsConfigInfo *), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setCdmaBroadcastActivation(int32_t serial, bool activate) {
+#if VDBG
+    RLOGD("setCdmaBroadcastActivation: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_SMS_BROADCAST_ACTIVATION,
+            1, BOOL_TO_INT(!activate));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getCDMASubscription(int32_t serial) {
+#if VDBG
+    RLOGD("getCDMASubscription: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_SUBSCRIPTION);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::writeSmsToRuim(int32_t serial, const CdmaSmsWriteArgs& cdmaSms) {
+#if VDBG
+    RLOGD("writeSmsToRuim: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_CDMA_SMS_WriteArgs rcsw = {};
+    rcsw.status = (int) cdmaSms.status;
+    constructCdmaSms(rcsw.message, cdmaSms.message);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rcsw, sizeof(rcsw), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::deleteSmsOnRuim(int32_t serial, int32_t index) {
+#if VDBG
+    RLOGD("deleteSmsOnRuim: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, 1, index);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getDeviceIdentity(int32_t serial) {
+#if VDBG
+    RLOGD("getDeviceIdentity: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_DEVICE_IDENTITY);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::exitEmergencyCallbackMode(int32_t serial) {
+#if VDBG
+    RLOGD("exitEmergencyCallbackMode: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getSmscAddress(int32_t serial) {
+#if VDBG
+    RLOGD("getSmscAddress: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_SMSC_ADDRESS);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setSmscAddress(int32_t serial, const hidl_string& smsc) {
+#if VDBG
+    RLOGD("setSmscAddress: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_SET_SMSC_ADDRESS,
+            smsc.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::reportSmsMemoryStatus(int32_t serial, bool available) {
+#if VDBG
+    RLOGD("reportSmsMemoryStatus: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, 1,
+            BOOL_TO_INT(available));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::reportStkServiceIsRunning(int32_t serial) {
+#if VDBG
+    RLOGD("reportStkServiceIsRunning: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getCdmaSubscriptionSource(int32_t serial) {
+#if VDBG
+    RLOGD("getCdmaSubscriptionSource: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::requestIsimAuthentication(int32_t serial, const hidl_string& challenge) {
+#if VDBG
+    RLOGD("requestIsimAuthentication: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_ISIM_AUTHENTICATION,
+            challenge.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::acknowledgeIncomingGsmSmsWithPdu(int32_t serial, bool success,
+                                                         const hidl_string& ackPdu) {
+#if VDBG
+    RLOGD("acknowledgeIncomingGsmSmsWithPdu: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, false,
+            2, success ? "1" : "0", ackPdu.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendEnvelopeWithStatus(int32_t serial, const hidl_string& contents) {
+#if VDBG
+    RLOGD("sendEnvelopeWithStatus: serial %d", serial);
+#endif
+    dispatchString(serial, mSlotId, RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS,
+            contents.c_str());
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getVoiceRadioTechnology(int32_t serial) {
+#if VDBG
+    RLOGD("getVoiceRadioTechnology: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_VOICE_RADIO_TECH);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getCellInfoList(int32_t serial) {
+#if VDBG
+    RLOGD("getCellInfoList: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CELL_INFO_LIST);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setCellInfoListRate(int32_t serial, int32_t rate) {
+#if VDBG
+    RLOGD("setCellInfoListRate: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, 1, rate);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setInitialAttachApn(int32_t serial, const DataProfileInfo& dataProfileInfo,
+                                            bool modemCognitive, bool isRoaming) {
+#if VDBG
+    RLOGD("setInitialAttachApn: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_SET_INITIAL_ATTACH_APN);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    if (s_vendorFunctions->version <= 14) {
+        RIL_InitialAttachApn iaa = {};
+
+        if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI, true)) {
+            return Void();
+        }
+
+        const hidl_string &protocol =
+                (isRoaming ? dataProfileInfo.roamingProtocol : dataProfileInfo.protocol);
+
+        if (!copyHidlStringToRil(&iaa.protocol, protocol, pRI)) {
+            memsetAndFreeStrings(1, iaa.apn);
+            return Void();
+        }
+        iaa.authtype = (int) dataProfileInfo.authType;
+        if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) {
+            memsetAndFreeStrings(2, iaa.apn, iaa.protocol);
+            return Void();
+        }
+        if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) {
+            memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.username);
+            return Void();
+        }
+
+        CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId);
+
+        memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.username, iaa.password);
+    } else {
+        RIL_InitialAttachApn_v15 iaa = {};
+
+        if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI, true)) {
+            return Void();
+        }
+
+        if (!copyHidlStringToRil(&iaa.protocol, dataProfileInfo.protocol, pRI)) {
+            memsetAndFreeStrings(1, iaa.apn);
+            return Void();
+        }
+        if (!copyHidlStringToRil(&iaa.roamingProtocol, dataProfileInfo.roamingProtocol, pRI)) {
+            memsetAndFreeStrings(2, iaa.apn, iaa.protocol);
+            return Void();
+        }
+        iaa.authtype = (int) dataProfileInfo.authType;
+        if (!copyHidlStringToRil(&iaa.username, dataProfileInfo.user, pRI)) {
+            memsetAndFreeStrings(3, iaa.apn, iaa.protocol, iaa.roamingProtocol);
+            return Void();
+        }
+        if (!copyHidlStringToRil(&iaa.password, dataProfileInfo.password, pRI)) {
+            memsetAndFreeStrings(4, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username);
+            return Void();
+        }
+        iaa.supportedTypesBitmask = dataProfileInfo.supportedApnTypesBitmap;
+        iaa.bearerBitmask = dataProfileInfo.bearerBitmap;
+        iaa.modemCognitive = BOOL_TO_INT(modemCognitive);
+        iaa.mtu = dataProfileInfo.mtu;
+
+        if (!convertMvnoTypeToString(dataProfileInfo.mvnoType, iaa.mvnoType)) {
+            sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+            memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username,
+                    iaa.password);
+            return Void();
+        }
+
+        if (!copyHidlStringToRil(&iaa.mvnoMatchData, dataProfileInfo.mvnoMatchData, pRI)) {
+            memsetAndFreeStrings(5, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username,
+                    iaa.password);
+            return Void();
+        }
+
+        CALL_ONREQUEST(RIL_REQUEST_SET_INITIAL_ATTACH_APN, &iaa, sizeof(iaa), pRI, mSlotId);
+
+        memsetAndFreeStrings(6, iaa.apn, iaa.protocol, iaa.roamingProtocol, iaa.username,
+                iaa.password, iaa.mvnoMatchData);
+    }
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getImsRegistrationState(int32_t serial) {
+#if VDBG
+    RLOGD("getImsRegistrationState: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_IMS_REGISTRATION_STATE);
+    return Void();
+}
+
+bool dispatchImsGsmSms(const ImsSmsMessage& message, RequestInfo *pRI) {
+    RIL_IMS_SMS_Message rism = {};
+    char **pStrings;
+    int countStrings = 2;
+    int dataLen = sizeof(char *) * countStrings;
+
+    rism.tech = RADIO_TECH_3GPP;
+    rism.retry = BOOL_TO_INT(message.retry);
+    rism.messageRef = message.messageRef;
+
+    if (message.gsmMessage.size() != 1) {
+        RLOGE("dispatchImsGsmSms: Invalid len %s", requestToString(pRI->pCI->requestNumber));
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return false;
+    }
+
+    pStrings = (char **)calloc(countStrings, sizeof(char *));
+    if (pStrings == NULL) {
+        RLOGE("dispatchImsGsmSms: Memory allocation failed for request %s",
+                requestToString(pRI->pCI->requestNumber));
+        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+        return false;
+    }
+
+    if (!copyHidlStringToRil(&pStrings[0], message.gsmMessage[0].smscPdu, pRI)) {
+#ifdef MEMSET_FREED
+        memset(pStrings, 0, dataLen);
+#endif
+        free(pStrings);
+        return false;
+    }
+
+    if (!copyHidlStringToRil(&pStrings[1], message.gsmMessage[0].pdu, pRI)) {
+        memsetAndFreeStrings(1, pStrings[0]);
+#ifdef MEMSET_FREED
+        memset(pStrings, 0, dataLen);
+#endif
+        free(pStrings);
+        return false;
+    }
+
+    rism.message.gsmMessage = pStrings;
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily) +
+            sizeof(uint8_t) + sizeof(int32_t) + dataLen, pRI, pRI->socket_id);
+
+    for (int i = 0 ; i < countStrings ; i++) {
+        memsetAndFreeStrings(1, pStrings[i]);
+    }
+
+#ifdef MEMSET_FREED
+    memset(pStrings, 0, dataLen);
+#endif
+    free(pStrings);
+
+    return true;
+}
+
+struct ImsCdmaSms {
+    RIL_IMS_SMS_Message imsSms;
+    RIL_CDMA_SMS_Message cdmaSms;
+};
+
+bool dispatchImsCdmaSms(const ImsSmsMessage& message, RequestInfo *pRI) {
+    ImsCdmaSms temp = {};
+
+    if (message.cdmaMessage.size() != 1) {
+        RLOGE("dispatchImsCdmaSms: Invalid len %s", requestToString(pRI->pCI->requestNumber));
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return false;
+    }
+
+    temp.imsSms.tech = RADIO_TECH_3GPP2;
+    temp.imsSms.retry = BOOL_TO_INT(message.retry);
+    temp.imsSms.messageRef = message.messageRef;
+    temp.imsSms.message.cdmaMessage = &temp.cdmaSms;
+
+    constructCdmaSms(temp.cdmaSms, message.cdmaMessage[0]);
+
+    // Vendor code expects payload length to include actual msg payload
+    // (sizeof(RIL_CDMA_SMS_Message)) instead of (RIL_CDMA_SMS_Message *) + size of other fields in
+    // RIL_IMS_SMS_Message
+    int payloadLen = sizeof(RIL_RadioTechnologyFamily) + sizeof(uint8_t) + sizeof(int32_t)
+            + sizeof(RIL_CDMA_SMS_Message);
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &temp.imsSms, payloadLen, pRI, pRI->socket_id);
+
+    return true;
+}
+
+Return<void> RadioImpl_1_4::sendImsSms(int32_t serial, const ImsSmsMessage& message) {
+#if VDBG
+    RLOGD("sendImsSms: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_IMS_SEND_SMS);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_RadioTechnologyFamily format = (RIL_RadioTechnologyFamily) message.tech;
+
+    if (RADIO_TECH_3GPP == format) {
+        dispatchImsGsmSms(message, pRI);
+    } else if (RADIO_TECH_3GPP2 == format) {
+        dispatchImsCdmaSms(message, pRI);
+    } else {
+        RLOGE("sendImsSms: Invalid radio tech %s",
+                requestToString(pRI->pCI->requestNumber));
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+    }
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::iccTransmitApduBasicChannel(int32_t serial, const SimApdu& message) {
+#if VDBG
+    RLOGD("iccTransmitApduBasicChannel: serial %d", serial);
+#endif
+    dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, message);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::iccOpenLogicalChannel(int32_t serial, const hidl_string& aid, int32_t p2) {
+#if VDBG
+    RLOGD("iccOpenLogicalChannel: serial %d", serial);
+#endif
+    if (s_vendorFunctions->version < 15) {
+        dispatchString(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL, aid.c_str());
+    } else {
+        RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_OPEN_CHANNEL);
+        if (pRI == NULL) {
+            return Void();
+        }
+
+        RIL_OpenChannelParams params = {};
+
+        params.p2 = p2;
+
+        if (!copyHidlStringToRil(&params.aidPtr, aid, pRI)) {
+            return Void();
+        }
+
+        CALL_ONREQUEST(pRI->pCI->requestNumber, &params, sizeof(params), pRI, mSlotId);
+
+        memsetAndFreeStrings(1, params.aidPtr);
+    }
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::iccCloseLogicalChannel(int32_t serial, int32_t channelId) {
+#if VDBG
+    RLOGD("iccCloseLogicalChannel: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SIM_CLOSE_CHANNEL, 1, channelId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::iccTransmitApduLogicalChannel(int32_t serial, const SimApdu& message) {
+#if VDBG
+    RLOGD("iccTransmitApduLogicalChannel: serial %d", serial);
+#endif
+    dispatchIccApdu(serial, mSlotId, RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, message);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::nvReadItem(int32_t serial, NvItem itemId) {
+#if VDBG
+    RLOGD("nvReadItem: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_READ_ITEM);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_NV_ReadItem nvri = {};
+    nvri.itemID = (RIL_NV_Item) itemId;
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &nvri, sizeof(nvri), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::nvWriteItem(int32_t serial, const NvWriteItem& item) {
+#if VDBG
+    RLOGD("nvWriteItem: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_NV_WRITE_ITEM);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_NV_WriteItem nvwi = {};
+
+    nvwi.itemID = (RIL_NV_Item) item.itemId;
+
+    if (!copyHidlStringToRil(&nvwi.value, item.value, pRI)) {
+        return Void();
+    }
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &nvwi, sizeof(nvwi), pRI, mSlotId);
+
+    memsetAndFreeStrings(1, nvwi.value);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::nvWriteCdmaPrl(int32_t serial, const hidl_vec<uint8_t>& prl) {
+#if VDBG
+    RLOGD("nvWriteCdmaPrl: serial %d", serial);
+#endif
+    dispatchRaw(serial, mSlotId, RIL_REQUEST_NV_WRITE_CDMA_PRL, prl);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::nvResetConfig(int32_t serial, ResetNvType resetType) {
+    int rilResetType = -1;
+#if VDBG
+    RLOGD("nvResetConfig: serial %d", serial);
+#endif
+    /* Convert ResetNvType to RIL.h values
+     * RIL_REQUEST_NV_RESET_CONFIG
+     * 1 - reload all NV items
+     * 2 - erase NV reset (SCRTN)
+     * 3 - factory reset (RTN)
+     */
+    switch(resetType) {
+      case ResetNvType::RELOAD:
+        rilResetType = 1;
+        break;
+      case ResetNvType::ERASE:
+        rilResetType = 2;
+        break;
+      case ResetNvType::FACTORY_RESET:
+        rilResetType = 3;
+        break;
+    }
+    dispatchInts(serial, mSlotId, RIL_REQUEST_NV_RESET_CONFIG, 1, rilResetType);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setUiccSubscription(int32_t serial, const SelectUiccSub& uiccSub) {
+#if VDBG
+    RLOGD("setUiccSubscription: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_SET_UICC_SUBSCRIPTION);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_SelectUiccSub rilUiccSub = {};
+
+    rilUiccSub.slot = uiccSub.slot;
+    rilUiccSub.app_index = uiccSub.appIndex;
+    rilUiccSub.sub_type = (RIL_SubscriptionType) uiccSub.subType;
+    rilUiccSub.act_status = (RIL_UiccSubActStatus) uiccSub.actStatus;
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rilUiccSub, sizeof(rilUiccSub), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setDataAllowed(int32_t serial, bool allow) {
+#if VDBG
+    RLOGD("setDataAllowed: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_ALLOW_DATA, 1, BOOL_TO_INT(allow));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getHardwareConfig(int32_t serial) {
+#if VDBG
+    RLOGD("getHardwareConfig: serial %d", serial);
+#endif
+    RLOGD("getHardwareConfig: serial %d, mSlotId = %d", serial, mSlotId);
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_HARDWARE_CONFIG);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::requestIccSimAuthentication(int32_t serial, int32_t authContext,
+        const hidl_string& authData, const hidl_string& aid) {
+#if VDBG
+    RLOGD("requestIccSimAuthentication: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SIM_AUTHENTICATION);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_SimAuthentication pf = {};
+
+    pf.authContext = authContext;
+
+    if (!copyHidlStringToRil(&pf.authData, authData, pRI)) {
+        return Void();
+    }
+
+    if (!copyHidlStringToRil(&pf.aid, aid, pRI)) {
+        memsetAndFreeStrings(1, pf.authData);
+        return Void();
+    }
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI, mSlotId);
+
+    memsetAndFreeStrings(2, pf.authData, pf.aid);
+    return Void();
+}
+
+/**
+ * @param numProfiles number of data profile
+ * @param dataProfiles the pointer to the actual data profiles. The acceptable type is
+          RIL_DataProfileInfo or RIL_DataProfileInfo_v15.
+ * @param dataProfilePtrs the pointer to the pointers that point to each data profile structure
+ * @param numfields number of string-type member in the data profile structure
+ * @param ... the variadic parameters are pointers to each string-type member
+ **/
+template <typename T>
+void freeSetDataProfileData(int numProfiles, T *dataProfiles, T **dataProfilePtrs,
+                            int numfields, ...) {
+    va_list args;
+    va_start(args, numfields);
+
+    // Iterate through each string-type field that need to be free.
+    for (int i = 0; i < numfields; i++) {
+        // Iterate through each data profile and free that specific string-type field.
+        // The type 'char *T::*' is a type of pointer to a 'char *' member inside T structure.
+        char *T::*ptr = va_arg(args, char *T::*);
+        for (int j = 0; j < numProfiles; j++) {
+            memsetAndFreeStrings(1, dataProfiles[j].*ptr);
+        }
+    }
+
+    va_end(args);
+
+#ifdef MEMSET_FREED
+    memset(dataProfiles, 0, numProfiles * sizeof(T));
+    memset(dataProfilePtrs, 0, numProfiles * sizeof(T *));
+#endif
+    free(dataProfiles);
+    free(dataProfilePtrs);
+}
+
+Return<void> RadioImpl_1_4::setDataProfile(int32_t serial, const hidl_vec<DataProfileInfo>& profiles,
+                                       bool isRoaming) {
+#if VDBG
+    RLOGD("setDataProfile: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_DATA_PROFILE);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    size_t num = profiles.size();
+    bool success = false;
+
+    if (s_vendorFunctions->version <= 14) {
+
+        RIL_DataProfileInfo *dataProfiles =
+            (RIL_DataProfileInfo *) calloc(num, sizeof(RIL_DataProfileInfo));
+
+        if (dataProfiles == NULL) {
+            RLOGE("Memory allocation failed for request %s",
+                    requestToString(pRI->pCI->requestNumber));
+            sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+            return Void();
+        }
+
+        RIL_DataProfileInfo **dataProfilePtrs =
+            (RIL_DataProfileInfo **) calloc(num, sizeof(RIL_DataProfileInfo *));
+        if (dataProfilePtrs == NULL) {
+            RLOGE("Memory allocation failed for request %s",
+                    requestToString(pRI->pCI->requestNumber));
+            free(dataProfiles);
+            sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+            return Void();
+        }
+
+        for (size_t i = 0; i < num; i++) {
+            dataProfilePtrs[i] = &dataProfiles[i];
+
+            success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI, true);
+
+            const hidl_string &protocol =
+                    (isRoaming ? profiles[i].roamingProtocol : profiles[i].protocol);
+
+            if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, protocol, pRI, true)) {
+                success = false;
+            }
+
+            if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI,
+                    true)) {
+                success = false;
+            }
+            if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password,
+                    pRI, true)) {
+                success = false;
+            }
+
+            if (!success) {
+                freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4,
+                    &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol,
+                    &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password);
+                return Void();
+            }
+
+            dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId;
+            dataProfiles[i].authType = (int) profiles[i].authType;
+            dataProfiles[i].type = (int) profiles[i].type;
+            dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime;
+            dataProfiles[i].maxConns = profiles[i].maxConns;
+            dataProfiles[i].waitTime = profiles[i].waitTime;
+            dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled);
+        }
+
+        CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs,
+                num * sizeof(RIL_DataProfileInfo *), pRI, mSlotId);
+
+        freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 4,
+                &RIL_DataProfileInfo::apn, &RIL_DataProfileInfo::protocol,
+                &RIL_DataProfileInfo::user, &RIL_DataProfileInfo::password);
+    } else {
+        RIL_DataProfileInfo_v15 *dataProfiles =
+            (RIL_DataProfileInfo_v15 *) calloc(num, sizeof(RIL_DataProfileInfo_v15));
+
+        if (dataProfiles == NULL) {
+            RLOGE("Memory allocation failed for request %s",
+                    requestToString(pRI->pCI->requestNumber));
+            sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+            return Void();
+        }
+
+        RIL_DataProfileInfo_v15 **dataProfilePtrs =
+            (RIL_DataProfileInfo_v15 **) calloc(num, sizeof(RIL_DataProfileInfo_v15 *));
+        if (dataProfilePtrs == NULL) {
+            RLOGE("Memory allocation failed for request %s",
+                    requestToString(pRI->pCI->requestNumber));
+            free(dataProfiles);
+            sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+            return Void();
+        }
+
+        for (size_t i = 0; i < num; i++) {
+            dataProfilePtrs[i] = &dataProfiles[i];
+
+            success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI, true);
+            if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, profiles[i].protocol,
+                    pRI)) {
+                success = false;
+            }
+            if (success && !copyHidlStringToRil(&dataProfiles[i].roamingProtocol,
+                    profiles[i].roamingProtocol, pRI, true)) {
+                success = false;
+            }
+            if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI,
+                    true)) {
+                success = false;
+            }
+            if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password,
+                    pRI, true)) {
+                success = false;
+            }
+            if (success && !copyHidlStringToRil(&dataProfiles[i].mvnoMatchData,
+                    profiles[i].mvnoMatchData, pRI, true)) {
+                success = false;
+            }
+
+            if (success && !convertMvnoTypeToString(profiles[i].mvnoType,
+                    dataProfiles[i].mvnoType)) {
+                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+                success = false;
+            }
+
+            if (!success) {
+                freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6,
+                    &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol,
+                    &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user,
+                    &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData);
+                return Void();
+            }
+
+            dataProfiles[i].profileId = (RIL_DataProfile) profiles[i].profileId;
+            dataProfiles[i].authType = (int) profiles[i].authType;
+            dataProfiles[i].type = (int) profiles[i].type;
+            dataProfiles[i].maxConnsTime = profiles[i].maxConnsTime;
+            dataProfiles[i].maxConns = profiles[i].maxConns;
+            dataProfiles[i].waitTime = profiles[i].waitTime;
+            dataProfiles[i].enabled = BOOL_TO_INT(profiles[i].enabled);
+            dataProfiles[i].supportedTypesBitmask = profiles[i].supportedApnTypesBitmap;
+            dataProfiles[i].bearerBitmask = profiles[i].bearerBitmap;
+            dataProfiles[i].mtu = profiles[i].mtu;
+        }
+
+        CALL_ONREQUEST(RIL_REQUEST_SET_DATA_PROFILE, dataProfilePtrs,
+                num * sizeof(RIL_DataProfileInfo_v15 *), pRI, mSlotId);
+
+        freeSetDataProfileData(num, dataProfiles, dataProfilePtrs, 6,
+                &RIL_DataProfileInfo_v15::apn, &RIL_DataProfileInfo_v15::protocol,
+                &RIL_DataProfileInfo_v15::roamingProtocol, &RIL_DataProfileInfo_v15::user,
+                &RIL_DataProfileInfo_v15::password, &RIL_DataProfileInfo_v15::mvnoMatchData);
+    }
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::requestShutdown(int32_t serial) {
+#if VDBG
+    RLOGD("requestShutdown: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_SHUTDOWN);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getRadioCapability(int32_t serial) {
+#if VDBG
+    RLOGD("getRadioCapability: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_RADIO_CAPABILITY);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setRadioCapability(int32_t serial, const RadioCapability& rc) {
+#if VDBG
+    RLOGD("setRadioCapability: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_RADIO_CAPABILITY);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_RadioCapability rilRc = {};
+
+    // TODO : set rilRc.version using HIDL version ?
+    rilRc.session = rc.session;
+    rilRc.phase = (int) rc.phase;
+    rilRc.rat = (int) rc.raf;
+    rilRc.status = (int) rc.status;
+    strlcpy(rilRc.logicalModemUuid, rc.logicalModemUuid.c_str(), sizeof(rilRc.logicalModemUuid));
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &rilRc, sizeof(rilRc), pRI, mSlotId);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::startLceService(int32_t serial, int32_t reportInterval, bool pullMode) {
+#if VDBG
+    RLOGD("startLceService: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_START_LCE, 2, reportInterval,
+            BOOL_TO_INT(pullMode));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::stopLceService(int32_t serial) {
+#if VDBG
+    RLOGD("stopLceService: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_STOP_LCE);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::pullLceData(int32_t serial) {
+#if VDBG
+    RLOGD("pullLceData: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_PULL_LCEDATA);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getModemActivityInfo(int32_t serial) {
+#if VDBG
+    RLOGD("getModemActivityInfo: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_ACTIVITY_INFO);
+    return Void();
+}
+
+int prepareCarrierRestrictions(RIL_CarrierRestrictions &request, bool allAllowed,
+                               const hidl_vec<Carrier>& allowedList,
+                               const hidl_vec<Carrier>& excludedList,
+                               RequestInfo *pRI) {
+    RIL_Carrier *allowedCarriers = NULL;
+    RIL_Carrier *excludedCarriers = NULL;
+
+    request.len_allowed_carriers = allowedList.size();
+    allowedCarriers = (RIL_Carrier *)calloc(request.len_allowed_carriers, sizeof(RIL_Carrier));
+    if (allowedCarriers == NULL) {
+        RLOGE("prepareCarrierRestrictions: Memory allocation failed for request %s",
+                requestToString(pRI->pCI->requestNumber));
+        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+        return -1;
+    }
+    request.allowed_carriers = allowedCarriers;
+
+    request.len_excluded_carriers = excludedList.size();
+    excludedCarriers = (RIL_Carrier *)calloc(request.len_excluded_carriers, sizeof(RIL_Carrier));
+    if (excludedCarriers == NULL) {
+        RLOGE("prepareCarrierRestrictions: Memory allocation failed for request %s",
+                requestToString(pRI->pCI->requestNumber));
+        sendErrorResponse(pRI, RIL_E_NO_MEMORY);
+#ifdef MEMSET_FREED
+        memset(allowedCarriers, 0, request.len_allowed_carriers * sizeof(RIL_Carrier));
+#endif
+        free(allowedCarriers);
+        return -1;
+    }
+    request.excluded_carriers = excludedCarriers;
+
+    for (int i = 0; i < request.len_allowed_carriers; i++) {
+        allowedCarriers[i].mcc = allowedList[i].mcc.c_str();
+        allowedCarriers[i].mnc = allowedList[i].mnc.c_str();
+        allowedCarriers[i].match_type = (RIL_CarrierMatchType) allowedList[i].matchType;
+        allowedCarriers[i].match_data = allowedList[i].matchData.c_str();
+    }
+
+    for (int i = 0; i < request.len_excluded_carriers; i++) {
+        excludedCarriers[i].mcc = excludedList[i].mcc.c_str();
+        excludedCarriers[i].mnc = excludedList[i].mnc.c_str();
+        excludedCarriers[i].match_type =
+                (RIL_CarrierMatchType) excludedList[i].matchType;
+        excludedCarriers[i].match_data = excludedList[i].matchData.c_str();
+    }
+
+    return 0;
+}
+
+void freeCarrierRestrictions(RIL_CarrierRestrictions &request) {
+    if (request.allowed_carriers != NULL) {
+#ifdef MEMSET_FREED
+        memset(request.allowed_carriers, 0, request.len_allowed_carriers * sizeof(RIL_Carrier));
+#endif
+        free(request.allowed_carriers);
+    }
+    if (request.excluded_carriers != NULL) {
+#ifdef MEMSET_FREED
+        memset(request.excluded_carriers, 0, request.len_excluded_carriers * sizeof(RIL_Carrier));
+#endif
+        free(request.excluded_carriers);
+    }
+}
+
+
+Return<void> RadioImpl_1_4::setAllowedCarriers(int32_t serial, bool allAllowed,
+                                           const CarrierRestrictions& carriers) {
+#if VDBG
+    RLOGD("setAllowedCarriers: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_SET_CARRIER_RESTRICTIONS);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_CarrierRestrictions cr = {};
+    if (prepareCarrierRestrictions(cr, allAllowed, carriers.allowedCarriers,
+            carriers.excludedCarriers, pRI) < 0) {
+        return Void();
+    }
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &cr, sizeof(RIL_CarrierRestrictions), pRI, mSlotId);
+
+    freeCarrierRestrictions(cr);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setAllowedCarriers_1_4(int32_t  serial,
+        const ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority& carriers,
+        ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicy) {
+#if VDBG
+    RLOGD("setAllowedCarriers_1_4: serial %d", serial);
+#endif
+
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_SET_CARRIER_RESTRICTIONS_1_4);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    // Prepare legacy structure (defined in IRadio 1.0) to re-use existing code.
+    RIL_CarrierRestrictions cr = {};
+    if (prepareCarrierRestrictions(cr, false, carriers.allowedCarriers,
+                                   carriers.excludedCarriers, pRI) < 0) {
+        return Void();
+    }
+    // Copy the legacy structure into the new structure (defined in IRadio 1.4)
+    RIL_CarrierRestrictionsWithPriority crExt = {};
+    crExt.len_allowed_carriers = cr.len_allowed_carriers;
+    crExt.allowed_carriers = cr.allowed_carriers;
+    crExt.len_excluded_carriers = cr.len_excluded_carriers;
+    crExt.excluded_carriers = cr.excluded_carriers;
+    crExt.allowedCarriersPrioritized = BOOL_TO_INT(carriers.allowedCarriersPrioritized);
+    crExt.multiSimPolicy = (RIL_SimLockMultiSimPolicy)multiSimPolicy;
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &crExt,
+                   sizeof(RIL_CarrierRestrictionsWithPriority), pRI, mSlotId);
+
+    freeCarrierRestrictions(cr);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getAllowedCarriers(int32_t serial) {
+#if VDBG
+    RLOGD("getAllowedCarriers: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getAllowedCarriers_1_4(int32_t serial) {
+#if VDBG
+    RLOGD("getAllowedCarriers_1_4: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_CARRIER_RESTRICTIONS_1_4);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::sendDeviceState(int32_t serial, DeviceStateType deviceStateType,
+                                        bool state) {
+#if VDBG
+    RLOGD("sendDeviceState: serial %d", serial);
+#endif
+    if (s_vendorFunctions->version < 15) {
+        if (deviceStateType ==  DeviceStateType::LOW_DATA_EXPECTED) {
+            RLOGD("sendDeviceState: calling screen state %d", BOOL_TO_INT(!state));
+            dispatchInts(serial, mSlotId, RIL_REQUEST_SCREEN_STATE, 1, BOOL_TO_INT(!state));
+        } else {
+            RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+                    RIL_REQUEST_SEND_DEVICE_STATE);
+            sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED);
+        }
+        return Void();
+    }
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SEND_DEVICE_STATE, 2, (int) deviceStateType,
+            BOOL_TO_INT(state));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setIndicationFilter(int32_t serial, int32_t indicationFilter) {
+#if VDBG
+    RLOGD("setIndicationFilter: serial %d", serial);
+#endif
+    if (s_vendorFunctions->version < 15) {
+        RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+                RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER);
+        sendErrorResponse(pRI, RIL_E_REQUEST_NOT_SUPPORTED);
+        return Void();
+    }
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, 1, indicationFilter);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setSimCardPower(int32_t serial, bool powerUp) {
+#if VDBG
+    RLOGD("setSimCardPower: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SIM_CARD_POWER, 1, BOOL_TO_INT(powerUp));
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setSimCardPower_1_1(int32_t serial, const V1_1::CardPowerState state) {
+#if VDBG
+    RLOGD("setSimCardPower_1_1: serial %d state %d", serial, state);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_SIM_CARD_POWER, 1, state);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setCarrierInfoForImsiEncryption(int32_t serial,
+        const V1_1::ImsiEncryptionInfo& data) {
+#if VDBG
+    RLOGD("setCarrierInfoForImsiEncryption: serial %d", serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(
+            serial, mSlotId, RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_CarrierInfoForImsiEncryption imsiEncryption = {};
+
+    if (!copyHidlStringToRil(&imsiEncryption.mnc, data.mnc, pRI)) {
+        return Void();
+    }
+    if (!copyHidlStringToRil(&imsiEncryption.mcc, data.mcc, pRI)) {
+        memsetAndFreeStrings(1, imsiEncryption.mnc);
+        return Void();
+    }
+    if (!copyHidlStringToRil(&imsiEncryption.keyIdentifier, data.keyIdentifier, pRI)) {
+        memsetAndFreeStrings(2, imsiEncryption.mnc, imsiEncryption.mcc);
+        return Void();
+    }
+    imsiEncryption.carrierKeyLength = data.carrierKey.size();
+    imsiEncryption.carrierKey = new uint8_t[imsiEncryption.carrierKeyLength];
+    memcpy(imsiEncryption.carrierKey, data.carrierKey.data(), imsiEncryption.carrierKeyLength);
+    imsiEncryption.expirationTime = data.expirationTime;
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &imsiEncryption,
+            sizeof(RIL_CarrierInfoForImsiEncryption), pRI, mSlotId);
+    delete(imsiEncryption.carrierKey);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::startKeepalive(int32_t serial, const V1_1::KeepaliveRequest& keepalive) {
+#if VDBG
+    RLOGD("%s(): %d", __FUNCTION__, serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_KEEPALIVE);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RIL_KeepaliveRequest kaReq = {};
+
+    kaReq.type = static_cast<RIL_KeepaliveType>(keepalive.type);
+    switch(kaReq.type) {
+        case NATT_IPV4:
+            if (keepalive.sourceAddress.size() != 4 ||
+                    keepalive.destinationAddress.size() != 4) {
+                RLOGE("Invalid address for keepalive!");
+                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+                return Void();
+            }
+            break;
+        case NATT_IPV6:
+            if (keepalive.sourceAddress.size() != 16 ||
+                    keepalive.destinationAddress.size() != 16) {
+                RLOGE("Invalid address for keepalive!");
+                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+                return Void();
+            }
+            break;
+        default:
+            RLOGE("Unknown packet keepalive type!");
+            sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+            return Void();
+    }
+
+    ::memcpy(kaReq.sourceAddress, keepalive.sourceAddress.data(), keepalive.sourceAddress.size());
+    kaReq.sourcePort = keepalive.sourcePort;
+
+    ::memcpy(kaReq.destinationAddress,
+            keepalive.destinationAddress.data(), keepalive.destinationAddress.size());
+    kaReq.destinationPort = keepalive.destinationPort;
+
+    kaReq.maxKeepaliveIntervalMillis = keepalive.maxKeepaliveIntervalMillis;
+    kaReq.cid = keepalive.cid; // This is the context ID of the data call
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &kaReq, sizeof(RIL_KeepaliveRequest), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::stopKeepalive(int32_t serial, int32_t sessionHandle) {
+#if VDBG
+    RLOGD("%s(): %d", __FUNCTION__, serial);
+#endif
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_STOP_KEEPALIVE);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    CALL_ONREQUEST(pRI->pCI->requestNumber, &sessionHandle, sizeof(uint32_t), pRI, mSlotId);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::responseAcknowledgement() {
+    android::releaseWakeLock();
+    return Void();
+}
+
+int prepareNetworkScanRequest_1_2(RIL_NetworkScanRequest &scan_request,
+    const ::android::hardware::radio::V1_2::NetworkScanRequest& request,
+    RequestInfo *pRI) {
+
+    scan_request.type = (RIL_ScanType) request.type;
+    scan_request.interval = request.interval;
+    scan_request.specifiers_length = request.specifiers.size();
+
+    int intervalLow = static_cast<int>(::android::hardware::radio::V1_2::ScanIntervalRange::MIN);
+    int intervalHigh = static_cast<int>(::android::hardware::radio::V1_2::ScanIntervalRange::MAX);
+    int maxSearchTimeLow =
+        static_cast<int>(::android::hardware::radio::V1_2::MaxSearchTimeRange::MIN);
+    int maxSearchTimeHigh =
+        static_cast<int>(::android::hardware::radio::V1_2::MaxSearchTimeRange::MAX);
+    int incrementalResultsPeriodicityRangeLow =
+        static_cast<int>(::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MIN);
+    int incrementalResultsPeriodicityRangeHigh =
+        static_cast<int>(::android::hardware::radio::V1_2::IncrementalResultsPeriodicityRange::MAX);
+    uint maxSpecifierSize =
+        static_cast<uint>(::android::hardware::radio::V1_2::RadioConst
+            ::RADIO_ACCESS_SPECIFIER_MAX_SIZE);
+
+    if (request.interval < intervalLow || request.interval > intervalHigh) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return -1;
+    }
+    // If defined, must fall in correct range.
+    if (request.maxSearchTime != 0
+        && (request.maxSearchTime < maxSearchTimeLow
+            || request.maxSearchTime > maxSearchTimeHigh)) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return -1;
+    }
+    if (request.maxSearchTime != 0
+        && (request.incrementalResultsPeriodicity < incrementalResultsPeriodicityRangeLow
+            || request.incrementalResultsPeriodicity > incrementalResultsPeriodicityRangeHigh
+            || request.incrementalResultsPeriodicity > request.maxSearchTime)) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return -1;
+    }
+    if (request.specifiers.size() == 0 || request.specifiers.size() > maxSpecifierSize) {
+        sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        return -1;
+    }
+
+    for (size_t i = 0; i < request.specifiers.size(); ++i) {
+        if (request.specifiers[i].geranBands.size() > MAX_BANDS ||
+            request.specifiers[i].utranBands.size() > MAX_BANDS ||
+            request.specifiers[i].eutranBands.size() > MAX_BANDS ||
+            request.specifiers[i].channels.size() > MAX_CHANNELS) {
+            sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+            return -1;
+        }
+        const V1_1::RadioAccessSpecifier& ras_from =
+                request.specifiers[i];
+        RIL_RadioAccessSpecifier& ras_to = scan_request.specifiers[i];
+
+        ras_to.radio_access_network = (RIL_RadioAccessNetworks) ras_from.radioAccessNetwork;
+        ras_to.channels_length = ras_from.channels.size();
+
+        std::copy(ras_from.channels.begin(), ras_from.channels.end(), ras_to.channels);
+        const std::vector<uint32_t> * bands = nullptr;
+        switch (request.specifiers[i].radioAccessNetwork) {
+            case V1_1::RadioAccessNetworks::GERAN:
+                ras_to.bands_length = ras_from.geranBands.size();
+                bands = (std::vector<uint32_t> *) &ras_from.geranBands;
+                break;
+            case V1_1::RadioAccessNetworks::UTRAN:
+                ras_to.bands_length = ras_from.utranBands.size();
+                bands = (std::vector<uint32_t> *) &ras_from.utranBands;
+                break;
+            case V1_1::RadioAccessNetworks::EUTRAN:
+                ras_to.bands_length = ras_from.eutranBands.size();
+                bands = (std::vector<uint32_t> *) &ras_from.eutranBands;
+                break;
+            default:
+                sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+                return -1;
+        }
+        // safe to copy to geran_bands because it's a union member
+        for (size_t idx = 0; idx < ras_to.bands_length; ++idx) {
+            ras_to.bands.geran_bands[idx] = (RIL_GeranBands) (*bands)[idx];
+        }
+    }
+
+    return 0;
+}
+
+// Methods from ::android::hardware::radio::V1_2::IRadio follow.
+Return<void> RadioImpl_1_4::startNetworkScan_1_2(int32_t serial,
+        const ::android::hardware::radio::V1_2::NetworkScanRequest& request) {
+#if VDBG
+    RLOGD("startNetworkScan_1_2: serial %d", serial);
+#endif
+
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    // TODO: implement checks for new fields.
+    // NetworkScanRequest added maxSearchTime, incrementalResults, incrementalResultsPeriodicity and
+    // mccMncs, could add more validations using request2 here.
+
+    RIL_NetworkScanRequest scan_request = {};
+
+    if (prepareNetworkScanRequest_1_2(scan_request, request, pRI) < 0) {
+        return Void();
+    }
+
+    CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI,
+            mSlotId);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setIndicationFilter_1_2(int32_t /* serial */,
+        hidl_bitfield<::android::hardware::radio::V1_2::IndicationFilter> /* indicationFilter */) {
+    // TODO implement
+#if VDBG
+    RLOGE("[%04d]< %s", serial, "Method is not implemented");
+#endif
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setSignalStrengthReportingCriteria(int32_t /* serial */,
+        int32_t /* hysteresisMs */, int32_t /* hysteresisDb */,
+        const hidl_vec<int32_t>& /* thresholdsDbm */,
+        ::android::hardware::radio::V1_2::AccessNetwork /* accessNetwork */) {
+    // TODO implement
+#if VDBG
+    RLOGE("[%04d]< %s", serial, "Method is not implemented");
+#endif
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setLinkCapacityReportingCriteria(int32_t /* serial */,
+        int32_t /* hysteresisMs */, int32_t /* hysteresisDlKbps */, int32_t /* hysteresisUlKbps */,
+        const hidl_vec<int32_t>& /* thresholdsDownlinkKbps */,
+        const hidl_vec<int32_t>& /* thresholdsUplinkKbps */,
+        ::android::hardware::radio::V1_2::AccessNetwork /* accessNetwork */) {
+    // TODO implement
+#if VDBG
+    RLOGE("[%04d]< %s", serial, "Method is not implemented");
+#endif
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setupDataCall_1_2(int32_t /* serial */,
+        ::android::hardware::radio::V1_2::AccessNetwork /* accessNetwork */,
+        const ::android::hardware::radio::V1_0::DataProfileInfo& /* dataProfileInfo */,
+        bool /* modemCognitive */, bool /* roamingAllowed */, bool /* isRoaming */,
+        ::android::hardware::radio::V1_2::DataRequestReason /* reason */,
+        const hidl_vec<hidl_string>& /* addresses */, const hidl_vec<hidl_string>& /* dnses */) {
+    // TODO implement
+#if VDBG
+    RLOGE("[%04d]< %s", serial, "Method is not implemented");
+#endif
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::deactivateDataCall_1_2(int32_t /* serial */, int32_t /* cid */,
+        ::android::hardware::radio::V1_2::DataRequestReason /* reason */) {
+    // TODO implement
+#if VDBG
+    RLOGE("[%04d]< %s", serial, "Method is not implemented");
+#endif
+    return Void();
+}
+
+// Methods from ::android::hardware::radio::V1_3::IRadio follow.
+Return<void> RadioImpl_1_4::setSystemSelectionChannels(int32_t serial, bool /* specifyChannels */,
+        const hidl_vec<::android::hardware::radio::V1_1::RadioAccessSpecifier>& /* specifiers */) {
+#if VDBG
+    RLOGD("setSystemSelectionChannels: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::enableModem(int32_t serial, bool /* on */) {
+#if VDBG
+    RLOGE("enableModem: serial = %d, enable = %s", serial, on);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_ENABLE_MODEM);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getModemStackStatus(int32_t serial) {
+#if VDBG
+    RLOGD("getModemStackStatus: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_MODEM_STACK_STATUS);
+    return Void();
+}
+
+const char * getProtocolString(const ::android::hardware::radio::V1_4::PdpProtocolType protocolVal) {
+    switch(protocolVal) {
+        case ::android::hardware::radio::V1_4::PdpProtocolType::IP:
+            return "IP";
+        case ::android::hardware::radio::V1_4::PdpProtocolType::IPV6:
+            return "IPV6";
+        case ::android::hardware::radio::V1_4::PdpProtocolType::IPV4V6:
+            return "IPV4V6";
+        case ::android::hardware::radio::V1_4::PdpProtocolType::PPP:
+            return "PPP";
+        case ::android::hardware::radio::V1_4::PdpProtocolType::NON_IP:
+            return "NON_IP";
+        case ::android::hardware::radio::V1_4::PdpProtocolType::UNSTRUCTURED:
+            return "UNSTRUCTURED";
+        default:
+            return "UNKNOWN";
+    }
+}
+
+// Methods from ::android::hardware::radio::V1_4::IRadio follow.
+Return<void> RadioImpl_1_4::setupDataCall_1_4(int32_t serial ,
+        ::android::hardware::radio::V1_4::AccessNetwork /* accessNetwork */,
+        const ::android::hardware::radio::V1_4::DataProfileInfo& dataProfileInfo,
+        bool roamingAllowed, ::android::hardware::radio::V1_2::DataRequestReason /* reason */,
+        const hidl_vec<hidl_string>& /* addresses */, const hidl_vec<hidl_string>& /* dnses */) {
+
+#if VDBG
+    RLOGD("setupDataCall_1_4: serial %d", serial);
+#endif
+
+    char *mvnoTypeStr = NULL;
+    if (!convertMvnoTypeToString(MvnoType::IMSI, mvnoTypeStr)) {
+        RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+                RIL_REQUEST_SETUP_DATA_CALL);
+        if (pRI != NULL) {
+            sendErrorResponse(pRI, RIL_E_INVALID_ARGUMENTS);
+        }
+        return Void();
+    }
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, true, 15,
+        std::to_string((int) RadioTechnology::UNKNOWN + 2).c_str(),
+        std::to_string((int) dataProfileInfo.profileId).c_str(),
+        dataProfileInfo.apn.c_str(),
+        dataProfileInfo.user.c_str(),
+        dataProfileInfo.password.c_str(),
+        std::to_string((int) dataProfileInfo.authType).c_str(),
+        getProtocolString(dataProfileInfo.protocol),
+        getProtocolString(dataProfileInfo.roamingProtocol),
+        std::to_string(dataProfileInfo.supportedApnTypesBitmap).c_str(),
+        std::to_string(dataProfileInfo.bearerBitmap).c_str(),
+        dataProfileInfo.persistent ? "1" : "0",
+        std::to_string(dataProfileInfo.mtu).c_str(),
+        mvnoTypeStr,
+        "302720x94",
+        roamingAllowed ? "1" : "0");
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setInitialAttachApn_1_4(int32_t  serial ,
+        const ::android::hardware::radio::V1_4::DataProfileInfo& dataProfileInfo) {
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_SET_INITIAL_ATTACH_APN);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, RESPONSE_SOLICITED, RIL_E_SUCCESS);
+
+    if (radioService[mSlotId]->mRadioResponseV1_4 != NULL) {
+        Return<void> retStatus
+                = radioService[mSlotId]->mRadioResponseV1_4->setInitialAttachApnResponse(responseInfo);
+        radioService[mSlotId]->checkReturnStatus(retStatus);
+    } else if (radioService[mSlotId]->mRadioResponse != NULL) {
+        Return<void> retStatus
+                = radioService[mSlotId]->mRadioResponse->setInitialAttachApnResponse(responseInfo);
+        radioService[mSlotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setInitialAttachApnResponse: radioService[%d]->mRadioResponse == NULL", mSlotId);
+    }
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setDataProfile_1_4(int32_t  serial ,
+        const hidl_vec<::android::hardware::radio::V1_4::DataProfileInfo>& /* profiles */) {
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId,
+            RIL_REQUEST_SET_DATA_PROFILE);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, RESPONSE_SOLICITED, RIL_E_SUCCESS);
+
+    if (radioService[mSlotId]->mRadioResponseV1_4 != NULL) {
+        Return<void> retStatus
+                = radioService[mSlotId]->mRadioResponseV1_4->setDataProfileResponse(responseInfo);
+        radioService[mSlotId]->checkReturnStatus(retStatus);
+    } else if (radioService[mSlotId]->mRadioResponse != NULL) {
+        Return<void> retStatus
+                = radioService[mSlotId]->mRadioResponse->setDataProfileResponse(responseInfo);
+        radioService[mSlotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setDataProfileResponse: radioService[%d]->mRadioResponse == NULL", mSlotId);
+    }
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::emergencyDial(int32_t serial,
+        const ::android::hardware::radio::V1_0::Dial& dialInfo,
+        hidl_bitfield<android::hardware::radio::V1_4::EmergencyServiceCategory> /* categories */,
+        const hidl_vec<hidl_string>& /* urns */,
+        ::android::hardware::radio::V1_4::EmergencyCallRouting /* routing */,
+        bool /* fromEmergencyDialer */, bool /* isTesting */) {
+#if VDBG
+    RLOGD("emergencyDial: serial %d", serial);
+#endif
+
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_EMERGENCY_DIAL);
+    if (pRI == NULL) {
+        return Void();
+    }
+    RIL_Dial dial = {};
+    RIL_UUS_Info uusInfo = {};
+    int32_t sizeOfDial = sizeof(dial);
+
+    if (!copyHidlStringToRil(&dial.address, dialInfo.address, pRI)) {
+        return Void();
+    }
+    dial.clir = (int) dialInfo.clir;
+
+    if (dialInfo.uusInfo.size() != 0) {
+        uusInfo.uusType = (RIL_UUS_Type) dialInfo.uusInfo[0].uusType;
+        uusInfo.uusDcs = (RIL_UUS_DCS) dialInfo.uusInfo[0].uusDcs;
+
+        if (dialInfo.uusInfo[0].uusData.size() == 0) {
+            uusInfo.uusData = NULL;
+            uusInfo.uusLength = 0;
+        } else {
+            if (!copyHidlStringToRil(&uusInfo.uusData, dialInfo.uusInfo[0].uusData, pRI)) {
+                memsetAndFreeStrings(1, dial.address);
+                return Void();
+            }
+            uusInfo.uusLength = dialInfo.uusInfo[0].uusData.size();
+        }
+
+        dial.uusInfo = &uusInfo;
+    }
+
+    CALL_ONREQUEST(RIL_REQUEST_EMERGENCY_DIAL, &dial, sizeOfDial, pRI, mSlotId);
+
+    memsetAndFreeStrings(2, dial.address, uusInfo.uusData);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::startNetworkScan_1_4(int32_t serial,
+        const ::android::hardware::radio::V1_2::NetworkScanRequest& request) {
+#if VDBG
+    RLOGD("startNetworkScan_1_4: serial %d", serial);
+#endif
+
+    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_START_NETWORK_SCAN4);
+    if (pRI == NULL) {
+        return Void();
+    }
+
+    // TODO: implement checks for new fields.
+    // NetworkScanRequest added maxSearchTime, incrementalResults, incrementalResultsPeriodicity and
+    // mccMncs, could add more validations using request2 here.
+
+    RIL_NetworkScanRequest scan_request = {};
+
+    if (prepareNetworkScanRequest_1_2(scan_request, request, pRI) < 0) {
+        return Void();
+    }
+
+    CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN4, &scan_request, sizeof(scan_request), pRI,
+            mSlotId);
+
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getPreferredNetworkTypeBitmap(int32_t serial ) {
+#if VDBG
+    RLOGD("getPreferredNetworkTypeBitmap: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE_BITMAP);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::setPreferredNetworkTypeBitmap(
+        int32_t serial, hidl_bitfield<RadioAccessFamily> networkTypeBitmap) {
+#if VDBG
+    RLOGD("setPreferredNetworkTypeBitmap: serial %d", serial);
+#endif
+    dispatchInts(serial, mSlotId, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE_BITMAP, 1, networkTypeBitmap);
+    return Void();
+}
+
+Return<void> RadioImpl_1_4::getSignalStrength_1_4(int32_t serial) {
+#if VDBG
+    RLOGD("getSignalStrength_1_4: serial %d", serial);
+#endif
+    dispatchVoid(serial, mSlotId, RIL_REQUEST_SIGNAL_STRENGTH);
+    return Void();
+}
+
+Return<void> OemHookImpl::setResponseFunctions(
+        const ::android::sp<IOemHookResponse>& oemHookResponseParam,
+        const ::android::sp<IOemHookIndication>& oemHookIndicationParam) {
+#if VDBG
+    RLOGD("OemHookImpl::setResponseFunctions");
+#endif
+
+    pthread_rwlock_t *radioServiceRwlockPtr = radio_1_4::getRadioServiceRwlock(mSlotId);
+    int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
+    assert(ret == 0);
+
+    mOemHookResponse = oemHookResponseParam;
+    mOemHookIndication = oemHookIndicationParam;
+    mCounterOemHook[mSlotId]++;
+
+    ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
+    assert(ret == 0);
+
+    return Void();
+}
+
+Return<void> OemHookImpl::sendRequestRaw(int32_t serial, const hidl_vec<uint8_t>& data) {
+#if VDBG
+    RLOGD("OemHookImpl::sendRequestRaw: serial %d", serial);
+#endif
+    dispatchRaw(serial, mSlotId, RIL_REQUEST_OEM_HOOK_RAW, data);
+    return Void();
+}
+
+Return<void> OemHookImpl::sendRequestStrings(int32_t serial,
+        const hidl_vec<hidl_string>& data) {
+#if VDBG
+    RLOGD("OemHookImpl::sendRequestStrings: serial %d", serial);
+#endif
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_OEM_HOOK_STRINGS, data);
+    return Void();
+}
+
+/***************************************************************************************************
+ * RESPONSE FUNCTIONS
+ * Functions above are used for requests going from framework to vendor code. The ones below are
+ * responses for those requests coming back from the vendor code.
+ **************************************************************************************************/
+
+void radio_1_4::acknowledgeRequest(int slotId, int serial) {
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->acknowledgeRequest(serial);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("acknowledgeRequest: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+}
+
+void populateResponseInfo(RadioResponseInfo& responseInfo, int serial, int responseType,
+                         RIL_Errno e) {
+    responseInfo.serial = serial;
+    switch (responseType) {
+        case RESPONSE_SOLICITED:
+            responseInfo.type = RadioResponseType::SOLICITED;
+            break;
+        case RESPONSE_SOLICITED_ACK_EXP:
+            responseInfo.type = RadioResponseType::SOLICITED_ACK_EXP;
+            break;
+    }
+    responseInfo.error = (RadioError) e;
+}
+
+int responseIntOrEmpty(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e,
+               void *response, size_t responseLen) {
+    populateResponseInfo(responseInfo, serial, responseType, e);
+    int ret = -1;
+
+    if (response == NULL && responseLen == 0) {
+        // Earlier RILs did not send a response for some cases although the interface
+        // expected an integer as response. Do not return error if response is empty. Instead
+        // Return -1 in those cases to maintain backward compatibility.
+    } else if (response == NULL || responseLen != sizeof(int)) {
+        RLOGE("responseIntOrEmpty: Invalid response");
+        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+    } else {
+        int *p_int = (int *) response;
+        ret = p_int[0];
+    }
+    return ret;
+}
+
+int responseInt(RadioResponseInfo& responseInfo, int serial, int responseType, RIL_Errno e,
+               void *response, size_t responseLen) {
+    populateResponseInfo(responseInfo, serial, responseType, e);
+    int ret = -1;
+
+    if (response == NULL || responseLen != sizeof(int)) {
+        RLOGE("responseInt: Invalid response");
+        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+    } else {
+        int *p_int = (int *) response;
+        ret = p_int[0];
+    }
+    return ret;
+}
+
+int radio_1_4::getIccCardStatusResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e,
+                                   void *response, size_t responseLen) {
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL
+        || radioService[slotId]->mRadioResponseV1_2 != NULL
+        || radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        CardStatus cardStatus = {CardState::ABSENT, PinState::UNKNOWN, -1, -1, -1, {}};
+        RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
+        if (response == NULL || responseLen != sizeof(RIL_CardStatus_v6)
+                || p_cur->gsm_umts_subscription_app_index >= p_cur->num_applications
+                || p_cur->cdma_subscription_app_index >= p_cur->num_applications
+                || p_cur->ims_subscription_app_index >= p_cur->num_applications) {
+            RLOGE("getIccCardStatusResponse: Invalid response");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            cardStatus.cardState = (CardState) p_cur->card_state;
+            cardStatus.universalPinState = (PinState) p_cur->universal_pin_state;
+            cardStatus.gsmUmtsSubscriptionAppIndex = p_cur->gsm_umts_subscription_app_index;
+            cardStatus.cdmaSubscriptionAppIndex = p_cur->cdma_subscription_app_index;
+            cardStatus.imsSubscriptionAppIndex = p_cur->ims_subscription_app_index;
+
+            RIL_AppStatus *rilAppStatus = p_cur->applications;
+            cardStatus.applications.resize(p_cur->num_applications);
+            AppStatus *appStatus = cardStatus.applications.data();
+#if VDBG
+            RLOGD("getIccCardStatusResponse: num_applications %d", p_cur->num_applications);
+#endif
+            for (int i = 0; i < p_cur->num_applications; i++) {
+                appStatus[i].appType = (AppType) rilAppStatus[i].app_type;
+                appStatus[i].appState = (AppState) rilAppStatus[i].app_state;
+                appStatus[i].persoSubstate = (PersoSubstate) rilAppStatus[i].perso_substate;
+                appStatus[i].aidPtr = convertCharPtrToHidlString(rilAppStatus[i].aid_ptr);
+                appStatus[i].appLabelPtr = convertCharPtrToHidlString(
+                        rilAppStatus[i].app_label_ptr);
+                appStatus[i].pin1Replaced = rilAppStatus[i].pin1_replaced;
+                appStatus[i].pin1 = (PinState) rilAppStatus[i].pin1;
+                appStatus[i].pin2 = (PinState) rilAppStatus[i].pin2;
+            }
+        }
+
+        if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+            ::android::hardware::radio::V1_2::CardStatus cardStatusV1_2;
+            ::android::hardware::radio::V1_4::CardStatus cardStatusV1_4;
+            cardStatusV1_2.base = cardStatus;
+            cardStatusV1_2.physicalSlotId = -1;
+            cardStatusV1_4.base = cardStatusV1_2;
+            Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4->
+                    getIccCardStatusResponse_1_4(responseInfo, cardStatusV1_4);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else if (radioService[slotId]->mRadioResponseV1_3 != NULL) {
+            ::android::hardware::radio::V1_2::CardStatus cardStatusV1_2;
+            cardStatusV1_2.base = cardStatus;
+            cardStatusV1_2.physicalSlotId = -1;
+            Return<void> retStatus = radioService[slotId]->mRadioResponseV1_3->
+                    getIccCardStatusResponse_1_2(responseInfo, cardStatusV1_2);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else if (radioService[slotId]->mRadioResponseV1_2 != NULL) {
+            ::android::hardware::radio::V1_2::CardStatus cardStatusV1_2;
+            cardStatusV1_2.base = cardStatus;
+            cardStatusV1_2.physicalSlotId = -1;
+            Return<void> retStatus = radioService[slotId]->mRadioResponseV1_2->
+                    getIccCardStatusResponse_1_2(responseInfo, cardStatusV1_2);
+            radioService[slotId]->checkReturnStatus(retStatus);
+            // TODO: add 1.1 if needed.
+        } else {
+            Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                    getIccCardStatusResponse(responseInfo, cardStatus);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        }
+    } else {
+        RLOGE("getIccCardStatusResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::supplyIccPinForAppResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("supplyIccPinForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                supplyIccPinForAppResponse(responseInfo, ret);
+        RLOGE("supplyIccPinForAppResponse: amit ret %d", ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("supplyIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::supplyIccPukForAppResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("supplyIccPukForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->supplyIccPukForAppResponse(
+                responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("supplyIccPukForAppResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::supplyIccPin2ForAppResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("supplyIccPin2ForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                supplyIccPin2ForAppResponse(responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("supplyIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::supplyIccPuk2ForAppResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("supplyIccPuk2ForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                supplyIccPuk2ForAppResponse(responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("supplyIccPuk2ForAppResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::changeIccPinForAppResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("changeIccPinForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                changeIccPinForAppResponse(responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("changeIccPinForAppResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::changeIccPin2ForAppResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("changeIccPin2ForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                changeIccPin2ForAppResponse(responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("changeIccPin2ForAppResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::supplyNetworkDepersonalizationResponse(int slotId,
+                                                 int responseType, int serial, RIL_Errno e,
+                                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("supplyNetworkDepersonalizationResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                supplyNetworkDepersonalizationResponse(responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("supplyNetworkDepersonalizationResponse: radioService[%d]->mRadioResponse == "
+                "NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getCurrentCallsResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getCurrentCallsResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        hidl_vec<Call> calls;
+        if ((response == NULL && responseLen != 0)
+                || (responseLen % sizeof(RIL_Call *)) != 0) {
+            RLOGE("getCurrentCallsResponse: Invalid response");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int num = responseLen / sizeof(RIL_Call *);
+            calls.resize(num);
+
+            for (int i = 0 ; i < num ; i++) {
+                RIL_Call *p_cur = ((RIL_Call **) response)[i];
+                /* each call info */
+                calls[i].state = (CallState) p_cur->state;
+                calls[i].index = p_cur->index;
+                calls[i].toa = p_cur->toa;
+                calls[i].isMpty = p_cur->isMpty;
+                calls[i].isMT = p_cur->isMT;
+                calls[i].als = p_cur->als;
+                calls[i].isVoice = p_cur->isVoice;
+                calls[i].isVoicePrivacy = p_cur->isVoicePrivacy;
+                calls[i].number = convertCharPtrToHidlString(p_cur->number);
+                calls[i].numberPresentation = (CallPresentation) p_cur->numberPresentation;
+                calls[i].name = convertCharPtrToHidlString(p_cur->name);
+                calls[i].namePresentation = (CallPresentation) p_cur->namePresentation;
+                if (p_cur->uusInfo != NULL && p_cur->uusInfo->uusData != NULL) {
+                    RIL_UUS_Info *uusInfo = p_cur->uusInfo;
+                    calls[i].uusInfo.resize(1);
+                    calls[i].uusInfo[0].uusType = (UusType) uusInfo->uusType;
+                    calls[i].uusInfo[0].uusDcs = (UusDcs) uusInfo->uusDcs;
+                    // convert uusInfo->uusData to a null-terminated string
+                    char *nullTermStr = strndup(uusInfo->uusData, uusInfo->uusLength);
+                    calls[i].uusInfo[0].uusData = nullTermStr;
+                    free(nullTermStr);
+                }
+            }
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                getCurrentCallsResponse(responseInfo, calls);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getCurrentCallsResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::dialResponse(int slotId,
+                       int responseType, int serial, RIL_Errno e, void *response,
+                       size_t responseLen) {
+#if VDBG
+    RLOGD("dialResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->dialResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("dialResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getIMSIForAppResponse(int slotId,
+                                int responseType, int serial, RIL_Errno e, void *response,
+                                size_t responseLen) {
+#if VDBG
+    RLOGD("getIMSIForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getIMSIForAppResponse(
+                responseInfo, convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getIMSIForAppResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::hangupConnectionResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e,
+                                   void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("hangupConnectionResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->hangupConnectionResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("hangupConnectionResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::hangupWaitingOrBackgroundResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus =
+                radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::hangupForegroundResumeBackgroundResponse(int slotId, int responseType, int serial,
+                                                    RIL_Errno e, void *response,
+                                                    size_t responseLen) {
+#if VDBG
+    RLOGD("hangupWaitingOrBackgroundResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus =
+                radioService[slotId]->mRadioResponse->hangupWaitingOrBackgroundResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("hangupWaitingOrBackgroundResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::switchWaitingOrHoldingAndActiveResponse(int slotId, int responseType, int serial,
+                                                   RIL_Errno e, void *response,
+                                                   size_t responseLen) {
+#if VDBG
+    RLOGD("switchWaitingOrHoldingAndActiveResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus =
+                radioService[slotId]->mRadioResponse->switchWaitingOrHoldingAndActiveResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("switchWaitingOrHoldingAndActiveResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::conferenceResponse(int slotId, int responseType,
+                             int serial, RIL_Errno e, void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("conferenceResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->conferenceResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("conferenceResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::rejectCallResponse(int slotId, int responseType,
+                             int serial, RIL_Errno e, void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("rejectCallResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->rejectCallResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("rejectCallResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getLastCallFailCauseResponse(int slotId,
+                                       int responseType, int serial, RIL_Errno e, void *response,
+                                       size_t responseLen) {
+#if VDBG
+    RLOGD("getLastCallFailCauseResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        LastCallFailCauseInfo info = {};
+        info.vendorCause = hidl_string();
+        if (response == NULL) {
+            RLOGE("getCurrentCallsResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else if (responseLen == sizeof(int)) {
+            int *pInt = (int *) response;
+            info.causeCode = (LastCallFailCause) pInt[0];
+        } else if (responseLen == sizeof(RIL_LastCallFailCauseInfo))  {
+            RIL_LastCallFailCauseInfo *pFailCauseInfo = (RIL_LastCallFailCauseInfo *) response;
+            info.causeCode = (LastCallFailCause) pFailCauseInfo->cause_code;
+            info.vendorCause = convertCharPtrToHidlString(pFailCauseInfo->vendor_cause);
+        } else {
+            RLOGE("getCurrentCallsResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getLastCallFailCauseResponse(
+                responseInfo, info);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getLastCallFailCauseResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getSignalStrengthResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getSignalStrengthResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        SignalStrength signalStrength = {};
+        if (response == NULL || responseLen != sizeof(RIL_SignalStrength_v10)) {
+            RLOGE("getSignalStrengthResponse: Invalid response");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            convertRilSignalStrengthToHal(response, responseLen, signalStrength);
+        }
+
+        ::android::hardware::radio::V1_4::SignalStrength signalStrength_1_4;
+        signalStrength_1_4.gsm = signalStrength.gw;
+        signalStrength_1_4.cdma = signalStrength.cdma;
+        signalStrength_1_4.evdo = signalStrength.evdo;
+        signalStrength_1_4.lte = signalStrength.lte;
+        //TODO: future implementation needs to fill tdScdma, wcdma and nr signal strength.
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4->
+                getSignalStrengthResponse_1_4(responseInfo, signalStrength_1_4);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        SignalStrength signalStrength = {};
+        if (response == NULL || responseLen != sizeof(RIL_SignalStrength_v10)) {
+            RLOGE("getSignalStrengthResponse: Invalid response");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            convertRilSignalStrengthToHal(response, responseLen, signalStrength);
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getSignalStrengthResponse(
+                responseInfo, signalStrength);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getSignalStrengthResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+RIL_CellInfoType getCellInfoTypeRadioTechnology(char *rat) {
+    if (rat == NULL) {
+        return RIL_CELL_INFO_TYPE_NONE;
+    }
+
+    int radioTech = atoi(rat);
+
+    switch(radioTech) {
+
+        case RADIO_TECH_GPRS:
+        case RADIO_TECH_EDGE:
+        case RADIO_TECH_GSM: {
+            return RIL_CELL_INFO_TYPE_GSM;
+        }
+
+        case RADIO_TECH_UMTS:
+        case RADIO_TECH_HSDPA:
+        case RADIO_TECH_HSUPA:
+        case RADIO_TECH_HSPA:
+        case RADIO_TECH_HSPAP: {
+            return RIL_CELL_INFO_TYPE_WCDMA;
+        }
+
+        case RADIO_TECH_IS95A:
+        case RADIO_TECH_IS95B:
+        case RADIO_TECH_1xRTT:
+        case RADIO_TECH_EVDO_0:
+        case RADIO_TECH_EVDO_A:
+        case RADIO_TECH_EVDO_B:
+        case RADIO_TECH_EHRPD: {
+            return RIL_CELL_INFO_TYPE_CDMA;
+        }
+
+        case RADIO_TECH_LTE:
+        case RADIO_TECH_LTE_CA: {
+            return RIL_CELL_INFO_TYPE_LTE;
+        }
+
+        case RADIO_TECH_TD_SCDMA: {
+            return RIL_CELL_INFO_TYPE_TD_SCDMA;
+        }
+
+        default: {
+            break;
+        }
+    }
+
+    return RIL_CELL_INFO_TYPE_NONE;
+
+}
+
+void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &rilCellIdentity) {
+
+    cellIdentity.cellIdentityGsm.resize(0);
+    cellIdentity.cellIdentityWcdma.resize(0);
+    cellIdentity.cellIdentityCdma.resize(0);
+    cellIdentity.cellIdentityTdscdma.resize(0);
+    cellIdentity.cellIdentityLte.resize(0);
+    cellIdentity.cellInfoType = (CellInfoType)rilCellIdentity.cellInfoType;
+    switch(rilCellIdentity.cellInfoType) {
+
+        case RIL_CELL_INFO_TYPE_GSM: {
+            cellIdentity.cellIdentityGsm.resize(1);
+            cellIdentity.cellIdentityGsm[0].mcc =
+                    std::to_string(rilCellIdentity.cellIdentityGsm.mcc);
+            cellIdentity.cellIdentityGsm[0].mnc =
+                    ril::util::mnc::decode(rilCellIdentity.cellIdentityGsm.mnc);
+            cellIdentity.cellIdentityGsm[0].lac = rilCellIdentity.cellIdentityGsm.lac;
+            cellIdentity.cellIdentityGsm[0].cid = rilCellIdentity.cellIdentityGsm.cid;
+            cellIdentity.cellIdentityGsm[0].arfcn = rilCellIdentity.cellIdentityGsm.arfcn;
+            cellIdentity.cellIdentityGsm[0].bsic = rilCellIdentity.cellIdentityGsm.bsic;
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_WCDMA: {
+            cellIdentity.cellIdentityWcdma.resize(1);
+            cellIdentity.cellIdentityWcdma[0].mcc =
+                    std::to_string(rilCellIdentity.cellIdentityWcdma.mcc);
+            cellIdentity.cellIdentityWcdma[0].mnc =
+                    ril::util::mnc::decode(rilCellIdentity.cellIdentityWcdma.mnc);
+            cellIdentity.cellIdentityWcdma[0].lac = rilCellIdentity.cellIdentityWcdma.lac;
+            cellIdentity.cellIdentityWcdma[0].cid = rilCellIdentity.cellIdentityWcdma.cid;
+            cellIdentity.cellIdentityWcdma[0].psc = rilCellIdentity.cellIdentityWcdma.psc;
+            cellIdentity.cellIdentityWcdma[0].uarfcn = rilCellIdentity.cellIdentityWcdma.uarfcn;
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_CDMA: {
+            cellIdentity.cellIdentityCdma.resize(1);
+            cellIdentity.cellIdentityCdma[0].networkId = rilCellIdentity.cellIdentityCdma.networkId;
+            cellIdentity.cellIdentityCdma[0].systemId = rilCellIdentity.cellIdentityCdma.systemId;
+            cellIdentity.cellIdentityCdma[0].baseStationId =
+                    rilCellIdentity.cellIdentityCdma.basestationId;
+            cellIdentity.cellIdentityCdma[0].longitude = rilCellIdentity.cellIdentityCdma.longitude;
+            cellIdentity.cellIdentityCdma[0].latitude = rilCellIdentity.cellIdentityCdma.latitude;
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_LTE: {
+            cellIdentity.cellIdentityLte.resize(1);
+            cellIdentity.cellIdentityLte[0].mcc =
+                    std::to_string(rilCellIdentity.cellIdentityLte.mcc);
+            cellIdentity.cellIdentityLte[0].mnc =
+                    ril::util::mnc::decode(rilCellIdentity.cellIdentityLte.mnc);
+            cellIdentity.cellIdentityLte[0].ci = rilCellIdentity.cellIdentityLte.ci;
+            cellIdentity.cellIdentityLte[0].pci = rilCellIdentity.cellIdentityLte.pci;
+            cellIdentity.cellIdentityLte[0].tac = rilCellIdentity.cellIdentityLte.tac;
+            cellIdentity.cellIdentityLte[0].earfcn = rilCellIdentity.cellIdentityLte.earfcn;
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_TD_SCDMA: {
+            cellIdentity.cellIdentityTdscdma.resize(1);
+            cellIdentity.cellIdentityTdscdma[0].mcc =
+                    std::to_string(rilCellIdentity.cellIdentityTdscdma.mcc);
+            cellIdentity.cellIdentityTdscdma[0].mnc =
+                    ril::util::mnc::decode(rilCellIdentity.cellIdentityTdscdma.mnc);
+            cellIdentity.cellIdentityTdscdma[0].lac = rilCellIdentity.cellIdentityTdscdma.lac;
+            cellIdentity.cellIdentityTdscdma[0].cid = rilCellIdentity.cellIdentityTdscdma.cid;
+            cellIdentity.cellIdentityTdscdma[0].cpid = rilCellIdentity.cellIdentityTdscdma.cpid;
+            break;
+        }
+
+        default: {
+            break;
+        }
+    }
+}
+
+int convertResponseStringEntryToInt(char **response, int index, int numStrings) {
+    if ((response != NULL) &&  (numStrings > index) && (response[index] != NULL)) {
+        return atoi(response[index]);
+    }
+
+    return -1;
+}
+
+int convertResponseHexStringEntryToInt(char **response, int index, int numStrings) {
+    const int hexBase = 16;
+    if ((response != NULL) &&  (numStrings > index) && (response[index] != NULL)) {
+        return strtol(response[index], NULL, hexBase);
+    }
+
+    return -1;
+}
+
+/* Fill Cell Identity info from Voice Registration State Response.
+ * This fucntion is applicable only for RIL Version < 15.
+ * Response is a  "char **".
+ * First and Second entries are in hex string format
+ * and rest are integers represented in ascii format. */
+void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity,
+        int numStrings, char** response) {
+
+    RIL_CellIdentity_v16 rilCellIdentity;
+    memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16));
+
+    rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]);
+    switch(rilCellIdentity.cellInfoType) {
+
+        case RIL_CELL_INFO_TYPE_GSM: {
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
+            rilCellIdentity.cellIdentityGsm.lac =
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
+            rilCellIdentity.cellIdentityGsm.cid =
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_WCDMA: {
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
+            rilCellIdentity.cellIdentityWcdma.lac =
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
+            rilCellIdentity.cellIdentityWcdma.cid =
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
+            rilCellIdentity.cellIdentityWcdma.psc =
+                    convertResponseStringEntryToInt(response, 14, numStrings);
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_TD_SCDMA:{
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
+            rilCellIdentity.cellIdentityTdscdma.lac =
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
+            rilCellIdentity.cellIdentityTdscdma.cid =
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_CDMA:{
+            rilCellIdentity.cellIdentityCdma.basestationId =
+                    convertResponseStringEntryToInt(response, 4, numStrings);
+            /* Order of Lat. and Long. swapped between RIL and HIDL interface versions. */
+            rilCellIdentity.cellIdentityCdma.latitude =
+                    convertResponseStringEntryToInt(response, 5, numStrings);
+            rilCellIdentity.cellIdentityCdma.longitude =
+                    convertResponseStringEntryToInt(response, 6, numStrings);
+            rilCellIdentity.cellIdentityCdma.systemId =
+                    convertResponseStringEntryToInt(response, 8, numStrings);
+            rilCellIdentity.cellIdentityCdma.networkId =
+                    convertResponseStringEntryToInt(response, 9, numStrings);
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_LTE:{
+            /* valid TAC are hexstrings in the range 0x0000 - 0xffff */
+            rilCellIdentity.cellIdentityLte.tac =
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
+            rilCellIdentity.cellIdentityLte.ci =
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+
+        default: {
+            break;
+        }
+    }
+
+    fillCellIdentityResponse(cellIdentity, rilCellIdentity);
+}
+
+/* Fill Cell Identity info from Data Registration State Response.
+ * This fucntion is applicable only for RIL Version < 15.
+ * Response is a  "char **".
+ * First and Second entries are in hex string format
+ * and rest are integers represented in ascii format. */
+void fillCellIdentityFromDataRegStateResponseString(CellIdentity &cellIdentity,
+        int numStrings, char** response) {
+
+    RIL_CellIdentity_v16 rilCellIdentity;
+    memset(&rilCellIdentity, -1, sizeof(RIL_CellIdentity_v16));
+
+    rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]);
+    switch(rilCellIdentity.cellInfoType) {
+        case RIL_CELL_INFO_TYPE_GSM: {
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
+            rilCellIdentity.cellIdentityGsm.lac =
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
+            rilCellIdentity.cellIdentityGsm.cid =
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_WCDMA: {
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
+            rilCellIdentity.cellIdentityWcdma.lac =
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
+            rilCellIdentity.cellIdentityWcdma.cid =
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_TD_SCDMA:{
+            /* valid LAC are hexstrings in the range 0x0000 - 0xffff */
+            rilCellIdentity.cellIdentityTdscdma.lac =
+                    convertResponseHexStringEntryToInt(response, 1, numStrings);
+
+            /* valid CID are hexstrings in the range 0x00000000 - 0xffffffff */
+            rilCellIdentity.cellIdentityTdscdma.cid =
+                    convertResponseHexStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_LTE: {
+            rilCellIdentity.cellIdentityLte.tac =
+                    convertResponseStringEntryToInt(response, 6, numStrings);
+            rilCellIdentity.cellIdentityLte.pci =
+                    convertResponseStringEntryToInt(response, 7, numStrings);
+            rilCellIdentity.cellIdentityLte.ci =
+                    convertResponseStringEntryToInt(response, 8, numStrings);
+            break;
+        }
+        default: {
+            break;
+        }
+    }
+
+    fillCellIdentityResponse(cellIdentity, rilCellIdentity);
+}
+
+int radio_1_4::getVoiceRegistrationStateResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getVoiceRegistrationStateResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        VoiceRegStateResult voiceRegResponse = {};
+        int numStrings = responseLen / sizeof(char *);
+        if (response == NULL) {
+               RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL");
+               if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else if (s_vendorFunctions->version <= 14) {
+            if (numStrings != 15) {
+                RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            } else {
+                char **resp = (char **) response;
+                voiceRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4);
+                voiceRegResponse.rat = ATOI_NULL_HANDLED(resp[3]);
+                voiceRegResponse.cssSupported = ATOI_NULL_HANDLED_DEF(resp[7], 0);
+                voiceRegResponse.roamingIndicator = ATOI_NULL_HANDLED(resp[10]);
+                voiceRegResponse.systemIsInPrl = ATOI_NULL_HANDLED_DEF(resp[11], 0);
+                voiceRegResponse.defaultRoamingIndicator = ATOI_NULL_HANDLED_DEF(resp[12], 0);
+                voiceRegResponse.reasonForDenial = ATOI_NULL_HANDLED_DEF(resp[13], 0);
+                fillCellIdentityFromVoiceRegStateResponseString(voiceRegResponse.cellIdentity,
+                        numStrings, resp);
+            }
+        } else {
+            RIL_VoiceRegistrationStateResponse *voiceRegState =
+                    (RIL_VoiceRegistrationStateResponse *)response;
+
+            if (responseLen != sizeof(RIL_VoiceRegistrationStateResponse)) {
+                RLOGE("getVoiceRegistrationStateResponse Invalid response: NULL");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            } else {
+                voiceRegResponse.regState = (RegState) voiceRegState->regState;
+                voiceRegResponse.rat = voiceRegState->rat;;
+                voiceRegResponse.cssSupported = voiceRegState->cssSupported;
+                voiceRegResponse.roamingIndicator = voiceRegState->roamingIndicator;
+                voiceRegResponse.systemIsInPrl = voiceRegState->systemIsInPrl;
+                voiceRegResponse.defaultRoamingIndicator = voiceRegState->defaultRoamingIndicator;
+                voiceRegResponse.reasonForDenial = voiceRegState->reasonForDenial;
+                fillCellIdentityResponse(voiceRegResponse.cellIdentity,
+                        voiceRegState->cellIdentity);
+            }
+        }
+
+        Return<void> retStatus =
+                radioService[slotId]->mRadioResponse->getVoiceRegistrationStateResponse(
+                responseInfo, voiceRegResponse);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getVoiceRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getDataRegistrationStateResponse(int slotId,
+                                           int responseType, int serial, RIL_Errno e,
+                                           void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getDataRegistrationStateResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        DataRegStateResult dataRegResponse = {};
+        if (response == NULL) {
+            RLOGE("getDataRegistrationStateResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else if (s_vendorFunctions->version <= 14) {
+            int numStrings = responseLen / sizeof(char *);
+            if ((numStrings != 6) && (numStrings != 11)) {
+                RLOGE("getDataRegistrationStateResponse Invalid response: NULL");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            } else {
+                char **resp = (char **) response;
+                dataRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4);
+                dataRegResponse.rat =  ATOI_NULL_HANDLED_DEF(resp[3], 0);
+                dataRegResponse.reasonDataDenied =  ATOI_NULL_HANDLED(resp[4]);
+                dataRegResponse.maxDataCalls =  ATOI_NULL_HANDLED_DEF(resp[5], 1);
+                fillCellIdentityFromDataRegStateResponseString(dataRegResponse.cellIdentity,
+                        numStrings, resp);
+            }
+        } else {
+            RIL_DataRegistrationStateResponse *dataRegState =
+                    (RIL_DataRegistrationStateResponse *)response;
+
+            if (responseLen != sizeof(RIL_DataRegistrationStateResponse)) {
+                RLOGE("getDataRegistrationStateResponse Invalid response: NULL");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            } else {
+                dataRegResponse.regState = (RegState) dataRegState->regState;
+                dataRegResponse.rat = dataRegState->rat;;
+                dataRegResponse.reasonDataDenied = dataRegState->reasonDataDenied;
+                dataRegResponse.maxDataCalls = dataRegState->maxDataCalls;
+                fillCellIdentityResponse(dataRegResponse.cellIdentity, dataRegState->cellIdentity);
+            }
+        }
+
+        Return<void> retStatus =
+                radioService[slotId]->mRadioResponse->getDataRegistrationStateResponse(responseInfo,
+                dataRegResponse);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getDataRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getOperatorResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responseLen) {
+#if VDBG
+    RLOGD("getOperatorResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        hidl_string longName;
+        hidl_string shortName;
+        hidl_string numeric;
+        int numStrings = responseLen / sizeof(char *);
+        if (response == NULL || numStrings != 3) {
+            RLOGE("getOperatorResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+
+        } else {
+            char **resp = (char **) response;
+            longName = convertCharPtrToHidlString(resp[0]);
+            shortName = convertCharPtrToHidlString(resp[1]);
+            numeric = convertCharPtrToHidlString(resp[2]);
+        }
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getOperatorResponse(
+                responseInfo, longName, shortName, numeric);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getOperatorResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setRadioPowerResponse(int slotId,
+                                int responseType, int serial, RIL_Errno e, void *response,
+                                size_t responseLen) {
+    RLOGD("setRadioPowerResponse: serial %d", serial);
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->setRadioPowerResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setRadioPowerResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendDtmfResponse(int slotId,
+                           int responseType, int serial, RIL_Errno e, void *response,
+                           size_t responseLen) {
+#if VDBG
+    RLOGD("sendDtmfResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->sendDtmfResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendDtmfResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+SendSmsResult makeSendSmsResult(RadioResponseInfo& responseInfo, int serial, int responseType,
+                                RIL_Errno e, void *response, size_t responseLen) {
+    populateResponseInfo(responseInfo, serial, responseType, e);
+    SendSmsResult result = {};
+
+    if (response == NULL || responseLen != sizeof(RIL_SMS_Response)) {
+        RLOGE("Invalid response: NULL");
+        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        result.ackPDU = hidl_string();
+    } else {
+        RIL_SMS_Response *resp = (RIL_SMS_Response *) response;
+        result.messageRef = resp->messageRef;
+        result.ackPDU = convertCharPtrToHidlString(resp->ackPDU);
+        result.errorCode = resp->errorCode;
+    }
+    return result;
+}
+
+int radio_1_4::sendSmsResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responseLen) {
+#if VDBG
+    RLOGD("sendSmsResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
+                responseLen);
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->sendSmsResponse(responseInfo,
+                result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendSMSExpectMoreResponse(int slotId,
+                                    int responseType, int serial, RIL_Errno e, void *response,
+                                    size_t responseLen) {
+#if VDBG
+    RLOGD("sendSMSExpectMoreResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
+                responseLen);
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->sendSMSExpectMoreResponse(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendSMSExpectMoreResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setupDataCallResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e, void *response,
+                                 size_t responseLen) {
+#if VDBG
+    RLOGD("setupDataCallResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        ::android::hardware::radio::V1_4::SetupDataCallResult result;
+        if (response == NULL || (responseLen % sizeof(RIL_Data_Call_Response_v11)) != 0) {
+            if (response != NULL) {
+                RLOGE("setupDataCallResponse: Invalid response");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            }
+            result.cause = ::android::hardware::radio::V1_4::DataCallFailCause::ERROR_UNSPECIFIED;
+            result.type = ::android::hardware::radio::V1_4::PdpProtocolType::UNKNOWN;
+            result.ifname = hidl_string();
+            result.addresses = hidl_vec<hidl_string>();
+            result.dnses = hidl_vec<hidl_string>();
+            result.gateways = hidl_vec<hidl_string>();
+            result.pcscf = hidl_vec<hidl_string>();
+        } else {
+            convertRilDataCallToHal((RIL_Data_Call_Response_v11 *) response, result);
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4->setupDataCallResponse_1_4(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        SetupDataCallResult result = {};
+        if (response == NULL || (responseLen % sizeof(RIL_Data_Call_Response_v11)) != 0) {
+           if (response != NULL) {
+               RLOGE("setupDataCallResponse: Invalid response");
+               if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+           }
+           result.status = DataCallFailCause::ERROR_UNSPECIFIED;
+           result.type = hidl_string();
+           result.ifname = hidl_string();
+           result.addresses = hidl_string();
+           result.dnses = hidl_string();
+           result.gateways = hidl_string();
+           result.pcscf = hidl_string();
+        } else {
+           convertRilDataCallToHal((RIL_Data_Call_Response_v11 *) response, result);
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->setupDataCallResponse(
+               responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setupDataCallResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+IccIoResult responseIccIo(RadioResponseInfo& responseInfo, int serial, int responseType,
+                           RIL_Errno e, void *response, size_t responseLen) {
+    populateResponseInfo(responseInfo, serial, responseType, e);
+    IccIoResult result = {};
+
+    if (response == NULL || responseLen != sizeof(RIL_SIM_IO_Response)) {
+        RLOGE("Invalid response: NULL");
+        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        result.simResponse = hidl_string();
+    } else {
+        RIL_SIM_IO_Response *resp = (RIL_SIM_IO_Response *) response;
+        result.sw1 = resp->sw1;
+        result.sw2 = resp->sw2;
+        result.simResponse = convertCharPtrToHidlString(resp->simResponse);
+    }
+    return result;
+}
+
+int radio_1_4::iccIOForAppResponse(int slotId,
+                      int responseType, int serial, RIL_Errno e, void *response,
+                      size_t responseLen) {
+#if VDBG
+    RLOGD("iccIOForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response,
+                responseLen);
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->iccIOForAppResponse(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("iccIOForAppResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendUssdResponse(int slotId,
+                           int responseType, int serial, RIL_Errno e, void *response,
+                           size_t responseLen) {
+#if VDBG
+    RLOGD("sendUssdResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->sendUssdResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendUssdResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::cancelPendingUssdResponse(int slotId,
+                                    int responseType, int serial, RIL_Errno e, void *response,
+                                    size_t responseLen) {
+#if VDBG
+    RLOGD("cancelPendingUssdResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->cancelPendingUssdResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("cancelPendingUssdResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getClirResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responseLen) {
+#if VDBG
+    RLOGD("getClirResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        int n = -1, m = -1;
+        int numInts = responseLen / sizeof(int);
+        if (response == NULL || numInts != 2) {
+            RLOGE("getClirResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int *pInt = (int *) response;
+            n = pInt[0];
+            m = pInt[1];
+        }
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getClirResponse(responseInfo,
+                n, m);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getClirResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setClirResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responseLen) {
+#if VDBG
+    RLOGD("setClirResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->setClirResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setClirResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getCallForwardStatusResponse(int slotId,
+                                       int responseType, int serial, RIL_Errno e,
+                                       void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getCallForwardStatusResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        hidl_vec<CallForwardInfo> callForwardInfos;
+
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_CallForwardInfo *) != 0) {
+            RLOGE("getCallForwardStatusResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int num = responseLen / sizeof(RIL_CallForwardInfo *);
+            callForwardInfos.resize(num);
+            for (int i = 0 ; i < num; i++) {
+                RIL_CallForwardInfo *resp = ((RIL_CallForwardInfo **) response)[i];
+                callForwardInfos[i].status = (CallForwardInfoStatus) resp->status;
+                callForwardInfos[i].reason = resp->reason;
+                callForwardInfos[i].serviceClass = resp->serviceClass;
+                callForwardInfos[i].toa = resp->toa;
+                callForwardInfos[i].number = convertCharPtrToHidlString(resp->number);
+                callForwardInfos[i].timeSeconds = resp->timeSeconds;
+            }
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getCallForwardStatusResponse(
+                responseInfo, callForwardInfos);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getCallForwardStatusResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setCallForwardResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e, void *response,
+                                 size_t responseLen) {
+#if VDBG
+    RLOGD("setCallForwardResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->setCallForwardResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setCallForwardResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getCallWaitingResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e, void *response,
+                                 size_t responseLen) {
+#if VDBG
+    RLOGD("getCallWaitingResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        bool enable = false;
+        int serviceClass = -1;
+        int numInts = responseLen / sizeof(int);
+        if (response == NULL || numInts != 2) {
+            RLOGE("getCallWaitingResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int *pInt = (int *) response;
+            enable = pInt[0] == 1 ? true : false;
+            serviceClass = pInt[1];
+        }
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getCallWaitingResponse(
+                responseInfo, enable, serviceClass);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setCallWaitingResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e, void *response,
+                                 size_t responseLen) {
+#if VDBG
+    RLOGD("setCallWaitingResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->setCallWaitingResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setCallWaitingResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::acknowledgeLastIncomingGsmSmsResponse(int slotId,
+                                                int responseType, int serial, RIL_Errno e,
+                                                void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("acknowledgeLastIncomingGsmSmsResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus =
+                radioService[slotId]->mRadioResponse->acknowledgeLastIncomingGsmSmsResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("acknowledgeLastIncomingGsmSmsResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::acceptCallResponse(int slotId,
+                             int responseType, int serial, RIL_Errno e,
+                             void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("acceptCallResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->acceptCallResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("acceptCallResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::deactivateDataCallResponse(int slotId,
+                                                int responseType, int serial, RIL_Errno e,
+                                                void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("deactivateDataCallResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->deactivateDataCallResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("deactivateDataCallResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getFacilityLockForAppResponse(int slotId,
+                                        int responseType, int serial, RIL_Errno e,
+                                        void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getFacilityLockForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                getFacilityLockForAppResponse(responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setFacilityLockForAppResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setFacilityLockForAppResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseIntOrEmpty(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setFacilityLockForAppResponse(responseInfo,
+                ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setFacilityLockForAppResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setBarringPasswordResponse(int slotId,
+                             int responseType, int serial, RIL_Errno e,
+                             void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("acceptCallResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setBarringPasswordResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setBarringPasswordResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getNetworkSelectionModeResponse(int slotId,
+                                          int responseType, int serial, RIL_Errno e, void *response,
+                                          size_t responseLen) {
+#if VDBG
+    RLOGD("getNetworkSelectionModeResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        bool manual = false;
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("getNetworkSelectionModeResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int *pInt = (int *) response;
+            manual = pInt[0] == 1 ? true : false;
+        }
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getNetworkSelectionModeResponse(
+                responseInfo,
+                manual);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getNetworkSelectionModeResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setNetworkSelectionModeAutomaticResponse(int slotId, int responseType, int serial,
+                                                    RIL_Errno e, void *response,
+                                                    size_t responseLen) {
+#if VDBG
+    RLOGD("setNetworkSelectionModeAutomaticResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setNetworkSelectionModeAutomaticResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setNetworkSelectionModeAutomaticResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setNetworkSelectionModeManualResponse(int slotId,
+                             int responseType, int serial, RIL_Errno e,
+                             void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setNetworkSelectionModeManualResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setNetworkSelectionModeManualResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("acceptCallResponse: radioService[%d]->setNetworkSelectionModeManualResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int convertOperatorStatusToInt(const char *str) {
+    if (strncmp("unknown", str, 9) == 0) {
+        return (int) OperatorStatus::UNKNOWN;
+    } else if (strncmp("available", str, 9) == 0) {
+        return (int) OperatorStatus::AVAILABLE;
+    } else if (strncmp("current", str, 9) == 0) {
+        return (int) OperatorStatus::CURRENT;
+    } else if (strncmp("forbidden", str, 9) == 0) {
+        return (int) OperatorStatus::FORBIDDEN;
+    } else {
+        return -1;
+    }
+}
+
+int radio_1_4::getAvailableNetworksResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responseLen) {
+#if VDBG
+    RLOGD("getAvailableNetworksResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        hidl_vec<OperatorInfo> networks;
+        if ((response == NULL && responseLen != 0)
+                || responseLen % (4 * sizeof(char *))!= 0) {
+            RLOGE("getAvailableNetworksResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            char **resp = (char **) response;
+            int numStrings = responseLen / sizeof(char *);
+            networks.resize(numStrings/4);
+            for (int i = 0, j = 0; i < numStrings; i = i + 4, j++) {
+                networks[j].alphaLong = convertCharPtrToHidlString(resp[i]);
+                networks[j].alphaShort = convertCharPtrToHidlString(resp[i + 1]);
+                networks[j].operatorNumeric = convertCharPtrToHidlString(resp[i + 2]);
+                int status = convertOperatorStatusToInt(resp[i + 3]);
+                if (status == -1) {
+                    if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+                } else {
+                    networks[j].status = (OperatorStatus) status;
+                }
+            }
+        }
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getAvailableNetworksResponse(responseInfo,
+                networks);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getAvailableNetworksResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::startDtmfResponse(int slotId,
+                            int responseType, int serial, RIL_Errno e,
+                            void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("startDtmfResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->startDtmfResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("startDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::stopDtmfResponse(int slotId,
+                           int responseType, int serial, RIL_Errno e,
+                           void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("stopDtmfResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->stopDtmfResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("stopDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getBasebandVersionResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getBasebandVersionResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getBasebandVersionResponse(responseInfo,
+                convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getBasebandVersionResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::separateConnectionResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("separateConnectionResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->separateConnectionResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("separateConnectionResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setMuteResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e,
+                          void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setMuteResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setMuteResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getMuteResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responseLen) {
+#if VDBG
+    RLOGD("getMuteResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        bool enable = false;
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("getMuteResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int *pInt = (int *) response;
+            enable = pInt[0] == 1 ? true : false;
+        }
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getMuteResponse(responseInfo,
+                enable);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getMuteResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getClipResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e,
+                          void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getClipResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getClipResponse(responseInfo,
+                (ClipStatus) ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getClipResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getDataCallListResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e,
+                                   void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getDataCallListResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        hidl_vec<SetupDataCallResult> ret;
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) {
+            RLOGE("getDataCallListResponse: invalid response");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            convertRilDataCallListToHal(response, responseLen, ret);
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getDataCallListResponse(
+                responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getDataCallListResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setSuppServiceNotificationsResponse(int slotId,
+                                              int responseType, int serial, RIL_Errno e,
+                                              void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setSuppServiceNotificationsResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setSuppServiceNotificationsResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setSuppServiceNotificationsResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::deleteSmsOnSimResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("deleteSmsOnSimResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->deleteSmsOnSimResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("deleteSmsOnSimResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setBandModeResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setBandModeResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setBandModeResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setBandModeResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::writeSmsToSimResponse(int slotId,
+                                int responseType, int serial, RIL_Errno e,
+                                void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("writeSmsToSimResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->writeSmsToSimResponse(responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("writeSmsToSimResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getAvailableBandModesResponse(int slotId,
+                                        int responseType, int serial, RIL_Errno e, void *response,
+                                        size_t responseLen) {
+#if VDBG
+    RLOGD("getAvailableBandModesResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        hidl_vec<RadioBandMode> modes;
+        if ((response == NULL && responseLen != 0)|| responseLen % sizeof(int) != 0) {
+            RLOGE("getAvailableBandModesResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int *pInt = (int *) response;
+            int numInts = responseLen / sizeof(int);
+            modes.resize(numInts);
+            for (int i = 0; i < numInts; i++) {
+                modes[i] = (RadioBandMode) pInt[i];
+            }
+        }
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getAvailableBandModesResponse(responseInfo,
+                modes);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getAvailableBandModesResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendEnvelopeResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("sendEnvelopeResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->sendEnvelopeResponse(responseInfo,
+                convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendEnvelopeResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendTerminalResponseToSimResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("sendTerminalResponseToSimResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->sendTerminalResponseToSimResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendTerminalResponseToSimResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::handleStkCallSetupRequestFromSimResponse(int slotId,
+                                                   int responseType, int serial,
+                                                   RIL_Errno e, void *response,
+                                                   size_t responseLen) {
+#if VDBG
+    RLOGD("handleStkCallSetupRequestFromSimResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->handleStkCallSetupRequestFromSimResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("handleStkCallSetupRequestFromSimResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::explicitCallTransferResponse(int slotId,
+                                       int responseType, int serial, RIL_Errno e,
+                                       void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("explicitCallTransferResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->explicitCallTransferResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("explicitCallTransferResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setPreferredNetworkTypeResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setPreferredNetworkTypeResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setPreferredNetworkTypeResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+
+int radio_1_4::getPreferredNetworkTypeResponse(int slotId,
+                                          int responseType, int serial, RIL_Errno e,
+                                          void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getPreferredNetworkTypeResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getPreferredNetworkTypeResponse(
+                responseInfo, (PreferredNetworkType) ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getPreferredNetworkTypeResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setPreferredNetworkTypeBitmapResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setPreferredNetworkTypeBitmapResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponseV1_4->setPreferredNetworkTypeBitmapResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setPreferredNetworkTypeBitmapResponse: radioService[%d]->mRadioResponseV1_4 == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+
+int radio_1_4::getPreferredNetworkTypeBitmapResponse(int slotId,
+                                          int responseType, int serial, RIL_Errno e,
+                                          void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getPreferredNetworkTypeBitmapResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponseV1_4->getPreferredNetworkTypeBitmapResponse(
+                responseInfo,
+                (const ::android::hardware::hidl_bitfield<
+                ::android::hardware::radio::V1_4::RadioAccessFamily>) ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getPreferredNetworkTypeBitmapResponse: radioService[%d]->mRadioResponseV1_4 == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getNeighboringCidsResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getNeighboringCidsResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        hidl_vec<NeighboringCell> cells;
+
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_NeighboringCell *) != 0) {
+            RLOGE("getNeighboringCidsResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int num = responseLen / sizeof(RIL_NeighboringCell *);
+            cells.resize(num);
+            for (int i = 0 ; i < num; i++) {
+                RIL_NeighboringCell *resp = ((RIL_NeighboringCell **) response)[i];
+                cells[i].cid = convertCharPtrToHidlString(resp->cid);
+                cells[i].rssi = resp->rssi;
+            }
+        }
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getNeighboringCidsResponse(responseInfo,
+                cells);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getNeighboringCidsResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setLocationUpdatesResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setLocationUpdatesResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setLocationUpdatesResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setLocationUpdatesResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setCdmaSubscriptionSourceResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setCdmaSubscriptionSourceResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setCdmaSubscriptionSourceResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setCdmaRoamingPreferenceResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setCdmaRoamingPreferenceResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setCdmaRoamingPreferenceResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getCdmaRoamingPreferenceResponse(int slotId,
+                                           int responseType, int serial, RIL_Errno e,
+                                           void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getCdmaRoamingPreferenceResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getCdmaRoamingPreferenceResponse(
+                responseInfo, (CdmaRoamingType) ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getCdmaRoamingPreferenceResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setTTYModeResponse(int slotId,
+                             int responseType, int serial, RIL_Errno e,
+                             void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setTTYModeResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setTTYModeResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getTTYModeResponse(int slotId,
+                             int responseType, int serial, RIL_Errno e,
+                             void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getTTYModeResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getTTYModeResponse(responseInfo,
+                (TtyMode) ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getTTYModeResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setPreferredVoicePrivacyResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setPreferredVoicePrivacyResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setPreferredVoicePrivacyResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getPreferredVoicePrivacyResponse(int slotId,
+                                           int responseType, int serial, RIL_Errno e,
+                                           void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getPreferredVoicePrivacyResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        bool enable = false;
+        int numInts = responseLen / sizeof(int);
+        if (response == NULL || numInts != 1) {
+            RLOGE("getPreferredVoicePrivacyResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int *pInt = (int *) response;
+            enable = pInt[0] == 1 ? true : false;
+        }
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getPreferredVoicePrivacyResponse(
+                responseInfo, enable);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getPreferredVoicePrivacyResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendCDMAFeatureCodeResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("sendCDMAFeatureCodeResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->sendCDMAFeatureCodeResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendCDMAFeatureCodeResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendBurstDtmfResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("sendBurstDtmfResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->sendBurstDtmfResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendBurstDtmfResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendCdmaSmsResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responseLen) {
+#if VDBG
+    RLOGD("sendCdmaSmsResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
+                responseLen);
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->sendCdmaSmsResponse(responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendCdmaSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::acknowledgeLastIncomingCdmaSmsResponse(int slotId,
+                                                 int responseType, int serial, RIL_Errno e,
+                                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("acknowledgeLastIncomingCdmaSmsResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->acknowledgeLastIncomingCdmaSmsResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("acknowledgeLastIncomingCdmaSmsResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getGsmBroadcastConfigResponse(int slotId,
+                                        int responseType, int serial, RIL_Errno e,
+                                        void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getGsmBroadcastConfigResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        hidl_vec<GsmBroadcastSmsConfigInfo> configs;
+
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_GSM_BroadcastSmsConfigInfo *) != 0) {
+            RLOGE("getGsmBroadcastConfigResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int num = responseLen / sizeof(RIL_GSM_BroadcastSmsConfigInfo *);
+            configs.resize(num);
+            for (int i = 0 ; i < num; i++) {
+                RIL_GSM_BroadcastSmsConfigInfo *resp =
+                        ((RIL_GSM_BroadcastSmsConfigInfo **) response)[i];
+                configs[i].fromServiceId = resp->fromServiceId;
+                configs[i].toServiceId = resp->toServiceId;
+                configs[i].fromCodeScheme = resp->fromCodeScheme;
+                configs[i].toCodeScheme = resp->toCodeScheme;
+                configs[i].selected = resp->selected == 1 ? true : false;
+            }
+        }
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getGsmBroadcastConfigResponse(responseInfo,
+                configs);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setGsmBroadcastConfigResponse(int slotId,
+                                        int responseType, int serial, RIL_Errno e,
+                                        void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setGsmBroadcastConfigResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setGsmBroadcastConfigResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setGsmBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setGsmBroadcastActivationResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setGsmBroadcastActivationResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setGsmBroadcastActivationResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setGsmBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getCdmaBroadcastConfigResponse(int slotId,
+                                         int responseType, int serial, RIL_Errno e,
+                                         void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getCdmaBroadcastConfigResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        hidl_vec<CdmaBroadcastSmsConfigInfo> configs;
+
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_CDMA_BroadcastSmsConfigInfo *) != 0) {
+            RLOGE("getCdmaBroadcastConfigResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int num = responseLen / sizeof(RIL_CDMA_BroadcastSmsConfigInfo *);
+            configs.resize(num);
+            for (int i = 0 ; i < num; i++) {
+                RIL_CDMA_BroadcastSmsConfigInfo *resp =
+                        ((RIL_CDMA_BroadcastSmsConfigInfo **) response)[i];
+                configs[i].serviceCategory = resp->service_category;
+                configs[i].language = resp->language;
+                configs[i].selected = resp->selected == 1 ? true : false;
+            }
+        }
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getCdmaBroadcastConfigResponse(responseInfo,
+                configs);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setCdmaBroadcastConfigResponse(int slotId,
+                                         int responseType, int serial, RIL_Errno e,
+                                         void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setCdmaBroadcastConfigResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setCdmaBroadcastConfigResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setCdmaBroadcastConfigResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setCdmaBroadcastActivationResponse(int slotId,
+                                             int responseType, int serial, RIL_Errno e,
+                                             void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setCdmaBroadcastActivationResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setCdmaBroadcastActivationResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setCdmaBroadcastActivationResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getCDMASubscriptionResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e, void *response,
+                                      size_t responseLen) {
+#if VDBG
+    RLOGD("getCDMASubscriptionResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        int numStrings = responseLen / sizeof(char *);
+        hidl_string emptyString;
+        if (response == NULL || numStrings != 5) {
+            RLOGE("getOperatorResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            Return<void> retStatus
+                    = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse(
+                    responseInfo, emptyString, emptyString, emptyString, emptyString, emptyString);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else {
+            char **resp = (char **) response;
+            Return<void> retStatus
+                    = radioService[slotId]->mRadioResponse->getCDMASubscriptionResponse(
+                    responseInfo,
+                    convertCharPtrToHidlString(resp[0]),
+                    convertCharPtrToHidlString(resp[1]),
+                    convertCharPtrToHidlString(resp[2]),
+                    convertCharPtrToHidlString(resp[3]),
+                    convertCharPtrToHidlString(resp[4]));
+            radioService[slotId]->checkReturnStatus(retStatus);
+        }
+    } else {
+        RLOGE("getCDMASubscriptionResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::writeSmsToRuimResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("writeSmsToRuimResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->writeSmsToRuimResponse(responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("writeSmsToRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::deleteSmsOnRuimResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("deleteSmsOnRuimResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->deleteSmsOnRuimResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("deleteSmsOnRuimResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getDeviceIdentityResponse(int slotId,
+                                    int responseType, int serial, RIL_Errno e, void *response,
+                                    size_t responseLen) {
+#if VDBG
+    RLOGD("getDeviceIdentityResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        int numStrings = responseLen / sizeof(char *);
+        hidl_string emptyString;
+        if (response == NULL || numStrings != 4) {
+            RLOGE("getDeviceIdentityResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            Return<void> retStatus
+                    = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo,
+                    emptyString, emptyString, emptyString, emptyString);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else {
+            char **resp = (char **) response;
+            Return<void> retStatus
+                    = radioService[slotId]->mRadioResponse->getDeviceIdentityResponse(responseInfo,
+                    convertCharPtrToHidlString(resp[0]),
+                    convertCharPtrToHidlString(resp[1]),
+                    convertCharPtrToHidlString(resp[2]),
+                    convertCharPtrToHidlString(resp[3]));
+            radioService[slotId]->checkReturnStatus(retStatus);
+        }
+    } else {
+        RLOGE("getDeviceIdentityResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::exitEmergencyCallbackModeResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("exitEmergencyCallbackModeResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->exitEmergencyCallbackModeResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("exitEmergencyCallbackModeResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getSmscAddressResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getSmscAddressResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getSmscAddressResponse(responseInfo,
+                convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setSmscAddressResponse(int slotId,
+                                             int responseType, int serial, RIL_Errno e,
+                                             void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setSmscAddressResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setSmscAddressResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setSmscAddressResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::reportSmsMemoryStatusResponse(int slotId,
+                                        int responseType, int serial, RIL_Errno e,
+                                        void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("reportSmsMemoryStatusResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->reportSmsMemoryStatusResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("reportSmsMemoryStatusResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::reportStkServiceIsRunningResponse(int slotId,
+                                             int responseType, int serial, RIL_Errno e,
+                                             void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("reportStkServiceIsRunningResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->
+                reportStkServiceIsRunningResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("reportStkServiceIsRunningResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getCdmaSubscriptionSourceResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getCdmaSubscriptionSourceResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getCdmaSubscriptionSourceResponse(
+                responseInfo, (CdmaSubscriptionSource) ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getCdmaSubscriptionSourceResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::requestIsimAuthenticationResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("requestIsimAuthenticationResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->requestIsimAuthenticationResponse(
+                responseInfo,
+                convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("requestIsimAuthenticationResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::acknowledgeIncomingGsmSmsWithPduResponse(int slotId,
+                                                   int responseType,
+                                                   int serial, RIL_Errno e, void *response,
+                                                   size_t responseLen) {
+#if VDBG
+    RLOGD("acknowledgeIncomingGsmSmsWithPduResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->acknowledgeIncomingGsmSmsWithPduResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("acknowledgeIncomingGsmSmsWithPduResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendEnvelopeWithStatusResponse(int slotId,
+                                         int responseType, int serial, RIL_Errno e, void *response,
+                                         size_t responseLen) {
+#if VDBG
+    RLOGD("sendEnvelopeWithStatusResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e,
+                response, responseLen);
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->sendEnvelopeWithStatusResponse(responseInfo,
+                result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendEnvelopeWithStatusResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getVoiceRadioTechnologyResponse(int slotId,
+                                          int responseType, int serial, RIL_Errno e,
+                                          void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getVoiceRadioTechnologyResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getVoiceRadioTechnologyResponse(
+                responseInfo, (RadioTechnology) ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getVoiceRadioTechnologyResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getCellInfoListResponse(int slotId,
+                                   int responseType,
+                                   int serial, RIL_Errno e, void *response,
+                                   size_t responseLen) {
+#if VDBG
+    RLOGD("getCellInfoListResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        hidl_vec<CellInfo> ret;
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_CellInfo_v12) != 0) {
+            RLOGE("getCellInfoListResponse: Invalid response");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            convertRilCellInfoListToHal(response, responseLen, ret);
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getCellInfoListResponse(
+                responseInfo, ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getCellInfoListResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setCellInfoListRateResponse(int slotId,
+                                       int responseType,
+                                       int serial, RIL_Errno e, void *response,
+                                       size_t responseLen) {
+#if VDBG
+    RLOGD("setCellInfoListRateResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setCellInfoListRateResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setCellInfoListRateResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setInitialAttachApnResponse(int slotId,
+                                       int responseType, int serial, RIL_Errno e,
+                                       void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setInitialAttachApnResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setInitialAttachApnResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setInitialAttachApnResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getImsRegistrationStateResponse(int slotId,
+                                           int responseType, int serial, RIL_Errno e,
+                                           void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getImsRegistrationStateResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        bool isRegistered = false;
+        int ratFamily = 0;
+        int numInts = responseLen / sizeof(int);
+        if (response == NULL || numInts != 2) {
+            RLOGE("getImsRegistrationStateResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            int *pInt = (int *) response;
+            isRegistered = pInt[0] == 1 ? true : false;
+            ratFamily = pInt[1];
+        }
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getImsRegistrationStateResponse(
+                responseInfo, isRegistered, (RadioTechnologyFamily) ratFamily);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getImsRegistrationStateResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendImsSmsResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responseLen) {
+#if VDBG
+    RLOGD("sendImsSmsResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        SendSmsResult result = makeSendSmsResult(responseInfo, serial, responseType, e, response,
+                responseLen);
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->sendImsSmsResponse(responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendSmsResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::iccTransmitApduBasicChannelResponse(int slotId,
+                                               int responseType, int serial, RIL_Errno e,
+                                               void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("iccTransmitApduBasicChannelResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response,
+                responseLen);
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->iccTransmitApduBasicChannelResponse(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("iccTransmitApduBasicChannelResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::iccOpenLogicalChannelResponse(int slotId,
+                                         int responseType, int serial, RIL_Errno e, void *response,
+                                         size_t responseLen) {
+#if VDBG
+    RLOGD("iccOpenLogicalChannelResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        int channelId = -1;
+        hidl_vec<int8_t> selectResponse;
+        int numInts = responseLen / sizeof(int);
+        if (response == NULL || responseLen % sizeof(int) != 0) {
+            RLOGE("iccOpenLogicalChannelResponse Invalid response: NULL");
+            if (response != NULL) {
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            }
+        } else {
+            int *pInt = (int *) response;
+            channelId = pInt[0];
+            selectResponse.resize(numInts - 1);
+            for (int i = 1; i < numInts; i++) {
+                selectResponse[i - 1] = (int8_t) pInt[i];
+            }
+        }
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->iccOpenLogicalChannelResponse(responseInfo,
+                channelId, selectResponse);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("iccOpenLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::iccCloseLogicalChannelResponse(int slotId,
+                                          int responseType, int serial, RIL_Errno e,
+                                          void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("iccCloseLogicalChannelResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->iccCloseLogicalChannelResponse(
+                responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("iccCloseLogicalChannelResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::iccTransmitApduLogicalChannelResponse(int slotId,
+                                                 int responseType, int serial, RIL_Errno e,
+                                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("iccTransmitApduLogicalChannelResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response,
+                responseLen);
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->iccTransmitApduLogicalChannelResponse(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("iccTransmitApduLogicalChannelResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::nvReadItemResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("nvReadItemResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->nvReadItemResponse(
+                responseInfo,
+                convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("nvReadItemResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::nvWriteItemResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("nvWriteItemResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->nvWriteItemResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("nvWriteItemResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::nvWriteCdmaPrlResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("nvWriteCdmaPrlResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->nvWriteCdmaPrlResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("nvWriteCdmaPrlResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::nvResetConfigResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("nvResetConfigResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->nvResetConfigResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("nvResetConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setUiccSubscriptionResponse(int slotId,
+                                       int responseType, int serial, RIL_Errno e,
+                                       void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setUiccSubscriptionResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setUiccSubscriptionResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setUiccSubscriptionResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setDataAllowedResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setDataAllowedResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setDataAllowedResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setDataAllowedResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getHardwareConfigResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getHardwareConfigResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        hidl_vec<HardwareConfig> result;
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_HardwareConfig) != 0) {
+            RLOGE("hardwareConfigChangedInd: invalid response");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            convertRilHardwareConfigListToHal(response, responseLen, result);
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getHardwareConfigResponse(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getHardwareConfigResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::requestIccSimAuthenticationResponse(int slotId,
+                                               int responseType, int serial, RIL_Errno e,
+                                               void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("requestIccSimAuthenticationResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        IccIoResult result = responseIccIo(responseInfo, serial, responseType, e, response,
+                responseLen);
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->requestIccSimAuthenticationResponse(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("requestIccSimAuthenticationResponse: radioService[%d]->mRadioResponse "
+                "== NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setDataProfileResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setDataProfileResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setDataProfileResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setDataProfileResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::requestShutdownResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("requestShutdownResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->requestShutdownResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("requestShutdownResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+void responseRadioCapability(RadioResponseInfo& responseInfo, int serial,
+        int responseType, RIL_Errno e, void *response, size_t responseLen, RadioCapability& rc) {
+    populateResponseInfo(responseInfo, serial, responseType, e);
+
+    if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) {
+        RLOGE("responseRadioCapability: Invalid response");
+        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        rc.logicalModemUuid = hidl_string();
+    } else {
+        convertRilRadioCapabilityToHal(response, responseLen, rc);
+    }
+}
+
+int radio_1_4::getRadioCapabilityResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getRadioCapabilityResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        RadioCapability result = {};
+        responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen,
+                result);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->getRadioCapabilityResponse(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setRadioCapabilityResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e,
+                                     void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setRadioCapabilityResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        RadioCapability result = {};
+        responseRadioCapability(responseInfo, serial, responseType, e, response, responseLen,
+                result);
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->setRadioCapabilityResponse(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setRadioCapabilityResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+LceStatusInfo responseLceStatusInfo(RadioResponseInfo& responseInfo, int serial, int responseType,
+                                    RIL_Errno e, void *response, size_t responseLen) {
+    populateResponseInfo(responseInfo, serial, responseType, e);
+    LceStatusInfo result = {};
+
+    if (response == NULL || responseLen != sizeof(RIL_LceStatusInfo)) {
+        RLOGE("Invalid response: NULL");
+        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+    } else {
+        RIL_LceStatusInfo *resp = (RIL_LceStatusInfo *) response;
+        result.lceStatus = (LceStatus) resp->lce_status;
+        result.actualIntervalMs = (uint8_t) resp->actual_interval_ms;
+    }
+    return result;
+}
+
+int radio_1_4::startLceServiceResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e,
+                                   void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("startLceServiceResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e,
+                response, responseLen);
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->startLceServiceResponse(responseInfo,
+                result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("startLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::stopLceServiceResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("stopLceServiceResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        LceStatusInfo result = responseLceStatusInfo(responseInfo, serial, responseType, e,
+                response, responseLen);
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->stopLceServiceResponse(responseInfo,
+                result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("stopLceServiceResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::pullLceDataResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("pullLceDataResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        LceDataInfo result = {};
+        if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) {
+            RLOGE("pullLceDataResponse: Invalid response");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            convertRilLceDataInfoToHal(response, responseLen, result);
+        }
+
+        Return<void> retStatus = radioService[slotId]->mRadioResponse->pullLceDataResponse(
+                responseInfo, result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("pullLceDataResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getModemActivityInfoResponse(int slotId,
+                                        int responseType, int serial, RIL_Errno e,
+                                        void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getModemActivityInfoResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        ActivityStatsInfo info;
+        if (response == NULL || responseLen != sizeof(RIL_ActivityStatsInfo)) {
+            RLOGE("getModemActivityInfoResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            RIL_ActivityStatsInfo *resp = (RIL_ActivityStatsInfo *)response;
+            info.sleepModeTimeMs = resp->sleep_mode_time_ms;
+            info.idleModeTimeMs = resp->idle_mode_time_ms;
+            for(int i = 0; i < RIL_NUM_TX_POWER_LEVELS; i++) {
+                info.txmModetimeMs[i] = resp->tx_mode_time_ms[i];
+            }
+            info.rxModeTimeMs = resp->rx_mode_time_ms;
+        }
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getModemActivityInfoResponse(responseInfo,
+                info);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getModemActivityInfoResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setAllowedCarriersResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setAllowedCarriersResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        int ret = responseInt(responseInfo, serial, responseType, e, response, responseLen);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setAllowedCarriersResponse(responseInfo,
+                ret);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setAllowedCarriersResponse4(int slotId, int responseType, int serial, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setAllowedCarriersResponse4: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponseV1_4->setAllowedCarriersResponse_1_4(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setAllowedCarriersResponse4: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
+    }
+
+    return 0;
+}
+
+void prepareCarrierRestrictionsResponse(hidl_vec<Carrier>& allowedCarriers,
+                                       hidl_vec<Carrier>& excludedCarriers,
+                                       bool& allAllowed,
+                                       const RIL_CarrierRestrictions* pCr) {
+    if (pCr->len_allowed_carriers > 0 || pCr->len_excluded_carriers > 0) {
+        allAllowed = false;
+    }
+    allowedCarriers.resize(pCr->len_allowed_carriers);
+    for(int i = 0; i < pCr->len_allowed_carriers; i++) {
+        RIL_Carrier *carrier = pCr->allowed_carriers + i;
+        allowedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc);
+        allowedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc);
+        allowedCarriers[i].matchType = (CarrierMatchType) carrier->match_type;
+        allowedCarriers[i].matchData =
+                convertCharPtrToHidlString(carrier->match_data);
+    }
+
+    excludedCarriers.resize(pCr->len_excluded_carriers);
+    for(int i = 0; i < pCr->len_excluded_carriers; i++) {
+        RIL_Carrier *carrier = pCr->excluded_carriers + i;
+        excludedCarriers[i].mcc = convertCharPtrToHidlString(carrier->mcc);
+        excludedCarriers[i].mnc = convertCharPtrToHidlString(carrier->mnc);
+        excludedCarriers[i].matchType = (CarrierMatchType) carrier->match_type;
+        excludedCarriers[i].matchData =
+                convertCharPtrToHidlString(carrier->match_data);
+    }
+}
+
+int radio_1_4::getAllowedCarriersResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getAllowedCarriersResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        CarrierRestrictions carrierInfo = {};
+        bool allAllowed = true;
+        if (response == NULL) {
+#if VDBG
+            RLOGD("getAllowedCarriersResponse response is NULL: all allowed");
+#endif
+            carrierInfo.allowedCarriers.resize(0);
+            carrierInfo.excludedCarriers.resize(0);
+        } else if (responseLen != sizeof(RIL_CarrierRestrictions)) {
+            RLOGE("getAllowedCarriersResponse Invalid response");
+            if (e == RIL_E_SUCCESS) {
+                responseInfo.error = RadioError::INVALID_RESPONSE;
+            }
+        } else {
+            RIL_CarrierRestrictions *pCr = (RIL_CarrierRestrictions *)response;
+            prepareCarrierRestrictionsResponse(carrierInfo.allowedCarriers, carrierInfo.excludedCarriers, allAllowed, pCr);
+        }
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->getAllowedCarriersResponse(responseInfo,
+                allAllowed, carrierInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getAllowedCarriersResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::getAllowedCarriersResponse4(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("getAllowedCarriersResponse4: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+
+        ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierInfo = {};
+        ::android::hardware::radio::V1_4::SimLockMultiSimPolicy multiSimPolicy =
+                ::android::hardware::radio::V1_4::SimLockMultiSimPolicy::NO_MULTISIM_POLICY;
+        bool allAllowed = true;
+
+        if (response == NULL) {
+#if VDBG
+            RLOGD("getAllowedCarriersResponse4 response is NULL: all allowed");
+#endif
+            carrierInfo.allowedCarriers.resize(0);
+            carrierInfo.excludedCarriers.resize(0);
+            carrierInfo.allowedCarriersPrioritized = false;
+        } else if (responseLen != sizeof(RIL_CarrierRestrictionsWithPriority)) {
+            RLOGE("getAllowedCarriersResponse4 Invalid response");
+            if (e == RIL_E_SUCCESS) {
+                responseInfo.error = RadioError::INVALID_RESPONSE;
+            }
+        } else {
+            RIL_CarrierRestrictionsWithPriority *pCrExt = (RIL_CarrierRestrictionsWithPriority *)response;
+
+            // Convert into the structure used in IRadio 1.0 to re-use existing code
+            RIL_CarrierRestrictions cr = {};
+            cr.len_allowed_carriers = pCrExt->len_allowed_carriers;
+            cr.len_excluded_carriers = pCrExt->len_excluded_carriers;
+            cr.allowed_carriers = pCrExt->allowed_carriers;
+            cr.excluded_carriers = pCrExt->excluded_carriers;
+            prepareCarrierRestrictionsResponse(carrierInfo.allowedCarriers, carrierInfo.excludedCarriers, allAllowed, &cr);
+
+            carrierInfo.allowedCarriersPrioritized = (bool)pCrExt->allowedCarriersPrioritized;
+            multiSimPolicy = (::android::hardware::radio::V1_4::SimLockMultiSimPolicy)pCrExt->multiSimPolicy;
+        }
+
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponseV1_4->getAllowedCarriersResponse_1_4(responseInfo,
+                carrierInfo, multiSimPolicy);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("getAllowedCarriersResponse4: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendDeviceStateResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responselen) {
+#if VDBG
+    RLOGD("sendDeviceStateResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->sendDeviceStateResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("sendDeviceStateResponse: radioService[%d]->mRadioResponse == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setCarrierInfoForImsiEncryptionResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responseLen) {
+    RLOGD("setCarrierInfoForImsiEncryptionResponse: serial %d", serial);
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4->
+                setCarrierInfoForImsiEncryptionResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setCarrierInfoForImsiEncryptionResponse: radioService[%d]->mRadioResponseV1_4 == "
+                "NULL", slotId);
+    }
+    return 0;
+}
+
+int radio_1_4::setIndicationFilterResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responselen) {
+#if VDBG
+    RLOGD("setIndicationFilterResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponse->setIndicationFilterResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("setIndicationFilterResponse: radioService[%d]->mRadioResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setSimCardPowerResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e,
+                                   void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("setSimCardPowerResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponse != NULL
+            || radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+            Return<void> retStatus = radioService[slotId]->mRadioResponseV1_4->
+                    setSimCardPowerResponse_1_1(responseInfo);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        } else {
+            RLOGD("setSimCardPowerResponse: radioService[%d]->mRadioResponseV1_4 == NULL",
+                    slotId);
+            Return<void> retStatus
+                    = radioService[slotId]->mRadioResponse->setSimCardPowerResponse(responseInfo);
+            radioService[slotId]->checkReturnStatus(retStatus);
+        }
+    } else {
+        RLOGE("setSimCardPowerResponse: radioService[%d]->mRadioResponse == NULL && "
+                "radioService[%d]->mRadioResponseV1_4 == NULL", slotId, slotId);
+    }
+    return 0;
+}
+
+int radio_1_4::startNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("startNetworkScanResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponseV1_4->startNetworkScanResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::startNetworkScanResponse4(int slotId, int responseType, int serial, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("startNetworkScanResponse4: serial %d", serial);
+#endif
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponseV1_4->startNetworkScanResponse_1_4(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("startNetworkScanResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::stopNetworkScanResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                   void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("stopNetworkScanResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponseV1_4->stopNetworkScanResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("stopNetworkScanResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::emergencyDialResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("emergencyDialResponse: serial %d", serial);
+#endif
+
+    if (radioService[slotId]->mRadioResponseV1_4 != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        Return<void> retStatus
+                = radioService[slotId]->mRadioResponseV1_4->emergencyDialResponse(responseInfo);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("emergencyDialResponse: radioService[%d]->mRadioResponseV1_4 == NULL", slotId);
+    }
+    return 0;
+}
+
+void convertRilKeepaliveStatusToHal(const RIL_KeepaliveStatus *rilStatus,
+        V1_1::KeepaliveStatus& halStatus) {
+    halStatus.sessionHandle = rilStatus->sessionHandle;
+    halStatus.code = static_cast<V1_1::KeepaliveStatusCode>(rilStatus->code);
+}
+
+int radio_1_4::startKeepaliveResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("%s(): %d", __FUNCTION__, serial);
+#endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
+
+    // If we don't have a radio service, there's nothing we can do
+    if (radioService[slotId]->mRadioResponseV1_4 == NULL) {
+        RLOGE("%s: radioService[%d]->mRadioResponseV1_4 == NULL", __FUNCTION__, slotId);
+        return 0;
+    }
+
+    V1_1::KeepaliveStatus ks = {};
+    if (response == NULL || responseLen != sizeof(V1_1::KeepaliveStatus)) {
+        RLOGE("%s: invalid response - %d", __FUNCTION__, static_cast<int>(e));
+        if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+    } else {
+        convertRilKeepaliveStatusToHal(static_cast<RIL_KeepaliveStatus*>(response), ks);
+    }
+
+    Return<void> retStatus =
+            radioService[slotId]->mRadioResponseV1_4->startKeepaliveResponse(responseInfo, ks);
+    radioService[slotId]->checkReturnStatus(retStatus);
+    return 0;
+}
+
+int radio_1_4::stopKeepaliveResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("%s(): %d", __FUNCTION__, serial);
+#endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
+
+    // If we don't have a radio service, there's nothing we can do
+    if (radioService[slotId]->mRadioResponseV1_4 == NULL) {
+        RLOGE("%s: radioService[%d]->mRadioResponseV1_4 == NULL", __FUNCTION__, slotId);
+        return 0;
+    }
+
+    Return<void> retStatus =
+            radioService[slotId]->mRadioResponseV1_4->stopKeepaliveResponse(responseInfo);
+    radioService[slotId]->checkReturnStatus(retStatus);
+    return 0;
+}
+
+int radio_1_4::getModemStackStatusResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("%s(): %d", __FUNCTION__, serial);
+#endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
+
+    // If we don't have a radio service, there's nothing we can do
+    if (radioService[slotId]->mRadioResponseV1_3 == NULL) {
+        RLOGE("%s: radioService[%d]->mRadioResponseV1_3 == NULL", __FUNCTION__, slotId);
+        return 0;
+    }
+
+    Return<void> retStatus =
+            radioService[slotId]->mRadioResponseV1_3->getModemStackStatusResponse(
+            responseInfo, true);
+    radioService[slotId]->checkReturnStatus(retStatus);
+    return 0;
+}
+
+int radio_1_4::enableModemResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("%s(): %d", __FUNCTION__, serial);
+#endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
+
+    // If we don't have a radio service, there's nothing we can do
+    if (radioService[slotId]->mRadioResponseV1_3 == NULL) {
+        RLOGE("%s: radioService[%d]->mRadioResponseV1_3 == NULL", __FUNCTION__, slotId);
+        return 0;
+    }
+
+    Return<void> retStatus =
+            radioService[slotId]->mRadioResponseV1_3->enableModemResponse(responseInfo);
+    radioService[slotId]->checkReturnStatus(retStatus);
+    return 0;
+}
+
+int radio_1_4::sendRequestRawResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responseLen) {
+#if VDBG
+   RLOGD("sendRequestRawResponse: serial %d", serial);
+#endif
+
+    if (!kOemHookEnabled) return 0;
+
+    if (oemHookService[slotId]->mOemHookResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        hidl_vec<uint8_t> data;
+
+        if (response == NULL) {
+            RLOGE("sendRequestRawResponse: Invalid response");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            data.setToExternal((uint8_t *) response, responseLen);
+        }
+        Return<void> retStatus = oemHookService[slotId]->mOemHookResponse->
+                sendRequestRawResponse(responseInfo, data);
+        checkReturnStatus(slotId, retStatus, false);
+    } else {
+        RLOGE("sendRequestRawResponse: oemHookService[%d]->mOemHookResponse == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::sendRequestStringsResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responseLen) {
+#if VDBG
+    RLOGD("sendRequestStringsResponse: serial %d", serial);
+#endif
+
+    if (!kOemHookEnabled) return 0;
+
+    if (oemHookService[slotId]->mOemHookResponse != NULL) {
+        RadioResponseInfo responseInfo = {};
+        populateResponseInfo(responseInfo, serial, responseType, e);
+        hidl_vec<hidl_string> data;
+
+        if ((response == NULL && responseLen != 0) || responseLen % sizeof(char *) != 0) {
+            RLOGE("sendRequestStringsResponse Invalid response: NULL");
+            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else {
+            char **resp = (char **) response;
+            int numStrings = responseLen / sizeof(char *);
+            data.resize(numStrings);
+            for (int i = 0; i < numStrings; i++) {
+                data[i] = convertCharPtrToHidlString(resp[i]);
+            }
+        }
+        Return<void> retStatus
+                = oemHookService[slotId]->mOemHookResponse->sendRequestStringsResponse(
+                responseInfo, data);
+        checkReturnStatus(slotId, retStatus, false);
+    } else {
+        RLOGE("sendRequestStringsResponse: oemHookService[%d]->mOemHookResponse == "
+                "NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::setSystemSelectionChannelsResponse(int slotId, int responseType, int serial,
+                                        RIL_Errno e, void* /* response */, size_t responseLen) {
+#if VDBG
+    RLOGD("%s(): %d", __FUNCTION__, serial);
+#endif
+    RadioResponseInfo responseInfo = {};
+    populateResponseInfo(responseInfo, serial, responseType, e);
+
+    // If we don't have a radio service, there's nothing we can do
+    if (radioService[slotId]->mRadioResponseV1_3 == NULL) {
+        RLOGE("%s: radioService[%d]->mRadioResponseV1_3 == NULL", __FUNCTION__, slotId);
+        return 0;
+    }
+
+    Return<void> retStatus =
+            radioService[slotId]->mRadioResponseV1_3->setSystemSelectionChannelsResponse(
+            responseInfo);
+    radioService[slotId]->checkReturnStatus(retStatus);
+    return 0;
+}
+
+/***************************************************************************************************
+ * INDICATION FUNCTIONS
+ * The below function handle unsolicited messages coming from the Radio
+ * (messages for which there is no pending request)
+ **************************************************************************************************/
+
+RadioIndicationType convertIntToRadioIndicationType(int indicationType) {
+    return indicationType == RESPONSE_UNSOLICITED ? (RadioIndicationType::UNSOLICITED) :
+            (RadioIndicationType::UNSOLICITED_ACK_EXP);
+}
+
+int radio_1_4::radioStateChangedInd(int slotId,
+                                 int indicationType, int token, RIL_Errno e, void *response,
+                                 size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        RadioState radioState =
+                (RadioState) CALL_ONSTATEREQUEST(slotId);
+        RLOGD("radioStateChangedInd: radioState %d", radioState);
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->radioStateChanged(
+                convertIntToRadioIndicationType(indicationType), radioState);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("radioStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::callStateChangedInd(int slotId,
+                               int indicationType, int token, RIL_Errno e, void *response,
+                               size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("callStateChangedInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->callStateChanged(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("callStateChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::networkStateChangedInd(int slotId,
+                                  int indicationType, int token, RIL_Errno e, void *response,
+                                  size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("networkStateChangedInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->networkStateChanged(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("networkStateChangedInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+uint8_t hexCharToInt(uint8_t c) {
+    if (c >= '0' && c <= '9') return (c - '0');
+    if (c >= 'A' && c <= 'F') return (c - 'A' + 10);
+    if (c >= 'a' && c <= 'f') return (c - 'a' + 10);
+
+    return INVALID_HEX_CHAR;
+}
+
+uint8_t * convertHexStringToBytes(void *response, size_t responseLen) {
+    if (responseLen % 2 != 0) {
+        return NULL;
+    }
+
+    uint8_t *bytes = (uint8_t *)calloc(responseLen/2, sizeof(uint8_t));
+    if (bytes == NULL) {
+        RLOGE("convertHexStringToBytes: cannot allocate memory for bytes string");
+        return NULL;
+    }
+    uint8_t *hexString = (uint8_t *)response;
+
+    for (size_t i = 0; i < responseLen; i += 2) {
+        uint8_t hexChar1 = hexCharToInt(hexString[i]);
+        uint8_t hexChar2 = hexCharToInt(hexString[i + 1]);
+
+        if (hexChar1 == INVALID_HEX_CHAR || hexChar2 == INVALID_HEX_CHAR) {
+            RLOGE("convertHexStringToBytes: invalid hex char %d %d",
+                    hexString[i], hexString[i + 1]);
+            free(bytes);
+            return NULL;
+        }
+        bytes[i/2] = ((hexChar1 << 4) | hexChar2);
+    }
+
+    return bytes;
+}
+
+int radio_1_4::newSmsInd(int slotId, int indicationType,
+                     int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("newSmsInd: invalid response");
+            return 0;
+        }
+
+        uint8_t *bytes = convertHexStringToBytes(response, responseLen);
+        if (bytes == NULL) {
+            RLOGE("newSmsInd: convertHexStringToBytes failed");
+            return 0;
+        }
+
+        hidl_vec<uint8_t> pdu;
+        pdu.setToExternal(bytes, responseLen/2);
+#if VDBG
+        RLOGD("newSmsInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->newSms(
+                convertIntToRadioIndicationType(indicationType), pdu);
+        radioService[slotId]->checkReturnStatus(retStatus);
+        free(bytes);
+    } else {
+        RLOGE("newSmsInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::newSmsStatusReportInd(int slotId,
+                                 int indicationType, int token, RIL_Errno e, void *response,
+                                 size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("newSmsStatusReportInd: invalid response");
+            return 0;
+        }
+
+        uint8_t *bytes = convertHexStringToBytes(response, responseLen);
+        if (bytes == NULL) {
+            RLOGE("newSmsStatusReportInd: convertHexStringToBytes failed");
+            return 0;
+        }
+
+        hidl_vec<uint8_t> pdu;
+        pdu.setToExternal(bytes, responseLen/2);
+#if VDBG
+        RLOGD("newSmsStatusReportInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->newSmsStatusReport(
+                convertIntToRadioIndicationType(indicationType), pdu);
+        radioService[slotId]->checkReturnStatus(retStatus);
+        free(bytes);
+    } else {
+        RLOGE("newSmsStatusReportInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::newSmsOnSimInd(int slotId, int indicationType,
+                          int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("newSmsOnSimInd: invalid response");
+            return 0;
+        }
+        int32_t recordNumber = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("newSmsOnSimInd: slotIndex %d", recordNumber);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->newSmsOnSim(
+                convertIntToRadioIndicationType(indicationType), recordNumber);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("newSmsOnSimInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::onUssdInd(int slotId, int indicationType,
+                     int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != 2 * sizeof(char *)) {
+            RLOGE("onUssdInd: invalid response");
+            return 0;
+        }
+        char **strings = (char **) response;
+        char *mode = strings[0];
+        hidl_string msg = convertCharPtrToHidlString(strings[1]);
+        UssdModeType modeType = (UssdModeType) atoi(mode);
+#if VDBG
+        RLOGD("onUssdInd: mode %s", mode);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->onUssd(
+                convertIntToRadioIndicationType(indicationType), modeType, msg);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("onUssdInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::nitzTimeReceivedInd(int slotId,
+                               int indicationType, int token, RIL_Errno e, void *response,
+                               size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("nitzTimeReceivedInd: invalid response");
+            return 0;
+        }
+        hidl_string nitzTime = convertCharPtrToHidlString((char *) response);
+#if VDBG
+        RLOGD("nitzTimeReceivedInd: nitzTime %s receivedTime %" PRId64, nitzTime.c_str(),
+                nitzTimeReceived[slotId]);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->nitzTimeReceived(
+                convertIntToRadioIndicationType(indicationType), nitzTime,
+                nitzTimeReceived[slotId]);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("nitzTimeReceivedInd: radioService[%d]->mRadioIndication == NULL", slotId);
+        return -1;
+    }
+
+    return 0;
+}
+
+void convertRilSignalStrengthToHal(void *response, size_t responseLen,
+        SignalStrength& signalStrength) {
+    RIL_SignalStrength_v10 *rilSignalStrength = (RIL_SignalStrength_v10 *) response;
+
+    // Fixup LTE for backwards compatibility
+    // signalStrength: -1 -> 99
+    if (rilSignalStrength->LTE_SignalStrength.signalStrength == -1) {
+        rilSignalStrength->LTE_SignalStrength.signalStrength = 99;
+    }
+    // rsrp: -1 -> INT_MAX all other negative value to positive.
+    // So remap here
+    if (rilSignalStrength->LTE_SignalStrength.rsrp == -1) {
+        rilSignalStrength->LTE_SignalStrength.rsrp = INT_MAX;
+    } else if (rilSignalStrength->LTE_SignalStrength.rsrp < -1) {
+        rilSignalStrength->LTE_SignalStrength.rsrp = -rilSignalStrength->LTE_SignalStrength.rsrp;
+    }
+    // rsrq: -1 -> INT_MAX
+    if (rilSignalStrength->LTE_SignalStrength.rsrq == -1) {
+        rilSignalStrength->LTE_SignalStrength.rsrq = INT_MAX;
+    }
+    // Not remapping rssnr is already using INT_MAX
+    // cqi: -1 -> INT_MAX
+    if (rilSignalStrength->LTE_SignalStrength.cqi == -1) {
+        rilSignalStrength->LTE_SignalStrength.cqi = INT_MAX;
+    }
+
+    signalStrength.gw.signalStrength = rilSignalStrength->GW_SignalStrength.signalStrength;
+    signalStrength.gw.bitErrorRate = rilSignalStrength->GW_SignalStrength.bitErrorRate;
+    // RIL_SignalStrength_v10 not support gw.timingAdvance. Set to INT_MAX as
+    // invalid value.
+    signalStrength.gw.timingAdvance = INT_MAX;
+
+    signalStrength.cdma.dbm = rilSignalStrength->CDMA_SignalStrength.dbm;
+    signalStrength.cdma.ecio = rilSignalStrength->CDMA_SignalStrength.ecio;
+    signalStrength.evdo.dbm = rilSignalStrength->EVDO_SignalStrength.dbm;
+    signalStrength.evdo.ecio = rilSignalStrength->EVDO_SignalStrength.ecio;
+    signalStrength.evdo.signalNoiseRatio =
+            rilSignalStrength->EVDO_SignalStrength.signalNoiseRatio;
+    signalStrength.lte.signalStrength = rilSignalStrength->LTE_SignalStrength.signalStrength;
+    signalStrength.lte.rsrp = rilSignalStrength->LTE_SignalStrength.rsrp;
+    signalStrength.lte.rsrq = rilSignalStrength->LTE_SignalStrength.rsrq;
+    signalStrength.lte.rssnr = rilSignalStrength->LTE_SignalStrength.rssnr;
+    signalStrength.lte.cqi = rilSignalStrength->LTE_SignalStrength.cqi;
+    signalStrength.lte.timingAdvance = rilSignalStrength->LTE_SignalStrength.timingAdvance;
+    signalStrength.tdScdma.rscp = rilSignalStrength->TD_SCDMA_SignalStrength.rscp;
+}
+
+int radio_1_4::currentSignalStrengthInd(int slotId,
+                                    int indicationType, int token, RIL_Errno e,
+                                    void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_SignalStrength_v10)) {
+            RLOGE("currentSignalStrengthInd: invalid response");
+            return 0;
+        }
+
+        SignalStrength signalStrength = {};
+        convertRilSignalStrengthToHal(response, responseLen, signalStrength);
+
+#if VDBG
+        RLOGD("currentSignalStrengthInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->currentSignalStrength(
+                convertIntToRadioIndicationType(indicationType), signalStrength);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("currentSignalStrengthInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse,
+        SetupDataCallResult& dcResult) {
+    dcResult.status = (DataCallFailCause) dcResponse->status;
+    dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime;
+    dcResult.cid = dcResponse->cid;
+    dcResult.active = dcResponse->active;
+    dcResult.type = convertCharPtrToHidlString(dcResponse->type);
+    dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname);
+    dcResult.addresses = convertCharPtrToHidlString(dcResponse->addresses);
+    dcResult.dnses = convertCharPtrToHidlString(dcResponse->dnses);
+    dcResult.gateways = convertCharPtrToHidlString(dcResponse->gateways);
+    dcResult.pcscf = convertCharPtrToHidlString(dcResponse->pcscf);
+    dcResult.mtu = dcResponse->mtu;
+}
+
+hidl_vec<hidl_string> split(hidl_string str) {
+    std::vector<hidl_string> ret;
+    std::stringstream ss(static_cast<std::string>(str));
+
+    std::string tok;
+
+    while(getline(ss, tok, ' ')) {
+        ret.push_back(hidl_string(tok));
+    }
+
+    return ret;
+}
+
+::android::hardware::radio::V1_4::PdpProtocolType convertToPdpProtocolType(hidl_string str) {
+    if (strncmp("IP", str.c_str(), 2) == 0) {
+        return ::android::hardware::radio::V1_4::PdpProtocolType::IP;
+    } else if (strncmp("IPV6", str.c_str(), 4) == 0) {
+        return ::android::hardware::radio::V1_4::PdpProtocolType::IPV6;
+    } else if (strncmp("IPV4V6", str.c_str(), 6) == 0) {
+        return ::android::hardware::radio::V1_4::PdpProtocolType::IPV4V6;
+    } else if (strncmp("PPP", str.c_str(), 3) == 0) {
+        return ::android::hardware::radio::V1_4::PdpProtocolType::PPP;
+    } else if (strncmp("NON_IP", str.c_str(), 6) == 0) {
+        return ::android::hardware::radio::V1_4::PdpProtocolType::NON_IP;
+    } else if (strncmp("UNSTRUCTURED", str.c_str(), 12) == 0) {
+        return ::android::hardware::radio::V1_4::PdpProtocolType::UNSTRUCTURED;
+    } else {
+        return ::android::hardware::radio::V1_4::PdpProtocolType::UNKNOWN;
+    }
+}
+
+void convertRilDataCallToHal(RIL_Data_Call_Response_v11 *dcResponse,
+        ::android::hardware::radio::V1_4::SetupDataCallResult& dcResult) {
+    dcResult.cause = (::android::hardware::radio::V1_4::DataCallFailCause) dcResponse->status;
+    dcResult.suggestedRetryTime = dcResponse->suggestedRetryTime;
+    dcResult.cid = dcResponse->cid;
+    dcResult.active = (::android::hardware::radio::V1_4::DataConnActiveStatus)dcResponse->active;
+    dcResult.type = convertToPdpProtocolType(convertCharPtrToHidlString(dcResponse->type));
+    dcResult.ifname = convertCharPtrToHidlString(dcResponse->ifname);
+    dcResult.addresses = split(convertCharPtrToHidlString(dcResponse->addresses));
+    dcResult.dnses = split(convertCharPtrToHidlString(dcResponse->dnses));
+    dcResult.gateways = split(convertCharPtrToHidlString(dcResponse->gateways));
+    dcResult.pcscf = split(convertCharPtrToHidlString(dcResponse->pcscf));
+    dcResult.mtu = dcResponse->mtu;
+}
+
+
+void convertRilDataCallListToHal(void *response, size_t responseLen,
+        hidl_vec<SetupDataCallResult>& dcResultList) {
+    int num = responseLen / sizeof(RIL_Data_Call_Response_v11);
+
+    RIL_Data_Call_Response_v11 *dcResponse = (RIL_Data_Call_Response_v11 *) response;
+    dcResultList.resize(num);
+    for (int i = 0; i < num; i++) {
+        convertRilDataCallToHal(&dcResponse[i], dcResultList[i]);
+    }
+}
+
+int radio_1_4::dataCallListChangedInd(int slotId,
+                                  int indicationType, int token, RIL_Errno e, void *response,
+                                  size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_Data_Call_Response_v11) != 0) {
+            RLOGE("dataCallListChangedInd: invalid response");
+            return 0;
+        }
+        hidl_vec<SetupDataCallResult> dcList;
+        convertRilDataCallListToHal(response, responseLen, dcList);
+#if VDBG
+        RLOGD("dataCallListChangedInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->dataCallListChanged(
+                convertIntToRadioIndicationType(indicationType), dcList);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("dataCallListChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::suppSvcNotifyInd(int slotId, int indicationType,
+                            int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_SuppSvcNotification)) {
+            RLOGE("suppSvcNotifyInd: invalid response");
+            return 0;
+        }
+
+        SuppSvcNotification suppSvc = {};
+        RIL_SuppSvcNotification *ssn = (RIL_SuppSvcNotification *) response;
+        suppSvc.isMT = ssn->notificationType;
+        suppSvc.code = ssn->code;
+        suppSvc.index = ssn->index;
+        suppSvc.type = ssn->type;
+        suppSvc.number = convertCharPtrToHidlString(ssn->number);
+
+#if VDBG
+        RLOGD("suppSvcNotifyInd: isMT %d code %d index %d type %d",
+                suppSvc.isMT, suppSvc.code, suppSvc.index, suppSvc.type);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->suppSvcNotify(
+                convertIntToRadioIndicationType(indicationType), suppSvc);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("suppSvcNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::stkSessionEndInd(int slotId, int indicationType,
+                            int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("stkSessionEndInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkSessionEnd(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("stkSessionEndInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::stkProactiveCommandInd(int slotId,
+                                  int indicationType, int token, RIL_Errno e, void *response,
+                                  size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("stkProactiveCommandInd: invalid response");
+            return 0;
+        }
+#if VDBG
+        RLOGD("stkProactiveCommandInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkProactiveCommand(
+                convertIntToRadioIndicationType(indicationType),
+                convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("stkProactiveCommandInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::stkEventNotifyInd(int slotId, int indicationType,
+                             int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("stkEventNotifyInd: invalid response");
+            return 0;
+        }
+#if VDBG
+        RLOGD("stkEventNotifyInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkEventNotify(
+                convertIntToRadioIndicationType(indicationType),
+                convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("stkEventNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::stkCallSetupInd(int slotId, int indicationType,
+                           int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("stkCallSetupInd: invalid response");
+            return 0;
+        }
+        int32_t timeout = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("stkCallSetupInd: timeout %d", timeout);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkCallSetup(
+                convertIntToRadioIndicationType(indicationType), timeout);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("stkCallSetupInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::simSmsStorageFullInd(int slotId,
+                                int indicationType, int token, RIL_Errno e, void *response,
+                                size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("simSmsStorageFullInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->simSmsStorageFull(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("simSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::simRefreshInd(int slotId, int indicationType,
+                         int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_SimRefreshResponse_v7)) {
+            RLOGE("simRefreshInd: invalid response");
+            return 0;
+        }
+
+        SimRefreshResult refreshResult = {};
+        RIL_SimRefreshResponse_v7 *simRefreshResponse = ((RIL_SimRefreshResponse_v7 *) response);
+        refreshResult.type =
+                (V1_0::SimRefreshType) simRefreshResponse->result;
+        refreshResult.efId = simRefreshResponse->ef_id;
+        refreshResult.aid = convertCharPtrToHidlString(simRefreshResponse->aid);
+
+#if VDBG
+        RLOGD("simRefreshInd: type %d efId %d", refreshResult.type, refreshResult.efId);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->simRefresh(
+                convertIntToRadioIndicationType(indicationType), refreshResult);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("simRefreshInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+void convertRilCdmaSignalInfoRecordToHal(RIL_CDMA_SignalInfoRecord *signalInfoRecord,
+        CdmaSignalInfoRecord& record) {
+    record.isPresent = signalInfoRecord->isPresent;
+    record.signalType = signalInfoRecord->signalType;
+    record.alertPitch = signalInfoRecord->alertPitch;
+    record.signal = signalInfoRecord->signal;
+}
+
+int radio_1_4::callRingInd(int slotId, int indicationType,
+                       int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        bool isGsm;
+        CdmaSignalInfoRecord record = {};
+        if (response == NULL || responseLen == 0) {
+            isGsm = true;
+        } else {
+            isGsm = false;
+            if (responseLen != sizeof (RIL_CDMA_SignalInfoRecord)) {
+                RLOGE("callRingInd: invalid response");
+                return 0;
+            }
+            convertRilCdmaSignalInfoRecordToHal((RIL_CDMA_SignalInfoRecord *) response, record);
+        }
+
+#if VDBG
+        RLOGD("callRingInd: isGsm %d", isGsm);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->callRing(
+                convertIntToRadioIndicationType(indicationType), isGsm, record);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("callRingInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::simStatusChangedInd(int slotId,
+                               int indicationType, int token, RIL_Errno e, void *response,
+                               size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("simStatusChangedInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->simStatusChanged(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("simStatusChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::cdmaNewSmsInd(int slotId, int indicationType,
+                         int token, RIL_Errno e, void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_CDMA_SMS_Message)) {
+            RLOGE("cdmaNewSmsInd: invalid response");
+            return 0;
+        }
+
+        CdmaSmsMessage msg = {};
+        RIL_CDMA_SMS_Message *rilMsg = (RIL_CDMA_SMS_Message *) response;
+        msg.teleserviceId = rilMsg->uTeleserviceID;
+        msg.isServicePresent = rilMsg->bIsServicePresent;
+        msg.serviceCategory = rilMsg->uServicecategory;
+        msg.address.digitMode =
+                (V1_0::CdmaSmsDigitMode) rilMsg->sAddress.digit_mode;
+        msg.address.numberMode =
+                (V1_0::CdmaSmsNumberMode) rilMsg->sAddress.number_mode;
+        msg.address.numberType =
+                (V1_0::CdmaSmsNumberType) rilMsg->sAddress.number_type;
+        msg.address.numberPlan =
+                (V1_0::CdmaSmsNumberPlan) rilMsg->sAddress.number_plan;
+
+        int digitLimit = MIN((rilMsg->sAddress.number_of_digits), RIL_CDMA_SMS_ADDRESS_MAX);
+        msg.address.digits.setToExternal(rilMsg->sAddress.digits, digitLimit);
+
+        msg.subAddress.subaddressType = (V1_0::CdmaSmsSubaddressType)
+                rilMsg->sSubAddress.subaddressType;
+        msg.subAddress.odd = rilMsg->sSubAddress.odd;
+
+        digitLimit= MIN((rilMsg->sSubAddress.number_of_digits), RIL_CDMA_SMS_SUBADDRESS_MAX);
+        msg.subAddress.digits.setToExternal(rilMsg->sSubAddress.digits, digitLimit);
+
+        digitLimit = MIN((rilMsg->uBearerDataLen), RIL_CDMA_SMS_BEARER_DATA_MAX);
+        msg.bearerData.setToExternal(rilMsg->aBearerData, digitLimit);
+
+#if VDBG
+        RLOGD("cdmaNewSmsInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaNewSms(
+                convertIntToRadioIndicationType(indicationType), msg);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("cdmaNewSmsInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::newBroadcastSmsInd(int slotId,
+                              int indicationType, int token, RIL_Errno e, void *response,
+                              size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("newBroadcastSmsInd: invalid response");
+            return 0;
+        }
+
+        hidl_vec<uint8_t> data;
+        data.setToExternal((uint8_t *) response, responseLen);
+#if VDBG
+        RLOGD("newBroadcastSmsInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->newBroadcastSms(
+                convertIntToRadioIndicationType(indicationType), data);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("newBroadcastSmsInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::cdmaRuimSmsStorageFullInd(int slotId,
+                                     int indicationType, int token, RIL_Errno e, void *response,
+                                     size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("cdmaRuimSmsStorageFullInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaRuimSmsStorageFull(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("cdmaRuimSmsStorageFullInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::restrictedStateChangedInd(int slotId,
+                                     int indicationType, int token, RIL_Errno e, void *response,
+                                     size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("restrictedStateChangedInd: invalid response");
+            return 0;
+        }
+        int32_t state = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("restrictedStateChangedInd: state %d", state);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->restrictedStateChanged(
+                convertIntToRadioIndicationType(indicationType), (PhoneRestrictedState) state);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("restrictedStateChangedInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::enterEmergencyCallbackModeInd(int slotId,
+                                         int indicationType, int token, RIL_Errno e, void *response,
+                                         size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("enterEmergencyCallbackModeInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->enterEmergencyCallbackMode(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("enterEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::cdmaCallWaitingInd(int slotId,
+                              int indicationType, int token, RIL_Errno e, void *response,
+                              size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_CDMA_CallWaiting_v6)) {
+            RLOGE("cdmaCallWaitingInd: invalid response");
+            return 0;
+        }
+
+        CdmaCallWaiting callWaitingRecord = {};
+        RIL_CDMA_CallWaiting_v6 *callWaitingRil = ((RIL_CDMA_CallWaiting_v6 *) response);
+        callWaitingRecord.number = convertCharPtrToHidlString(callWaitingRil->number);
+        callWaitingRecord.numberPresentation =
+                (CdmaCallWaitingNumberPresentation) callWaitingRil->numberPresentation;
+        callWaitingRecord.name = convertCharPtrToHidlString(callWaitingRil->name);
+        convertRilCdmaSignalInfoRecordToHal(&callWaitingRil->signalInfoRecord,
+                callWaitingRecord.signalInfoRecord);
+        callWaitingRecord.numberType = (CdmaCallWaitingNumberType) callWaitingRil->number_type;
+        callWaitingRecord.numberPlan = (CdmaCallWaitingNumberPlan) callWaitingRil->number_plan;
+
+#if VDBG
+        RLOGD("cdmaCallWaitingInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaCallWaiting(
+                convertIntToRadioIndicationType(indicationType), callWaitingRecord);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("cdmaCallWaitingInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::cdmaOtaProvisionStatusInd(int slotId,
+                                     int indicationType, int token, RIL_Errno e, void *response,
+                                     size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("cdmaOtaProvisionStatusInd: invalid response");
+            return 0;
+        }
+        int32_t status = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("cdmaOtaProvisionStatusInd: status %d", status);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaOtaProvisionStatus(
+                convertIntToRadioIndicationType(indicationType), (CdmaOtaProvisionStatus) status);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("cdmaOtaProvisionStatusInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::cdmaInfoRecInd(int slotId,
+                          int indicationType, int token, RIL_Errno e, void *response,
+                          size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_CDMA_InformationRecords)) {
+            RLOGE("cdmaInfoRecInd: invalid response");
+            return 0;
+        }
+
+        CdmaInformationRecords records = {};
+        RIL_CDMA_InformationRecords *recordsRil = (RIL_CDMA_InformationRecords *) response;
+
+        char* string8 = NULL;
+        int num = MIN(recordsRil->numberOfInfoRecs, RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
+        if (recordsRil->numberOfInfoRecs > RIL_CDMA_MAX_NUMBER_OF_INFO_RECS) {
+            RLOGE("cdmaInfoRecInd: received %d recs which is more than %d, dropping "
+                    "additional ones", recordsRil->numberOfInfoRecs,
+                    RIL_CDMA_MAX_NUMBER_OF_INFO_RECS);
+        }
+        records.infoRec.resize(num);
+        for (int i = 0 ; i < num ; i++) {
+            CdmaInformationRecord *record = &records.infoRec[i];
+            RIL_CDMA_InformationRecord *infoRec = &recordsRil->infoRec[i];
+            record->name = (CdmaInfoRecName) infoRec->name;
+            // All vectors should be size 0 except one which will be size 1. Set everything to
+            // size 0 initially.
+            record->display.resize(0);
+            record->number.resize(0);
+            record->signal.resize(0);
+            record->redir.resize(0);
+            record->lineCtrl.resize(0);
+            record->clir.resize(0);
+            record->audioCtrl.resize(0);
+            switch (infoRec->name) {
+                case RIL_CDMA_DISPLAY_INFO_REC:
+                case RIL_CDMA_EXTENDED_DISPLAY_INFO_REC: {
+                    if (infoRec->rec.display.alpha_len > CDMA_ALPHA_INFO_BUFFER_LENGTH) {
+                        RLOGE("cdmaInfoRecInd: invalid display info response length %d "
+                                "expected not more than %d", (int) infoRec->rec.display.alpha_len,
+                                CDMA_ALPHA_INFO_BUFFER_LENGTH);
+                        return 0;
+                    }
+                    string8 = (char*) malloc((infoRec->rec.display.alpha_len + 1) * sizeof(char));
+                    if (string8 == NULL) {
+                        RLOGE("cdmaInfoRecInd: Memory allocation failed for "
+                                "responseCdmaInformationRecords");
+                        return 0;
+                    }
+                    memcpy(string8, infoRec->rec.display.alpha_buf, infoRec->rec.display.alpha_len);
+                    string8[(int)infoRec->rec.display.alpha_len] = '\0';
+
+                    record->display.resize(1);
+                    record->display[0].alphaBuf = string8;
+                    free(string8);
+                    string8 = NULL;
+                    break;
+                }
+
+                case RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
+                case RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
+                case RIL_CDMA_CONNECTED_NUMBER_INFO_REC: {
+                    if (infoRec->rec.number.len > CDMA_NUMBER_INFO_BUFFER_LENGTH) {
+                        RLOGE("cdmaInfoRecInd: invalid display info response length %d "
+                                "expected not more than %d", (int) infoRec->rec.number.len,
+                                CDMA_NUMBER_INFO_BUFFER_LENGTH);
+                        return 0;
+                    }
+                    string8 = (char*) malloc((infoRec->rec.number.len + 1) * sizeof(char));
+                    if (string8 == NULL) {
+                        RLOGE("cdmaInfoRecInd: Memory allocation failed for "
+                                "responseCdmaInformationRecords");
+                        return 0;
+                    }
+                    memcpy(string8, infoRec->rec.number.buf, infoRec->rec.number.len);
+                    string8[(int)infoRec->rec.number.len] = '\0';
+
+                    record->number.resize(1);
+                    record->number[0].number = string8;
+                    free(string8);
+                    string8 = NULL;
+                    record->number[0].numberType = infoRec->rec.number.number_type;
+                    record->number[0].numberPlan = infoRec->rec.number.number_plan;
+                    record->number[0].pi = infoRec->rec.number.pi;
+                    record->number[0].si = infoRec->rec.number.si;
+                    break;
+                }
+
+                case RIL_CDMA_SIGNAL_INFO_REC: {
+                    record->signal.resize(1);
+                    record->signal[0].isPresent = infoRec->rec.signal.isPresent;
+                    record->signal[0].signalType = infoRec->rec.signal.signalType;
+                    record->signal[0].alertPitch = infoRec->rec.signal.alertPitch;
+                    record->signal[0].signal = infoRec->rec.signal.signal;
+                    break;
+                }
+
+                case RIL_CDMA_REDIRECTING_NUMBER_INFO_REC: {
+                    if (infoRec->rec.redir.redirectingNumber.len >
+                                                  CDMA_NUMBER_INFO_BUFFER_LENGTH) {
+                        RLOGE("cdmaInfoRecInd: invalid display info response length %d "
+                                "expected not more than %d\n",
+                                (int)infoRec->rec.redir.redirectingNumber.len,
+                                CDMA_NUMBER_INFO_BUFFER_LENGTH);
+                        return 0;
+                    }
+                    string8 = (char*) malloc((infoRec->rec.redir.redirectingNumber.len + 1) *
+                            sizeof(char));
+                    if (string8 == NULL) {
+                        RLOGE("cdmaInfoRecInd: Memory allocation failed for "
+                                "responseCdmaInformationRecords");
+                        return 0;
+                    }
+                    memcpy(string8, infoRec->rec.redir.redirectingNumber.buf,
+                            infoRec->rec.redir.redirectingNumber.len);
+                    string8[(int)infoRec->rec.redir.redirectingNumber.len] = '\0';
+
+                    record->redir.resize(1);
+                    record->redir[0].redirectingNumber.number = string8;
+                    free(string8);
+                    string8 = NULL;
+                    record->redir[0].redirectingNumber.numberType =
+                            infoRec->rec.redir.redirectingNumber.number_type;
+                    record->redir[0].redirectingNumber.numberPlan =
+                            infoRec->rec.redir.redirectingNumber.number_plan;
+                    record->redir[0].redirectingNumber.pi = infoRec->rec.redir.redirectingNumber.pi;
+                    record->redir[0].redirectingNumber.si = infoRec->rec.redir.redirectingNumber.si;
+                    record->redir[0].redirectingReason =
+                            (CdmaRedirectingReason) infoRec->rec.redir.redirectingReason;
+                    break;
+                }
+
+                case RIL_CDMA_LINE_CONTROL_INFO_REC: {
+                    record->lineCtrl.resize(1);
+                    record->lineCtrl[0].lineCtrlPolarityIncluded =
+                            infoRec->rec.lineCtrl.lineCtrlPolarityIncluded;
+                    record->lineCtrl[0].lineCtrlToggle = infoRec->rec.lineCtrl.lineCtrlToggle;
+                    record->lineCtrl[0].lineCtrlReverse = infoRec->rec.lineCtrl.lineCtrlReverse;
+                    record->lineCtrl[0].lineCtrlPowerDenial =
+                            infoRec->rec.lineCtrl.lineCtrlPowerDenial;
+                    break;
+                }
+
+                case RIL_CDMA_T53_CLIR_INFO_REC: {
+                    record->clir.resize(1);
+                    record->clir[0].cause = infoRec->rec.clir.cause;
+                    break;
+                }
+
+                case RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC: {
+                    record->audioCtrl.resize(1);
+                    record->audioCtrl[0].upLink = infoRec->rec.audioCtrl.upLink;
+                    record->audioCtrl[0].downLink = infoRec->rec.audioCtrl.downLink;
+                    break;
+                }
+
+                case RIL_CDMA_T53_RELEASE_INFO_REC:
+                    RLOGE("cdmaInfoRecInd: RIL_CDMA_T53_RELEASE_INFO_REC: INVALID");
+                    return 0;
+
+                default:
+                    RLOGE("cdmaInfoRecInd: Incorrect name value");
+                    return 0;
+            }
+        }
+
+#if VDBG
+        RLOGD("cdmaInfoRecInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaInfoRec(
+                convertIntToRadioIndicationType(indicationType), records);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("cdmaInfoRecInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::indicateRingbackToneInd(int slotId,
+                                   int indicationType, int token, RIL_Errno e, void *response,
+                                   size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("indicateRingbackToneInd: invalid response");
+            return 0;
+        }
+        bool start = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("indicateRingbackToneInd: start %d", start);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->indicateRingbackTone(
+                convertIntToRadioIndicationType(indicationType), start);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("indicateRingbackToneInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::resendIncallMuteInd(int slotId,
+                               int indicationType, int token, RIL_Errno e, void *response,
+                               size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("resendIncallMuteInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->resendIncallMute(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("resendIncallMuteInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::cdmaSubscriptionSourceChangedInd(int slotId,
+                                            int indicationType, int token, RIL_Errno e,
+                                            void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("cdmaSubscriptionSourceChangedInd: invalid response");
+            return 0;
+        }
+        int32_t cdmaSource = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("cdmaSubscriptionSourceChangedInd: cdmaSource %d", cdmaSource);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->
+                cdmaSubscriptionSourceChanged(convertIntToRadioIndicationType(indicationType),
+                (CdmaSubscriptionSource) cdmaSource);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("cdmaSubscriptionSourceChangedInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::cdmaPrlChangedInd(int slotId,
+                             int indicationType, int token, RIL_Errno e, void *response,
+                             size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("cdmaPrlChangedInd: invalid response");
+            return 0;
+        }
+        int32_t version = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("cdmaPrlChangedInd: version %d", version);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->cdmaPrlChanged(
+                convertIntToRadioIndicationType(indicationType), version);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("cdmaPrlChangedInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::exitEmergencyCallbackModeInd(int slotId,
+                                        int indicationType, int token, RIL_Errno e, void *response,
+                                        size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("exitEmergencyCallbackModeInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->exitEmergencyCallbackMode(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("exitEmergencyCallbackModeInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::rilConnectedInd(int slotId,
+                           int indicationType, int token, RIL_Errno e, void *response,
+                           size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        RLOGD("rilConnectedInd");
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->rilConnected(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("rilConnectedInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::voiceRadioTechChangedInd(int slotId,
+                                    int indicationType, int token, RIL_Errno e, void *response,
+                                    size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("voiceRadioTechChangedInd: invalid response");
+            return 0;
+        }
+        int32_t rat = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("voiceRadioTechChangedInd: rat %d", rat);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->voiceRadioTechChanged(
+                convertIntToRadioIndicationType(indicationType), (RadioTechnology) rat);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("voiceRadioTechChangedInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<CellInfo>& records) {
+    int num = responseLen / sizeof(RIL_CellInfo_v12);
+    records.resize(num);
+
+    RIL_CellInfo_v12 *rillCellInfo = (RIL_CellInfo_v12 *) response;
+    for (int i = 0; i < num; i++) {
+        records[i].cellInfoType = (CellInfoType) rillCellInfo->cellInfoType;
+        records[i].registered = rillCellInfo->registered;
+        records[i].timeStampType = (TimeStampType) rillCellInfo->timeStampType;
+        records[i].timeStamp = rillCellInfo->timeStamp;
+        // All vectors should be size 0 except one which will be size 1. Set everything to
+        // size 0 initially.
+        records[i].gsm.resize(0);
+        records[i].wcdma.resize(0);
+        records[i].cdma.resize(0);
+        records[i].lte.resize(0);
+        records[i].tdscdma.resize(0);
+        switch(rillCellInfo->cellInfoType) {
+            case RIL_CELL_INFO_TYPE_GSM: {
+                records[i].gsm.resize(1);
+                CellInfoGsm *cellInfoGsm = &records[i].gsm[0];
+                cellInfoGsm->cellIdentityGsm.mcc =
+                        std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mcc);
+                cellInfoGsm->cellIdentityGsm.mnc =
+                        ril::util::mnc::decode(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mnc);
+                cellInfoGsm->cellIdentityGsm.lac =
+                        rillCellInfo->CellInfo.gsm.cellIdentityGsm.lac;
+                cellInfoGsm->cellIdentityGsm.cid =
+                        rillCellInfo->CellInfo.gsm.cellIdentityGsm.cid;
+                cellInfoGsm->cellIdentityGsm.arfcn =
+                        rillCellInfo->CellInfo.gsm.cellIdentityGsm.arfcn;
+                cellInfoGsm->cellIdentityGsm.bsic =
+                        rillCellInfo->CellInfo.gsm.cellIdentityGsm.bsic;
+                cellInfoGsm->signalStrengthGsm.signalStrength =
+                        rillCellInfo->CellInfo.gsm.signalStrengthGsm.signalStrength;
+                cellInfoGsm->signalStrengthGsm.bitErrorRate =
+                        rillCellInfo->CellInfo.gsm.signalStrengthGsm.bitErrorRate;
+                cellInfoGsm->signalStrengthGsm.timingAdvance =
+                        rillCellInfo->CellInfo.gsm.signalStrengthGsm.timingAdvance;
+                break;
+            }
+
+            case RIL_CELL_INFO_TYPE_WCDMA: {
+                records[i].wcdma.resize(1);
+                CellInfoWcdma *cellInfoWcdma = &records[i].wcdma[0];
+                cellInfoWcdma->cellIdentityWcdma.mcc =
+                        std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mcc);
+                cellInfoWcdma->cellIdentityWcdma.mnc =
+                        ril::util::mnc::decode(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mnc);
+                cellInfoWcdma->cellIdentityWcdma.lac =
+                        rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.lac;
+                cellInfoWcdma->cellIdentityWcdma.cid =
+                        rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.cid;
+                cellInfoWcdma->cellIdentityWcdma.psc =
+                        rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.psc;
+                cellInfoWcdma->cellIdentityWcdma.uarfcn =
+                        rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.uarfcn;
+                cellInfoWcdma->signalStrengthWcdma.signalStrength =
+                        rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.signalStrength;
+                cellInfoWcdma->signalStrengthWcdma.bitErrorRate =
+                        rillCellInfo->CellInfo.wcdma.signalStrengthWcdma.bitErrorRate;
+                break;
+            }
+
+            case RIL_CELL_INFO_TYPE_CDMA: {
+                records[i].cdma.resize(1);
+                CellInfoCdma *cellInfoCdma = &records[i].cdma[0];
+                cellInfoCdma->cellIdentityCdma.networkId =
+                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.networkId;
+                cellInfoCdma->cellIdentityCdma.systemId =
+                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.systemId;
+                cellInfoCdma->cellIdentityCdma.baseStationId =
+                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.basestationId;
+                cellInfoCdma->cellIdentityCdma.longitude =
+                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.longitude;
+                cellInfoCdma->cellIdentityCdma.latitude =
+                        rillCellInfo->CellInfo.cdma.cellIdentityCdma.latitude;
+                cellInfoCdma->signalStrengthCdma.dbm =
+                        rillCellInfo->CellInfo.cdma.signalStrengthCdma.dbm;
+                cellInfoCdma->signalStrengthCdma.ecio =
+                        rillCellInfo->CellInfo.cdma.signalStrengthCdma.ecio;
+                cellInfoCdma->signalStrengthEvdo.dbm =
+                        rillCellInfo->CellInfo.cdma.signalStrengthEvdo.dbm;
+                cellInfoCdma->signalStrengthEvdo.ecio =
+                        rillCellInfo->CellInfo.cdma.signalStrengthEvdo.ecio;
+                cellInfoCdma->signalStrengthEvdo.signalNoiseRatio =
+                        rillCellInfo->CellInfo.cdma.signalStrengthEvdo.signalNoiseRatio;
+                break;
+            }
+
+            case RIL_CELL_INFO_TYPE_LTE: {
+                records[i].lte.resize(1);
+                CellInfoLte *cellInfoLte = &records[i].lte[0];
+                cellInfoLte->cellIdentityLte.mcc =
+                        std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mcc);
+                cellInfoLte->cellIdentityLte.mnc =
+                        ril::util::mnc::decode(rillCellInfo->CellInfo.lte.cellIdentityLte.mnc);
+                cellInfoLte->cellIdentityLte.ci =
+                        rillCellInfo->CellInfo.lte.cellIdentityLte.ci;
+                cellInfoLte->cellIdentityLte.pci =
+                        rillCellInfo->CellInfo.lte.cellIdentityLte.pci;
+                cellInfoLte->cellIdentityLte.tac =
+                        rillCellInfo->CellInfo.lte.cellIdentityLte.tac;
+                cellInfoLte->cellIdentityLte.earfcn =
+                        rillCellInfo->CellInfo.lte.cellIdentityLte.earfcn;
+                cellInfoLte->signalStrengthLte.signalStrength =
+                        rillCellInfo->CellInfo.lte.signalStrengthLte.signalStrength;
+                cellInfoLte->signalStrengthLte.rsrp =
+                        rillCellInfo->CellInfo.lte.signalStrengthLte.rsrp;
+                cellInfoLte->signalStrengthLte.rsrq =
+                        rillCellInfo->CellInfo.lte.signalStrengthLte.rsrq;
+                cellInfoLte->signalStrengthLte.rssnr =
+                        rillCellInfo->CellInfo.lte.signalStrengthLte.rssnr;
+                cellInfoLte->signalStrengthLte.cqi =
+                        rillCellInfo->CellInfo.lte.signalStrengthLte.cqi;
+                cellInfoLte->signalStrengthLte.timingAdvance =
+                        rillCellInfo->CellInfo.lte.signalStrengthLte.timingAdvance;
+                break;
+            }
+
+            case RIL_CELL_INFO_TYPE_TD_SCDMA: {
+                records[i].tdscdma.resize(1);
+                CellInfoTdscdma *cellInfoTdscdma = &records[i].tdscdma[0];
+                cellInfoTdscdma->cellIdentityTdscdma.mcc =
+                        std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
+                cellInfoTdscdma->cellIdentityTdscdma.mnc =
+                        ril::util::mnc::decode(
+                                rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
+                cellInfoTdscdma->cellIdentityTdscdma.lac =
+                        rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.lac;
+                cellInfoTdscdma->cellIdentityTdscdma.cid =
+                        rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cid;
+                cellInfoTdscdma->cellIdentityTdscdma.cpid =
+                        rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.cpid;
+                cellInfoTdscdma->signalStrengthTdscdma.rscp =
+                        rillCellInfo->CellInfo.tdscdma.signalStrengthTdscdma.rscp;
+                break;
+            }
+            default: {
+                break;
+            }
+        }
+        rillCellInfo += 1;
+    }
+}
+
+int radio_1_4::cellInfoListInd(int slotId,
+                           int indicationType, int token, RIL_Errno e, void *response,
+                           size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if ((response == NULL && responseLen != 0) || responseLen % sizeof(RIL_CellInfo_v12) != 0) {
+            RLOGE("cellInfoListInd: invalid response");
+            return 0;
+        }
+
+        hidl_vec<CellInfo> records;
+        convertRilCellInfoListToHal(response, responseLen, records);
+
+#if VDBG
+        RLOGD("cellInfoListInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->cellInfoList(
+                convertIntToRadioIndicationType(indicationType), records);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("cellInfoListInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::imsNetworkStateChangedInd(int slotId,
+                                     int indicationType, int token, RIL_Errno e, void *response,
+                                     size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+#if VDBG
+        RLOGD("imsNetworkStateChangedInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->imsNetworkStateChanged(
+                convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("imsNetworkStateChangedInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::subscriptionStatusChangedInd(int slotId,
+                                        int indicationType, int token, RIL_Errno e, void *response,
+                                        size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("subscriptionStatusChangedInd: invalid response");
+            return 0;
+        }
+        bool activate = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("subscriptionStatusChangedInd: activate %d", activate);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->subscriptionStatusChanged(
+                convertIntToRadioIndicationType(indicationType), activate);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("subscriptionStatusChangedInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::srvccStateNotifyInd(int slotId,
+                               int indicationType, int token, RIL_Errno e, void *response,
+                               size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(int)) {
+            RLOGE("srvccStateNotifyInd: invalid response");
+            return 0;
+        }
+        int32_t state = ((int32_t *) response)[0];
+#if VDBG
+        RLOGD("srvccStateNotifyInd: rat %d", state);
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->srvccStateNotify(
+                convertIntToRadioIndicationType(indicationType), (SrvccState) state);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("srvccStateNotifyInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+void convertRilHardwareConfigListToHal(void *response, size_t responseLen,
+        hidl_vec<HardwareConfig>& records) {
+    int num = responseLen / sizeof(RIL_HardwareConfig);
+    records.resize(num);
+
+    RIL_HardwareConfig *rilHardwareConfig = (RIL_HardwareConfig *) response;
+    for (int i = 0; i < num; i++) {
+        records[i].type = (HardwareConfigType) rilHardwareConfig[i].type;
+        records[i].uuid = convertCharPtrToHidlString(rilHardwareConfig[i].uuid);
+        records[i].state = (HardwareConfigState) rilHardwareConfig[i].state;
+        switch (rilHardwareConfig[i].type) {
+            case RIL_HARDWARE_CONFIG_MODEM: {
+                records[i].modem.resize(1);
+                records[i].sim.resize(0);
+                HardwareConfigModem *hwConfigModem = &records[i].modem[0];
+                hwConfigModem->rat = rilHardwareConfig[i].cfg.modem.rat;
+                hwConfigModem->maxVoice = rilHardwareConfig[i].cfg.modem.maxVoice;
+                hwConfigModem->maxData = rilHardwareConfig[i].cfg.modem.maxData;
+                hwConfigModem->maxStandby = rilHardwareConfig[i].cfg.modem.maxStandby;
+                break;
+            }
+
+            case RIL_HARDWARE_CONFIG_SIM: {
+                records[i].sim.resize(1);
+                records[i].modem.resize(0);
+                records[i].sim[0].modemUuid =
+                        convertCharPtrToHidlString(rilHardwareConfig[i].cfg.sim.modemUuid);
+                break;
+            }
+        }
+    }
+}
+
+int radio_1_4::hardwareConfigChangedInd(int slotId,
+                                    int indicationType, int token, RIL_Errno e, void *response,
+                                    size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if ((response == NULL && responseLen != 0)
+                || responseLen % sizeof(RIL_HardwareConfig) != 0) {
+            RLOGE("hardwareConfigChangedInd: invalid response");
+            return 0;
+        }
+
+        hidl_vec<HardwareConfig> configs;
+        convertRilHardwareConfigListToHal(response, responseLen, configs);
+
+#if VDBG
+        RLOGD("hardwareConfigChangedInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->hardwareConfigChanged(
+                convertIntToRadioIndicationType(indicationType), configs);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("hardwareConfigChangedInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+void convertRilRadioCapabilityToHal(void *response, size_t responseLen, RadioCapability& rc) {
+    RIL_RadioCapability *rilRadioCapability = (RIL_RadioCapability *) response;
+    rc.session = rilRadioCapability->session;
+    rc.phase = (V1_0::RadioCapabilityPhase) rilRadioCapability->phase;
+    rc.raf = rilRadioCapability->rat;
+    rc.logicalModemUuid = convertCharPtrToHidlString(rilRadioCapability->logicalModemUuid);
+    rc.status = (V1_0::RadioCapabilityStatus) rilRadioCapability->status;
+}
+
+int radio_1_4::radioCapabilityIndicationInd(int slotId,
+                                        int indicationType, int token, RIL_Errno e, void *response,
+                                        size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_RadioCapability)) {
+            RLOGE("radioCapabilityIndicationInd: invalid response");
+            return 0;
+        }
+
+        RadioCapability rc = {};
+        convertRilRadioCapabilityToHal(response, responseLen, rc);
+
+#if VDBG
+        RLOGD("radioCapabilityIndicationInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->radioCapabilityIndication(
+                convertIntToRadioIndicationType(indicationType), rc);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("radioCapabilityIndicationInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType) {
+    if ((reqType == SS_INTERROGATION) &&
+        (serType == SS_CFU ||
+         serType == SS_CF_BUSY ||
+         serType == SS_CF_NO_REPLY ||
+         serType == SS_CF_NOT_REACHABLE ||
+         serType == SS_CF_ALL ||
+         serType == SS_CF_ALL_CONDITIONAL)) {
+        return true;
+    }
+    return false;
+}
+
+int radio_1_4::onSupplementaryServiceIndicationInd(int slotId,
+                                               int indicationType, int token, RIL_Errno e,
+                                               void *response, size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_StkCcUnsolSsResponse)) {
+            RLOGE("onSupplementaryServiceIndicationInd: invalid response");
+            return 0;
+        }
+
+        RIL_StkCcUnsolSsResponse *rilSsResponse = (RIL_StkCcUnsolSsResponse *) response;
+        StkCcUnsolSsResult ss = {};
+        ss.serviceType = (SsServiceType) rilSsResponse->serviceType;
+        ss.requestType = (SsRequestType) rilSsResponse->requestType;
+        ss.teleserviceType = (SsTeleserviceType) rilSsResponse->teleserviceType;
+        ss.serviceClass = rilSsResponse->serviceClass;
+        ss.result = (RadioError) rilSsResponse->result;
+
+        if (isServiceTypeCfQuery(rilSsResponse->serviceType, rilSsResponse->requestType)) {
+#if VDBG
+            RLOGD("onSupplementaryServiceIndicationInd CF type, num of Cf elements %d",
+                    rilSsResponse->cfData.numValidIndexes);
+#endif
+            if (rilSsResponse->cfData.numValidIndexes > NUM_SERVICE_CLASSES) {
+                RLOGE("onSupplementaryServiceIndicationInd numValidIndexes is greater than "
+                        "max value %d, truncating it to max value", NUM_SERVICE_CLASSES);
+                rilSsResponse->cfData.numValidIndexes = NUM_SERVICE_CLASSES;
+            }
+
+            ss.cfData.resize(1);
+            ss.ssInfo.resize(0);
+
+            /* number of call info's */
+            ss.cfData[0].cfInfo.resize(rilSsResponse->cfData.numValidIndexes);
+
+            for (int i = 0; i < rilSsResponse->cfData.numValidIndexes; i++) {
+                 RIL_CallForwardInfo cf = rilSsResponse->cfData.cfInfo[i];
+                 CallForwardInfo *cfInfo = &ss.cfData[0].cfInfo[i];
+
+                 cfInfo->status = (CallForwardInfoStatus) cf.status;
+                 cfInfo->reason = cf.reason;
+                 cfInfo->serviceClass = cf.serviceClass;
+                 cfInfo->toa = cf.toa;
+                 cfInfo->number = convertCharPtrToHidlString(cf.number);
+                 cfInfo->timeSeconds = cf.timeSeconds;
+#if VDBG
+                 RLOGD("onSupplementaryServiceIndicationInd: "
+                        "Data: %d,reason=%d,cls=%d,toa=%d,num=%s,tout=%d],", cf.status,
+                        cf.reason, cf.serviceClass, cf.toa, (char*)cf.number, cf.timeSeconds);
+#endif
+            }
+        } else {
+            ss.ssInfo.resize(1);
+            ss.cfData.resize(0);
+
+            /* each int */
+            ss.ssInfo[0].ssInfo.resize(SS_INFO_MAX);
+            for (int i = 0; i < SS_INFO_MAX; i++) {
+#if VDBG
+                 RLOGD("onSupplementaryServiceIndicationInd: Data: %d",
+                        rilSsResponse->ssInfo[i]);
+#endif
+                 ss.ssInfo[0].ssInfo[i] = rilSsResponse->ssInfo[i];
+            }
+        }
+
+#if VDBG
+        RLOGD("onSupplementaryServiceIndicationInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->
+                onSupplementaryServiceIndication(convertIntToRadioIndicationType(indicationType),
+                ss);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("onSupplementaryServiceIndicationInd: "
+                "radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::stkCallControlAlphaNotifyInd(int slotId,
+                                        int indicationType, int token, RIL_Errno e, void *response,
+                                        size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("stkCallControlAlphaNotifyInd: invalid response");
+            return 0;
+        }
+#if VDBG
+        RLOGD("stkCallControlAlphaNotifyInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->stkCallControlAlphaNotify(
+                convertIntToRadioIndicationType(indicationType),
+                convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("stkCallControlAlphaNotifyInd: radioService[%d]->mRadioIndication == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+void convertRilLceDataInfoToHal(void *response, size_t responseLen, LceDataInfo& lce) {
+    RIL_LceDataInfo *rilLceDataInfo = (RIL_LceDataInfo *)response;
+    lce.lastHopCapacityKbps = rilLceDataInfo->last_hop_capacity_kbps;
+    lce.confidenceLevel = rilLceDataInfo->confidence_level;
+    lce.lceSuspended = rilLceDataInfo->lce_suspended;
+}
+
+int radio_1_4::lceDataInd(int slotId,
+                      int indicationType, int token, RIL_Errno e, void *response,
+                      size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_LceDataInfo)) {
+            RLOGE("lceDataInd: invalid response");
+            return 0;
+        }
+
+        LceDataInfo lce = {};
+        convertRilLceDataInfoToHal(response, responseLen, lce);
+#if VDBG
+        RLOGD("lceDataInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->lceData(
+                convertIntToRadioIndicationType(indicationType), lce);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("lceDataInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::pcoDataInd(int slotId,
+                      int indicationType, int token, RIL_Errno e, void *response,
+                      size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen != sizeof(RIL_PCO_Data)) {
+            RLOGE("pcoDataInd: invalid response");
+            return 0;
+        }
+
+        PcoDataInfo pco = {};
+        RIL_PCO_Data *rilPcoData = (RIL_PCO_Data *)response;
+        pco.cid = rilPcoData->cid;
+        pco.bearerProto = convertCharPtrToHidlString(rilPcoData->bearer_proto);
+        pco.pcoId = rilPcoData->pco_id;
+        pco.contents.setToExternal((uint8_t *) rilPcoData->contents, rilPcoData->contents_length);
+
+#if VDBG
+        RLOGD("pcoDataInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->pcoData(
+                convertIntToRadioIndicationType(indicationType), pco);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("pcoDataInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::modemResetInd(int slotId,
+                         int indicationType, int token, RIL_Errno e, void *response,
+                         size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("modemResetInd: invalid response");
+            return 0;
+        }
+#if VDBG
+        RLOGD("modemResetInd");
+#endif
+        Return<void> retStatus = radioService[slotId]->mRadioIndication->modemReset(
+                convertIntToRadioIndicationType(indicationType),
+                convertCharPtrToHidlString((char *) response));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("modemResetInd: radioService[%d]->mRadioIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::networkScanResultInd(int slotId,
+                                int indicationType, int token, RIL_Errno e, void *response,
+                                size_t responseLen) {
+#if VDBG
+    RLOGD("networkScanResultInd");
+#endif
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndicationV1_4 != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("networkScanResultInd: invalid response");
+            return 0;
+        }
+        RLOGD("networkScanResultInd");
+
+#if VDBG
+        RLOGD("networkScanResultInd");
+#endif
+
+        RIL_NetworkScanResult *networkScanResult = (RIL_NetworkScanResult *) response;
+
+        V1_1::NetworkScanResult result;
+        result.status = (V1_1::ScanStatus) networkScanResult->status;
+        result.error = (RadioError) networkScanResult->error;
+        convertRilCellInfoListToHal(
+                networkScanResult->network_infos,
+                networkScanResult->network_infos_length * sizeof(RIL_CellInfo_v12),
+                result.networkInfos);
+
+        Return<void> retStatus = radioService[slotId]->mRadioIndicationV1_4->networkScanResult(
+                convertIntToRadioIndicationType(indicationType), result);
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("networkScanResultInd: radioService[%d]->mRadioIndicationV1_4 == NULL", slotId);
+    }
+    return 0;
+}
+
+int radio_1_4::carrierInfoForImsiEncryption(int slotId,
+                                  int indicationType, int token, RIL_Errno e, void *response,
+                                  size_t responseLen) {
+    if (radioService[slotId] != NULL && radioService[slotId]->mRadioIndicationV1_4 != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("carrierInfoForImsiEncryption: invalid response");
+            return 0;
+        }
+        RLOGD("carrierInfoForImsiEncryption");
+        Return<void> retStatus = radioService[slotId]->mRadioIndicationV1_4->
+                carrierInfoForImsiEncryption(convertIntToRadioIndicationType(indicationType));
+        radioService[slotId]->checkReturnStatus(retStatus);
+    } else {
+        RLOGE("carrierInfoForImsiEncryption: radioService[%d]->mRadioIndicationV1_4 == NULL",
+                slotId);
+    }
+
+    return 0;
+}
+
+int radio_1_4::keepaliveStatusInd(int slotId,
+                         int indicationType, int token, RIL_Errno e, void *response,
+                         size_t responseLen) {
+#if VDBG
+    RLOGD("%s(): token=%d", __FUNCTION__, token);
+#endif
+    if (radioService[slotId] == NULL || radioService[slotId]->mRadioIndication == NULL) {
+        RLOGE("%s: radioService[%d]->mRadioIndication == NULL", __FUNCTION__, slotId);
+        return 0;
+    }
+
+    auto ret = V1_1::IRadioIndication::castFrom(
+        radioService[slotId]->mRadioIndication);
+    if (!ret.isOk()) {
+        RLOGE("%s: ret.isOk() == false for radioService[%d]", __FUNCTION__, slotId);
+        return 0;
+    }
+    sp<V1_1::IRadioIndication> radioIndicationV1_1 = ret;
+
+    if (response == NULL || responseLen != sizeof(V1_1::KeepaliveStatus)) {
+        RLOGE("%s: invalid response", __FUNCTION__);
+        return 0;
+    }
+
+    V1_1::KeepaliveStatus ks;
+    convertRilKeepaliveStatusToHal(static_cast<RIL_KeepaliveStatus*>(response), ks);
+
+    Return<void> retStatus = radioIndicationV1_1->keepaliveStatus(
+            convertIntToRadioIndicationType(indicationType), ks);
+    radioService[slotId]->checkReturnStatus(retStatus);
+    return 0;
+}
+
+int radio_1_4::oemHookRawInd(int slotId,
+                         int indicationType, int token, RIL_Errno e, void *response,
+                         size_t responseLen) {
+    if (!kOemHookEnabled) return 0;
+
+    if (oemHookService[slotId] != NULL && oemHookService[slotId]->mOemHookIndication != NULL) {
+        if (response == NULL || responseLen == 0) {
+            RLOGE("oemHookRawInd: invalid response");
+            return 0;
+        }
+
+        hidl_vec<uint8_t> data;
+        data.setToExternal((uint8_t *) response, responseLen);
+#if VDBG
+        RLOGD("oemHookRawInd");
+#endif
+        Return<void> retStatus = oemHookService[slotId]->mOemHookIndication->oemHookRaw(
+                convertIntToRadioIndicationType(indicationType), data);
+        checkReturnStatus(slotId, retStatus, false);
+    } else {
+        RLOGE("oemHookRawInd: oemHookService[%d]->mOemHookIndication == NULL", slotId);
+    }
+
+    return 0;
+}
+
+void radio_1_4::registerService(RIL_RadioFunctions *callbacks, CommandInfo *commands) {
+    using namespace android::hardware;
+    int simCount = 1;
+    const char *serviceNames[] = {
+            android::RIL_getServiceName()
+            #if (SIM_COUNT >= 2)
+            , RIL2_SERVICE_NAME
+            #if (SIM_COUNT >= 3)
+            , RIL3_SERVICE_NAME
+            #if (SIM_COUNT >= 4)
+            , RIL4_SERVICE_NAME
+            #endif
+            #endif
+            #endif
+            };
+
+    #if (SIM_COUNT >= 2)
+    simCount = SIM_COUNT;
+    #endif
+
+    s_vendorFunctions = callbacks;
+    s_commands = commands;
+
+    configureRpcThreadpool(1, true /* callerWillJoin */);
+    for (int i = 0; i < simCount; i++) {
+        pthread_rwlock_t *radioServiceRwlockPtr = getRadioServiceRwlock(i);
+        int ret = pthread_rwlock_wrlock(radioServiceRwlockPtr);
+        assert(ret == 0);
+
+        RLOGD("sim i = %d registering ...", i);
+
+        radioService[i] = new RadioImpl_1_4;
+        radioService[i]->mSlotId = i;
+        RLOGD("registerService: starting android::hardware::radio::V1_4::IRadio %s for slot %d",
+                serviceNames[i], i);
+        android::status_t status = radioService[i]->registerAsService(serviceNames[i]);
+
+        RLOGD("registerService: OemHook is enabled = %s", kOemHookEnabled ? "true" : "false");
+        if (kOemHookEnabled) {
+            oemHookService[i] = new OemHookImpl;
+            oemHookService[i]->mSlotId = i;
+            status = oemHookService[i]->registerAsService(serviceNames[i]);
+        }
+
+        ret = pthread_rwlock_unlock(radioServiceRwlockPtr);
+        assert(ret == 0);
+    }
+}
+
+void rilc_thread_pool() {
+    joinRpcThreadpool();
+}
+
+pthread_rwlock_t * radio_1_4::getRadioServiceRwlock(int slotId) {
+    pthread_rwlock_t *radioServiceRwlockPtr = &radioServiceRwlock;
+
+    #if (SIM_COUNT >= 2)
+    if (slotId == 2) radioServiceRwlockPtr = &radioServiceRwlock2;
+    #if (SIM_COUNT >= 3)
+    if (slotId == 3) radioServiceRwlockPtr = &radioServiceRwlock3;
+    #if (SIM_COUNT >= 4)
+    if (slotId == 4) radioServiceRwlockPtr = &radioServiceRwlock4;
+    #endif
+    #endif
+    #endif
+
+    return radioServiceRwlockPtr;
+}
+
+// should acquire write lock for the corresponding service before calling this
+void radio_1_4::setNitzTimeReceived(int slotId, long timeReceived) {
+    nitzTimeReceived[slotId] = timeReceived;
+}
diff --git a/guest/hals/ril/libril/ril_service.h b/guest/hals/ril/libril/ril_service.h
new file mode 100644
index 0000000..fc19bcd
--- /dev/null
+++ b/guest/hals/ril/libril/ril_service.h
@@ -0,0 +1,787 @@
+/*
+ * Copyright (c) 2016 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 is 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.
+ */
+
+#ifndef RIL_SERVICE_H
+#define RIL_SERVICE_H
+
+#include <guest/hals/ril/libril/ril.h>
+#include <ril_internal.h>
+
+namespace radio_1_4 {
+void registerService(RIL_RadioFunctions *callbacks, android::CommandInfo *commands);
+
+int getIccCardStatusResponse(int slotId, int responseType,
+                            int token, RIL_Errno e, void *response, size_t responselen);
+
+int supplyIccPinForAppResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int supplyIccPukForAppResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int supplyIccPin2ForAppResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e, void *response,
+                               size_t responselen);
+
+int supplyIccPuk2ForAppResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e, void *response,
+                               size_t responselen);
+
+int changeIccPinForAppResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int changeIccPin2ForAppResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e, void *response,
+                               size_t responselen);
+
+int supplyNetworkDepersonalizationResponse(int slotId,
+                                          int responseType, int serial, RIL_Errno e,
+                                          void *response, size_t responselen);
+
+int getCurrentCallsResponse(int slotId,
+                           int responseType, int serial, RIL_Errno e, void *response,
+                           size_t responselen);
+
+int dialResponse(int slotId,
+                int responseType, int serial, RIL_Errno e, void *response, size_t responselen);
+
+int getIMSIForAppResponse(int slotId, int responseType,
+                         int serial, RIL_Errno e, void *response, size_t responselen);
+
+int hangupConnectionResponse(int slotId, int responseType,
+                            int serial, RIL_Errno e, void *response, size_t responselen);
+
+int hangupWaitingOrBackgroundResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e, void *response,
+                                     size_t responselen);
+
+int hangupForegroundResumeBackgroundResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responselen);
+
+int switchWaitingOrHoldingAndActiveResponse(int slotId,
+                                           int responseType, int serial, RIL_Errno e,
+                                           void *response, size_t responselen);
+
+int conferenceResponse(int slotId, int responseType,
+                      int serial, RIL_Errno e, void *response, size_t responselen);
+
+int rejectCallResponse(int slotId, int responseType,
+                      int serial, RIL_Errno e, void *response, size_t responselen);
+
+int getLastCallFailCauseResponse(int slotId,
+                                int responseType, int serial, RIL_Errno e, void *response,
+                                size_t responselen);
+
+int getSignalStrengthResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responseLen);
+
+int getVoiceRegistrationStateResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e, void *response,
+                                     size_t responselen);
+
+int getDataRegistrationStateResponse(int slotId,
+                                    int responseType, int serial, RIL_Errno e, void *response,
+                                    size_t responselen);
+
+int getOperatorResponse(int slotId,
+                       int responseType, int serial, RIL_Errno e, void *response,
+                       size_t responselen);
+
+int setRadioPowerResponse(int slotId,
+                         int responseType, int serial, RIL_Errno e, void *response,
+                         size_t responselen);
+
+int sendDtmfResponse(int slotId,
+                    int responseType, int serial, RIL_Errno e, void *response,
+                    size_t responselen);
+
+int sendSmsResponse(int slotId,
+                   int responseType, int serial, RIL_Errno e, void *response,
+                   size_t responselen);
+
+int sendSMSExpectMoreResponse(int slotId,
+                             int responseType, int serial, RIL_Errno e, void *response,
+                             size_t responselen);
+
+int setupDataCallResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responseLen);
+
+int iccIOForAppResponse(int slotId,
+                       int responseType, int serial, RIL_Errno e, void *response,
+                       size_t responselen);
+
+int sendUssdResponse(int slotId,
+                    int responseType, int serial, RIL_Errno e, void *response,
+                    size_t responselen);
+
+int cancelPendingUssdResponse(int slotId,
+                             int responseType, int serial, RIL_Errno e, void *response,
+                             size_t responselen);
+
+int getClirResponse(int slotId,
+                   int responseType, int serial, RIL_Errno e, void *response, size_t responselen);
+
+int setClirResponse(int slotId,
+                   int responseType, int serial, RIL_Errno e, void *response, size_t responselen);
+
+int getCallForwardStatusResponse(int slotId,
+                                int responseType, int serial, RIL_Errno e, void *response,
+                                size_t responselen);
+
+int setCallForwardResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responselen);
+
+int getCallWaitingResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responselen);
+
+int setCallWaitingResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responselen);
+
+int acknowledgeLastIncomingGsmSmsResponse(int slotId,
+                                         int responseType, int serial, RIL_Errno e, void *response,
+                                         size_t responselen);
+
+int acceptCallResponse(int slotId,
+                      int responseType, int serial, RIL_Errno e, void *response,
+                      size_t responselen);
+
+int deactivateDataCallResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int getFacilityLockForAppResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e, void *response,
+                                 size_t responselen);
+
+int setFacilityLockForAppResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e, void *response,
+                                 size_t responselen);
+
+int setBarringPasswordResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int getNetworkSelectionModeResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e, void *response,
+                                   size_t responselen);
+
+int setNetworkSelectionModeAutomaticResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responselen);
+
+int setNetworkSelectionModeManualResponse(int slotId,
+                                         int responseType, int serial, RIL_Errno e, void *response,
+                                         size_t responselen);
+
+int getAvailableNetworksResponse(int slotId,
+                                int responseType, int serial, RIL_Errno e, void *response,
+                                size_t responselen);
+
+int startNetworkScanResponse(int slotId,
+                             int responseType, int serial, RIL_Errno e, void *response,
+                             size_t responselen);
+
+int startNetworkScanResponse4(int slotId,
+                             int responseType, int serial, RIL_Errno e, void *response,
+                             size_t responselen);
+
+int stopNetworkScanResponse(int slotId,
+                            int responseType, int serial, RIL_Errno e, void *response,
+                            size_t responselen);
+
+int startDtmfResponse(int slotId,
+                     int responseType, int serial, RIL_Errno e, void *response,
+                     size_t responselen);
+
+int stopDtmfResponse(int slotId,
+                    int responseType, int serial, RIL_Errno e, void *response,
+                    size_t responselen);
+
+int getBasebandVersionResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int separateConnectionResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int setMuteResponse(int slotId,
+                   int responseType, int serial, RIL_Errno e, void *response,
+                   size_t responselen);
+
+int getMuteResponse(int slotId,
+                   int responseType, int serial, RIL_Errno e, void *response,
+                   size_t responselen);
+
+int getClipResponse(int slotId,
+                   int responseType, int serial, RIL_Errno e, void *response,
+                   size_t responselen);
+
+int getDataCallListResponse(int slotId,
+                            int responseType, int serial, RIL_Errno e,
+                            void *response, size_t responseLen);
+
+int setSuppServiceNotificationsResponse(int slotId,
+                                       int responseType, int serial, RIL_Errno e, void *response,
+                                       size_t responselen);
+
+int writeSmsToSimResponse(int slotId,
+                         int responseType, int serial, RIL_Errno e, void *response,
+                         size_t responselen);
+
+int deleteSmsOnSimResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responselen);
+
+int setBandModeResponse(int slotId,
+                       int responseType, int serial, RIL_Errno e, void *response,
+                       size_t responselen);
+
+int getAvailableBandModesResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e, void *response,
+                                 size_t responselen);
+
+int sendEnvelopeResponse(int slotId,
+                        int responseType, int serial, RIL_Errno e, void *response,
+                        size_t responselen);
+
+int sendTerminalResponseToSimResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e, void *response,
+                                     size_t responselen);
+
+int handleStkCallSetupRequestFromSimResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responselen);
+
+int explicitCallTransferResponse(int slotId,
+                                int responseType, int serial, RIL_Errno e, void *response,
+                                size_t responselen);
+
+int setPreferredNetworkTypeResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e, void *response,
+                                   size_t responselen);
+
+int getPreferredNetworkTypeResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e, void *response,
+                                   size_t responselen);
+
+int setPreferredNetworkTypeBitmapResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e, void *response,
+                                   size_t responselen);
+
+int getPreferredNetworkTypeBitmapResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e, void *response,
+                                   size_t responselen);
+
+int getNeighboringCidsResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int setLocationUpdatesResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int setCdmaSubscriptionSourceResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e, void *response,
+                                     size_t responselen);
+
+int setCdmaRoamingPreferenceResponse(int slotId,
+                                    int responseType, int serial, RIL_Errno e, void *response,
+                                    size_t responselen);
+
+int getCdmaRoamingPreferenceResponse(int slotId,
+                                    int responseType, int serial, RIL_Errno e, void *response,
+                                    size_t responselen);
+
+int setTTYModeResponse(int slotId,
+                      int responseType, int serial, RIL_Errno e, void *response,
+                      size_t responselen);
+
+int getTTYModeResponse(int slotId,
+                      int responseType, int serial, RIL_Errno e, void *response,
+                      size_t responselen);
+
+int setPreferredVoicePrivacyResponse(int slotId,
+                                    int responseType, int serial, RIL_Errno e, void *response,
+                                    size_t responselen);
+
+int getPreferredVoicePrivacyResponse(int slotId,
+                                    int responseType, int serial, RIL_Errno e, void *response,
+                                    size_t responselen);
+
+int sendCDMAFeatureCodeResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responselen);
+
+int sendBurstDtmfResponse(int slotId,
+                         int responseType, int serial, RIL_Errno e, void *response,
+                         size_t responselen);
+
+int sendCdmaSmsResponse(int slotId,
+                       int responseType, int serial, RIL_Errno e, void *response,
+                       size_t responselen);
+
+int acknowledgeLastIncomingCdmaSmsResponse(int slotId,
+                                          int responseType, int serial, RIL_Errno e, void *response,
+                                          size_t responselen);
+
+int getGsmBroadcastConfigResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e, void *response,
+                                 size_t responselen);
+
+int setGsmBroadcastConfigResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e, void *response,
+                                 size_t responselen);
+
+int setGsmBroadcastActivationResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e, void *response,
+                                     size_t responselen);
+
+int getCdmaBroadcastConfigResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e, void *response,
+                                  size_t responselen);
+
+int setCdmaBroadcastConfigResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e, void *response,
+                                  size_t responselen);
+
+int setCdmaBroadcastActivationResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responselen);
+
+int getCDMASubscriptionResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e, void *response,
+                               size_t responselen);
+
+int writeSmsToRuimResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responselen);
+
+int deleteSmsOnRuimResponse(int slotId,
+                           int responseType, int serial, RIL_Errno e, void *response,
+                           size_t responselen);
+
+int getDeviceIdentityResponse(int slotId,
+                             int responseType, int serial, RIL_Errno e, void *response,
+                             size_t responselen);
+
+int exitEmergencyCallbackModeResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e, void *response,
+                                     size_t responselen);
+
+int getSmscAddressResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e, void *response,
+                          size_t responselen);
+
+int setCdmaBroadcastActivationResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responselen);
+
+int setSmscAddressResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e,
+                          void *response, size_t responselen);
+
+int reportSmsMemoryStatusResponse(int slotId,
+                                 int responseType, int serial, RIL_Errno e,
+                                 void *response, size_t responselen);
+
+int reportStkServiceIsRunningResponse(int slotId,
+                                      int responseType, int serial, RIL_Errno e,
+                                      void *response, size_t responseLen);
+
+int getCdmaSubscriptionSourceResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e, void *response,
+                                     size_t responselen);
+
+int requestIsimAuthenticationResponse(int slotId,
+                                     int responseType, int serial, RIL_Errno e, void *response,
+                                     size_t responselen);
+
+int acknowledgeIncomingGsmSmsWithPduResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responselen);
+
+int sendEnvelopeWithStatusResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e, void *response,
+                                  size_t responselen);
+
+int getVoiceRadioTechnologyResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e,
+                                   void *response, size_t responselen);
+
+int getCellInfoListResponse(int slotId,
+                            int responseType,
+                            int serial, RIL_Errno e, void *response,
+                            size_t responseLen);
+
+int setCellInfoListRateResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responselen);
+
+int setInitialAttachApnResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responselen);
+
+int getImsRegistrationStateResponse(int slotId,
+                                   int responseType, int serial, RIL_Errno e,
+                                   void *response, size_t responselen);
+
+int sendImsSmsResponse(int slotId, int responseType,
+                      int serial, RIL_Errno e, void *response, size_t responselen);
+
+int iccTransmitApduBasicChannelResponse(int slotId,
+                                       int responseType, int serial, RIL_Errno e,
+                                       void *response, size_t responselen);
+
+int iccOpenLogicalChannelResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e, void *response,
+                                  size_t responselen);
+
+
+int iccCloseLogicalChannelResponse(int slotId,
+                                  int responseType, int serial, RIL_Errno e,
+                                  void *response, size_t responselen);
+
+int iccTransmitApduLogicalChannelResponse(int slotId,
+                                         int responseType, int serial, RIL_Errno e,
+                                         void *response, size_t responselen);
+
+int nvReadItemResponse(int slotId,
+                      int responseType, int serial, RIL_Errno e,
+                      void *response, size_t responselen);
+
+
+int nvWriteItemResponse(int slotId,
+                       int responseType, int serial, RIL_Errno e,
+                       void *response, size_t responselen);
+
+int nvWriteCdmaPrlResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e,
+                          void *response, size_t responselen);
+
+int nvResetConfigResponse(int slotId,
+                         int responseType, int serial, RIL_Errno e,
+                         void *response, size_t responselen);
+
+int setUiccSubscriptionResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responselen);
+
+int setDataAllowedResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e,
+                          void *response, size_t responselen);
+
+int getHardwareConfigResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responseLen);
+
+int requestIccSimAuthenticationResponse(int slotId,
+                                       int responseType, int serial, RIL_Errno e,
+                                       void *response, size_t responselen);
+
+int setDataProfileResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e,
+                          void *response, size_t responselen);
+
+int requestShutdownResponse(int slotId,
+                           int responseType, int serial, RIL_Errno e,
+                           void *response, size_t responselen);
+
+int getRadioCapabilityResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responseLen);
+
+int setRadioCapabilityResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responseLen);
+
+int startLceServiceResponse(int slotId,
+                           int responseType, int serial, RIL_Errno e,
+                           void *response, size_t responselen);
+
+int stopLceServiceResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e,
+                          void *response, size_t responselen);
+
+int pullLceDataResponse(int slotId,
+                        int responseType, int serial, RIL_Errno e,
+                        void *response, size_t responseLen);
+
+int getModemActivityInfoResponse(int slotId,
+                                int responseType, int serial, RIL_Errno e,
+                                void *response, size_t responselen);
+
+int getModemStackStatusResponse(int slotId,
+                                int responseType, int serial, RIL_Errno e,
+                                void *response, size_t responselen);
+
+int enableModemResponse(int slotId, int responseType, int serial, RIL_Errno e,
+                                void *response, size_t responselen);
+
+int setAllowedCarriersResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responselen);
+
+int getAllowedCarriersResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responselen);
+
+int sendDeviceStateResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responselen);
+
+int setIndicationFilterResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responselen);
+
+int setSimCardPowerResponse(int slotId,
+                              int responseType, int serial, RIL_Errno e,
+                              void *response, size_t responselen);
+
+int startKeepaliveResponse(int slotId,
+                           int responseType, int serial, RIL_Errno e,
+                           void *response, size_t responselen);
+
+int stopKeepaliveResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e,
+                          void *response, size_t responselen);
+
+void acknowledgeRequest(int slotId, int serial);
+
+int radioStateChangedInd(int slotId,
+                          int indicationType, int token, RIL_Errno e, void *response,
+                          size_t responseLen);
+
+int callStateChangedInd(int slotId, int indType, int token,
+                        RIL_Errno e, void *response, size_t responselen);
+
+int networkStateChangedInd(int slotId, int indType,
+                                int token, RIL_Errno e, void *response, size_t responselen);
+
+int newSmsInd(int slotId, int indicationType,
+              int token, RIL_Errno e, void *response, size_t responselen);
+
+int newSmsStatusReportInd(int slotId, int indicationType,
+                          int token, RIL_Errno e, void *response, size_t responselen);
+
+int newSmsOnSimInd(int slotId, int indicationType,
+                   int token, RIL_Errno e, void *response, size_t responselen);
+
+int onUssdInd(int slotId, int indicationType,
+              int token, RIL_Errno e, void *response, size_t responselen);
+
+int nitzTimeReceivedInd(int slotId, int indicationType,
+                        int token, RIL_Errno e, void *response, size_t responselen);
+
+int currentSignalStrengthInd(int slotId,
+                             int indicationType, int token, RIL_Errno e,
+                             void *response, size_t responselen);
+
+int dataCallListChangedInd(int slotId, int indicationType,
+                           int token, RIL_Errno e, void *response, size_t responselen);
+
+int suppSvcNotifyInd(int slotId, int indicationType,
+                     int token, RIL_Errno e, void *response, size_t responselen);
+
+int stkSessionEndInd(int slotId, int indicationType,
+                     int token, RIL_Errno e, void *response, size_t responselen);
+
+int stkProactiveCommandInd(int slotId, int indicationType,
+                           int token, RIL_Errno e, void *response, size_t responselen);
+
+int stkEventNotifyInd(int slotId, int indicationType,
+                      int token, RIL_Errno e, void *response, size_t responselen);
+
+int stkCallSetupInd(int slotId, int indicationType,
+                    int token, RIL_Errno e, void *response, size_t responselen);
+
+int simSmsStorageFullInd(int slotId, int indicationType,
+                         int token, RIL_Errno e, void *response, size_t responselen);
+
+int simRefreshInd(int slotId, int indicationType,
+                  int token, RIL_Errno e, void *response, size_t responselen);
+
+int callRingInd(int slotId, int indicationType,
+                int token, RIL_Errno e, void *response, size_t responselen);
+
+int simStatusChangedInd(int slotId, int indicationType,
+                        int token, RIL_Errno e, void *response, size_t responselen);
+
+int cdmaNewSmsInd(int slotId, int indicationType,
+                  int token, RIL_Errno e, void *response, size_t responselen);
+
+int newBroadcastSmsInd(int slotId,
+                       int indicationType, int token, RIL_Errno e, void *response,
+                       size_t responselen);
+
+int cdmaRuimSmsStorageFullInd(int slotId,
+                              int indicationType, int token, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int restrictedStateChangedInd(int slotId,
+                              int indicationType, int token, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int enterEmergencyCallbackModeInd(int slotId,
+                                  int indicationType, int token, RIL_Errno e, void *response,
+                                  size_t responselen);
+
+int cdmaCallWaitingInd(int slotId,
+                       int indicationType, int token, RIL_Errno e, void *response,
+                       size_t responselen);
+
+int cdmaOtaProvisionStatusInd(int slotId,
+                              int indicationType, int token, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int cdmaInfoRecInd(int slotId,
+                   int indicationType, int token, RIL_Errno e, void *response,
+                   size_t responselen);
+
+int oemHookRawInd(int slotId,
+                  int indicationType, int token, RIL_Errno e, void *response,
+                  size_t responselen);
+
+int indicateRingbackToneInd(int slotId,
+                            int indicationType, int token, RIL_Errno e, void *response,
+                            size_t responselen);
+
+int resendIncallMuteInd(int slotId,
+                        int indicationType, int token, RIL_Errno e, void *response,
+                        size_t responselen);
+
+int cdmaSubscriptionSourceChangedInd(int slotId,
+                                     int indicationType, int token, RIL_Errno e,
+                                     void *response, size_t responselen);
+
+int cdmaPrlChangedInd(int slotId,
+                      int indicationType, int token, RIL_Errno e, void *response,
+                      size_t responselen);
+
+int exitEmergencyCallbackModeInd(int slotId,
+                                 int indicationType, int token, RIL_Errno e, void *response,
+                                 size_t responselen);
+
+int rilConnectedInd(int slotId,
+                    int indicationType, int token, RIL_Errno e, void *response,
+                    size_t responselen);
+
+int voiceRadioTechChangedInd(int slotId,
+                             int indicationType, int token, RIL_Errno e, void *response,
+                             size_t responselen);
+
+int cellInfoListInd(int slotId,
+                    int indicationType, int token, RIL_Errno e, void *response,
+                    size_t responselen);
+
+int imsNetworkStateChangedInd(int slotId,
+                              int indicationType, int token, RIL_Errno e, void *response,
+                              size_t responselen);
+
+int subscriptionStatusChangedInd(int slotId,
+                                 int indicationType, int token, RIL_Errno e, void *response,
+                                 size_t responselen);
+
+int srvccStateNotifyInd(int slotId,
+                        int indicationType, int token, RIL_Errno e, void *response,
+                        size_t responselen);
+
+int hardwareConfigChangedInd(int slotId,
+                             int indicationType, int token, RIL_Errno e, void *response,
+                             size_t responselen);
+
+int radioCapabilityIndicationInd(int slotId,
+                                 int indicationType, int token, RIL_Errno e, void *response,
+                                 size_t responselen);
+
+int onSupplementaryServiceIndicationInd(int slotId,
+                                        int indicationType, int token, RIL_Errno e,
+                                        void *response, size_t responselen);
+
+int stkCallControlAlphaNotifyInd(int slotId,
+                                 int indicationType, int token, RIL_Errno e, void *response,
+                                 size_t responselen);
+
+int lceDataInd(int slotId,
+               int indicationType, int token, RIL_Errno e, void *response,
+               size_t responselen);
+
+int pcoDataInd(int slotId,
+               int indicationType, int token, RIL_Errno e, void *response,
+               size_t responselen);
+
+int modemResetInd(int slotId,
+                  int indicationType, int token, RIL_Errno e, void *response,
+                  size_t responselen);
+
+int networkScanResultInd(int slotId,
+                         int indicationType, int token, RIL_Errno e, void *response,
+                         size_t responselen);
+
+int keepaliveStatusInd(int slotId,
+                       int indicationType, int token, RIL_Errno e, void *response,
+                       size_t responselen);
+
+int sendRequestRawResponse(int slotId,
+                           int responseType, int serial, RIL_Errno e,
+                           void *response, size_t responseLen);
+
+int sendRequestStringsResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responseLen);
+
+int setCarrierInfoForImsiEncryptionResponse(int slotId,
+                                            int responseType, int serial, RIL_Errno e,
+                                            void *response, size_t responseLen);
+
+int emergencyDialResponse(int slotId,
+                          int responseType, int serial, RIL_Errno e,
+                          void *response, size_t responselen);
+
+int carrierInfoForImsiEncryption(int slotId,
+                        int responseType, int serial, RIL_Errno e,
+                        void *response, size_t responseLen);
+
+int setSystemSelectionChannelsResponse(int slotId,
+                               int responseType, int serial, RIL_Errno e,
+                               void *response, size_t responseLen);
+
+int setAllowedCarriersResponse4(int slotId,
+                                int responseType, int serial, RIL_Errno e,
+                                void *response,
+                                size_t responselen);
+
+int getAllowedCarriersResponse4(int slotId,
+                                int responseType, int serial, RIL_Errno e,
+                                void *response,
+                                size_t responselen);
+
+pthread_rwlock_t * getRadioServiceRwlock(int slotId);
+
+void setNitzTimeReceived(int slotId, long timeReceived);
+
+}   // namespace radio
+
+#endif  // RIL_SERVICE_H
diff --git a/guest/hals/ril/libril/ril_unsol_commands.h b/guest/hals/ril/libril/ril_unsol_commands.h
new file mode 100644
index 0000000..072a0fa
--- /dev/null
+++ b/guest/hals/ril/libril/ril_unsol_commands.h
@@ -0,0 +1,66 @@
+/* ///guest/hals/ril/libril/ril_unsol_commands.h
+**
+** Copyright 2006, 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 is 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.
+*/
+    {RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, radio_1_4::radioStateChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, radio_1_4::callStateChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED, radio_1_4::networkStateChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_NEW_SMS, radio_1_4::newSmsInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, radio_1_4::newSmsStatusReportInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, radio_1_4::newSmsOnSimInd, WAKE_PARTIAL},
+    {RIL_UNSOL_ON_USSD, radio_1_4::onUssdInd, WAKE_PARTIAL},
+    {RIL_UNSOL_ON_USSD_REQUEST, radio_1_4::onUssdInd, DONT_WAKE},
+    {RIL_UNSOL_NITZ_TIME_RECEIVED, radio_1_4::nitzTimeReceivedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_SIGNAL_STRENGTH, radio_1_4::currentSignalStrengthInd, DONT_WAKE},
+    {RIL_UNSOL_DATA_CALL_LIST_CHANGED, radio_1_4::dataCallListChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_SUPP_SVC_NOTIFICATION, radio_1_4::suppSvcNotifyInd, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_SESSION_END, radio_1_4::stkSessionEndInd, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_PROACTIVE_COMMAND, radio_1_4::stkProactiveCommandInd, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_EVENT_NOTIFY, radio_1_4::stkEventNotifyInd, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_CALL_SETUP, radio_1_4::stkCallSetupInd, WAKE_PARTIAL},
+    {RIL_UNSOL_SIM_SMS_STORAGE_FULL, radio_1_4::simSmsStorageFullInd, WAKE_PARTIAL},
+    {RIL_UNSOL_SIM_REFRESH, radio_1_4::simRefreshInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CALL_RING, radio_1_4::callRingInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED, radio_1_4::simStatusChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_CDMA_NEW_SMS, radio_1_4::cdmaNewSmsInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS, radio_1_4::newBroadcastSmsInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL, radio_1_4::cdmaRuimSmsStorageFullInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESTRICTED_STATE_CHANGED, radio_1_4::restrictedStateChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE, radio_1_4::enterEmergencyCallbackModeInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_CALL_WAITING, radio_1_4::cdmaCallWaitingInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, radio_1_4::cdmaOtaProvisionStatusInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_INFO_REC, radio_1_4::cdmaInfoRecInd, WAKE_PARTIAL},
+    {RIL_UNSOL_OEM_HOOK_RAW, radio_1_4::oemHookRawInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RINGBACK_TONE, radio_1_4::indicateRingbackToneInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESEND_INCALL_MUTE, radio_1_4::resendIncallMuteInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, radio_1_4::cdmaSubscriptionSourceChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CDMA_PRL_CHANGED, radio_1_4::cdmaPrlChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE, radio_1_4::exitEmergencyCallbackModeInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RIL_CONNECTED, radio_1_4::rilConnectedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, radio_1_4::voiceRadioTechChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CELL_INFO_LIST, radio_1_4::cellInfoListInd, WAKE_PARTIAL},
+    {RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, radio_1_4::imsNetworkStateChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED, radio_1_4::subscriptionStatusChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_SRVCC_STATE_NOTIFY, radio_1_4::srvccStateNotifyInd, WAKE_PARTIAL},
+    {RIL_UNSOL_HARDWARE_CONFIG_CHANGED, radio_1_4::hardwareConfigChangedInd, WAKE_PARTIAL},
+    {RIL_UNSOL_DC_RT_INFO_CHANGED, NULL, WAKE_PARTIAL},
+    {RIL_UNSOL_RADIO_CAPABILITY, radio_1_4::radioCapabilityIndicationInd, WAKE_PARTIAL},
+    {RIL_UNSOL_ON_SS, radio_1_4::onSupplementaryServiceIndicationInd, WAKE_PARTIAL},
+    {RIL_UNSOL_STK_CC_ALPHA_NOTIFY, radio_1_4::stkCallControlAlphaNotifyInd, WAKE_PARTIAL},
+    {RIL_UNSOL_LCEDATA_RECV, radio_1_4::lceDataInd, WAKE_PARTIAL},
+    {RIL_UNSOL_PCO_DATA, radio_1_4::pcoDataInd, WAKE_PARTIAL},
+    {RIL_UNSOL_MODEM_RESTART, radio_1_4::modemResetInd, WAKE_PARTIAL},
+    {RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION, radio_1_4::carrierInfoForImsiEncryption, WAKE_PARTIAL},
+    {RIL_UNSOL_NETWORK_SCAN_RESULT, radio_1_4::networkScanResultInd, WAKE_PARTIAL},
diff --git a/guest/hals/ril/libril/sap_service.cpp b/guest/hals/ril/libril/sap_service.cpp
new file mode 100644
index 0000000..cd5b137
--- /dev/null
+++ b/guest/hals/ril/libril/sap_service.cpp
@@ -0,0 +1,966 @@
+/*
+ * Copyright (c) 2016 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 is 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.
+ */
+
+#define LOG_TAG "RIL_SAP"
+
+#include <android/hardware/radio/1.1/ISap.h>
+
+#include <hwbinder/IPCThreadState.h>
+#include <hwbinder/ProcessState.h>
+#include <sap_service.h>
+#include "pb_decode.h"
+#include "pb_encode.h"
+
+using namespace android::hardware::radio::V1_0;
+using ::android::hardware::Return;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_array;
+using ::android::hardware::Void;
+using android::CommandInfo;
+using android::RequestInfo;
+using android::requestToString;
+using android::sp;
+
+struct SapImpl;
+
+#if (SIM_COUNT >= 2)
+sp<SapImpl> sapService[SIM_COUNT];
+#else
+sp<SapImpl> sapService[1];
+#endif
+
+struct SapImpl : public android::hardware::radio::V1_1::ISap {
+    int32_t slotId;
+    sp<ISapCallback> sapCallback;
+    RIL_SOCKET_ID rilSocketId;
+
+    Return<void> setCallback(const ::android::sp<ISapCallback>& sapCallbackParam);
+
+    Return<void> connectReq(int32_t token, int32_t maxMsgSize);
+
+    Return<void> disconnectReq(int32_t token);
+
+    Return<void> apduReq(int32_t token, SapApduType type, const hidl_vec<uint8_t>& command);
+
+    Return<void> transferAtrReq(int32_t token);
+
+    Return<void> powerReq(int32_t token, bool state);
+
+    Return<void> resetSimReq(int32_t token);
+
+    Return<void> transferCardReaderStatusReq(int32_t token);
+
+    Return<void> setTransferProtocolReq(int32_t token, SapTransferProtocol transferProtocol);
+
+    MsgHeader* createMsgHeader(MsgId msgId, int32_t token);
+
+    Return<void> addPayloadAndDispatchRequest(MsgHeader *msg, uint16_t reqLen, uint8_t *reqPtr);
+
+    void sendFailedResponse(MsgId msgId, int32_t token, int numPointers, ...);
+
+    void checkReturnStatus(Return<void>& ret);
+};
+
+void SapImpl::checkReturnStatus(Return<void>& ret) {
+    if (ret.isOk() == false) {
+        RLOGE("checkReturnStatus: unable to call response/indication callback: %s",
+                ret.description().c_str());
+        // Remote process (SapRilReceiver.java) hosting the callback must be dead. Reset the
+        // callback object; there's no other recovery to be done here. When the client process is
+        // back up, it will call setCallback()
+        sapCallback = NULL;
+    }
+}
+
+Return<void> SapImpl::setCallback(const ::android::sp<ISapCallback>& sapCallbackParam) {
+    RLOGD("SapImpl::setCallback for slotId %d", slotId);
+    sapCallback = sapCallbackParam;
+    return Void();
+}
+
+MsgHeader* SapImpl::createMsgHeader(MsgId msgId, int32_t token) {
+    // Memory for msg will be freed by RilSapSocket::onRequestComplete()
+    MsgHeader *msg = (MsgHeader *)calloc(1, sizeof(MsgHeader));
+    if (msg == NULL) {
+        return NULL;
+    }
+    msg->token = token;
+    msg->type = MsgType_REQUEST;
+    msg->id = msgId;
+    msg->error = Error_RIL_E_SUCCESS;
+    return msg;
+}
+
+Return<void> SapImpl::addPayloadAndDispatchRequest(MsgHeader *msg, uint16_t reqLen,
+        uint8_t *reqPtr) {
+    pb_bytes_array_t *payload = (pb_bytes_array_t *) malloc(sizeof(pb_bytes_array_t) - 1 + reqLen);
+    if (payload == NULL) {
+        sendFailedResponse(msg->id, msg->token, 2, reqPtr, msg);
+        return Void();
+    }
+
+    msg->payload = payload;
+    msg->payload->size = reqLen;
+    memcpy(msg->payload->bytes, reqPtr, reqLen);
+
+    RilSapSocket *sapSocket = RilSapSocket::getSocketById(rilSocketId);
+    if (sapSocket) {
+        RLOGD("SapImpl::addPayloadAndDispatchRequest: calling dispatchRequest");
+        sapSocket->dispatchRequest(msg);
+    } else {
+        RLOGE("SapImpl::addPayloadAndDispatchRequest: sapSocket is null");
+        sendFailedResponse(msg->id, msg->token, 3, payload, reqPtr, msg);
+        return Void();
+    }
+    free(msg->payload);
+    free(reqPtr);
+    return Void();
+}
+
+void SapImpl::sendFailedResponse(MsgId msgId, int32_t token, int numPointers, ...) {
+    va_list ap;
+    va_start(ap, numPointers);
+    for (int i = 0; i < numPointers; i++) {
+        void *ptr = va_arg(ap, void *);
+        if (ptr) free(ptr);
+    }
+    va_end(ap);
+    Return<void> retStatus;
+    switch(msgId) {
+        case MsgId_RIL_SIM_SAP_CONNECT:
+            retStatus = sapCallback->connectResponse(token, SapConnectRsp::CONNECT_FAILURE, 0);
+            break;
+
+        case MsgId_RIL_SIM_SAP_DISCONNECT:
+            retStatus = sapCallback->disconnectResponse(token);
+            break;
+
+        case MsgId_RIL_SIM_SAP_APDU: {
+            hidl_vec<uint8_t> apduRsp;
+            retStatus = sapCallback->apduResponse(token, SapResultCode::GENERIC_FAILURE, apduRsp);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_TRANSFER_ATR: {
+            hidl_vec<uint8_t> atr;
+            retStatus = sapCallback->transferAtrResponse(token, SapResultCode::GENERIC_FAILURE,
+                    atr);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_POWER:
+            retStatus = sapCallback->powerResponse(token, SapResultCode::GENERIC_FAILURE);
+            break;
+
+        case MsgId_RIL_SIM_SAP_RESET_SIM:
+            retStatus = sapCallback->resetSimResponse(token, SapResultCode::GENERIC_FAILURE);
+            break;
+
+        case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS:
+            retStatus = sapCallback->transferCardReaderStatusResponse(token,
+                    SapResultCode::GENERIC_FAILURE, 0);
+            break;
+
+        case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL:
+            retStatus = sapCallback->transferProtocolResponse(token, SapResultCode::NOT_SUPPORTED);
+            break;
+
+        default:
+            return;
+    }
+    sapService[slotId]->checkReturnStatus(retStatus);
+}
+
+Return<void> SapImpl::connectReq(int32_t token, int32_t maxMsgSize) {
+    RLOGD("SapImpl::connectReq");
+    MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_CONNECT, token);
+    if (msg == NULL) {
+        RLOGE("SapImpl::connectReq: Error allocating memory for msg");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 0);
+        return Void();
+    }
+
+    /***** Encode RIL_SIM_SAP_CONNECT_REQ *****/
+    RIL_SIM_SAP_CONNECT_REQ req;
+    memset(&req, 0, sizeof(RIL_SIM_SAP_CONNECT_REQ));
+    req.max_message_size = maxMsgSize;
+
+    size_t encodedSize = 0;
+    if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_CONNECT_REQ_fields, &req)) {
+        RLOGE("SapImpl::connectReq: Error getting encoded size for RIL_SIM_SAP_CONNECT_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 1, msg);
+        return Void();
+    }
+
+    uint8_t *buffer = (uint8_t *)calloc(1, encodedSize);
+    if (buffer == NULL) {
+        RLOGE("SapImpl::connectReq: Error allocating memory for buffer");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 1, msg);
+        return Void();
+    }
+    pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize);
+
+    RLOGD("SapImpl::connectReq calling pb_encode");
+    if (!pb_encode(&stream, RIL_SIM_SAP_CONNECT_REQ_fields, &req)) {
+        RLOGE("SapImpl::connectReq: Error encoding RIL_SIM_SAP_CONNECT_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_CONNECT, token, 2, buffer, msg);
+        return Void();
+    }
+    /***** Encode RIL_SIM_SAP_CONNECT_REQ done *****/
+
+    /* encoded req is payload */
+    return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer);
+}
+
+Return<void> SapImpl::disconnectReq(int32_t token) {
+    RLOGD("SapImpl::disconnectReq");
+    MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_DISCONNECT, token);
+    if (msg == NULL) {
+        RLOGE("SapImpl::disconnectReq: Error allocating memory for msg");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 0);
+        return Void();
+    }
+
+    /***** Encode RIL_SIM_SAP_DISCONNECT_REQ *****/
+    RIL_SIM_SAP_DISCONNECT_REQ req;
+    memset(&req, 0, sizeof(RIL_SIM_SAP_DISCONNECT_REQ));
+
+    size_t encodedSize = 0;
+    if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_DISCONNECT_REQ_fields, &req)) {
+        RLOGE("SapImpl::disconnectReq: Error getting encoded size for RIL_SIM_SAP_DISCONNECT_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 1, msg);
+        return Void();
+    }
+
+    uint8_t *buffer = (uint8_t *)calloc(1, encodedSize);
+    if (buffer == NULL) {
+        RLOGE("SapImpl::disconnectReq: Error allocating memory for buffer");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 1, msg);
+        return Void();
+    }
+
+    pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize);
+
+    RLOGD("SapImpl::disconnectReq calling pb_encode");
+    if (!pb_encode(&stream, RIL_SIM_SAP_DISCONNECT_REQ_fields, &req)) {
+        RLOGE("SapImpl::disconnectReq: Error encoding RIL_SIM_SAP_DISCONNECT_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_DISCONNECT, token, 2, buffer, msg);
+        return Void();
+    }
+    /***** Encode RIL_SIM_SAP_DISCONNECT_REQ done *****/
+
+    /* encoded req is payload */
+    return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer);
+}
+
+Return<void> SapImpl::apduReq(int32_t token, SapApduType type, const hidl_vec<uint8_t>& command) {
+    RLOGD("SapImpl::apduReq");
+    MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_APDU, token);
+    if (msg == NULL) {
+        RLOGE("SapImpl::apduReq: Error allocating memory for msg");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 0);
+        return Void();
+    }
+
+    /***** Encode RIL_SIM_SAP_APDU_REQ *****/
+    RIL_SIM_SAP_APDU_REQ req;
+    memset(&req, 0, sizeof(RIL_SIM_SAP_APDU_REQ));
+    req.type = (RIL_SIM_SAP_APDU_REQ_Type)type;
+
+    if (command.size() > 0) {
+        req.command = (pb_bytes_array_t *)malloc(sizeof(pb_bytes_array_t) - 1 + command.size());
+        if (req.command == NULL) {
+            RLOGE("SapImpl::apduReq: Error allocating memory for req.command");
+            sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 1, msg);
+            return Void();
+        }
+        req.command->size = command.size();
+        memcpy(req.command->bytes, command.data(), command.size());
+    }
+
+    size_t encodedSize = 0;
+    if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_APDU_REQ_fields, &req)) {
+        RLOGE("SapImpl::apduReq: Error getting encoded size for RIL_SIM_SAP_APDU_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 2, req.command, msg);
+        return Void();
+    }
+
+    uint8_t *buffer = (uint8_t *)calloc(1, encodedSize);
+    if (buffer == NULL) {
+        RLOGE("SapImpl::apduReq: Error allocating memory for buffer");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 2, req.command, msg);
+        return Void();
+    }
+
+    pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize);
+
+    RLOGD("SapImpl::apduReq calling pb_encode");
+    if (!pb_encode(&stream, RIL_SIM_SAP_APDU_REQ_fields, &req)) {
+        RLOGE("SapImpl::apduReq: Error encoding RIL_SIM_SAP_APDU_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_APDU, token, 3, req.command, buffer, msg);
+        return Void();
+    }
+    /***** Encode RIL_SIM_SAP_APDU_REQ done *****/
+
+    /* encoded req is payload */
+    return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer);
+}
+
+Return<void> SapImpl::transferAtrReq(int32_t token) {
+    RLOGD("SapImpl::transferAtrReq");
+    MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token);
+    if (msg == NULL) {
+        RLOGE("SapImpl::transferAtrReq: Error allocating memory for msg");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 0);
+        return Void();
+    }
+
+    /***** Encode RIL_SIM_SAP_TRANSFER_ATR_REQ *****/
+    RIL_SIM_SAP_TRANSFER_ATR_REQ req;
+    memset(&req, 0, sizeof(RIL_SIM_SAP_TRANSFER_ATR_REQ));
+
+    size_t encodedSize = 0;
+    if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_TRANSFER_ATR_REQ_fields, &req)) {
+        RLOGE("SapImpl::transferAtrReq: Error getting encoded size for "
+                "RIL_SIM_SAP_TRANSFER_ATR_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 1, msg);
+        return Void();
+    }
+
+    uint8_t *buffer = (uint8_t *)calloc(1, encodedSize);
+    if (buffer == NULL) {
+        RLOGE("SapImpl::transferAtrReq: Error allocating memory for buffer");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 1, msg);
+        return Void();
+    }
+
+    pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize);
+
+    RLOGD("SapImpl::transferAtrReq calling pb_encode");
+    if (!pb_encode(&stream, RIL_SIM_SAP_TRANSFER_ATR_REQ_fields, &req)) {
+        RLOGE("SapImpl::transferAtrReq: Error encoding RIL_SIM_SAP_TRANSFER_ATR_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_ATR, token, 2, buffer, msg);
+        return Void();
+    }
+    /***** Encode RIL_SIM_SAP_TRANSFER_ATR_REQ done *****/
+
+    /* encoded req is payload */
+    return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer);
+}
+
+Return<void> SapImpl::powerReq(int32_t token, bool state) {
+    RLOGD("SapImpl::powerReq");
+    MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_POWER, token);
+    if (msg == NULL) {
+        RLOGE("SapImpl::powerReq: Error allocating memory for msg");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 0);
+        return Void();
+    }
+
+    /***** Encode RIL_SIM_SAP_POWER_REQ *****/
+    RIL_SIM_SAP_POWER_REQ req;
+    memset(&req, 0, sizeof(RIL_SIM_SAP_POWER_REQ));
+    req.state = state;
+
+    size_t encodedSize = 0;
+    if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_POWER_REQ_fields, &req)) {
+        RLOGE("SapImpl::powerReq: Error getting encoded size for RIL_SIM_SAP_POWER_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 1, msg);
+        return Void();
+    }
+
+    uint8_t *buffer = (uint8_t *)calloc(1, encodedSize);
+    if (buffer == NULL) {
+        RLOGE("SapImpl::powerReq: Error allocating memory for buffer");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 1, msg);
+        return Void();
+    }
+
+    pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize);
+
+    RLOGD("SapImpl::powerReq calling pb_encode");
+    if (!pb_encode(&stream, RIL_SIM_SAP_POWER_REQ_fields, &req)) {
+        RLOGE("SapImpl::powerReq: Error encoding RIL_SIM_SAP_POWER_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_POWER, token, 2, buffer, msg);
+        return Void();
+    }
+    /***** Encode RIL_SIM_SAP_POWER_REQ done *****/
+
+    /* encoded req is payload */
+    return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer);
+}
+
+Return<void> SapImpl::resetSimReq(int32_t token) {
+    RLOGD("SapImpl::resetSimReq");
+    MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_RESET_SIM, token);
+    if (msg == NULL) {
+        RLOGE("SapImpl::resetSimReq: Error allocating memory for msg");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 0);
+        return Void();
+    }
+
+    /***** Encode RIL_SIM_SAP_RESET_SIM_REQ *****/
+    RIL_SIM_SAP_RESET_SIM_REQ req;
+    memset(&req, 0, sizeof(RIL_SIM_SAP_RESET_SIM_REQ));
+
+    size_t encodedSize = 0;
+    if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_RESET_SIM_REQ_fields, &req)) {
+        RLOGE("SapImpl::resetSimReq: Error getting encoded size for RIL_SIM_SAP_RESET_SIM_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 1, msg);
+        return Void();
+    }
+
+    uint8_t *buffer = (uint8_t *)calloc(1, encodedSize);
+    if (buffer == NULL) {
+        RLOGE("SapImpl::resetSimReq: Error allocating memory for buffer");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 1, msg);
+        return Void();
+    }
+
+    pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize);
+
+    RLOGD("SapImpl::resetSimReq calling pb_encode");
+    if (!pb_encode(&stream, RIL_SIM_SAP_RESET_SIM_REQ_fields, &req)) {
+        RLOGE("SapImpl::resetSimReq: Error encoding RIL_SIM_SAP_RESET_SIM_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_RESET_SIM, token, 2, buffer, msg);
+        return Void();
+    }
+    /***** Encode RIL_SIM_SAP_RESET_SIM_REQ done *****/
+
+    /* encoded req is payload */
+    return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer);
+}
+
+Return<void> SapImpl::transferCardReaderStatusReq(int32_t token) {
+    RLOGD("SapImpl::transferCardReaderStatusReq");
+    MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token);
+    if (msg == NULL) {
+        RLOGE("SapImpl::transferCardReaderStatusReq: Error allocating memory for msg");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 0);
+        return Void();
+    }
+
+    /***** Encode RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ *****/
+    RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ req;
+    memset(&req, 0, sizeof(RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ));
+
+    size_t encodedSize = 0;
+    if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ_fields,
+            &req)) {
+        RLOGE("SapImpl::transferCardReaderStatusReq: Error getting encoded size for "
+                "RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 1, msg);
+        return Void();
+    }
+
+    uint8_t *buffer = (uint8_t *)calloc(1, encodedSize);
+    if (buffer == NULL) {
+        RLOGE("SapImpl::transferCardReaderStatusReq: Error allocating memory for buffer");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 1, msg);
+        return Void();
+    }
+
+    pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize);
+
+    RLOGD("SapImpl::transferCardReaderStatusReq calling pb_encode");
+    if (!pb_encode(&stream, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ_fields, &req)) {
+        RLOGE("SapImpl::transferCardReaderStatusReq: Error encoding "
+                "RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS, token, 2, buffer, msg);
+        return Void();
+    }
+    /***** Encode RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_REQ done *****/
+
+    /* encoded req is payload */
+    return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer);
+}
+
+Return<void> SapImpl::setTransferProtocolReq(int32_t token, SapTransferProtocol transferProtocol) {
+    RLOGD("SapImpl::setTransferProtocolReq");
+    MsgHeader *msg = createMsgHeader(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token);
+    if (msg == NULL) {
+        RLOGE("SapImpl::setTransferProtocolReq: Error allocating memory for msg");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 0);
+        return Void();
+    }
+
+    /***** Encode RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ *****/
+    RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ req;
+    memset(&req, 0, sizeof(RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ));
+    req.protocol = (RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_Protocol)transferProtocol;
+
+    size_t encodedSize = 0;
+    if (!pb_get_encoded_size(&encodedSize, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_fields, &req)) {
+        RLOGE("SapImpl::setTransferProtocolReq: Error getting encoded size for "
+                "RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 1, msg);
+        return Void();
+    }
+
+    uint8_t *buffer = (uint8_t *)calloc(1, encodedSize);
+    if (buffer == NULL) {
+        RLOGE("SapImpl::setTransferProtocolReq: Error allocating memory for buffer");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 1, msg);
+        return Void();
+    }
+
+    pb_ostream_t stream = pb_ostream_from_buffer(buffer, encodedSize);
+
+    RLOGD("SapImpl::setTransferProtocolReq calling pb_encode");
+    if (!pb_encode(&stream, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ_fields, &req)) {
+        RLOGE("SapImpl::setTransferProtocolReq: Error encoding "
+                "RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ");
+        sendFailedResponse(MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL, token, 2, buffer, msg);
+        return Void();
+    }
+    /***** Encode RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_REQ done *****/
+
+    /* encoded req is payload */
+    return addPayloadAndDispatchRequest(msg, stream.bytes_written, buffer);
+}
+
+void *sapDecodeMessage(MsgId msgId, MsgType msgType, uint8_t *payloadPtr, size_t payloadLen) {
+    void *responsePtr = NULL;
+    pb_istream_t stream;
+
+    /* Create the stream */
+    stream = pb_istream_from_buffer((uint8_t *)payloadPtr, payloadLen);
+
+    /* Decode based on the message id */
+    switch (msgId)
+    {
+        case MsgId_RIL_SIM_SAP_CONNECT:
+            responsePtr = malloc(sizeof(RIL_SIM_SAP_CONNECT_RSP));
+            if (responsePtr) {
+                if (!pb_decode(&stream, RIL_SIM_SAP_CONNECT_RSP_fields, responsePtr)) {
+                    RLOGE("Error decoding RIL_SIM_SAP_CONNECT_RSP");
+                    return NULL;
+                }
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_DISCONNECT:
+            if (msgType == MsgType_RESPONSE) {
+                responsePtr = malloc(sizeof(RIL_SIM_SAP_DISCONNECT_RSP));
+                if (responsePtr) {
+                    if (!pb_decode(&stream, RIL_SIM_SAP_DISCONNECT_RSP_fields, responsePtr)) {
+                        RLOGE("Error decoding RIL_SIM_SAP_DISCONNECT_RSP");
+                        return NULL;
+                    }
+                }
+            } else {
+                responsePtr = malloc(sizeof(RIL_SIM_SAP_DISCONNECT_IND));
+                if (responsePtr) {
+                    if (!pb_decode(&stream, RIL_SIM_SAP_DISCONNECT_IND_fields, responsePtr)) {
+                        RLOGE("Error decoding RIL_SIM_SAP_DISCONNECT_IND");
+                        return NULL;
+                    }
+                }
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_APDU:
+            responsePtr = malloc(sizeof(RIL_SIM_SAP_APDU_RSP));
+            if (responsePtr) {
+                if (!pb_decode(&stream, RIL_SIM_SAP_APDU_RSP_fields, responsePtr)) {
+                    RLOGE("Error decoding RIL_SIM_SAP_APDU_RSP");
+                    return NULL;
+                }
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_TRANSFER_ATR:
+            responsePtr = malloc(sizeof(RIL_SIM_SAP_TRANSFER_ATR_RSP));
+            if (responsePtr) {
+                if (!pb_decode(&stream, RIL_SIM_SAP_TRANSFER_ATR_RSP_fields, responsePtr)) {
+                    RLOGE("Error decoding RIL_SIM_SAP_TRANSFER_ATR_RSP");
+                    return NULL;
+                }
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_POWER:
+            responsePtr = malloc(sizeof(RIL_SIM_SAP_POWER_RSP));
+            if (responsePtr) {
+                if (!pb_decode(&stream, RIL_SIM_SAP_POWER_RSP_fields, responsePtr)) {
+                    RLOGE("Error decoding RIL_SIM_SAP_POWER_RSP");
+                    return NULL;
+                }
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_RESET_SIM:
+            responsePtr = malloc(sizeof(RIL_SIM_SAP_RESET_SIM_RSP));
+            if (responsePtr) {
+                if (!pb_decode(&stream, RIL_SIM_SAP_RESET_SIM_RSP_fields, responsePtr)) {
+                    RLOGE("Error decoding RIL_SIM_SAP_RESET_SIM_RSP");
+                    return NULL;
+                }
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_STATUS:
+            responsePtr = malloc(sizeof(RIL_SIM_SAP_STATUS_IND));
+            if (responsePtr) {
+                if (!pb_decode(&stream, RIL_SIM_SAP_STATUS_IND_fields, responsePtr)) {
+                    RLOGE("Error decoding RIL_SIM_SAP_STATUS_IND");
+                    return NULL;
+                }
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS:
+            responsePtr = malloc(sizeof(RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP));
+            if (responsePtr) {
+                if (!pb_decode(&stream, RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_fields,
+                        responsePtr)) {
+                    RLOGE("Error decoding RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP");
+                    return NULL;
+                }
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_ERROR_RESP:
+            responsePtr = malloc(sizeof(RIL_SIM_SAP_ERROR_RSP));
+            if (responsePtr) {
+                if (!pb_decode(&stream, RIL_SIM_SAP_ERROR_RSP_fields, responsePtr)) {
+                    RLOGE("Error decoding RIL_SIM_SAP_ERROR_RSP");
+                    return NULL;
+                }
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL:
+            responsePtr = malloc(sizeof(RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP));
+            if (responsePtr) {
+                if (!pb_decode(&stream, RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP_fields,
+                        responsePtr)) {
+                    RLOGE("Error decoding RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP");
+                    return NULL;
+                }
+            }
+            break;
+
+        default:
+            break;
+    }
+    return responsePtr;
+} /* sapDecodeMessage */
+
+sp<SapImpl> getSapImpl(RilSapSocket *sapSocket) {
+    switch (sapSocket->getSocketId()) {
+        case RIL_SOCKET_1:
+            RLOGD("getSapImpl: returning sapService[0]");
+            return sapService[0];
+        #if (SIM_COUNT >= 2)
+        case RIL_SOCKET_2:
+            return sapService[1];
+        #if (SIM_COUNT >= 3)
+        case RIL_SOCKET_3:
+            return sapService[2];
+        #if (SIM_COUNT >= 4)
+        case RIL_SOCKET_4:
+            return sapService[3];
+        #endif
+        #endif
+        #endif
+        default:
+            return NULL;
+    }
+}
+
+SapResultCode convertApduResponseProtoToHal(RIL_SIM_SAP_APDU_RSP_Response responseProto) {
+    switch(responseProto) {
+        case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SUCCESS:
+            return SapResultCode::SUCCESS;
+        case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_GENERIC_FAILURE:
+            return SapResultCode::GENERIC_FAILURE;
+        case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_NOT_READY:
+            return SapResultCode::CARD_NOT_ACCESSSIBLE;
+        case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF:
+            return SapResultCode::CARD_ALREADY_POWERED_OFF;
+        case RIL_SIM_SAP_APDU_RSP_Response_RIL_E_SIM_ABSENT:
+            return SapResultCode::CARD_REMOVED;
+        default:
+            return SapResultCode::GENERIC_FAILURE;
+    }
+}
+
+SapResultCode convertTransferAtrResponseProtoToHal(
+        RIL_SIM_SAP_TRANSFER_ATR_RSP_Response responseProto) {
+    switch(responseProto) {
+        case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SUCCESS:
+            return SapResultCode::SUCCESS;
+        case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_GENERIC_FAILURE:
+            return SapResultCode::GENERIC_FAILURE;
+        case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF:
+            return SapResultCode::CARD_ALREADY_POWERED_OFF;
+        case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_ABSENT:
+            return SapResultCode::CARD_REMOVED;
+        case RIL_SIM_SAP_TRANSFER_ATR_RSP_Response_RIL_E_SIM_DATA_NOT_AVAILABLE:
+            return SapResultCode::DATA_NOT_AVAILABLE;
+        default:
+            return SapResultCode::GENERIC_FAILURE;
+    }
+}
+
+SapResultCode convertPowerResponseProtoToHal(RIL_SIM_SAP_POWER_RSP_Response responseProto) {
+    switch(responseProto) {
+        case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SUCCESS:
+            return SapResultCode::SUCCESS;
+        case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_GENERIC_FAILURE:
+            return SapResultCode::GENERIC_FAILURE;
+        case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ABSENT:
+            return SapResultCode::CARD_REMOVED;
+        case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF:
+            return SapResultCode::CARD_ALREADY_POWERED_OFF;
+        case RIL_SIM_SAP_POWER_RSP_Response_RIL_E_SIM_ALREADY_POWERED_ON:
+            return SapResultCode::CARD_ALREADY_POWERED_ON;
+        default:
+            return SapResultCode::GENERIC_FAILURE;
+    }
+}
+
+SapResultCode convertResetSimResponseProtoToHal(RIL_SIM_SAP_RESET_SIM_RSP_Response responseProto) {
+    switch(responseProto) {
+        case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SUCCESS:
+            return SapResultCode::SUCCESS;
+        case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_GENERIC_FAILURE:
+            return SapResultCode::GENERIC_FAILURE;
+        case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_ABSENT:
+            return SapResultCode::CARD_REMOVED;
+        case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_NOT_READY:
+            return SapResultCode::CARD_NOT_ACCESSSIBLE;
+        case RIL_SIM_SAP_RESET_SIM_RSP_Response_RIL_E_SIM_ALREADY_POWERED_OFF:
+            return SapResultCode::CARD_ALREADY_POWERED_OFF;
+    }
+    return SapResultCode::GENERIC_FAILURE;
+}
+
+SapResultCode convertTransferCardReaderStatusResponseProtoToHal(
+        RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response responseProto) {
+    switch(responseProto) {
+        case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_SUCCESS:
+            return SapResultCode::SUCCESS;
+        case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_GENERIC_FAILURE:
+            return SapResultCode::GENERIC_FAILURE;
+        case RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP_Response_RIL_E_SIM_DATA_NOT_AVAILABLE:
+            return SapResultCode::DATA_NOT_AVAILABLE;
+    }
+    return SapResultCode::GENERIC_FAILURE;
+}
+
+void processResponse(MsgHeader *rsp, RilSapSocket *sapSocket, MsgType msgType) {
+    MsgId msgId = rsp->id;
+    uint8_t *data = rsp->payload->bytes;
+    size_t dataLen = rsp->payload->size;
+
+    void *messagePtr = sapDecodeMessage(msgId, msgType, data, dataLen);
+
+    sp<SapImpl> sapImpl = getSapImpl(sapSocket);
+    if (sapImpl->sapCallback == NULL) {
+        RLOGE("processResponse: sapCallback == NULL; msgId = %d; msgType = %d",
+                msgId, msgType);
+        return;
+    }
+
+    if (messagePtr == NULL) {
+        RLOGE("processResponse: *messagePtr == NULL; msgId = %d; msgType = %d",
+                msgId, msgType);
+        sapImpl->sendFailedResponse(msgId, rsp->token, 0);
+        return;
+    }
+
+    RLOGD("processResponse: sapCallback != NULL; msgId = %d; msgType = %d",
+            msgId, msgType);
+
+    Return<void> retStatus;
+    switch (msgId) {
+        case MsgId_RIL_SIM_SAP_CONNECT: {
+            RIL_SIM_SAP_CONNECT_RSP *connectRsp = (RIL_SIM_SAP_CONNECT_RSP *)messagePtr;
+            RLOGD("processResponse: calling sapCallback->connectResponse %d %d %d",
+                    rsp->token,
+                    connectRsp->response,
+                    connectRsp->max_message_size);
+            retStatus = sapImpl->sapCallback->connectResponse(rsp->token,
+                    (SapConnectRsp)connectRsp->response,
+                    connectRsp->max_message_size);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_DISCONNECT:
+            if (msgType == MsgType_RESPONSE) {
+                RLOGD("processResponse: calling sapCallback->disconnectResponse %d", rsp->token);
+                retStatus = sapImpl->sapCallback->disconnectResponse(rsp->token);
+            } else {
+                RIL_SIM_SAP_DISCONNECT_IND *disconnectInd =
+                        (RIL_SIM_SAP_DISCONNECT_IND *)messagePtr;
+                RLOGD("processResponse: calling sapCallback->disconnectIndication %d %d",
+                        rsp->token, disconnectInd->disconnectType);
+                retStatus = sapImpl->sapCallback->disconnectIndication(rsp->token,
+                        (SapDisconnectType)disconnectInd->disconnectType);
+            }
+            break;
+
+        case MsgId_RIL_SIM_SAP_APDU: {
+            RIL_SIM_SAP_APDU_RSP *apduRsp = (RIL_SIM_SAP_APDU_RSP *)messagePtr;
+            SapResultCode apduResponse = convertApduResponseProtoToHal(apduRsp->response);
+            RLOGD("processResponse: calling sapCallback->apduResponse %d %d",
+                    rsp->token, apduResponse);
+            hidl_vec<uint8_t> apduRspVec;
+            if (apduRsp->apduResponse != NULL && apduRsp->apduResponse->size > 0) {
+                apduRspVec.setToExternal(apduRsp->apduResponse->bytes, apduRsp->apduResponse->size);
+            }
+            retStatus = sapImpl->sapCallback->apduResponse(rsp->token, apduResponse, apduRspVec);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_TRANSFER_ATR: {
+            RIL_SIM_SAP_TRANSFER_ATR_RSP *transferAtrRsp =
+                (RIL_SIM_SAP_TRANSFER_ATR_RSP *)messagePtr;
+            SapResultCode transferAtrResponse =
+                convertTransferAtrResponseProtoToHal(transferAtrRsp->response);
+            RLOGD("processResponse: calling sapCallback->transferAtrResponse %d %d",
+                    rsp->token, transferAtrResponse);
+            hidl_vec<uint8_t> transferAtrRspVec;
+            if (transferAtrRsp->atr != NULL && transferAtrRsp->atr->size > 0) {
+                transferAtrRspVec.setToExternal(transferAtrRsp->atr->bytes,
+                        transferAtrRsp->atr->size);
+            }
+            retStatus = sapImpl->sapCallback->transferAtrResponse(rsp->token, transferAtrResponse,
+                    transferAtrRspVec);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_POWER: {
+            SapResultCode powerResponse = convertPowerResponseProtoToHal(
+                    ((RIL_SIM_SAP_POWER_RSP *)messagePtr)->response);
+            RLOGD("processResponse: calling sapCallback->powerResponse %d %d",
+                    rsp->token, powerResponse);
+            retStatus = sapImpl->sapCallback->powerResponse(rsp->token, powerResponse);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_RESET_SIM: {
+            SapResultCode resetSimResponse = convertResetSimResponseProtoToHal(
+                    ((RIL_SIM_SAP_RESET_SIM_RSP *)messagePtr)->response);
+            RLOGD("processResponse: calling sapCallback->resetSimResponse %d %d",
+                    rsp->token, resetSimResponse);
+            retStatus = sapImpl->sapCallback->resetSimResponse(rsp->token, resetSimResponse);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_STATUS: {
+            RIL_SIM_SAP_STATUS_IND *statusInd = (RIL_SIM_SAP_STATUS_IND *)messagePtr;
+            RLOGD("processResponse: calling sapCallback->statusIndication %d %d",
+                    rsp->token, statusInd->statusChange);
+            retStatus = sapImpl->sapCallback->statusIndication(rsp->token,
+                    (SapStatus)statusInd->statusChange);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS: {
+            RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP *transferStatusRsp =
+                    (RIL_SIM_SAP_TRANSFER_CARD_READER_STATUS_RSP *)messagePtr;
+            SapResultCode transferCardReaderStatusResponse =
+                    convertTransferCardReaderStatusResponseProtoToHal(
+                    transferStatusRsp->response);
+            RLOGD("processResponse: calling sapCallback->transferCardReaderStatusResponse %d %d %d",
+                    rsp->token,
+                    transferCardReaderStatusResponse,
+                    transferStatusRsp->CardReaderStatus);
+            retStatus = sapImpl->sapCallback->transferCardReaderStatusResponse(rsp->token,
+                    transferCardReaderStatusResponse,
+                    transferStatusRsp->CardReaderStatus);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_ERROR_RESP: {
+            RLOGD("processResponse: calling sapCallback->errorResponse %d", rsp->token);
+            retStatus = sapImpl->sapCallback->errorResponse(rsp->token);
+            break;
+        }
+
+        case MsgId_RIL_SIM_SAP_SET_TRANSFER_PROTOCOL: {
+            SapResultCode setTransferProtocolResponse;
+            if (((RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP *)messagePtr)->response ==
+                    RIL_SIM_SAP_SET_TRANSFER_PROTOCOL_RSP_Response_RIL_E_SUCCESS) {
+                setTransferProtocolResponse = SapResultCode::SUCCESS;
+            } else {
+                setTransferProtocolResponse = SapResultCode::NOT_SUPPORTED;
+            }
+            RLOGD("processResponse: calling sapCallback->transferProtocolResponse %d %d",
+                    rsp->token, setTransferProtocolResponse);
+            retStatus = sapImpl->sapCallback->transferProtocolResponse(rsp->token,
+                    setTransferProtocolResponse);
+            break;
+        }
+
+        default:
+            return;
+    }
+    sapImpl->checkReturnStatus(retStatus);
+}
+
+void sap::processResponse(MsgHeader *rsp, RilSapSocket *sapSocket) {
+    processResponse(rsp, sapSocket, MsgType_RESPONSE);
+}
+
+void sap::processUnsolResponse(MsgHeader *rsp, RilSapSocket *sapSocket) {
+    processResponse(rsp, sapSocket, MsgType_UNSOL_RESPONSE);
+}
+
+void sap::registerService(const RIL_RadioFunctions *callbacks) {
+    using namespace android::hardware;
+    int simCount = 1;
+    const char *serviceNames[] = {
+        android::RIL_getServiceName()
+        #if (SIM_COUNT >= 2)
+        , RIL2_SERVICE_NAME
+        #if (SIM_COUNT >= 3)
+        , RIL3_SERVICE_NAME
+        #if (SIM_COUNT >= 4)
+        , RIL4_SERVICE_NAME
+        #endif
+        #endif
+        #endif
+    };
+
+    RIL_SOCKET_ID socketIds[] = {
+        RIL_SOCKET_1
+        #if (SIM_COUNT >= 2)
+        , RIL_SOCKET_2
+        #if (SIM_COUNT >= 3)
+        , RIL_SOCKET_3
+        #if (SIM_COUNT >= 4)
+        , RIL_SOCKET_4
+        #endif
+        #endif
+        #endif
+    };
+    #if (SIM_COUNT >= 2)
+    simCount = SIM_COUNT;
+    #endif
+
+    for (int i = 0; i < simCount; i++) {
+        sapService[i] = new SapImpl;
+        sapService[i]->slotId = i;
+        sapService[i]->rilSocketId = socketIds[i];
+        RLOGD("registerService: starting ISap %s for slotId %d", serviceNames[i], i);
+        android::status_t status = sapService[i]->registerAsService(serviceNames[i]);
+        RLOGD("registerService: started ISap %s status %d", serviceNames[i], status);
+    }
+}
diff --git a/guest/hals/rild/Android.mk b/guest/hals/rild/Android.mk
new file mode 100644
index 0000000..01c709b
--- /dev/null
+++ b/guest/hals/rild/Android.mk
@@ -0,0 +1,47 @@
+# Copyright (C) 2006 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 is 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.
+
+# only for PLATFORM_VERSION greater or equal to Q
+ifeq (true,$(ENABLE_CUTTLEFISH_RILD))
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    rild_cuttlefish.c
+
+LOCAL_SHARED_LIBRARIES := \
+    libcutils \
+    libdl \
+    liblog \
+    libril-cuttlefish-fork
+
+LOCAL_C_INCLUDES += \
+    device/google/cuttlefish_common
+
+# Temporary hack for broken vendor RILs.
+LOCAL_WHOLE_STATIC_LIBRARIES := \
+    librilutils
+
+LOCAL_CFLAGS := -DRIL_SHLIB
+LOCAL_CFLAGS += -Wall -Wextra -Werror
+
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE:= libcuttlefish-rild
+LOCAL_OVERRIDES_PACKAGES := rild
+PACKAGES.$(LOCAL_MODULE).OVERRIDES := rild
+LOCAL_INIT_RC := rild_cuttlefish.rc
+
+include $(BUILD_EXECUTABLE)
+endif
diff --git a/guest/hals/rild/rild_cuttlefish.c b/guest/hals/rild/rild_cuttlefish.c
new file mode 100644
index 0000000..c2efe44
--- /dev/null
+++ b/guest/hals/rild/rild_cuttlefish.c
@@ -0,0 +1,233 @@
+/* //device/system/rild/rild.c
+**
+** Copyright 2006 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 is 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 <stdio.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <guest/hals/ril/libril/ril.h>
+
+#define LOG_TAG "RILD"
+#include <log/log.h>
+#include <cutils/properties.h>
+#include <cutils/sockets.h>
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <guest/hals/ril/libril/ril_ex.h>
+
+#define LIB_PATH_PROPERTY   "vendor.rild.libpath"
+#define LIB_ARGS_PROPERTY   "vendor.rild.libargs"
+#define MAX_LIB_ARGS        16
+
+static void usage(const char *argv0) {
+    fprintf(stderr, "Usage: %s -l <ril impl library> [-- <args for impl library>]\n", argv0);
+    exit(EXIT_FAILURE);
+}
+
+extern char ril_service_name_base[MAX_SERVICE_NAME_LENGTH];
+extern char ril_service_name[MAX_SERVICE_NAME_LENGTH];
+
+extern void RIL_register (const RIL_RadioFunctions *callbacks);
+extern void rilc_thread_pool ();
+
+extern void RIL_register_socket (const RIL_RadioFunctions *(*rilUimInit)
+        (const struct RIL_Env *, int, char **), RIL_SOCKET_TYPE socketType, int argc, char **argv);
+
+extern void RIL_onRequestComplete(RIL_Token t, RIL_Errno e,
+        void *response, size_t responselen);
+
+extern void RIL_onRequestAck(RIL_Token t);
+
+#if defined(ANDROID_MULTI_SIM)
+extern void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+        size_t datalen, RIL_SOCKET_ID socket_id);
+#else
+extern void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
+        size_t datalen);
+#endif
+
+extern void RIL_requestTimedCallback (RIL_TimedCallback callback,
+        void *param, const struct timeval *relativeTime);
+
+
+static struct RIL_Env s_rilEnv = {
+    RIL_onRequestComplete,
+    RIL_onUnsolicitedResponse,
+    RIL_requestTimedCallback,
+    RIL_onRequestAck
+};
+
+extern void RIL_startEventLoop();
+
+static int make_argv(char * args, char ** argv) {
+    // Note: reserve argv[0]
+    int count = 1;
+    char * tok;
+    char * s = args;
+
+    while ((tok = strtok(s, " \0"))) {
+        argv[count] = tok;
+        s = NULL;
+        count++;
+    }
+    return count;
+}
+
+int main(int argc, char **argv) {
+    // vendor ril lib path either passed in as -l parameter, or read from rild.libpath property
+    const char *rilLibPath = NULL;
+    // ril arguments either passed in as -- parameter, or read from rild.libargs property
+    char **rilArgv;
+    // handle for vendor ril lib
+    void *dlHandle;
+    // Pointer to ril init function in vendor ril
+    const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **);
+    // Pointer to sap init function in vendor ril
+    const RIL_RadioFunctions *(*rilUimInit)(const struct RIL_Env *, int, char **);
+    const char *err_str = NULL;
+
+    // functions returned by ril init function in vendor ril
+    const RIL_RadioFunctions *funcs;
+    // lib path from rild.libpath property (if it's read)
+    char libPath[PROPERTY_VALUE_MAX];
+    // flat to indicate if -- parameters are present
+    unsigned char hasLibArgs = 0;
+
+    int i;
+    // ril/socket id received as -c parameter, otherwise set to 0
+    const char *clientId = NULL;
+
+    RLOGD("**RIL Daemon Started - Version 1.4**");
+    RLOGD("**RILd param count=%d**", argc);
+
+    umask(S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH);
+    for (i = 1; i < argc ;) {
+        if (0 == strcmp(argv[i], "-l") && (argc - i > 1)) {
+            rilLibPath = argv[i + 1];
+            i += 2;
+        } else if (0 == strcmp(argv[i], "--")) {
+            i++;
+            hasLibArgs = 1;
+            break;
+        } else if (0 == strcmp(argv[i], "-c") &&  (argc - i > 1)) {
+            clientId = argv[i+1];
+            i += 2;
+        } else {
+            usage(argv[0]);
+        }
+    }
+
+    if (clientId == NULL) {
+        clientId = "0";
+    } else if (atoi(clientId) >= MAX_RILDS) {
+        RLOGE("Max Number of rild's supported is: %d", MAX_RILDS);
+        exit(0);
+    }
+    if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
+        snprintf(ril_service_name, sizeof(ril_service_name), "%s%s", ril_service_name_base,
+                 clientId);
+    }
+
+    if (rilLibPath == NULL) {
+        if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
+            // No lib sepcified on the command line, and nothing set in props.
+            // Assume "no-ril" case.
+            goto done;
+        } else {
+            rilLibPath = libPath;
+        }
+    }
+
+    dlHandle = dlopen(rilLibPath, RTLD_NOW);
+
+    if (dlHandle == NULL) {
+        RLOGE("dlopen failed: %s", dlerror());
+        exit(EXIT_FAILURE);
+    }
+
+    RIL_startEventLoop();
+
+    rilInit =
+        (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
+        dlsym(dlHandle, "RIL_Init");
+
+    if (rilInit == NULL) {
+        RLOGE("RIL_Init not defined or exported in %s\n", rilLibPath);
+        exit(EXIT_FAILURE);
+    }
+
+    dlerror(); // Clear any previous dlerror
+    rilUimInit =
+        (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
+        dlsym(dlHandle, "RIL_SAP_Init");
+    err_str = dlerror();
+    if (err_str) {
+        RLOGW("RIL_SAP_Init not defined or exported in %s: %s\n", rilLibPath, err_str);
+    } else if (!rilUimInit) {
+        RLOGW("RIL_SAP_Init defined as null in %s. SAP Not usable\n", rilLibPath);
+    }
+
+    if (hasLibArgs) {
+        rilArgv = argv + i - 1;
+        argc = argc -i + 1;
+    } else {
+        static char * newArgv[MAX_LIB_ARGS];
+        static char args[PROPERTY_VALUE_MAX];
+        rilArgv = newArgv;
+        property_get(LIB_ARGS_PROPERTY, args, "");
+        argc = make_argv(args, rilArgv);
+    }
+
+    rilArgv[argc++] = "-c";
+    rilArgv[argc++] = (char*)clientId;
+    RLOGD("RIL_Init argc = %d clientId = %s", argc, rilArgv[argc-1]);
+
+    // Make sure there's a reasonable argv[0]
+    rilArgv[0] = argv[0];
+
+    funcs = rilInit(&s_rilEnv, argc, rilArgv);
+    RLOGD("RIL_Init rilInit completed");
+
+    RLOGD("RIL_Init callback versions = %d", funcs->version);
+
+    RIL_register(funcs);
+
+    RLOGD("RIL_Init RIL_register completed");
+
+    if (rilUimInit) {
+        RLOGD("RIL_register_socket started");
+        RIL_register_socket(rilUimInit, RIL_SAP_SOCKET, argc, rilArgv);
+    }
+
+    RLOGD("RIL_register_socket completed");
+
+done:
+
+    rilc_thread_pool();
+
+    RLOGD("RIL_Init starting sleep loop");
+    while (true) {
+        sleep(UINT32_MAX);
+    }
+}
diff --git a/guest/hals/rild/rild_cuttlefish.legacy.rc b/guest/hals/rild/rild_cuttlefish.legacy.rc
new file mode 100644
index 0000000..e9c2d07
--- /dev/null
+++ b/guest/hals/rild/rild_cuttlefish.legacy.rc
@@ -0,0 +1,5 @@
+service ril-daemon /vendor/bin/hw/libcuttlefish-rild
+    class main
+    user radio
+    group radio cache inet misc audio log readproc wakelock
+    capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW
diff --git a/guest/hals/rild/rild_cuttlefish.rc b/guest/hals/rild/rild_cuttlefish.rc
new file mode 100644
index 0000000..9990a7a
--- /dev/null
+++ b/guest/hals/rild/rild_cuttlefish.rc
@@ -0,0 +1,5 @@
+service vendor.ril-daemon /vendor/bin/hw/libcuttlefish-rild
+    class main
+    user radio
+    group radio cache inet misc audio log readproc wakelock
+    capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW
diff --git a/guest/libs/wpa_supplicant_8_lib/Android.mk b/guest/libs/wpa_supplicant_8_lib/Android.mk
deleted file mode 100644
index 95b9662..0000000
--- a/guest/libs/wpa_supplicant_8_lib/Android.mk
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright (C) 2016 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 is 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.
-
-LOCAL_PATH := $(call my-dir)
-
-ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_8_X)
-
-ifneq ($(BOARD_WPA_SUPPLICANT_DRIVER),)
-  CONFIG_DRIVER_$(BOARD_WPA_SUPPLICANT_DRIVER) := y
-endif
-
-# Use a custom libnl on releases before N
-ifeq (0, $(shell test $(PLATFORM_SDK_VERSION) -lt 24; echo $$?))
-EXTERNAL_VSOC_LIBNL_INCLUDE := external/gce/libnl/include
-else
-EXTERNAL_VSOC_LIBNL_INCLUDE :=
-endif
-
-
-WPA_SUPPL_DIR = external/wpa_supplicant_8
-WPA_SRC_FILE :=
-
-include $(WPA_SUPPL_DIR)/wpa_supplicant/android.config
-
-WPA_SUPPL_DIR_INCLUDE = $(WPA_SUPPL_DIR)/src \
-	$(WPA_SUPPL_DIR)/src/common \
-	$(WPA_SUPPL_DIR)/src/drivers \
-	$(WPA_SUPPL_DIR)/src/l2_packet \
-	$(WPA_SUPPL_DIR)/src/utils \
-	$(WPA_SUPPL_DIR)/src/wps \
-	$(WPA_SUPPL_DIR)/wpa_supplicant \
-	$(EXTERNAL_VSOC_LIBNL_INCLUDE)
-
-WPA_SUPPL_DIR_INCLUDE += external/libnl/include
-
-ifdef CONFIG_DRIVER_NL80211
-WPA_SRC_FILE += driver_cmd_nl80211.c
-endif
-
-ifeq ($(TARGET_ARCH),arm)
-# To force sizeof(enum) = 4
-L_CFLAGS += -mabi=aapcs-linux
-endif
-
-ifdef CONFIG_ANDROID_LOG
-L_CFLAGS += -DCONFIG_ANDROID_LOG
-endif
-
-########################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := lib_driver_cmd_simulated
-LOCAL_VENDOR_MODULE := true
-LOCAL_SHARED_LIBRARIES := libc libcutils
-
-LOCAL_CFLAGS := $(L_CFLAGS) \
-    $(VSOC_VERSION_CFLAGS)
-
-LOCAL_SRC_FILES := $(WPA_SRC_FILE)
-
-LOCAL_C_INCLUDES := \
-  device/google/cuttlefish_common \
-  $(WPA_SUPPL_DIR_INCLUDE)\
-
-include $(BUILD_STATIC_LIBRARY)
-
-########################
-
-endif
diff --git a/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.c b/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.c
deleted file mode 100644
index a2180aa..0000000
--- a/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2016 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 is 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.
- */
-/*
- * Driver interaction with extended Linux CFG8021
- */
-
-#include "driver_cmd_nl80211.h"
-
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#if VSOC_PLATFORM_SDK_AFTER(L_MR1)
-// Android M exposes headers more directly.
-#include <netinet/in.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include "driver_nl80211.h"
-#elif VSOC_PLATFORM_SDK_AFTER(J_MR2)
-// Android versions K and L put structures in hardware_legacy
-#include "hardware_legacy/driver_nl80211.h"
-#else
-// Android version J does not expose structures directly. These structures are
-// manually defined later.
-#include <netinet/in.h>
-#include <linux/if.h>
-#endif
-
-#include "common.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-#include "android_drv.h"
-
-
-int wpa_driver_nl80211_driver_cmd(
-    void* priv, char* cmd, char* buf, size_t buf_len) {
-  struct i802_bss* bss = priv;
-  struct wpa_driver_nl80211_data* drv = bss->drv;
-  struct ifreq ifr;
-  android_wifi_priv_cmd priv_cmd;
-  int ret = 0;
-
-  D("%s: called", __FUNCTION__);
-  if (os_strcasecmp(cmd, "STOP") == 0) {
-    linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
-    wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
-  } else if (os_strcasecmp(cmd, "START") == 0) {
-    linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
-    wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
-  } else if (os_strcasecmp(cmd, "MACADDR") == 0) {
-    u8 macaddr[ETH_ALEN] = {};
-
-    ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
-    if (!ret)
-      ret = os_snprintf(
-          buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
-  } else if (os_strcasecmp(cmd, "RELOAD") == 0) {
-    wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
-  } else {  // Use private command
-    return 0;
-  }
-  return ret;
-}
-
-
-int wpa_driver_set_p2p_noa(void* priv, u8 count, int start, int duration) {
-  D("%s: called", __FUNCTION__);
-  return 0;
-}
-
-
-int wpa_driver_get_p2p_noa(void* priv, u8* buf, size_t len) {
-  D("%s: called", __FUNCTION__);
-  return 0;
-}
-
-
-int wpa_driver_set_p2p_ps(void* priv, int legacy_ps, int opp_ps, int ctwindow) {
-  D("%s: called", __FUNCTION__);
-  return -1;
-}
-
-
-int wpa_driver_set_ap_wps_p2p_ie(
-    void* priv, const struct wpabuf* beacon,
-    const struct wpabuf* proberesp, const struct wpabuf* assocresp) {
-  D("%s: called", __FUNCTION__);
-  return 0;
-}
diff --git a/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.h b/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.h
deleted file mode 100644
index 4256664..0000000
--- a/guest/libs/wpa_supplicant_8_lib/driver_cmd_nl80211.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#pragma once
-/*
- * Copyright (C) 2016 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 is 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/libs/platform_support/api_level_fixes.h>
-
-#include <memory.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "common.h"
-#include "linux_ioctl.h"
-#include "wpa_supplicant_i.h"
-#include <linux/if_ether.h>
-
-#define VSOC_WPA_SUPPLICANT_DEBUG 0
-
-#if VSOC_WPA_SUPPLICANT_DEBUG
-#  define D(...) ALOGD(__VA_ARGS__)
-#else
-#  define D(...) ((void)0)
-#endif
-
-
-typedef struct android_wifi_priv_cmd {
-  char* buf;
-  int used_len;
-  int total_len;
-} android_wifi_priv_cmd;
-
-#if VSOC_PLATFORM_SDK_BEFORE(K)
-
-#include "driver.h"
-
-struct i802_bss {
-  struct wpa_driver_nl80211_data* drv;
-  struct i802_bss* next;
-  int ifindex;
-  char ifname[IFNAMSIZ + 1];
-  char brname[IFNAMSIZ];
-
-  unsigned int beacon_set:1;
-  unsigned int added_if_into_bridge:1;
-  unsigned int added_bridge:1;
-  unsigned int in_deinit:1;
-
-  u8 addr[ETH_ALEN];
-
-  int freq;
-
-  void* ctx;
-  struct nl_handle* nl_preq;
-  struct nl_handle* nl_mgmt;
-  struct nl_cb* nl_cb;
-
-  struct nl80211_wiphy_data *wiphy_data;
-  struct dl_list wiphy_list;
-};
-
-struct nl80211_global {
-  struct dl_list interfaces;
-  int if_add_ifindex;
-  struct netlink_data *netlink;
-  struct nl_cb* nl_cb;
-  struct nl_handle* nl;
-  int nl80211_id;
-  int ioctl_sock;  // socket for ioctl() use
-
-  struct nl_handle* nl_event;
-};
-
-struct wpa_driver_nl80211_data {
-  struct nl80211_global* global;
-  struct dl_list list;
-  struct dl_list wiphy_list;
-  char phyname[32];
-  void* ctx;
-  int ifindex;
-  int if_removed;
-  int if_disabled;
-  int ignore_if_down_event;
-  struct rfkill_data* rfkill;
-  struct wpa_driver_capa capa;
-  u8* extended_capa;
-  u8* extended_capa_mask;
-  unsigned int extended_capa_len;
-  int has_capability;
-  // More internal data follows.
-};
-
-#endif  // VSOC_PLATFORM_SDK_AFTER(J)
diff --git a/guest/monitoring/Android.bp b/guest/monitoring/Android.bp
new file mode 100644
index 0000000..a7f69c0
--- /dev/null
+++ b/guest/monitoring/Android.bp
@@ -0,0 +1,19 @@
+//
+// Copyright (C) 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 is 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.
+
+subdirs = [
+    "dumpstate_ext",
+    "tombstone_transmit",
+]
diff --git a/guest/monitoring/vsoc_service/Android.mk b/guest/monitoring/cuttlefish_service/Android.mk
similarity index 93%
rename from guest/monitoring/vsoc_service/Android.mk
rename to guest/monitoring/cuttlefish_service/Android.mk
index ad8ce40..d1baf7d 100644
--- a/guest/monitoring/vsoc_service/Android.mk
+++ b/guest/monitoring/cuttlefish_service/Android.mk
@@ -19,8 +19,8 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := $(call all-java-files-under, java)
 LOCAL_STATIC_JAVA_LIBRARIES := guava
-LOCAL_PACKAGE_NAME := VSoCService
-LOCAL_SDK_VERSION := 26
+LOCAL_PACKAGE_NAME := CuttlefishService
+LOCAL_SDK_VERSION := 28
 LOCAL_PROGUARD_FLAGS := -include build/core/proguard.flags
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 LOCAL_VENDOR_MODULE := true
diff --git a/guest/monitoring/vsoc_service/AndroidManifest.xml b/guest/monitoring/cuttlefish_service/AndroidManifest.xml
similarity index 100%
rename from guest/monitoring/vsoc_service/AndroidManifest.xml
rename to guest/monitoring/cuttlefish_service/AndroidManifest.xml
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/BluetoothChecker.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BluetoothChecker.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/BluetoothChecker.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BluetoothChecker.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/BootReporter.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BootReporter.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/BootReporter.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/BootReporter.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/ConnectivityChecker.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceBroadcastReceiver.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceFuture.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceFuture.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceFuture.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceFuture.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceService.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceService.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceService.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceWifiManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceWifiManager.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/GceWifiManager.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/GceWifiManager.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/JobBase.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobBase.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/JobBase.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobBase.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/JobExecutor.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobExecutor.java
similarity index 95%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/JobExecutor.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobExecutor.java
index 9cb3225..1eed006 100644
--- a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/JobExecutor.java
+++ b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/JobExecutor.java
@@ -49,8 +49,13 @@
     public void schedule(final JobBase job, final GceFuture<?>... futures) {
         mExecutor.schedule(new Runnable() {
             private boolean mDependenciesReady = false;
-            private ArrayList<GceFuture<?>> mFutures =
-                    new ArrayList<GceFuture<?>>(Arrays.asList(futures));
+            private ArrayList<GceFuture<?>> mFutures = new ArrayList<GceFuture<?>>();
+
+            {
+                for (GceFuture<?> future: futures) {
+                    mFutures.add(future);
+                }
+            }
 
             public void run() {
                 if (!mDependenciesReady) {
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/LocationServicesManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/LocationServicesManager.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/LocationServicesManager.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/LocationServicesManager.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerificationConsentEnforcer.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/PackageVerifierManager.java
diff --git a/guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/TombstoneChecker.java b/guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/TombstoneChecker.java
similarity index 100%
rename from guest/monitoring/vsoc_service/java/com/android/google/gce/gceservice/TombstoneChecker.java
rename to guest/monitoring/cuttlefish_service/java/com/android/google/gce/gceservice/TombstoneChecker.java
diff --git a/guest/monitoring/vsoc_service/proguard.flags b/guest/monitoring/cuttlefish_service/proguard.flags
similarity index 100%
rename from guest/monitoring/vsoc_service/proguard.flags
rename to guest/monitoring/cuttlefish_service/proguard.flags
diff --git a/guest/monitoring/dumpstate_ext/Android.bp b/guest/monitoring/dumpstate_ext/Android.bp
new file mode 100644
index 0000000..03f7b9f
--- /dev/null
+++ b/guest/monitoring/dumpstate_ext/Android.bp
@@ -0,0 +1,41 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+cc_binary {
+    name: "android.hardware.dumpstate@1.0-service.cuttlefish",
+    srcs: [
+        "dumpstate_device.cpp",
+        "service.cpp",
+    ],
+    shared_libs: [
+        "android.hardware.dumpstate@1.0",
+        "libbase",
+        "libcutils",
+        "libdumpstateutil",
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+    ],
+    cflags: [
+        "-DLOG_TAG=\"VSoC-dumpstate\"",
+    ],
+    relative_install_path: "hw",
+    init_rc: [
+        "android.hardware.dumpstate@1.0-service.cuttlefish.rc",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/monitoring/dumpstate_ext/Android.mk b/guest/monitoring/dumpstate_ext/Android.mk
deleted file mode 100644
index d425821..0000000
--- a/guest/monitoring/dumpstate_ext/Android.mk
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 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 is 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.
-
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common
-LOCAL_CFLAGS := $(VSOC_VERSION_CFLAGS) -DLOG_TAG=\"VSoC-dumpstate\"
-LOCAL_SRC_FILES := dumpstate.cpp
-LOCAL_MODULE := libdumpstate.vsoc
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := \
-    libbase \
-    libdumpstateaidl \
-    libdumpstateutil \
-    libziparchive \
-    libz
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := android.hardware.dumpstate@1.0-service.cuttlefish
-LOCAL_INIT_RC := android.hardware.dumpstate@1.0-service.cuttlefish.rc
-LOCAL_MODULE_RELATIVE_PATH := hw
-LOCAL_SRC_FILES := \
-    dumpstate_device.cpp \
-    service.cpp
-LOCAL_CFLAGS := $(VSOC_VERSION_CFLAGS) -DLOG_TAG=\"VSoC-dumpstate\"
-LOCAL_SHARED_LIBRARIES := \
-    android.hardware.dumpstate@1.0 \
-    libbase \
-    libcutils \
-    libdumpstateutil \
-    libhidlbase \
-    libhidltransport \
-    libhwbinder \
-    liblog \
-    libutils
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    frameworks/native/cmds/dumpstate
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_PROPRIETARY_MODULE := true
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
diff --git a/guest/monitoring/dumpstate_ext/dumpstate.cpp b/guest/monitoring/dumpstate_ext/dumpstate.cpp
deleted file mode 100644
index 89e820b..0000000
--- a/guest/monitoring/dumpstate_ext/dumpstate.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 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 is 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/libs/platform_support/api_level_fixes.h"
-
-#if VSOC_PLATFORM_SDK_BEFORE(N)
-extern "C" {
-#endif
-#include <dumpstate.h>
-#if VSOC_PLATFORM_SDK_BEFORE(N)
-}
-#endif
-
-void dumpstate_board() { Dumpstate& ds = Dumpstate::GetInstance(); };
diff --git a/guest/monitoring/tombstone_transmit/Android.bp b/guest/monitoring/tombstone_transmit/Android.bp
new file mode 100644
index 0000000..243877e
--- /dev/null
+++ b/guest/monitoring/tombstone_transmit/Android.bp
@@ -0,0 +1,34 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+cc_binary {
+    name: "tombstone_transmit",
+    srcs: [
+        "main.cpp",
+    ],
+    static_libs: [
+        "libcuttlefish_fs_static",
+        "libgflags",
+        "cuttlefish_auto_resources_static",
+        "liblog",
+        "libbase",
+        "libcutils",
+    ],
+    stl: "libc++_static",
+    header_libs: [
+        "cuttlefish_glog_product",
+    ],
+    defaults: ["cuttlefish_guest_product_only"],
+}
diff --git a/guest/monitoring/tombstone_transmit/main.cpp b/guest/monitoring/tombstone_transmit/main.cpp
new file mode 100644
index 0000000..3633612
--- /dev/null
+++ b/guest/monitoring/tombstone_transmit/main.cpp
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2019 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 is 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 <android-base/logging.h>
+#include <errno.h>
+#include <log/log.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/inotify.h>
+#include <unistd.h>
+#include <fstream>
+
+#include <cutils/properties.h>
+#include <gflags/gflags.h>
+
+#include "common/libs/fs/shared_fd.h"
+#include "common/libs/utils/subprocess.h"
+
+static const char TOMBSTONE_DIR[] = "/data/tombstones/";
+
+// returns a fd which when read from, provides inotify events when tombstones
+// are created
+static int new_tombstone_create_notifier(void) {
+  int file_create_notification_handle = inotify_init();
+  if (file_create_notification_handle == -1) {
+    ALOGE("%s: inotify_init failure error: '%s' (%d)", __FUNCTION__,
+      strerror(errno), errno);
+    return -1;
+  }
+
+  int watch_descriptor = inotify_add_watch(file_create_notification_handle,
+    TOMBSTONE_DIR, IN_CREATE);
+  if (watch_descriptor == -1) {
+    ALOGE("%s: Could not add watch for '%s', error: '%s' (%d)", __FUNCTION__,
+      TOMBSTONE_DIR, strerror(errno), errno);
+    close(file_create_notification_handle);
+    return -1;
+  }
+
+  return file_create_notification_handle;
+}
+
+#define INOTIFY_MAX_EVENT_SIZE (sizeof(struct inotify_event) + NAME_MAX + 1)
+static std::string get_next_tombstone_path_blocking(int fd) {
+  char event_readout[INOTIFY_MAX_EVENT_SIZE];
+  struct inotify_event *i = (inotify_event*)(event_readout);
+
+  int event_read_out_length = read(fd, event_readout, INOTIFY_MAX_EVENT_SIZE);
+
+  if(event_read_out_length == -1) {
+    ALOGE("%s: Couldn't read out inotify event due to error: '%s' (%d)",
+      __FUNCTION__, strerror(errno), errno);
+    return std::string();
+  }
+
+  // Create event didn't show up for some reason or no file name was present
+  if(event_read_out_length == sizeof(struct inotify_event)) {
+    ALOGE("%s: inotify event didn't contain filename",__FUNCTION__);
+    return std::string();
+  }
+
+  if(!(i->mask & IN_CREATE)) {
+    ALOGE("%s: inotify event didn't pertain to file creation",__FUNCTION__);
+    return std::string();
+  }
+
+  std::string ret_value(TOMBSTONE_DIR);
+  return ret_value + i->name;
+}
+
+DEFINE_uint32(port, property_get_int32("ro.boot.vsock_tombstone_port", 0),
+              "VSOCK port to send tombstones to");
+DEFINE_uint32(cid, 2, "VSOCK CID to send logcat output to");
+#define TOMBSTONE_BUFFER_SIZE (1024)
+#define MAX_TOMBSTONE_SIZE (50 * TOMBSTONE_BUFFER_SIZE)
+
+int main(int argc, char** argv) {
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
+
+  if(FLAGS_port == 0) {
+    LOG(FATAL_WITHOUT_ABORT) << "Port flag is required";
+    while(1) {sleep(1);};
+  }
+
+  int file_create_notification_handle = new_tombstone_create_notifier();
+  if (file_create_notification_handle == -1) {return -1;}
+
+  LOG(INFO) << "tombstone watcher successfully initialized";
+
+  while (true) {
+    std::string ts_path = get_next_tombstone_path_blocking(
+      file_create_notification_handle);
+
+    if(ts_path.empty()) {continue;}
+
+    auto log_fd = cvd::SharedFD::VsockClient(FLAGS_cid, FLAGS_port,
+      SOCK_STREAM);
+
+    std::ifstream ifs(ts_path);
+    char buffer[TOMBSTONE_BUFFER_SIZE];
+    uint num_transfers = 0;
+    int num_bytes_read = 0;
+    while (log_fd->IsOpen() && ifs.is_open() && !ifs.eof() &&
+           num_bytes_read < MAX_TOMBSTONE_SIZE) {
+      ifs.read(buffer, sizeof(buffer));
+      num_bytes_read += ifs.gcount();
+      log_fd->Write(buffer, ifs.gcount());
+      num_transfers++;
+    }
+
+    if (!log_fd->IsOpen()) {
+      ALOGE("Unable to connect to vsock:%u:%u: %s", FLAGS_cid, FLAGS_port,
+        log_fd->StrError());
+    } else if (!ifs.is_open()) {
+      ALOGE("%s closed in the middle of readout.", ts_path.c_str());
+    } else {
+      LOG(INFO) << num_bytes_read << " chars transferred from " <<
+        ts_path.c_str() << " over " << num_transfers << " "
+        << TOMBSTONE_BUFFER_SIZE << " byte sized transfers";
+    }
+  }
+
+  return 0;
+}
diff --git a/guest/vsoc/lib/Android.bp b/guest/vsoc/lib/Android.bp
new file mode 100644
index 0000000..d534a5d
--- /dev/null
+++ b/guest/vsoc/lib/Android.bp
@@ -0,0 +1,77 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+cc_binary {
+    name: "vsoc_driver_test",
+    srcs: [
+        "vsoc_driver_test.cpp",
+    ],
+    shared_libs: [
+        "vsoc_lib",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libbase",
+    ],
+    static_libs: [
+        "libgtest",
+    ],
+    cflags: [
+        "-DGTEST_OS_LINUX_ANDROID",
+        "-DGTEST_HAS_STD_STRING",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
+
+cc_binary {
+    name: "vsoc_guest_region_e2e_test",
+    srcs: [
+        "guest_region_e2e_test.cpp",
+    ],
+    shared_libs: [
+        "vsoc_lib",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libbase",
+    ],
+    static_libs: [
+        "libgtest",
+    ],
+    cflags: [
+        "-DGTEST_OS_LINUX_ANDROID",
+        "-DGTEST_HAS_STD_STRING",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
+
+cc_binary {
+    name: "vsoc_managed_region_e2e_test",
+    srcs: [
+        "managed_region_e2e_test.cpp",
+    ],
+    shared_libs: [
+        "vsoc_lib",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_fs",
+        "libbase",
+    ],
+    static_libs: [
+        "libgtest",
+    ],
+    cflags: [
+        "-DGTEST_OS_LINUX_ANDROID",
+        "-DGTEST_HAS_STD_STRING",
+    ],
+    defaults: ["cuttlefish_guest_only"]
+}
diff --git a/guest/vsoc/lib/Android.mk b/guest/vsoc/lib/Android.mk
deleted file mode 100644
index 73240f4..0000000
--- a/guest/vsoc/lib/Android.mk
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 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 is 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.
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := vsoc_driver_test
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := vsoc_driver_test.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_CFLAGS += -DGTEST_OS_LINUX_ANDROID -DGTEST_HAS_STD_STRING -Werror -Wall
-
-LOCAL_STATIC_LIBRARIES := \
-    libgtest
-
-LOCAL_SHARED_LIBRARIES := \
-    vsoc_lib \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libbase
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := vsoc_guest_region_e2e_test
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := guest_region_e2e_test.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_CFLAGS += -DGTEST_OS_LINUX_ANDROID -DGTEST_HAS_STD_STRING -Werror -Wall
-
-LOCAL_STATIC_LIBRARIES := \
-    libgtest
-
-LOCAL_SHARED_LIBRARIES := \
-    vsoc_lib \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libbase
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := vsoc_managed_region_e2e_test
-LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := managed_region_e2e_test.cpp
-
-LOCAL_C_INCLUDES := \
-    device/google/cuttlefish_common \
-    device/google/cuttlefish_kernel
-
-LOCAL_CFLAGS += -DGTEST_OS_LINUX_ANDROID -DGTEST_HAS_STD_STRING -Werror -Wall
-
-LOCAL_STATIC_LIBRARIES := \
-    libgtest
-
-LOCAL_SHARED_LIBRARIES := \
-    vsoc_lib \
-    cuttlefish_auto_resources \
-    libcuttlefish_fs \
-    libbase
-
-LOCAL_MULTILIB := first
-LOCAL_VENDOR_MODULE := true
-include $(BUILD_EXECUTABLE)
diff --git a/guest/vsoc/lib/guest_region_e2e_test.cpp b/guest/vsoc/lib/guest_region_e2e_test.cpp
index b7f5f9f..5fd644a 100644
--- a/guest/vsoc/lib/guest_region_e2e_test.cpp
+++ b/guest/vsoc/lib/guest_region_e2e_test.cpp
@@ -135,6 +135,13 @@
 }
 
 int main(int argc, char** argv) {
+  if (argc == 2) {
+    // gtest tries to leave temporary files in the current directory, so make the
+    // current directory something that we control.
+    if (chdir(argv[1]) != 0) {
+      abort();
+    }
+  }
   android::base::InitLogging(argv);
   testing::InitGoogleTest(&argc, argv);
   int rval = RUN_ALL_TESTS();
diff --git a/guest/vsoc/lib/managed_region_e2e_test.cpp b/guest/vsoc/lib/managed_region_e2e_test.cpp
index af10bb8..390a6b7 100644
--- a/guest/vsoc/lib/managed_region_e2e_test.cpp
+++ b/guest/vsoc/lib/managed_region_e2e_test.cpp
@@ -110,6 +110,13 @@
 }
 
 int main(int argc, char** argv) {
+  if (argc == 2) {
+    // gtest tries to leave temporary files in the current directory, so make the
+    // current directory something that we control.
+    if (chdir(argv[1]) != 0) {
+      abort();
+    }
+  }
   android::base::InitLogging(argv);
   testing::InitGoogleTest(&argc, argv);
   return RUN_ALL_TESTS();
diff --git a/host/commands/Android.bp b/host/commands/Android.bp
index c776291..89de143 100644
--- a/host/commands/Android.bp
+++ b/host/commands/Android.bp
@@ -21,4 +21,5 @@
     "record_audio",
     "virtual_usb_manager",
     "kernel_log_monitor",
+    "config_server",
 ]
diff --git a/host/commands/adbshell/main.cpp b/host/commands/adbshell/main.cpp
index 68ac18e..d893247 100644
--- a/host/commands/adbshell/main.cpp
+++ b/host/commands/adbshell/main.cpp
@@ -25,6 +25,8 @@
 #include <cstring>
 #include <string>
 #include <vector>
+
+#include <errno.h>
 #include <unistd.h>
 
 // Many of our users interact with CVDs via ssh. They expect to be able to
@@ -65,6 +67,14 @@
          "/cuttlefish_runtime/cuttlefish_config.json";
 }
 
+std::string CuttlefishFindAdb() {
+  std::string rval = std::string("/home/") + VsocUser() + "/bin/adb";
+  if (TEMP_FAILURE_RETRY(access(rval.c_str(), X_OK)) == -1) {
+    return "/usr/bin/adb";
+  }
+  return rval;
+}
+
 void SetCuttlefishConfigEnv() {
   setenv(vsoc::kCuttlefishConfigEnvVarName, CuttlefishConfigLocation().c_str(),
          true);
@@ -74,9 +84,10 @@
 int main(int argc, char* argv[]) {
   SetCuttlefishConfigEnv();
   auto instance = vsoc::CuttlefishConfig::Get()->adb_device_name();
+  std::string adb_path = CuttlefishFindAdb();
 
   std::vector<char*> new_argv = {
-      const_cast<char*>("/usr/bin/adb"), const_cast<char*>("-s"),
+      const_cast<char*>(adb_path.c_str()), const_cast<char*>("-s"),
       const_cast<char*>(instance.c_str()), const_cast<char*>("shell"),
       const_cast<char*>("/system/bin/sh")};
 
diff --git a/host/commands/config_server/Android.bp b/host/commands/config_server/Android.bp
new file mode 100644
index 0000000..07d832a
--- /dev/null
+++ b/host/commands/config_server/Android.bp
@@ -0,0 +1,38 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+cc_binary_host {
+    name: "config_server",
+    srcs: [
+        "main.cpp",
+    ],
+    header_libs: [
+        "cuttlefish_glog",
+    ],
+    shared_libs: [
+        "libbase",
+        "libcuttlefish_fs",
+        "liblog",
+        "libcuttlefish_utils",
+        "cuttlefish_auto_resources",
+        "libcuttlefish_device_config",
+    ],
+    static_libs: [
+        "libcuttlefish_host_config",
+        "libgflags",
+        "libjsoncpp",
+    ],
+    defaults: ["cuttlefish_host_only"],
+}
diff --git a/host/commands/config_server/main.cpp b/host/commands/config_server/main.cpp
new file mode 100644
index 0000000..5970edf
--- /dev/null
+++ b/host/commands/config_server/main.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 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 is 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 <common/libs/device_config/device_config.h>
+#include <gflags/gflags.h>
+#include <glog/logging.h>
+
+#include "common/libs/fs/shared_fd.h"
+#include "host/libs/config/cuttlefish_config.h"
+
+DEFINE_int32(
+    server_fd, -1,
+    "File descriptor to an already created vsock server. If negative a new "
+    "server will be created at the port specified on the config file");
+
+int main(int argc, char** argv) {
+  ::android::base::InitLogging(argv, android::base::StderrLogger);
+  google::ParseCommandLineFlags(&argc, &argv, true);
+
+  auto config = vsoc::CuttlefishConfig::Get();
+
+  cvd::SharedFD server_fd;
+  if (FLAGS_server_fd < 0) {
+    unsigned int port = config->config_server_port();
+    server_fd = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+  } else {
+    server_fd = cvd::SharedFD::Dup(FLAGS_server_fd);
+    close(FLAGS_server_fd);
+  }
+
+  CHECK(server_fd->IsOpen()) << "Error creating or inheriting logcat server: "
+                             << server_fd->StrError();
+
+  auto device_config = cvd::DeviceConfig::Get();
+  if (!device_config) {
+    LOG(ERROR) << "Failed to obtain device configuration";
+    return -1;
+  }
+
+  // Server loop
+  while (true) {
+    auto conn = cvd::SharedFD::Accept(*server_fd);
+    LOG(INFO) << "Connection received on configuration server";
+
+    bool succeeded = device_config->SendRawData(conn);
+    if (succeeded) {
+      LOG(INFO) << "Successfully sent device configuration";
+    } else {
+      LOG(ERROR) << "Failed to send the device configuration: "
+                 << conn->StrError();
+    }
+  }
+}
diff --git a/host/commands/kernel_log_monitor/Android.bp b/host/commands/kernel_log_monitor/Android.bp
index a7197e5..7bc29e0 100644
--- a/host/commands/kernel_log_monitor/Android.bp
+++ b/host/commands/kernel_log_monitor/Android.bp
@@ -24,6 +24,7 @@
     ],
     shared_libs: [
         "libcuttlefish_fs",
+        "libcuttlefish_strings",
         "libcuttlefish_utils",
         "cuttlefish_auto_resources",
         "libbase",
diff --git a/host/commands/kernel_log_monitor/kernel_log_server.cc b/host/commands/kernel_log_monitor/kernel_log_server.cc
index 0ecf5fe..84b2694 100644
--- a/host/commands/kernel_log_monitor/kernel_log_server.cc
+++ b/host/commands/kernel_log_monitor/kernel_log_server.cc
@@ -39,6 +39,8 @@
      monitor::BootEvent::MobileNetworkConnected},
     {"VIRTUAL_DEVICE_NETWORK_WIFI_CONNECTED",
      monitor::BootEvent::WifiNetworkConnected},
+    // TODO(b/131864854): Replace this with a string less likely to change
+    {"init: starting service 'adbd'", monitor::BootEvent::AdbdStarted},
 };
 
 void ProcessSubscriptions(
diff --git a/host/commands/kernel_log_monitor/kernel_log_server.h b/host/commands/kernel_log_monitor/kernel_log_server.h
index 80a6cfa..f71ebb7 100644
--- a/host/commands/kernel_log_monitor/kernel_log_server.h
+++ b/host/commands/kernel_log_monitor/kernel_log_server.h
@@ -23,7 +23,6 @@
 
 #include "common/libs/fs/shared_fd.h"
 #include "common/libs/fs/shared_select.h"
-//#include "host/libs/monitor/kernel_log_client.h"
 
 namespace monitor {
 
@@ -33,6 +32,7 @@
   BootFailed = 2,
   WifiNetworkConnected = 3,
   MobileNetworkConnected = 4,
+  AdbdStarted = 5,
 };
 
 enum class SubscriptionAction {
diff --git a/host/commands/kernel_log_monitor/main.cc b/host/commands/kernel_log_monitor/main.cc
index f87f0ea..a17b1b8 100644
--- a/host/commands/kernel_log_monitor/main.cc
+++ b/host/commands/kernel_log_monitor/main.cc
@@ -15,12 +15,17 @@
  */
 
 #include <signal.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
 
 #include <gflags/gflags.h>
 #include <glog/logging.h>
 
 #include <common/libs/fs/shared_fd.h>
 #include <common/libs/fs/shared_select.h>
+#include <common/libs/strings/str_split.h>
 #include <host/libs/config/cuttlefish_config.h>
 #include "host/commands/kernel_log_monitor/kernel_log_server.h"
 
@@ -28,14 +33,38 @@
              "A file descriptor representing a (UNIX) socket from which to "
              "read the logs. If -1 is given the socket is created according to "
              "the instance configuration");
-DEFINE_int32(subscriber_fd, -1,
-             "A file descriptor (a pipe) to write boot events to. If -1 is "
-             "given no events will be sent");
+DEFINE_string(subscriber_fds, "",
+             "A comma separated list of file descriptors (most likely pipes) to"
+             " send boot events to.");
+
+std::vector<cvd::SharedFD> SubscribersFromCmdline() {
+  // Validate the parameter
+  std::string fd_list = FLAGS_subscriber_fds;
+  for (auto c: fd_list) {
+    if (c != ',' && (c < '0' || c > '9')) {
+      LOG(ERROR) << "Invalid file descriptor list: " << fd_list;
+      std::exit(1);
+    }
+  }
+
+  auto fds = cvd::StrSplit(FLAGS_subscriber_fds, ',');
+  std::vector<cvd::SharedFD> shared_fds;
+  for (auto& fd_str: fds) {
+    auto fd = std::stoi(fd_str);
+    auto shared_fd = cvd::SharedFD::Dup(fd);
+    close(fd);
+    shared_fds.push_back(shared_fd);
+  }
+
+  return shared_fds;
+}
 
 int main(int argc, char** argv) {
   ::android::base::InitLogging(argv, android::base::StderrLogger);
   google::ParseCommandLineFlags(&argc, &argv, true);
 
+  auto subscriber_fds = SubscribersFromCmdline();
+
   // Disable default handling of SIGPIPE
   struct sigaction new_action {
   }, old_action{};
@@ -66,24 +95,22 @@
   monitor::KernelLogServer klog{server, config->PerInstancePath("kernel.log"),
                                 config->deprecated_boot_completed()};
 
-  if (FLAGS_subscriber_fd >= 0) {
-    auto pipe_fd = cvd::SharedFD::Dup(FLAGS_subscriber_fd);
-    close(FLAGS_subscriber_fd);
-    if (pipe_fd->IsOpen()) {
-      klog.SubscribeToBootEvents([pipe_fd](monitor::BootEvent evt) {
-        int retval = pipe_fd->Write(&evt, sizeof(evt));
+  for (auto subscriber_fd: subscriber_fds) {
+    if (subscriber_fd->IsOpen()) {
+      klog.SubscribeToBootEvents([subscriber_fd](monitor::BootEvent evt) {
+        int retval = subscriber_fd->Write(&evt, sizeof(evt));
         if (retval < 0) {
-          if (pipe_fd->GetErrno() != EPIPE) {
+          if (subscriber_fd->GetErrno() != EPIPE) {
             LOG(ERROR) << "Error while writing to pipe: "
-                       << pipe_fd->StrError();
+                       << subscriber_fd->StrError();
           }
-          pipe_fd->Close();
+          subscriber_fd->Close();
           return monitor::SubscriptionAction::CancelSubscription;
         }
         return monitor::SubscriptionAction::ContinueSubscription;
       });
     } else {
-      LOG(ERROR) << "Subscriber fd isn't valid: " << pipe_fd->StrError();
+      LOG(ERROR) << "Subscriber fd isn't valid: " << subscriber_fd->StrError();
       // Don't return here, we still need to write the logs to a file
     }
   }
diff --git a/host/commands/launch/Android.bp b/host/commands/launch/Android.bp
index 49672b1..b41cf77 100644
--- a/host/commands/launch/Android.bp
+++ b/host/commands/launch/Android.bp
@@ -18,7 +18,6 @@
     srcs: [
         "main.cc",
         "screen_region_handler.cc",
-        "ril_config.cc",
         "vsoc_shared_memory.cc",
         "boot_image_unpacker.cc",
         "process_monitor.cc",
diff --git a/host/commands/launch/data_image.cc b/host/commands/launch/data_image.cc
index 415a71e..9bdc421 100644
--- a/host/commands/launch/data_image.cc
+++ b/host/commands/launch/data_image.cc
@@ -11,11 +11,6 @@
 const std::string kDataPolicyAlwaysCreate = "always_create";
 const std::string kDataPolicyResizeUpTo= "resize_up_to";
 
-void RemoveFile(const std::string& file) {
-  LOG(INFO) << "Removing " << file;
-  remove(file.c_str());
-}
-
 const int FSCK_ERROR_CORRECTED = 1;
 const int FSCK_ERROR_CORRECTED_REQUIRES_REBOOT = 2;
 
@@ -117,7 +112,7 @@
   }
 
   if (remove) {
-    RemoveFile(data_image.c_str());
+    cvd::RemoveFile(data_image.c_str());
   }
 
   if (create) {
diff --git a/host/commands/launch/flags.cc b/host/commands/launch/flags.cc
index 49d34b3..ed50269 100644
--- a/host/commands/launch/flags.cc
+++ b/host/commands/launch/flags.cc
@@ -5,6 +5,7 @@
 #include <gflags/gflags.h>
 #include <glog/logging.h>
 
+#include "common/libs/strings/str_split.h"
 #include "common/libs/utils/environment.h"
 #include "common/libs/utils/files.h"
 #include "common/vsoc/lib/vsoc_memory.h"
@@ -12,7 +13,6 @@
 #include "host/commands/launch/data_image.h"
 #include "host/commands/launch/launch.h"
 #include "host/commands/launch/launcher_defs.h"
-#include "host/commands/launch/ril_config.h"
 #include "host/libs/vm_manager/crosvm_manager.h"
 #include "host/libs/vm_manager/qemu_manager.h"
 #include "host/libs/vm_manager/vm_manager.h"
@@ -64,7 +64,7 @@
     "The codename of the device's hardware, one of {cutf_ivsh, cutf_cvm}");
 DEFINE_string(guest_security, "selinux",
               "The security module to use in the guest");
-DEFINE_bool(guest_enforce_security, false,
+DEFINE_bool(guest_enforce_security, true,
             "Whether to run in enforcing mode (non permissive). Ignored if "
             "-guest_security is empty.");
 DEFINE_bool(guest_audit_security, true,
@@ -85,11 +85,19 @@
 DEFINE_string(instance_dir, "", // default handled on ParseCommandLine
               "A directory to put all instance specific files");
 DEFINE_string(
-    vm_manager, vm_manager::QemuManager::name(),
+    vm_manager, vm_manager::CrosvmManager::name(),
     "What virtual machine manager to use, one of {qemu_cli, crosvm}");
+DEFINE_string(
+    gpu_mode, vsoc::kGpuModeGuestSwiftshader,
+    "What gpu configuration to use, one of {guest_swiftshader, drm_virgl}");
+DEFINE_string(wayland_socket, "",
+    "Location of the wayland socket to use for drm_virgl gpu_mode.");
+
 DEFINE_string(system_image_dir, vsoc::DefaultGuestImagePath(""),
               "Location of the system partition images.");
 DEFINE_string(vendor_image, "", "Location of the vendor partition image.");
+DEFINE_string(product_image, "", "Location of the product partition image.");
+DEFINE_string(super_image, "", "Location of the super partition image.");
 
 DEFINE_bool(deprecated_boot_completed, false, "Log boot completed message to"
             " host kernel. This is only used during transition of our clients."
@@ -122,7 +130,7 @@
 DEFINE_string(socket_vsock_proxy_binary,
               vsoc::DefaultHostArtifactsPath("bin/socket_vsock_proxy"),
               "Location of the socket_vsock_proxy binary.");
-DEFINE_string(adb_mode, "",
+DEFINE_string(adb_mode, "vsock_half_tunnel",
               "Mode for ADB connection. Can be 'usb' for USB forwarding, "
               "'tunnel' for a TCP connection tunneled through VSoC, "
               "'vsock_tunnel' for a TCP connection tunneled through vsock, "
@@ -185,6 +193,20 @@
                                "guest to host. One of [serial, vsock]");
 DEFINE_int32(logcat_vsock_port, vsoc::GetPerInstanceDefault(5620),
              "The port for logcat over vsock");
+DEFINE_string(config_server_binary,
+              vsoc::DefaultHostArtifactsPath("bin/config_server"),
+              "Binary for the configuration server");
+DEFINE_int32(config_server_port, vsoc::GetPerInstanceDefault(4680),
+             "The (vsock) port for the configuration server");
+DEFINE_int32(frames_vsock_port, vsoc::GetPerInstanceDefault(5580),
+             "The vsock port to receive frames from the guest on");
+DEFINE_bool(enable_tombstone_receiver, false, "Enables the tombstone logger on "
+            "both the guest and the host");
+DEFINE_string(tombstone_receiver_binary,
+              vsoc::DefaultHostArtifactsPath("bin/tombstone_receiver"),
+              "Binary for the tombstone server");
+DEFINE_int32(tombstone_receiver_port, vsoc::GetPerInstanceDefault(5630),
+             "The vsock port for tombstones");
 namespace {
 
 template<typename S, typename T>
@@ -220,6 +242,12 @@
   std::string default_metadata_image = FLAGS_system_image_dir + "/metadata.img";
   SetCommandLineOptionWithMode("metadata_image", default_metadata_image.c_str(),
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
+  std::string default_product_image = FLAGS_system_image_dir + "/product.img";
+  SetCommandLineOptionWithMode("product_image", default_product_image.c_str(),
+                               google::FlagSettingMode::SET_FLAGS_DEFAULT);
+  std::string default_super_image = FLAGS_system_image_dir + "/super.img";
+  SetCommandLineOptionWithMode("super_image", default_super_image.c_str(),
+                               google::FlagSettingMode::SET_FLAGS_DEFAULT);
 
   return true;
 }
@@ -240,7 +268,20 @@
     LOG(ERROR) << "Invalid vm_manager: " << FLAGS_vm_manager;
     return false;
   }
+  if (!vm_manager::VmManager::IsValidName(FLAGS_vm_manager)) {
+    LOG(ERROR) << "Invalid vm_manager: " << FLAGS_vm_manager;
+    return false;
+  }
   tmp_config_obj.set_vm_manager(FLAGS_vm_manager);
+  tmp_config_obj.set_gpu_mode(FLAGS_gpu_mode);
+  if (!vm_manager::VmManager::ConfigureGpuMode(&tmp_config_obj)) {
+    LOG(ERROR) << "Invalid gpu_mode=" << FLAGS_gpu_mode <<
+               " does not work with vm_manager=" << FLAGS_vm_manager;
+    return false;
+  }
+  tmp_config_obj.set_wayland_socket(FLAGS_wayland_socket);
+
+  vm_manager::VmManager::ConfigureBootDevices(&tmp_config_obj);
 
   tmp_config_obj.set_serial_number(FLAGS_serial_number);
 
@@ -254,7 +295,8 @@
   tmp_config_obj.set_num_screen_buffers(FLAGS_num_screen_buffers);
   tmp_config_obj.set_refresh_rate_hz(FLAGS_refresh_rate_hz);
   tmp_config_obj.set_gdb_flag(FLAGS_qemu_gdb);
-  tmp_config_obj.set_adb_mode(FLAGS_adb_mode);
+  std::vector<std::string> adb = cvd::StrSplit(FLAGS_adb_mode, ',');
+  tmp_config_obj.set_adb_mode(std::set<std::string>(adb.begin(), adb.end()));
   tmp_config_obj.set_adb_ip_and_port("127.0.0.1:" + std::to_string(GetHostPort()));
 
   tmp_config_obj.set_device_title(FLAGS_device_title);
@@ -279,9 +321,16 @@
     ramdisk_path = "";
   }
 
+  // Fallback for older builds, or builds from branches without DAP
+  if (!FLAGS_super_image.empty() && !cvd::FileHasContent(FLAGS_super_image.c_str())) {
+    LOG(INFO) << "No super image detected; assuming non-DAP build";
+    FLAGS_super_image.clear();
+  }
+
   // This needs to be done here because the dtb path depends on the presence of
-  // the ramdisk
-  if (FLAGS_dtb.empty()) {
+  // the ramdisk. If we are booting a super image, the fstab is passed through
+  // from the ramdisk, it should never be defined by dt.
+  if (FLAGS_super_image.empty() && FLAGS_dtb.empty()) {
     if (use_ramdisk) {
       FLAGS_dtb = vsoc::DefaultHostArtifactsPath("config/initrd-root.dtb");
     } else {
@@ -293,6 +342,9 @@
   if (!use_ramdisk) {
     tmp_config_obj.add_kernel_cmdline("root=/dev/vda");
   }
+  if (!FLAGS_super_image.empty()) {
+    tmp_config_obj.add_kernel_cmdline("androidboot.super_partition=vda");
+  }
   tmp_config_obj.add_kernel_cmdline("init=/init");
   tmp_config_obj.add_kernel_cmdline(
       concat("androidboot.serialno=", FLAGS_serial_number));
@@ -316,6 +368,8 @@
     tmp_config_obj.add_kernel_cmdline(concat("androidboot.vsock_logcat_port=",
                                              FLAGS_logcat_vsock_port));
   }
+  tmp_config_obj.add_kernel_cmdline(concat("androidboot.cuttlefish_config_server_port=",
+                                           FLAGS_config_server_port));
   tmp_config_obj.set_hardware_name(FLAGS_hardware_name);
   if (!FLAGS_guest_security.empty()) {
     tmp_config_obj.add_kernel_cmdline(concat("security=", FLAGS_guest_security));
@@ -338,14 +392,26 @@
     tmp_config_obj.add_kernel_cmdline(FLAGS_extra_kernel_cmdline);
   }
 
+  if (FLAGS_super_image.empty()) {
+    tmp_config_obj.set_system_image_path(FLAGS_system_image);
+    tmp_config_obj.set_vendor_image_path(FLAGS_vendor_image);
+    tmp_config_obj.set_product_image_path(FLAGS_product_image);
+    tmp_config_obj.set_super_image_path("");
+    tmp_config_obj.set_dtb_path(FLAGS_dtb);
+    tmp_config_obj.set_gsi_fstab_path(FLAGS_gsi_fstab);
+  } else {
+    tmp_config_obj.set_system_image_path("");
+    tmp_config_obj.set_vendor_image_path("");
+    tmp_config_obj.set_product_image_path("");
+    tmp_config_obj.set_super_image_path(FLAGS_super_image);
+    tmp_config_obj.set_dtb_path("");
+    tmp_config_obj.set_gsi_fstab_path("");
+  }
+
   tmp_config_obj.set_ramdisk_image_path(ramdisk_path);
-  tmp_config_obj.set_system_image_path(FLAGS_system_image);
   tmp_config_obj.set_cache_image_path(FLAGS_cache_image);
   tmp_config_obj.set_data_image_path(FLAGS_data_image);
-  tmp_config_obj.set_vendor_image_path(FLAGS_vendor_image);
   tmp_config_obj.set_metadata_image_path(FLAGS_metadata_image);
-  tmp_config_obj.set_dtb_path(FLAGS_dtb);
-  tmp_config_obj.set_gsi_fstab_path(FLAGS_gsi_fstab);
 
   tmp_config_obj.set_mempath(FLAGS_mempath);
   tmp_config_obj.set_ivshmem_qemu_socket_path(
@@ -365,13 +431,13 @@
   tmp_config_obj.set_console_path(tmp_config_obj.PerInstancePath("console"));
   tmp_config_obj.set_logcat_path(tmp_config_obj.PerInstancePath("logcat"));
   tmp_config_obj.set_logcat_receiver_binary(FLAGS_logcat_receiver_binary);
+  tmp_config_obj.set_config_server_binary(FLAGS_config_server_binary);
   tmp_config_obj.set_launcher_log_path(tmp_config_obj.PerInstancePath("launcher.log"));
   tmp_config_obj.set_launcher_monitor_socket_path(
       tmp_config_obj.PerInstancePath("launcher_monitor.sock"));
 
   tmp_config_obj.set_mobile_bridge_name(FLAGS_mobile_interface);
   tmp_config_obj.set_mobile_tap_name(FLAGS_mobile_tap_name);
-  ConfigureRil(&tmp_config_obj);
 
   tmp_config_obj.set_wifi_tap_name(FLAGS_wifi_tap_name);
 
@@ -418,6 +484,25 @@
 
   tmp_config_obj.set_logcat_mode(FLAGS_logcat_mode);
   tmp_config_obj.set_logcat_vsock_port(FLAGS_logcat_vsock_port);
+  tmp_config_obj.set_config_server_port(FLAGS_config_server_port);
+  tmp_config_obj.set_frames_vsock_port(FLAGS_frames_vsock_port);
+  if (!tmp_config_obj.enable_ivserver()) {
+    tmp_config_obj.add_kernel_cmdline(concat("androidboot.vsock_frames_port=",
+                                             FLAGS_frames_vsock_port));
+  }
+
+  tmp_config_obj.set_enable_tombstone_receiver(FLAGS_enable_tombstone_receiver);
+  tmp_config_obj.set_tombstone_receiver_port(FLAGS_tombstone_receiver_port);
+  tmp_config_obj.set_tombstone_receiver_binary(FLAGS_tombstone_receiver_binary);
+  if (FLAGS_enable_tombstone_receiver) {
+    tmp_config_obj.add_kernel_cmdline("androidboot.tombstone_transmit=1");
+    tmp_config_obj.add_kernel_cmdline(concat("androidboot.vsock_tombstone_port="
+      ,FLAGS_tombstone_receiver_port));
+    // TODO (b/128842613) populate a cid flag to read the host CID during
+    // runtime
+  } else {
+    tmp_config_obj.add_kernel_cmdline("androidboot.tombstone_transmit=0");
+  }
 
   tmp_config_obj.set_cuttlefish_env_path(GetCuttlefishEnvPath());
 
@@ -458,8 +543,6 @@
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
   SetCommandLineOptionWithMode("hardware_name", "cutf_ivsh",
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
-  SetCommandLineOptionWithMode("adb_mode", "tunnel",
-                               google::FlagSettingMode::SET_FLAGS_DEFAULT);
   SetCommandLineOptionWithMode("decompress_kernel", "false",
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
   SetCommandLineOptionWithMode("logcat_mode", cvd::kLogcatSerialMode,
@@ -484,16 +567,17 @@
   SetCommandLineOptionWithMode("instance_dir",
                                default_instance_dir.c_str(),
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
-  SetCommandLineOptionWithMode("hardware_name", "cutf_cvm",
+  auto default_wayland_socket = vsoc::DefaultEnvironmentPath(
+      "XDG_RUNTIME_DIR", default_instance_dir.c_str(), "wayland-0");
+  SetCommandLineOptionWithMode("wayland_socket",
+                               default_wayland_socket.c_str(),
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
-  SetCommandLineOptionWithMode("adb_mode", "vsock_tunnel",
+  SetCommandLineOptionWithMode("hardware_name", "cutf_cvm",
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
   SetCommandLineOptionWithMode("decompress_kernel", "true",
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
   SetCommandLineOptionWithMode("run_e2e_test", "false",
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
-  SetCommandLineOptionWithMode("start_vnc_server", "false",
-                               google::FlagSettingMode::SET_FLAGS_DEFAULT);
   SetCommandLineOptionWithMode("logcat_mode", cvd::kLogcatVsockMode,
                                google::FlagSettingMode::SET_FLAGS_DEFAULT);
 }
@@ -633,10 +717,11 @@
 
   // Check that the files exist
   for (const auto& file :
-       {config->system_image_path(), config->vendor_image_path(),
-        config->cache_image_path(), config->data_image_path(),
-        config->metadata_image_path()}) {
-    if (!cvd::FileHasContent(file.c_str())) {
+       {config->system_image_path(), config->cache_image_path(),
+        config->data_image_path(), config->vendor_image_path(),
+        config->metadata_image_path(),  config->product_image_path(),
+        config->super_image_path()}) {
+    if (!file.empty() && !cvd::FileHasContent(file.c_str())) {
       LOG(ERROR) << "File not found: " << file;
       exit(cvd::kCuttlefishConfigurationInitError);
     }
diff --git a/host/commands/launch/launch.cc b/host/commands/launch/launch.cc
index 6af5b4f..e5f6d37 100644
--- a/host/commands/launch/launch.cc
+++ b/host/commands/launch/launch.cc
@@ -3,7 +3,7 @@
 #include <glog/logging.h>
 
 #include "common/libs/fs/shared_fd.h"
-#include "common/libs/strings/str_split.h"
+#include "common/libs/utils/files.h"
 #include "common/libs/utils/size_utils.h"
 #include "common/vsoc/shm/screen_layout.h"
 #include "host/commands/launch/launcher_defs.h"
@@ -46,8 +46,7 @@
 }
 
 bool AdbModeEnabled(const vsoc::CuttlefishConfig& config, const char* mode) {
-  auto modes = cvd::StrSplit(config.adb_mode(), ',');
-  return std::find(modes.begin(), modes.end(), mode) != modes.end();
+  return config.adb_mode().count(mode) > 0;
 }
 
 bool AdbTunnelEnabled(const vsoc::CuttlefishConfig& config) {
@@ -102,13 +101,13 @@
 
 void ValidateAdbModeFlag(const vsoc::CuttlefishConfig& config) {
   if (!AdbUsbEnabled(config) && !AdbTunnelEnabled(config)
-      && !AdbVsockTunnelEnabled(config)) {
+      && !AdbVsockTunnelEnabled(config) && !AdbVsockHalfTunnelEnabled(config)) {
     LOG(INFO) << "ADB not enabled";
   }
 }
 
 cvd::Command GetIvServerCommand(const vsoc::CuttlefishConfig& config) {
-  // Resize gralloc region
+  // Resize screen region
   auto actual_width = cvd::AlignToPowerOf2(config.x_res() * 4, 4);// align to 16
   uint32_t screen_buffers_size =
       config.num_screen_buffers() *
@@ -133,25 +132,40 @@
   return ivserver;
 }
 
-// Build the kernel log monitor command. If boot_event_pipe is not NULL, a
-// subscription to boot events from the kernel log monitor will be created and
-// events will appear on *boot_events_pipe
-cvd::Command GetKernelLogMonitorCommand(const vsoc::CuttlefishConfig& config,
-                                        cvd::SharedFD* boot_events_pipe) {
+std::vector<cvd::SharedFD> LaunchKernelLogMonitor(
+    const vsoc::CuttlefishConfig& config,
+    cvd::ProcessMonitor* process_monitor,
+    unsigned int number_of_event_pipes) {
   auto log_name = config.kernel_log_socket_name();
   auto server = cvd::SharedFD::SocketLocalServer(log_name.c_str(), false,
                                                  SOCK_STREAM, 0666);
-  cvd::Command kernel_log_monitor(config.kernel_log_monitor_binary());
-  kernel_log_monitor.AddParameter("-log_server_fd=", server);
-  if (boot_events_pipe) {
-    cvd::SharedFD pipe_write_end;
-    if (!cvd::SharedFD::Pipe(boot_events_pipe, &pipe_write_end)) {
-      LOG(ERROR) << "Unable to create boot events pipe: " << strerror(errno);
-      std::exit(LauncherExitCodes::kPipeIOError);
+  cvd::Command command(config.kernel_log_monitor_binary());
+  command.AddParameter("-log_server_fd=", server);
+
+  std::vector<cvd::SharedFD> ret;
+
+  if (number_of_event_pipes > 0) {
+    auto param_builder = command.GetParameterBuilder();
+    param_builder << "-subscriber_fds=";
+    for (unsigned int i = 0; i < number_of_event_pipes; ++i) {
+      cvd::SharedFD event_pipe_write_end, event_pipe_read_end;
+      if (!cvd::SharedFD::Pipe(&event_pipe_read_end, &event_pipe_write_end)) {
+        LOG(ERROR) << "Unable to create boot events pipe: " << strerror(errno);
+        std::exit(LauncherExitCodes::kPipeIOError);
+      }
+      if (i > 0) {
+        param_builder << ",";
+      }
+      param_builder << event_pipe_write_end;
+      ret.push_back(event_pipe_read_end);
     }
-    kernel_log_monitor.AddParameter("-subscriber_fd=", pipe_write_end);
+    param_builder.Build();
   }
-  return kernel_log_monitor;
+
+  process_monitor->StartSubprocess(std::move(command),
+                                   GetOnSubprocessExitCallback(config));
+
+  return ret;
 }
 
 void LaunchLogcatReceiverIfEnabled(const vsoc::CuttlefishConfig& config,
@@ -172,6 +186,53 @@
                                    GetOnSubprocessExitCallback(config));
 }
 
+void LaunchConfigServer(const vsoc::CuttlefishConfig& config,
+                        cvd::ProcessMonitor* process_monitor) {
+  auto port = config.config_server_port();
+  auto socket = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+  if (!socket->IsOpen()) {
+    LOG(ERROR) << "Unable to create configuration server socket: "
+               << socket->StrError();
+    std::exit(LauncherExitCodes::kConfigServerError);
+  }
+  cvd::Command cmd(config.config_server_binary());
+  cmd.AddParameter("-server_fd=", socket);
+  process_monitor->StartSubprocess(std::move(cmd),
+                                   GetOnSubprocessExitCallback(config));
+}
+
+void LaunchTombstoneReceiverIfEnabled(const vsoc::CuttlefishConfig& config,
+                                      cvd::ProcessMonitor* process_monitor) {
+  if (!config.enable_tombstone_receiver()) {
+    return;
+  }
+
+  std::string tombstoneDir = config.PerInstancePath("tombstones");
+  if (!cvd::DirectoryExists(tombstoneDir.c_str())) {
+    LOG(INFO) << "Setting up " << tombstoneDir;
+    if (mkdir(tombstoneDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) <
+        0) {
+      LOG(ERROR) << "Failed to create tombstone directory: " << tombstoneDir
+                 << ". Error: " << errno;
+      exit(LauncherExitCodes::kTombstoneDirCreationError);
+    }
+  }
+
+  auto port = config.tombstone_receiver_port();
+  auto socket = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+  if (!socket->IsOpen()) {
+    LOG(ERROR) << "Unable to create tombstone server socket: "
+               << socket->StrError();
+    std::exit(LauncherExitCodes::kTombstoneServerError);
+  }
+  cvd::Command cmd(config.tombstone_receiver_binary());
+  cmd.AddParameter("-server_fd=", socket);
+  cmd.AddParameter("-tombstone_dir=", tombstoneDir);
+
+  process_monitor->StartSubprocess(std::move(cmd),
+                                   GetOnSubprocessExitCallback(config));
+}
+
 void LaunchUsbServerIfEnabled(const vsoc::CuttlefishConfig& config,
                               cvd::ProcessMonitor* process_monitor) {
   if (!AdbUsbEnabled(config)) {
@@ -191,6 +252,16 @@
                                    GetOnSubprocessExitCallback(config));
 }
 
+cvd::SharedFD CreateVncInputServer(const std::string& path) {
+  auto server = cvd::SharedFD::SocketLocalServer(path.c_str(), false, SOCK_STREAM, 0666);
+  if (!server->IsOpen()) {
+    LOG(ERROR) << "Unable to create mouse server: "
+               << server->StrError();
+    return cvd::SharedFD();
+  }
+  return server;
+}
+
 void LaunchVNCServerIfEnabled(const vsoc::CuttlefishConfig& config,
                               cvd::ProcessMonitor* process_monitor,
                               std::function<bool(MonitorEntry*)> callback) {
@@ -199,6 +270,33 @@
     auto port_options = "-port=" + std::to_string(config.vnc_server_port());
     cvd::Command vnc_server(config.vnc_server_binary());
     vnc_server.AddParameter(port_options);
+    if (!config.enable_ivserver()) {
+      // When the ivserver is not enabled, the vnc touch_server needs to serve
+      // on unix sockets and send input events to whoever connects to it (namely
+      // crosvm)
+      auto touch_server = CreateVncInputServer(config.touch_socket_path());
+      if (!touch_server->IsOpen()) {
+        return;
+      }
+      vnc_server.AddParameter("-touch_fd=", touch_server);
+
+      auto keyboard_server =
+          CreateVncInputServer(config.keyboard_socket_path());
+      if (!keyboard_server->IsOpen()) {
+        return;
+      }
+      vnc_server.AddParameter("-keyboard_fd=", keyboard_server);
+      // TODO(b/128852363): This should be handled through the wayland mock
+      //  instead.
+      // Additionally it receives the frame updates from a virtual socket
+      // instead
+      auto frames_server =
+          cvd::SharedFD::VsockServer(config.frames_vsock_port(), SOCK_STREAM);
+      if (!frames_server->IsOpen()) {
+        return;
+      }
+      vnc_server.AddParameter("-frame_server_fd=", frames_server);
+    }
     process_monitor->StartSubprocess(std::move(vnc_server), callback);
   }
 }
@@ -215,16 +313,22 @@
 }
 
 void LaunchAdbConnectorIfEnabled(cvd::ProcessMonitor* process_monitor,
-                                 const vsoc::CuttlefishConfig& config) {
+                                 const vsoc::CuttlefishConfig& config,
+                                 cvd::SharedFD adbd_events_pipe) {
+  bool launch = false;
+  cvd::Command adb_connector(config.adb_connector_binary());
+  adb_connector.AddParameter("-adbd_events_fd=", adbd_events_pipe);
+
   if (AdbTcpConnectorEnabled(config)) {
-    cvd::Command adb_connector(config.adb_connector_binary());
+    launch = true;
     adb_connector.AddParameter(GetAdbConnectorTcpArg());
-    process_monitor->StartSubprocess(std::move(adb_connector),
-                                     GetOnSubprocessExitCallback(config));
   }
   if (AdbVsockConnectorEnabled(config)) {
-    cvd::Command adb_connector(config.adb_connector_binary());
+    launch = true;
     adb_connector.AddParameter(GetAdbConnectorVsockArg(config));
+  }
+
+  if (launch) {
     process_monitor->StartSubprocess(std::move(adb_connector),
                                      GetOnSubprocessExitCallback(config));
   }
diff --git a/host/commands/launch/launch.h b/host/commands/launch/launch.h
index 550ce02..4b23958 100644
--- a/host/commands/launch/launch.h
+++ b/host/commands/launch/launch.h
@@ -11,10 +11,14 @@
 void ValidateAdbModeFlag(const vsoc::CuttlefishConfig& config);
 
 cvd::Command GetIvServerCommand(const vsoc::CuttlefishConfig& config);
-cvd::Command GetKernelLogMonitorCommand(const vsoc::CuttlefishConfig& config,
-                                        cvd::SharedFD* boot_events_pipe);
+std::vector <cvd::SharedFD> LaunchKernelLogMonitor(
+    const vsoc::CuttlefishConfig& config,
+    cvd::ProcessMonitor* process_monitor,
+    unsigned int number_of_event_pipes);
 void LaunchLogcatReceiverIfEnabled(const vsoc::CuttlefishConfig& config,
                                    cvd::ProcessMonitor* process_monitor);
+void LaunchConfigServer(const vsoc::CuttlefishConfig& config,
+                        cvd::ProcessMonitor* process_monitor);
 void LaunchUsbServerIfEnabled(const vsoc::CuttlefishConfig& config,
                               cvd::ProcessMonitor* process_monitor);
 void LaunchVNCServerIfEnabled(const vsoc::CuttlefishConfig& config,
@@ -24,10 +28,13 @@
                                 cvd::ProcessMonitor* process_monitor,
                                 std::function<bool(cvd::MonitorEntry*)> callback);
 void LaunchAdbConnectorIfEnabled(cvd::ProcessMonitor* process_monitor,
-                                 const vsoc::CuttlefishConfig& config);
+                                 const vsoc::CuttlefishConfig& config,
+                                 cvd::SharedFD adbd_events_pipe);
 void LaunchSocketForwardProxyIfEnabled(cvd::ProcessMonitor* process_monitor,
                                  const vsoc::CuttlefishConfig& config);
 void LaunchSocketVsockProxyIfEnabled(cvd::ProcessMonitor* process_monitor,
                                  const vsoc::CuttlefishConfig& config);
 void LaunchIvServerIfEnabled(cvd::ProcessMonitor* process_monitor,
                              const vsoc::CuttlefishConfig& config);
+void LaunchTombstoneReceiverIfEnabled(const vsoc::CuttlefishConfig& config,
+                                      cvd::ProcessMonitor* process_monitor);
\ No newline at end of file
diff --git a/host/commands/launch/launcher_defs.h b/host/commands/launch/launcher_defs.h
index 9a78a4e..2bca212 100644
--- a/host/commands/launch/launcher_defs.h
+++ b/host/commands/launch/launcher_defs.h
@@ -40,6 +40,9 @@
   kE2eTestFailed = 16,
   kKernelDecompressError = 17,
   kLogcatServerError = 18,
+  kConfigServerError = 19,
+  kTombstoneServerError = 20,
+  kTombstoneDirCreationError = 21,
 };
 
 // Actions supported by the launcher server
diff --git a/host/commands/launch/main.cc b/host/commands/launch/main.cc
index ff2c7dd..a9c8e3e 100644
--- a/host/commands/launch/main.cc
+++ b/host/commands/launch/main.cc
@@ -412,20 +412,21 @@
   // Monitor and restart host processes supporting the CVD
   cvd::ProcessMonitor process_monitor;
 
-  cvd::SharedFD boot_events_pipe;
-  // Only subscribe to boot events if running as daemon
-  process_monitor.StartSubprocess(
-      GetKernelLogMonitorCommand(*config,
-                                 config->run_as_daemon()
-                                   ? &boot_events_pipe
-                                   : nullptr),
-      GetOnSubprocessExitCallback(*config));
+  auto event_pipes =
+      LaunchKernelLogMonitor(*config, &process_monitor, 2);
+  cvd::SharedFD boot_events_pipe = event_pipes[0];
+  cvd::SharedFD adbd_events_pipe = event_pipes[1];
+  event_pipes.clear();
 
   SetUpHandlingOfBootEvents(&process_monitor, boot_events_pipe,
                             boot_state_machine);
 
   LaunchLogcatReceiverIfEnabled(*config, &process_monitor);
 
+  LaunchConfigServer(*config, &process_monitor);
+
+  LaunchTombstoneReceiverIfEnabled(*config, &process_monitor);
+
   LaunchUsbServerIfEnabled(*config, &process_monitor);
 
   LaunchIvServerIfEnabled(&process_monitor, *config);
@@ -443,7 +444,7 @@
                            GetOnSubprocessExitCallback(*config));
   LaunchStreamAudioIfEnabled(*config, &process_monitor,
                              GetOnSubprocessExitCallback(*config));
-  LaunchAdbConnectorIfEnabled(&process_monitor, *config);
+  LaunchAdbConnectorIfEnabled(&process_monitor, *config, adbd_events_pipe);
 
   ServerLoop(launcher_monitor_socket, vm_manager); // Should not return
   LOG(ERROR) << "The server loop returned, it should never happen!!";
diff --git a/host/commands/tombstone_receiver/Android.bp b/host/commands/tombstone_receiver/Android.bp
new file mode 100644
index 0000000..5f5a5a5
--- /dev/null
+++ b/host/commands/tombstone_receiver/Android.bp
@@ -0,0 +1,37 @@
+//
+// Copyright (C) 2019 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 is 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.
+
+cc_binary_host {
+    name: "tombstone_receiver",
+    srcs: [
+        "main.cpp",
+    ],
+    header_libs: [
+        "cuttlefish_glog",
+    ],
+    shared_libs: [
+        "libbase",
+        "libcuttlefish_fs",
+        "liblog",
+        "libcuttlefish_utils",
+        "cuttlefish_auto_resources",
+    ],
+    static_libs: [
+        "libcuttlefish_host_config",
+        "libgflags",
+        "libjsoncpp",
+    ],
+    defaults: ["cuttlefish_host_only"],
+}
diff --git a/host/commands/tombstone_receiver/main.cpp b/host/commands/tombstone_receiver/main.cpp
new file mode 100644
index 0000000..7bea670
--- /dev/null
+++ b/host/commands/tombstone_receiver/main.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2019 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 is 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 <gflags/gflags.h>
+#include <glog/logging.h>
+
+#include <chrono>
+#include <fstream>
+#include <iomanip>
+#include <sstream>
+
+#include "common/libs/fs/shared_fd.h"
+#include "host/libs/config/cuttlefish_config.h"
+
+DEFINE_int32(
+    server_fd, -1,
+    "File descriptor to an already created vsock server. If negative a new "
+    "server will be created at the port specified on the config file");
+DEFINE_string(tombstone_dir, "", "directory to write out tombstones in");
+
+static uint num_tombstones_in_last_second = 0;
+static std::string last_tombstone_name = "";
+
+static std::string next_tombstone_path() {
+  auto in_time_t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
+  std::stringstream ss;
+  ss << FLAGS_tombstone_dir << "/tombstone_" <<
+    std::put_time(std::gmtime(&in_time_t), "%Y-%m-%d-%H%M%S");
+  auto retval = ss.str();
+
+  // Gives tombstones unique names
+  if(retval == last_tombstone_name) {
+    num_tombstones_in_last_second++;
+    retval += "_" + std::to_string(num_tombstones_in_last_second);
+  } else {
+    last_tombstone_name = retval;
+    num_tombstones_in_last_second = 0;
+  }
+
+  LOG(INFO) << "Creating " << retval;
+  return retval;
+}
+
+#define CHUNK_RECV_MAX_LEN (1024)
+int main(int argc, char** argv) {
+  ::android::base::InitLogging(argv, android::base::StderrLogger);
+  google::ParseCommandLineFlags(&argc, &argv, true);
+
+  auto config = vsoc::CuttlefishConfig::Get();
+  cvd::SharedFD server_fd;
+
+  if (FLAGS_server_fd < 0) {
+    unsigned int port = config->tombstone_receiver_port();
+    server_fd = cvd::SharedFD::VsockServer(port, SOCK_STREAM);
+  } else {
+    server_fd = cvd::SharedFD::Dup(FLAGS_server_fd);
+    close(FLAGS_server_fd);
+  }
+
+  CHECK(server_fd->IsOpen()) << "Error creating/inheriting tombstone server: "
+                             << server_fd->StrError();
+  LOG(INFO) << "Host is starting server on port "
+            << config->tombstone_receiver_port();
+
+  // Server loop
+  while (true) {
+    auto conn = cvd::SharedFD::Accept(*server_fd);
+    std::ofstream file(next_tombstone_path(),
+                       std::ofstream::out | std::ofstream::binary);
+
+    while (file.is_open()) {
+      char buff[CHUNK_RECV_MAX_LEN];
+      auto bytes_read = conn->Read(buff, sizeof(buff));
+      if (bytes_read <= 0) {
+        // reset the other side if it's still connected
+        break;
+      } else {
+        file.write(buff, bytes_read);
+      }
+    }
+  }
+
+  return 0;
+}
diff --git a/host/frontend/adb_connector/main.cpp b/host/frontend/adb_connector/main.cpp
index e046b3d..93a929d 100644
--- a/host/frontend/adb_connector/main.cpp
+++ b/host/frontend/adb_connector/main.cpp
@@ -25,12 +25,18 @@
 #include <gflags/gflags.h>
 
 #include <unistd.h>
+#include <host/commands/kernel_log_monitor/kernel_log_server.h>
 
+#include "common/libs/fs/shared_fd.h"
 #include "common/libs/strings/str_split.h"
 #include "host/libs/config/cuttlefish_config.h"
 #include "host/libs/adb_connection_maintainer/adb_connection_maintainer.h"
 
-DEFINE_string(addresses, "", "Comma-separated list of addresses to 'adb connect' to");
+DEFINE_string(addresses, "", "Comma-separated list of addresses to "
+                             "'adb connect' to");
+DEFINE_int32(adbd_events_fd, -1, "A file descriptor. If set it will wait for "
+                                 "AdbdStarted boot event from the kernel log "
+                                 "monitor before trying to connect adb");
 
 namespace {
 void LaunchConnectionMaintainerThread(const std::string& address) {
@@ -49,12 +55,36 @@
     sleep(std::numeric_limits<unsigned int>::max());
   }
 }
+
+void WaitForAdbdToBeStarted(int events_fd) {
+  auto evt_shared_fd = cvd::SharedFD::Dup(events_fd);
+  close(events_fd);
+  while (evt_shared_fd->IsOpen()) {
+    monitor::BootEvent event;
+    auto bytes_read = evt_shared_fd->Read(&event, sizeof(event));
+    if (bytes_read != sizeof(event)) {
+      LOG(ERROR) << "Fail to read a complete event, read " << bytes_read
+                 << " bytes only instead of the expected " << sizeof(event);
+      // The file descriptor can't be trusted anymore, stop waiting and try to
+      // connect
+      return;
+    }
+    if (event == monitor::BootEvent::AdbdStarted) {
+      LOG(INFO) << "Adbd has started in the guest, connecting adb";
+      return;
+    }
+  }
+}
 }  // namespace
 
 int main(int argc, char* argv[]) {
   gflags::ParseCommandLineFlags(&argc, &argv, true);
   CHECK(!FLAGS_addresses.empty()) << "Must specify --addresses flag";
 
+  if (FLAGS_adbd_events_fd >= 0) {
+    WaitForAdbdToBeStarted(FLAGS_adbd_events_fd);
+  }
+
   for (auto address : ParseAddressList(FLAGS_addresses)) {
     LaunchConnectionMaintainerThread(address);
   }
diff --git a/host/frontend/vnc_server/Android.bp b/host/frontend/vnc_server/Android.bp
index 241df83..fae5a17 100644
--- a/host/frontend/vnc_server/Android.bp
+++ b/host/frontend/vnc_server/Android.bp
@@ -20,6 +20,7 @@
         "frame_buffer_watcher.cpp",
         "jpeg_compressor.cpp",
         "main.cpp",
+        "screen_connector.cpp",
         "simulated_hw_composer.cpp",
         "virtual_inputs.cpp",
         "vnc_client_connection.cpp",
diff --git a/host/frontend/vnc_server/frame_buffer_watcher.cpp b/host/frontend/vnc_server/frame_buffer_watcher.cpp
index bc6b892..592b88e 100644
--- a/host/frontend/vnc_server/frame_buffer_watcher.cpp
+++ b/host/frontend/vnc_server/frame_buffer_watcher.cpp
@@ -64,13 +64,14 @@
     LOG(FATAL) << "Rotating a landscape stripe, this is a mistake";
   }
   auto w = stripe.width;
+  auto s = stripe.stride;
   auto h = stripe.height;
   const auto& raw = stripe.raw_data;
   Message rotated(raw.size(), 0xAA);
   for (std::uint16_t i = 0; i < w; ++i) {
     for (std::uint16_t j = 0; j < h; ++j) {
       size_t to = (i * h + j) * BytesPerPixel();
-      size_t from = (w - (i + 1) + w * j) * BytesPerPixel();
+      size_t from = (w - (i + 1)) * BytesPerPixel() + s * j;
       CHECK(from < raw.size());
       CHECK(to < rotated.size());
       std::memcpy(&rotated[to], &raw[from], BytesPerPixel());
@@ -78,6 +79,8 @@
   }
   std::swap(stripe.x, stripe.y);
   std::swap(stripe.width, stripe.height);
+  // The new stride after rotating is the height, as it is not aligned again.
+  stripe.stride = stripe.width * BytesPerPixel();
   stripe.raw_data = std::move(rotated);
   stripe.orientation = ScreenOrientation::Landscape;
   return stripe;
@@ -136,7 +139,7 @@
                                         Stripe* stripe) {
   stripe->jpeg_data = jpeg_compressor->Compress(
       stripe->raw_data, bb_->jpeg_quality_level(), 0, 0, stripe->width,
-      stripe->height, stripe->width);
+      stripe->height, stripe->stride);
 }
 
 void FrameBufferWatcher::Worker() {
diff --git a/host/frontend/vnc_server/jpeg_compressor.cpp b/host/frontend/vnc_server/jpeg_compressor.cpp
index 87f75fd..2d57707 100644
--- a/host/frontend/vnc_server/jpeg_compressor.cpp
+++ b/host/frontend/vnc_server/jpeg_compressor.cpp
@@ -43,7 +43,7 @@
                                       int jpeg_quality, std::uint16_t x,
                                       std::uint16_t y, std::uint16_t width,
                                       std::uint16_t height,
-                                      int screen_width) {
+                                      int stride) {
   jpeg_compress_struct cinfo{};
   jpeg_error_mgr err{};
   InitCinfo(&cinfo, &err, width, height, jpeg_quality);
@@ -55,8 +55,8 @@
 
   while (cinfo.next_scanline < cinfo.image_height) {
     auto row = static_cast<JSAMPROW>(const_cast<std::uint8_t*>(
-        &frame[(y * screen_width * BytesPerPixel()) +
-               (cinfo.next_scanline * BytesPerPixel() * screen_width) +
+        &frame[(y * stride) +
+               (cinfo.next_scanline * stride) +
                (x * BytesPerPixel())]));
     jpeg_write_scanlines(&cinfo, &row, 1);
   }
diff --git a/host/frontend/vnc_server/screen_connector.cpp b/host/frontend/vnc_server/screen_connector.cpp
new file mode 100644
index 0000000..1b9b900
--- /dev/null
+++ b/host/frontend/vnc_server/screen_connector.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2019 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 is 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 "host/frontend/vnc_server/screen_connector.h"
+
+#include <atomic>
+#include <condition_variable>
+
+#include <gflags/gflags.h>
+
+#include <common/vsoc/lib/screen_region_view.h>
+#include <host/libs/config/cuttlefish_config.h>
+#include "host/frontend/vnc_server/vnc_utils.h"
+
+DEFINE_int32(frame_server_fd, -1, "");
+
+namespace cvd {
+namespace vnc {
+
+namespace {
+class VSoCScreenConnector : public ScreenConnector {
+ public:
+  int WaitForNewFrameSince(std::uint32_t* seq_num) override {
+    if (!screen_view_) return -1;
+    return screen_view_->WaitForNewFrameSince(seq_num);
+  }
+
+  void* GetBuffer(int buffer_idx) override {
+    if (!screen_view_) return nullptr;
+    return screen_view_->GetBuffer(buffer_idx);
+  }
+
+ private:
+  vsoc::screen::ScreenRegionView* screen_view_ =
+      vsoc::screen::ScreenRegionView::GetInstance(vsoc::GetDomain().c_str());
+};
+
+// TODO(b/128852363): Substitute with one based on memory shared with the
+//  wayland mock
+class SocketBasedScreenConnector : public ScreenConnector {
+ public:
+  SocketBasedScreenConnector(vsoc::CuttlefishConfig* config) : config_(config) {
+    screen_server_thread_ = std::thread([this]() { ServerLoop(); });
+  }
+
+  int WaitForNewFrameSince(std::uint32_t* seq_num) override {
+    std::unique_lock<std::mutex> lock(new_frame_mtx_);
+    while (seq_num_ == *seq_num) {
+      new_frame_cond_var_.wait(lock);
+    }
+    *seq_num = seq_num_;
+    return newest_buffer_;
+  }
+
+  void* GetBuffer(int buffer_idx) override {
+    if (buffer_idx < 0) return nullptr;
+    buffer_idx %= NUM_BUFFERS_;
+    return &buffer_[buffer_idx * ScreenSizeInBytes()];
+  }
+
+ private:
+  static constexpr int NUM_BUFFERS_ = 4;
+
+  void ServerLoop() {
+    if (FLAGS_frame_server_fd < 0) {
+      LOG(FATAL) << "Invalid file descriptor: " << FLAGS_frame_server_fd;
+      return;
+    }
+    auto server = SharedFD::Dup(FLAGS_frame_server_fd);
+    close(FLAGS_frame_server_fd);
+    if (!server->IsOpen()) {
+      LOG(FATAL) << "Unable to dup screen server: " << server->StrError();
+      return;
+    }
+
+    int current_buffer = 0;
+
+    while (1) {
+      auto conn = SharedFD::Accept(*server);
+      while (conn->IsOpen()) {
+        SendScreenParameters(conn);
+
+        int32_t size = 0;
+        conn->Read(&size, sizeof(size));
+        auto buff = reinterpret_cast<uint8_t*>(GetBuffer(current_buffer));
+        while (size > 0) {
+          auto read = conn->Read(buff, size);
+          if (read < 0) {
+            LOG(ERROR) << "Failed to read from hwcomposer: "
+                       << conn->StrError();
+            return;
+          }
+          size -= read;
+          buff += read;
+        }
+        BroadcastNewFrame(current_buffer);
+        current_buffer = (current_buffer + 1) % NUM_BUFFERS_;
+      }
+    }
+  }
+
+  void SendScreenParameters(SharedFD conn) const {
+    // TODO(b/128842613): Send this info from the configuration server
+    int32_t screen_params[4];
+    screen_params[0] = config_->x_res();
+    screen_params[1] = config_->y_res();
+    screen_params[2] = config_->dpi();
+    screen_params[3] = config_->refresh_rate_hz();
+    int buff_size = sizeof(screen_params);
+    int res = conn->Write(screen_params, buff_size);
+    if (res != buff_size) {
+          LOG(FATAL)
+              << "Unable to send full screen parameters to the hwcomposer ("
+              << res << "): " << conn->StrError();
+        }
+  }
+
+  void BroadcastNewFrame(int buffer_idx) {
+    {
+      std::lock_guard<std::mutex> lock(new_frame_mtx_);
+      seq_num_++;
+      newest_buffer_ = buffer_idx;
+    }
+    new_frame_cond_var_.notify_all();
+  }
+
+  vsoc::CuttlefishConfig* config_;
+  std::vector<std::uint8_t> buffer_ =
+      std::vector<std::uint8_t>(NUM_BUFFERS_ * ScreenSizeInBytes());
+  std::uint32_t seq_num_{0};
+  int newest_buffer_ = 0;
+  std::condition_variable new_frame_cond_var_;
+  std::mutex new_frame_mtx_;
+  std::thread screen_server_thread_;
+};
+}  // namespace
+
+ScreenConnector* ScreenConnector::Get() {
+  auto config = vsoc::CuttlefishConfig::Get();
+  if (config->enable_ivserver()) {
+    return new VSoCScreenConnector();
+  } else {
+    return new SocketBasedScreenConnector(config);
+  }
+}
+
+}  // namespace vnc
+}  // namespace cvd
\ No newline at end of file
diff --git a/host/commands/launch/ril_config.h b/host/frontend/vnc_server/screen_connector.h
similarity index 63%
copy from host/commands/launch/ril_config.h
copy to host/frontend/vnc_server/screen_connector.h
index 49a43e8..9c7b9e0 100644
--- a/host/commands/launch/ril_config.h
+++ b/host/frontend/vnc_server/screen_connector.h
@@ -1,5 +1,3 @@
-#pragma once
-
 /*
  * Copyright (C) 2019 The Android Open Source Project
  *
@@ -16,6 +14,25 @@
  * limitations under the License.
  */
 
-#include "host/libs/config/cuttlefish_config.h"
+#pragma once
 
-void ConfigureRil(vsoc::CuttlefishConfig* config);
\ No newline at end of file
+#include <cstdint>
+
+namespace cvd {
+namespace vnc {
+
+class ScreenConnector {
+ public:
+  static ScreenConnector* Get();
+
+  virtual ~ScreenConnector() = default;
+
+  virtual int WaitForNewFrameSince(std::uint32_t* seq_num) = 0;
+  virtual void* GetBuffer(int buffer_idx) = 0;
+
+ protected:
+  ScreenConnector() = default;
+};
+
+}  // namespace vnc
+}  // namespace cvd
\ No newline at end of file
diff --git a/host/frontend/vnc_server/simulated_hw_composer.cpp b/host/frontend/vnc_server/simulated_hw_composer.cpp
index c8b7f03..7a94454 100644
--- a/host/frontend/vnc_server/simulated_hw_composer.cpp
+++ b/host/frontend/vnc_server/simulated_hw_composer.cpp
@@ -18,7 +18,6 @@
 
 #include "host/frontend/vnc_server/vnc_utils.h"
 #include "host/libs/config/cuttlefish_config.h"
-#include "common/vsoc/lib/screen_region_view.h"
 
 using cvd::vnc::SimulatedHWComposer;
 using vsoc::screen::ScreenRegionView;
@@ -74,12 +73,11 @@
   auto screen_height = ActualScreenHeight();
   Message raw_screen;
   std::uint64_t stripe_seq_num = 1;
-  auto screen_view = ScreenRegionView::GetInstance(vsoc::GetDomain().c_str());
   while (!closed()) {
     bb_->WaitForAtLeastOneClientConnection();
-    int buffer_idx = screen_view->WaitForNewFrameSince(&previous_seq_num);
+    int buffer_idx = screen_connector_->WaitForNewFrameSince(&previous_seq_num);
     const char* frame_start =
-        static_cast<char*>(screen_view->GetBuffer(buffer_idx));
+        static_cast<char*>(screen_connector_->GetBuffer(buffer_idx));
     raw_screen.assign(frame_start, frame_start + ScreenSizeInBytes());
 
     for (int i = 0; i < kNumStripes; ++i) {
@@ -105,6 +103,7 @@
       s.x = 0;
       s.y = y;
       s.width = ActualScreenWidth();
+      s.stride = ActualScreenStride();
       s.height = height;
       s.raw_data.assign(raw_start, raw_end);
       s.seq_number = StripeSeqNumber{stripe_seq_num};
diff --git a/host/frontend/vnc_server/simulated_hw_composer.h b/host/frontend/vnc_server/simulated_hw_composer.h
index 5d6e3e2..802cc7f 100644
--- a/host/frontend/vnc_server/simulated_hw_composer.h
+++ b/host/frontend/vnc_server/simulated_hw_composer.h
@@ -26,6 +26,7 @@
 #include "common/libs/thread_safe_queue/thread_safe_queue.h"
 #include "common/libs/threads/thread_annotations.h"
 #include "host/frontend/vnc_server/blackboard.h"
+#include "host/frontend/vnc_server/screen_connector.h"
 
 namespace cvd {
 namespace vnc {
@@ -59,6 +60,7 @@
   BlackBoard* bb_{};
   ThreadSafeQueue<Stripe> stripes_;
   std::thread stripe_maker_;
+  std::shared_ptr<ScreenConnector> screen_connector_{ScreenConnector::Get()};
 };
 }  // namespace vnc
 }  // namespace cvd
diff --git a/host/frontend/vnc_server/virtual_inputs.cpp b/host/frontend/vnc_server/virtual_inputs.cpp
index b2f519c..e7e3757 100644
--- a/host/frontend/vnc_server/virtual_inputs.cpp
+++ b/host/frontend/vnc_server/virtual_inputs.cpp
@@ -22,11 +22,20 @@
 #include <mutex>
 #include "keysyms.h"
 
+#include <common/libs/fs/shared_select.h>
+#include <host/libs/config/cuttlefish_config.h>
+
 using cvd::vnc::VirtualInputs;
 using vsoc::input_events::InputEventsRegionView;
 
+DEFINE_int32(touch_fd, -1,
+             "A fd for a socket where to accept touch connections");
+
+DEFINE_int32(keyboard_fd, -1,
+             "A fd for a socket where to accept keyboard connections");
+
 namespace {
-void AddKeyMappings(std::map<uint32_t, uint32_t>* key_mapping) {
+void AddKeyMappings(std::map<uint32_t, uint16_t>* key_mapping) {
   (*key_mapping)[cvd::xk::AltLeft] = KEY_LEFTALT;
   (*key_mapping)[cvd::xk::ControlLeft] = KEY_LEFTCTRL;
   (*key_mapping)[cvd::xk::ShiftLeft] = KEY_LEFTSHIFT;
@@ -214,30 +223,132 @@
   (*key_mapping)[cvd::xk::Menu] = KEY_MENU;
   (*key_mapping)[cvd::xk::VNCMenu] = KEY_MENU;
 }
+
+void InitInputEvent(struct input_event* evt, uint16_t type, uint16_t code,
+                    int32_t value) {
+  evt->type = type;
+  evt->code = code;
+  evt->value = value;
+}
+
 }  // namespace
 
-VirtualInputs::VirtualInputs()
-  : input_events_region_view_{
-      vsoc::input_events::InputEventsRegionView::GetInstance(
-          vsoc::GetDomain().c_str())} {
-  if (!input_events_region_view_) {
-    LOG(FATAL) << "Failed to open Input events region view";
+class VSoCVirtualInputs : public VirtualInputs {
+ public:
+  VSoCVirtualInputs()
+      : input_events_region_view_{
+            vsoc::input_events::InputEventsRegionView::GetInstance(
+                vsoc::GetDomain().c_str())} {
+    if (!input_events_region_view_) {
+      LOG(FATAL) << "Failed to open Input events region view";
+    }
   }
-  AddKeyMappings(&keymapping_);
-}
 
-void VirtualInputs::GenerateKeyPressEvent(int key_code, bool down) {
-  if (keymapping_.count(key_code)) {
-    input_events_region_view_->HandleKeyboardEvent(down, keymapping_[key_code]);
+  void GenerateKeyPressEvent(int code, bool down) override {
+    if (keymapping_.count(code)) {
+      input_events_region_view_->HandleKeyboardEvent(down, keymapping_[code]);
+    } else {
+      LOG(ERROR) << "Unknown keycode" << code;
+    }
+  }
+
+  void PressPowerButton(bool down) override {
+    input_events_region_view_->HandlePowerButtonEvent(down);
+  }
+
+  void HandlePointerEvent(bool touch_down, int x, int y) override {
+    input_events_region_view_->HandleSingleTouchEvent(touch_down, x, y);
+  }
+
+ private:
+  vsoc::input_events::InputEventsRegionView* input_events_region_view_{};
+};
+
+class SocketVirtualInputs : public VirtualInputs {
+ public:
+  SocketVirtualInputs()
+      : client_connector_([this]() { ClientConnectorLoop(); }) {}
+
+  void GenerateKeyPressEvent(int key_code, bool down) override {
+    struct input_event events[2];
+    InitInputEvent(&events[0], EV_KEY, keymapping_[key_code], down);
+    InitInputEvent(&events[1], EV_SYN, 0, 0);
+
+    SendEvents(keyboard_socket_, events, sizeof(events));
+  }
+
+  void PressPowerButton(bool down) override {
+    struct input_event events[2];
+    InitInputEvent(&events[0], EV_KEY, KEY_POWER, down);
+    InitInputEvent(&events[1], EV_SYN, 0, 0);
+
+    SendEvents(keyboard_socket_, events, sizeof(events));
+  }
+
+  void HandlePointerEvent(bool touch_down, int x, int y) override {
+    // TODO(b/124121375): Use multitouch when available
+    struct input_event events[4];
+    InitInputEvent(&events[0], EV_ABS, ABS_X, x);
+    InitInputEvent(&events[1], EV_ABS, ABS_Y, y);
+    InitInputEvent(&events[2], EV_KEY, BTN_TOUCH, touch_down);
+    InitInputEvent(&events[3], EV_SYN, 0, 0);
+
+    SendEvents(touch_socket_, events, sizeof(events));
+  }
+
+ private:
+  void SendEvents(cvd::SharedFD socket, void* event_buffer, int byte_count) {
+    std::lock_guard<std::mutex> lock(socket_mutex_);
+    if (!socket->IsOpen()) {
+      // This is unlikely as it would only happen between the start of the vnc
+      // server and the connection of the VMM to the socket.
+      // If it happens, just drop the events as the VM is not yet ready to
+      // handle it.
+      return;
+    }
+    auto ret = socket->Write(event_buffer, byte_count);
+    if (ret < 0) {
+      LOG(ERROR) << "Error sending input event: " << socket->StrError();
+    }
+  }
+
+  void ClientConnectorLoop() {
+    auto touch_server = cvd::SharedFD::Dup(FLAGS_touch_fd);
+    close(FLAGS_touch_fd);
+    FLAGS_touch_fd = -1;
+
+    auto keyboard_server = cvd::SharedFD::Dup(FLAGS_keyboard_fd);
+    close(FLAGS_keyboard_fd);
+    FLAGS_keyboard_fd = -1;
+
+    while (1) {
+      cvd::SharedFDSet read_set;
+      read_set.Set(touch_server);
+      read_set.Set(keyboard_server);
+      cvd::Select(&read_set, nullptr, nullptr, nullptr);
+      {
+        std::lock_guard<std::mutex> lock(socket_mutex_);
+        if (read_set.IsSet(touch_server)) {
+          touch_socket_ = cvd::SharedFD::Accept(*touch_server);
+        }
+        if (read_set.IsSet(keyboard_server)) {
+          keyboard_socket_ = cvd::SharedFD::Accept(*keyboard_server);
+        }
+      }
+    }
+  }
+  cvd::SharedFD touch_socket_;
+  cvd::SharedFD keyboard_socket_;
+  std::thread client_connector_;
+  std::mutex socket_mutex_;
+};
+
+VirtualInputs::VirtualInputs() { AddKeyMappings(&keymapping_); }
+
+VirtualInputs* VirtualInputs::Get() {
+  if (vsoc::CuttlefishConfig::Get()->enable_ivserver()) {
+    return new VSoCVirtualInputs();
   } else {
-    LOG(INFO) << "Unknown keycode" << key_code;
+    return new SocketVirtualInputs();
   }
 }
-
-void VirtualInputs::PressPowerButton(bool down) {
-  input_events_region_view_->HandlePowerButtonEvent(down);
-}
-
-void VirtualInputs::HandlePointerEvent(bool touch_down, int x, int y) {
-  input_events_region_view_->HandleSingleTouchEvent(touch_down, x, y);
-}
diff --git a/host/frontend/vnc_server/virtual_inputs.h b/host/frontend/vnc_server/virtual_inputs.h
index c937a12..f92693b 100644
--- a/host/frontend/vnc_server/virtual_inputs.h
+++ b/host/frontend/vnc_server/virtual_inputs.h
@@ -28,15 +28,18 @@
 
 class VirtualInputs {
  public:
+  static VirtualInputs* Get();
+
+  virtual ~VirtualInputs() = default;
+
+  virtual void GenerateKeyPressEvent(int code, bool down) = 0;
+  virtual void PressPowerButton(bool down) = 0;
+  virtual void HandlePointerEvent(bool touch_down, int x, int y) = 0;
+
+ protected:
   VirtualInputs();
 
-  void GenerateKeyPressEvent(int code, bool down);
-  void PressPowerButton(bool down);
-  void HandlePointerEvent(bool touch_down, int x, int y);
-
- private:
-  vsoc::input_events::InputEventsRegionView* input_events_region_view_{};
-  std::map<uint32_t, uint32_t> keymapping_;
+  std::map<uint32_t, uint16_t> keymapping_;
 };
 
 }  // namespace vnc
diff --git a/host/frontend/vnc_server/vnc_client_connection.cpp b/host/frontend/vnc_server/vnc_client_connection.cpp
index 9bed6ff..a8faf47 100644
--- a/host/frontend/vnc_server/vnc_client_connection.cpp
+++ b/host/frontend/vnc_server/vnc_client_connection.cpp
@@ -133,9 +133,9 @@
 }  // namespace vnc
 }  // namespace cvd
 
-VncClientConnection::VncClientConnection(ClientSocket client,
-                                         VirtualInputs* virtual_inputs,
-                                         BlackBoard* bb, bool aggressive)
+VncClientConnection::VncClientConnection(
+    ClientSocket client, std::shared_ptr<VirtualInputs> virtual_inputs,
+    BlackBoard* bb, bool aggressive)
     : client_{std::move(client)}, virtual_inputs_{virtual_inputs}, bb_{bb} {
   frame_buffer_request_handler_tid_ = std::thread(
       &VncClientConnection::FrameBufferUpdateRequestHandler, this, aggressive);
diff --git a/host/frontend/vnc_server/vnc_client_connection.h b/host/frontend/vnc_server/vnc_client_connection.h
index 80aaad1..73beae1 100644
--- a/host/frontend/vnc_server/vnc_client_connection.h
+++ b/host/frontend/vnc_server/vnc_client_connection.h
@@ -35,7 +35,8 @@
 
 class VncClientConnection {
  public:
-  VncClientConnection(ClientSocket client, VirtualInputs* virtual_inputs,
+  VncClientConnection(ClientSocket client,
+                      std::shared_ptr<VirtualInputs> virtual_inputs,
                       BlackBoard* bb, bool aggressive);
   VncClientConnection(const VncClientConnection&) = delete;
   VncClientConnection& operator=(const VncClientConnection&) = delete;
@@ -139,7 +140,7 @@
   ClientSocket client_;
   bool control_key_down_ = false;
   bool meta_key_down_ = false;
-  VirtualInputs* virtual_inputs_{};
+  std::shared_ptr<VirtualInputs> virtual_inputs_{};
 
   FrameBufferUpdateRequest previous_update_request_{};
   BlackBoard* bb_;
diff --git a/host/frontend/vnc_server/vnc_server.cpp b/host/frontend/vnc_server/vnc_server.cpp
index 03f5dbe..3aba467 100644
--- a/host/frontend/vnc_server/vnc_server.cpp
+++ b/host/frontend/vnc_server/vnc_server.cpp
@@ -28,7 +28,10 @@
 using cvd::vnc::VncServer;
 
 VncServer::VncServer(int port, bool aggressive)
-    : server_(port), frame_buffer_watcher_{&bb_}, aggressive_{aggressive} {}
+    : server_(port),
+    virtual_inputs_(VirtualInputs::Get()),
+    frame_buffer_watcher_{&bb_},
+    aggressive_{aggressive} {}
 
 void VncServer::MainLoop() {
   while (true) {
@@ -50,7 +53,7 @@
   // data members. In the current setup, if the VncServer is destroyed with
   // clients still running, the clients will all be left with dangling
   // pointers.
-  VncClientConnection client(std::move(sock), &virtual_inputs_, &bb_,
+  VncClientConnection client(std::move(sock), virtual_inputs_, &bb_,
                              aggressive_);
   client.StartSession();
 }
diff --git a/host/frontend/vnc_server/vnc_server.h b/host/frontend/vnc_server/vnc_server.h
index d88835c..66e17e0 100644
--- a/host/frontend/vnc_server/vnc_server.h
+++ b/host/frontend/vnc_server/vnc_server.h
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+#include <memory>
 #include <string>
 #include <thread>
 #include <utility>
@@ -46,7 +47,7 @@
   void StartClientThread(ClientSocket sock);
 
   ServerSocket server_;
-  VirtualInputs virtual_inputs_;
+  std::shared_ptr<VirtualInputs> virtual_inputs_;
   BlackBoard bb_;
   FrameBufferWatcher frame_buffer_watcher_;
   bool aggressive_{};
diff --git a/host/frontend/vnc_server/vnc_utils.h b/host/frontend/vnc_server/vnc_utils.h
index 3eac9f3..0953c4e 100644
--- a/host/frontend/vnc_server/vnc_utils.h
+++ b/host/frontend/vnc_server/vnc_utils.h
@@ -21,6 +21,7 @@
 #include <utility>
 #include <vector>
 
+#include "common/libs/utils/size_utils.h"
 #include "common/libs/tcp_socket/tcp_socket.h"
 #include "common/vsoc/lib/screen_region_view.h"
 #include "host/libs/config/cuttlefish_config.h"
@@ -55,6 +56,7 @@
   std::uint16_t x{};
   std::uint16_t y{};
   std::uint16_t width{};
+  std::uint16_t stride{};
   std::uint16_t height{};
   Message raw_data{};
   Message jpeg_data{};
@@ -68,16 +70,17 @@
 
 // The width of the screen regardless of orientation. Does not change.
 inline int ActualScreenWidth() {
-  return vsoc::screen::ScreenRegionView::GetInstance(
-             vsoc::GetDomain().c_str())
-      ->x_res();
+  return vsoc::CuttlefishConfig::Get()->x_res();
+}
+
+// The length of the screen stride regardless of orientation. Does not change.
+inline int ActualScreenStride() {
+  return AlignToPowerOf2(ActualScreenWidth() * BytesPerPixel(), 4);
 }
 
 // The height of the screen regardless of orientation. Does not change.
 inline int ActualScreenHeight() {
-  return vsoc::screen::ScreenRegionView::GetInstance(
-             vsoc::GetDomain().c_str())
-      ->y_res();
+  return vsoc::CuttlefishConfig::Get()->y_res();
 }
 
 inline int ScreenSizeInBytes() {
diff --git a/host/libs/config/cuttlefish_config.cpp b/host/libs/config/cuttlefish_config.cpp
index 1d18f56..55f0891 100644
--- a/host/libs/config/cuttlefish_config.cpp
+++ b/host/libs/config/cuttlefish_config.cpp
@@ -69,6 +69,8 @@
 const char* kSerialNumber = "serial_number";
 const char* kInstanceDir = "instance_dir";
 const char* kVmManager = "vm_manager";
+const char* const kGpuMode = "gpu_mode";
+const char* const kWaylandSocket = "wayland_socket";
 const char* kHardwareName = "hardware_name";
 const char* kDeviceTitle = "device_title";
 
@@ -93,6 +95,8 @@
 const char* kDataImagePath = "data_image_path";
 const char* kVendorImagePath = "vendor_image_path";
 const char* kMetadataImagePath = "metadata_image_path";
+const char* kProductImagePath = "product_image_path";
+const char* kSuperImagePath = "super_image_path";
 const char* kUsbV1SocketName = "usb_v1_socket_name";
 const char* kVhciPort = "vhci_port";
 const char* kUsbIpSocketName = "usb_ip_socket_name";
@@ -154,12 +158,29 @@
 const char* kBlankDataImageFmt = "blank_data_image_fmt";
 
 const char* kLogcatMode = "logcat_mode";
-const char* kLogcatVsockPort = "logcat_vsock_mode";
+const char* kLogcatVsockPort = "logcat_vsock_port";
+const char* kConfigServerPort = "config_server_port";
+const char* kFramesVsockPort = "frames_vsock_port";
 const char* kLogcatReceiverBinary = "logcat_receiver_binary";
+const char* kConfigServerBinary = "config_server_binary";
+
+const char* kRunTombstoneReceiver = "enable_tombstone_logger";
+const char* kTombstoneReceiverPort = "tombstone_logger_port";
+const char* kTombstoneReceiverBinary = "tombstone_receiver_binary";
 }  // namespace
 
 namespace vsoc {
 
+const char* const kGpuModeGuestSwiftshader = "guest_swiftshader";
+const char* const kGpuModeDrmVirgl = "drm_virgl";
+
+std::string DefaultEnvironmentPath(const char* environment_key,
+                                   const char* default_value,
+                                   const char* subpath) {
+  return cvd::StringFromEnv(environment_key, default_value) + "/" + subpath;
+}
+
+
 std::string CuttlefishConfig::instance_dir() const {
   return (*dictionary_)[kInstanceDir].asString();
 }
@@ -174,6 +195,21 @@
   (*dictionary_)[kVmManager] = name;
 }
 
+std::string CuttlefishConfig::gpu_mode() const {
+  return (*dictionary_)[kGpuMode].asString();
+}
+void CuttlefishConfig::set_gpu_mode(const std::string& name) {
+  (*dictionary_)[kGpuMode] = name;
+}
+
+std::string CuttlefishConfig::wayland_socket() const {
+  // Don't use SetPath here: the path is already fully formed.
+  return (*dictionary_)[kWaylandSocket].asString();
+}
+void CuttlefishConfig::set_wayland_socket(const std::string& path) {
+  (*dictionary_)[kWaylandSocket] = path;
+}
+
 std::string CuttlefishConfig::hardware_name() const {
   return (*dictionary_)[kHardwareName].asString();
 }
@@ -358,6 +394,22 @@
   SetPath(kMetadataImagePath, metadata_image_path);
 }
 
+std::string CuttlefishConfig::super_image_path() const {
+  return (*dictionary_)[kSuperImagePath].asString();
+}
+void CuttlefishConfig::set_super_image_path(
+    const std::string& super_image_path) {
+  SetPath(kSuperImagePath, super_image_path);
+}
+
+std::string CuttlefishConfig::product_image_path() const {
+  return (*dictionary_)[kProductImagePath].asString();
+}
+void CuttlefishConfig::set_product_image_path(
+    const std::string& product_image_path) {
+  SetPath(kProductImagePath, product_image_path);
+}
+
 std::string CuttlefishConfig::dtb_path() const {
   return (*dictionary_)[kDtbPath].asString();
 }
@@ -538,12 +590,20 @@
   return (*dictionary_)[kCuttlefishEnvPath].asString();
 }
 
-std::string CuttlefishConfig::adb_mode() const {
-  return (*dictionary_)[kAdbMode].asString();
+std::set<std::string> CuttlefishConfig::adb_mode() const {
+  std::set<std::string> args_set;
+  for (auto& mode : (*dictionary_)[kAdbMode]) {
+    args_set.insert(mode.asString());
+  }
+  return args_set;
 }
 
-void CuttlefishConfig::set_adb_mode(const std::string& mode) {
-  (*dictionary_)[kAdbMode] = mode;
+void CuttlefishConfig::set_adb_mode(const std::set<std::string>& mode) {
+  Json::Value mode_json_obj(Json::arrayValue);
+  for (const auto& arg : mode) {
+    mode_json_obj.append(arg);
+  }
+  (*dictionary_)[kAdbMode] = mode_json_obj;
 }
 
 std::string CuttlefishConfig::adb_ip_and_port() const {
@@ -555,9 +615,14 @@
 }
 
 std::string CuttlefishConfig::adb_device_name() const {
-  if (adb_mode().find("tunnel") != std::string::npos) {
+  // TODO(schuffelen): Deal with duplication between here and launch.cc
+  bool tunnelMode = adb_mode().count("tunnel") > 0;
+  bool vsockTunnel = adb_mode().count("vsock_tunnel") > 0;
+  bool vsockHalfProxy = adb_mode().count("vsock_half_tunnel") > 0;
+  bool nativeVsock = adb_mode().count("native_vsock") > 0;
+  if (tunnelMode || vsockTunnel || vsockHalfProxy || nativeVsock) {
     return adb_ip_and_port();
-  } else if (adb_mode().find("usb") != std::string::npos) {
+  } else if (adb_mode().count("usb") > 0) {
     return serial_number();
   }
   LOG(ERROR) << "no adb_mode found, returning bad device name";
@@ -780,6 +845,22 @@
   return (*dictionary_)[kLogcatVsockPort].asInt();
 }
 
+void CuttlefishConfig::set_config_server_port(int port) {
+  (*dictionary_)[kConfigServerPort] = port;
+}
+
+int CuttlefishConfig::config_server_port() const {
+  return (*dictionary_)[kConfigServerPort].asInt();
+}
+
+void CuttlefishConfig::set_frames_vsock_port(int port) {
+  (*dictionary_)[kFramesVsockPort] = port;
+}
+
+int CuttlefishConfig::frames_vsock_port() const {
+  return (*dictionary_)[kFramesVsockPort].asInt();
+}
+
 void CuttlefishConfig::set_logcat_receiver_binary(const std::string& binary) {
   SetPath(kLogcatReceiverBinary, binary);
 }
@@ -788,11 +869,50 @@
   return (*dictionary_)[kLogcatReceiverBinary].asString();
 }
 
+void CuttlefishConfig::set_config_server_binary(const std::string& binary) {
+  SetPath(kConfigServerBinary, binary);
+}
+
+std::string CuttlefishConfig::config_server_binary() const {
+  return (*dictionary_)[kConfigServerBinary].asString();
+}
+
+bool CuttlefishConfig::enable_tombstone_receiver() const {
+  return (*dictionary_)[kRunTombstoneReceiver].asBool();
+}
+
+void CuttlefishConfig::set_enable_tombstone_receiver(bool enable_tombstone_receiver) {
+  (*dictionary_)[kRunTombstoneReceiver] = enable_tombstone_receiver;
+}
+
+std::string CuttlefishConfig::tombstone_receiver_binary() const {
+  return (*dictionary_)[kTombstoneReceiverBinary].asString();
+}
+
+void CuttlefishConfig::set_tombstone_receiver_binary(const std::string& e2e_test_binary) {
+  (*dictionary_)[kTombstoneReceiverBinary] = e2e_test_binary;
+}
+
+void CuttlefishConfig::set_tombstone_receiver_port(int port) {
+  (*dictionary_)[kTombstoneReceiverPort] = port;
+}
+
+int CuttlefishConfig::tombstone_receiver_port() const {
+  return (*dictionary_)[kTombstoneReceiverPort].asInt();
+}
 
 bool CuttlefishConfig::enable_ivserver() const {
   return hardware_name() == "cutf_ivsh";
 }
 
+std::string CuttlefishConfig::touch_socket_path() const {
+  return PerInstancePath("touch.sock");
+}
+
+std::string CuttlefishConfig::keyboard_socket_path() const {
+  return PerInstancePath("keyboard.sock");
+}
+
 // Creates the (initially empty) config object and populates it with values from
 // the config file if the CUTTLEFISH_CONFIG_FILE env variable is present.
 // Returns nullptr if there was an error loading from file
diff --git a/host/libs/config/cuttlefish_config.h b/host/libs/config/cuttlefish_config.h
index f13a433..4d495f0 100644
--- a/host/libs/config/cuttlefish_config.h
+++ b/host/libs/config/cuttlefish_config.h
@@ -57,6 +57,12 @@
   std::string vm_manager() const;
   void set_vm_manager(const std::string& name);
 
+  std::string gpu_mode() const;
+  void set_gpu_mode(const std::string& name);
+
+  std::string wayland_socket() const;
+  void set_wayland_socket(const std::string& path);
+
   std::string hardware_name() const;
   void set_hardware_name(const std::string& name);
 
@@ -135,6 +141,12 @@
   std::string metadata_image_path() const;
   void set_metadata_image_path(const std::string& metadata_image_path);
 
+  std::string product_image_path() const;
+  void set_product_image_path(const std::string& product_image_path);
+
+  std::string super_image_path() const;
+  void set_super_image_path(const std::string& super_image_path);
+
   std::string dtb_path() const;
   void set_dtb_path(const std::string& dtb_path);
 
@@ -181,6 +193,9 @@
   std::string logcat_receiver_binary() const;
   void set_logcat_receiver_binary(const std::string& binary);
 
+  std::string config_server_binary() const;
+  void set_config_server_binary(const std::string& binary);
+
   std::string launcher_log_path() const;
   void set_launcher_log_path(const std::string& launcher_log_path);
 
@@ -215,8 +230,8 @@
   void set_cuttlefish_env_path(const std::string& path);
   std::string cuttlefish_env_path() const;
 
-  void set_adb_mode(const std::string& mode);
-  std::string adb_mode() const;
+  void set_adb_mode(const std::set<std::string>& modes);
+  std::set<std::string> adb_mode() const;
 
   void set_adb_ip_and_port(const std::string& ip_port);
   std::string adb_ip_and_port() const;
@@ -302,8 +317,26 @@
   void set_logcat_vsock_port(int port);
   int logcat_vsock_port() const;
 
+  void set_config_server_port(int port);
+  int config_server_port() const;
+
+  void set_frames_vsock_port(int port);
+  int frames_vsock_port() const;
+
+  void set_enable_tombstone_receiver(bool enable_tombstone_receiver);
+  bool enable_tombstone_receiver() const;
+
+  void set_tombstone_receiver_binary(const std::string& binary);
+  std::string tombstone_receiver_binary() const;
+
+  void set_tombstone_receiver_port(int port);
+  int tombstone_receiver_port() const;
+
   bool enable_ivserver() const;
 
+  std::string touch_socket_path() const;
+  std::string keyboard_socket_path() const;
+
  private:
   std::unique_ptr<Json::Value> dictionary_;
 
@@ -337,8 +370,15 @@
 
 std::string DefaultHostArtifactsPath(const std::string& file);
 std::string DefaultGuestImagePath(const std::string& file);
+std::string DefaultEnvironmentPath(const char* environment_key,
+                                   const char* default_value,
+                                   const char* path);
 
 // Whether the host supports qemu
 bool HostSupportsQemuCli();
 bool HostSupportsVsock();
+
+// GPU modes
+extern const char* const kGpuModeGuestSwiftshader;
+extern const char* const kGpuModeDrmVirgl;
 }  // namespace vsoc
diff --git a/host/libs/vm_manager/cf_qemu.sh b/host/libs/vm_manager/cf_qemu.sh
index ac63bbe..f20d33d 100755
--- a/host/libs/vm_manager/cf_qemu.sh
+++ b/host/libs/vm_manager/cf_qemu.sh
@@ -95,20 +95,42 @@
     -no-shutdown
     -boot "strict=on"
     -kernel "${kernel_image_path:-${HOME}/kernel}"
-    -append "${kernel_cmdline:-"loop.max_part=7 console=ttyS0 androidboot.console=ttyS1 androidboot.hardware=vsoc enforcing=0 audit=1 androidboot.selinux=permissive mac80211_hwsim.radios=0 security=selinux buildvariant=userdebug  androidboot.serialno=CUTTLEFISHCVD01 androidboot.lcd_density=160"}"
-    -dtb "${dtb_path:-${HOME}/config/cuttlefish.dtb}"
+    -append "${kernel_cmdline:-"loop.max_part=7 console=ttyS0 androidboot.console=ttyS1 androidboot.hardware=vsoc enforcing=0 audit=1 androidboot.selinux=permissive mac80211_hwsim.radios=0 security=selinux buildvariant=userdebug  androidboot.serialno=CUTTLEFISHCVD01 androidboot.lcd_density=160 androidboot.boot_devices=pci0000:00/0000:00:03.0"}"
     -device "piix3-usb-uhci,id=usb,addr=0x1.0x2"
     -device "virtio-serial-pci,id=virtio-serial0"
+)
+
+if [[ -n "${super_image_path}" ]]; then
+  args+=(
+    -drive "file=${super_image_path:-${HOME}/obj/PACKAGING/super.img_intermediates/super.img},format=raw,if=none,id=drive-virtio-disk0,aio=threads"
+    -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk0,id=virtio-disk0"
+  )
+else
+  args+=(
     -drive "file=${system_image_path:-${HOME}/system.img},format=raw,if=none,id=drive-virtio-disk0,aio=threads"
     -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1"
+  )
+fi
+
+args+=(
     -drive "file=${data_image_path:-${HOME}/userdata.img},format=raw,if=none,id=drive-virtio-disk1,aio=threads"
     -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk1,id=virtio-disk1"
     -drive "file=${cache_image_path:-${HOME}/cache.img},format=raw,if=none,id=drive-virtio-disk2,aio=threads"
     -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk2,id=virtio-disk2"
-    -drive "file=${vendor_image_path:-${HOME}/vendor.img},format=raw,if=none,id=drive-virtio-disk3,aio=threads"
+    -drive "file=${metadata_image_path:-${HOME}/metadata.img},format=raw,if=none,id=drive-virtio-disk3,aio=threads"
     -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk3,id=virtio-disk3"
-    -drive "file=${metadata_image_path:-${HOME}/metadata.img},format=raw,if=none,id=drive-virtio-disk4,aio=threads"
+)
+
+if [[ -z "${super_image_path}" ]]; then
+  args+=(
+    -drive "file=${vendor_image_path:-${HOME}/vendor.img},format=raw,if=none,id=drive-virtio-disk4,aio=threads"
     -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk4,id=virtio-disk4"
+    -drive "file=${product_image_path:-${HOME}/product.img},format=raw,if=none,id=drive-virtio-disk5,aio=threads"
+    -device "virtio-blk-pci,scsi=off,drive=drive-virtio-disk5,id=virtio-disk5"
+  )
+fi
+
+args+=(
     -netdev "tap,id=hostnet0,ifname=${wifi_tap_name:-${default_wifi_tap_name}},script=no,downscript=no"
     -device "virtio-net-pci,netdev=hostnet0,id=net0"
     -netdev "tap,id=hostnet1,ifname=${mobile_tap_name:-${default_mobile_tap_name}},script=no,downscript=no"
diff --git a/host/libs/vm_manager/crosvm_manager.cpp b/host/libs/vm_manager/crosvm_manager.cpp
index b623157..8ae3359 100644
--- a/host/libs/vm_manager/crosvm_manager.cpp
+++ b/host/libs/vm_manager/crosvm_manager.cpp
@@ -53,16 +53,39 @@
 
 const std::string CrosvmManager::name() { return "crosvm"; }
 
+bool CrosvmManager::ConfigureGpu(vsoc::CuttlefishConfig* config) {
+  // Override the default HAL search paths in all cases. We do this because
+  // the HAL search path allows for fallbacks, and fallbacks in conjunction
+  // with properities lead to non-deterministic behavior while loading the
+  // HALs.
+  if (config->gpu_mode() == vsoc::kGpuModeDrmVirgl) {
+    config->add_kernel_cmdline("androidboot.hardware.gralloc=minigbm");
+    config->add_kernel_cmdline("androidboot.hardware.hwcomposer=drm_minigbm");
+    config->add_kernel_cmdline("androidboot.hardware.egl=mesa");
+    return true;
+  }
+  if (config->gpu_mode() == vsoc::kGpuModeGuestSwiftshader) {
+    config->add_kernel_cmdline(
+        "androidboot.hardware.gralloc=cutf_ashmem");
+    config->add_kernel_cmdline(
+        "androidboot.hardware.hwcomposer=cutf_cvm_ashmem");
+    config->add_kernel_cmdline("androidboot.hardware.egl=swiftshader");
+    return true;
+  }
+  return false;
+}
+
+void CrosvmManager::ConfigureBootDevices(vsoc::CuttlefishConfig* config) {
+  // PCI domain 0, bus 0, device 5, function 0
+  // TODO There is no way to control this assignment with crosvm (yet)
+  config->add_kernel_cmdline(
+    "androidboot.boot_devices=pci0000:00/0000:00:05.0");
+}
+
 CrosvmManager::CrosvmManager(const vsoc::CuttlefishConfig* config)
     : VmManager(config) {}
 
 cvd::Command CrosvmManager::StartCommand() {
-  if (!config_->ramdisk_image_path().empty()) {
-    // TODO re-enable ramdisk when crosvm supports it
-    LOG(FATAL) << "initramfs not supported";
-    return cvd::Command("/bin/false");
-  }
-
   // TODO Add aarch64 support
   // TODO Add the tap interfaces (--tap-fd)
   // TODO Redirect logcat output
@@ -74,17 +97,36 @@
   cvd::Command command(config_->crosvm_binary());
   command.AddParameter("run");
 
+  if (config_->gpu_mode() != vsoc::kGpuModeGuestSwiftshader) {
+    command.AddParameter("--gpu");
+    command.AddParameter("--wayland-sock=", config_->wayland_socket());
+  }
+  if (!config_->ramdisk_image_path().empty()) {
+    command.AddParameter("--initrd=", config_->ramdisk_image_path());
+  }
   command.AddParameter("--null-audio");
   command.AddParameter("--mem=", config_->memory_mb());
   command.AddParameter("--cpus=", config_->cpus());
   command.AddParameter("--params=", config_->kernel_cmdline_as_string());
-  command.AddParameter("--rwdisk=", config_->system_image_path());
+  if (config_->super_image_path().empty()) {
+    command.AddParameter("--rwdisk=", config_->system_image_path());
+  } else {
+    command.AddParameter("--rwdisk=", config_->super_image_path());
+  }
   command.AddParameter("--rwdisk=", config_->data_image_path());
   command.AddParameter("--rwdisk=", config_->cache_image_path());
-  command.AddParameter("--rwdisk=", config_->vendor_image_path());
   command.AddParameter("--rwdisk=", config_->metadata_image_path());
+  if (config_->super_image_path().empty()) {
+    command.AddParameter("--rwdisk=", config_->vendor_image_path());
+    command.AddParameter("--rwdisk=", config_->product_image_path());
+  }
   command.AddParameter("--socket=", GetControlSocketPath(config_));
-  command.AddParameter("--android-fstab=", config_->gsi_fstab_path());
+  if (!config_->gsi_fstab_path().empty()) {
+    command.AddParameter("--android-fstab=", config_->gsi_fstab_path());
+  }
+  command.AddParameter("--single-touch=", config_->touch_socket_path(), ":",
+                       config_->x_res(), ":", config_->y_res());
+  command.AddParameter("--keyboard=", config_->keyboard_socket_path());
 
   AddTapFdParameter(&command, config_->wifi_tap_name());
   AddTapFdParameter(&command, config_->mobile_tap_name());
diff --git a/host/libs/vm_manager/crosvm_manager.h b/host/libs/vm_manager/crosvm_manager.h
index 7574e51..ac26ee8 100644
--- a/host/libs/vm_manager/crosvm_manager.h
+++ b/host/libs/vm_manager/crosvm_manager.h
@@ -28,6 +28,8 @@
  public:
   static const std::string name();
   static bool EnsureInstanceDirExists(const std::string& instance_dir);
+  static bool ConfigureGpu(vsoc::CuttlefishConfig* config);
+  static void ConfigureBootDevices(vsoc::CuttlefishConfig* config);
 
   CrosvmManager(const vsoc::CuttlefishConfig* config);
   virtual ~CrosvmManager() = default;
diff --git a/host/libs/vm_manager/qemu_manager.cpp b/host/libs/vm_manager/qemu_manager.cpp
index d986833..ac83972 100644
--- a/host/libs/vm_manager/qemu_manager.cpp
+++ b/host/libs/vm_manager/qemu_manager.cpp
@@ -55,6 +55,29 @@
 
 const std::string QemuManager::name() { return "qemu_cli"; }
 
+bool QemuManager::ConfigureGpu(vsoc::CuttlefishConfig *config) {
+  if (config->gpu_mode() != vsoc::kGpuModeGuestSwiftshader) {
+    return false;
+  }
+  // Override the default HAL search paths in all cases. We do this because
+  // the HAL search path allows for fallbacks, and fallbacks in conjunction
+  // with properities lead to non-deterministic behavior while loading the
+  // HALs.
+  config->add_kernel_cmdline("androidboot.hardware.gralloc=cutf_ashmem");
+  config->add_kernel_cmdline(
+      "androidboot.hardware.hwcomposer=cutf_ivsh_ashmem");
+  config->add_kernel_cmdline(
+      "androidboot.hardware.egl=swiftshader");
+  return true;
+}
+
+void QemuManager::ConfigureBootDevices(vsoc::CuttlefishConfig* config) {
+  // PCI domain 0, bus 0, device 3, function 0
+  // This is controlled with 'addr=0x3' in cf_qemu.sh
+  config->add_kernel_cmdline(
+    "androidboot.boot_devices=pci0000:00/0000:00:03.0");
+}
+
 QemuManager::QemuManager(const vsoc::CuttlefishConfig* config)
   : VmManager(config) {}
 
@@ -76,6 +99,8 @@
   LogAndSetEnv("cache_image_path", config_->cache_image_path());
   LogAndSetEnv("vendor_image_path", config_->vendor_image_path());
   LogAndSetEnv("metadata_image_path", config_->metadata_image_path());
+  LogAndSetEnv("product_image_path", config_->product_image_path());
+  LogAndSetEnv("super_image_path", config_->super_image_path());
   LogAndSetEnv("wifi_tap_name", config_->wifi_tap_name());
   LogAndSetEnv("mobile_tap_name", config_->mobile_tap_name());
   LogAndSetEnv("kernel_log_socket_name",
diff --git a/host/libs/vm_manager/qemu_manager.h b/host/libs/vm_manager/qemu_manager.h
index a0c6540..ea24644 100644
--- a/host/libs/vm_manager/qemu_manager.h
+++ b/host/libs/vm_manager/qemu_manager.h
@@ -26,6 +26,8 @@
 class QemuManager : public VmManager {
  public:
   static const std::string name();
+  static bool ConfigureGpu(vsoc::CuttlefishConfig* config);
+  static void ConfigureBootDevices(vsoc::CuttlefishConfig* config);
 
   QemuManager(const vsoc::CuttlefishConfig* config);
   virtual ~QemuManager() = default;
diff --git a/host/libs/vm_manager/vm_manager.cpp b/host/libs/vm_manager/vm_manager.cpp
index 5433d6d..d613a56 100644
--- a/host/libs/vm_manager/vm_manager.cpp
+++ b/host/libs/vm_manager/vm_manager.cpp
@@ -40,17 +40,38 @@
 
 std::map<std::string, VmManager::VmManagerHelper>
     VmManager::vm_manager_helpers_ = {
-        {QemuManager::name(),
-         {[](const vsoc::CuttlefishConfig* config) {
-            return GetManagerSingleton<QemuManager>(config);
+        {
+          QemuManager::name(),
+          {
+            [](const vsoc::CuttlefishConfig* config) {
+              return GetManagerSingleton<QemuManager>(config);
+            },
+            []() { return vsoc::HostSupportsQemuCli(); },
+            [](vsoc::CuttlefishConfig* c) {
+              return QemuManager::ConfigureGpu(c);
+            },
+            [](vsoc::CuttlefishConfig* c) {
+              return QemuManager::ConfigureBootDevices(c);
+            }
           },
-          []() { return vsoc::HostSupportsQemuCli(); }}},
-        {CrosvmManager::name(),
-         {[](const vsoc::CuttlefishConfig* config) {
-            return GetManagerSingleton<CrosvmManager>(config);
-          },
-        // Same as Qemu for the time being
-          []() { return vsoc::HostSupportsQemuCli(); }}}};
+        },
+        {
+          CrosvmManager::name(),
+          {
+            [](const vsoc::CuttlefishConfig* config) {
+              return GetManagerSingleton<CrosvmManager>(config);
+            },
+            // Same as Qemu for the time being
+            []() { return vsoc::HostSupportsQemuCli(); },
+            [](vsoc::CuttlefishConfig* c) {
+              return CrosvmManager::ConfigureGpu(c);
+            },
+            [](vsoc::CuttlefishConfig* c) {
+              return CrosvmManager::ConfigureBootDevices(c);
+            }
+          }
+        }
+    };
 
 VmManager* VmManager::Get(const std::string& vm_manager_name,
                           const vsoc::CuttlefishConfig* config) {
@@ -70,6 +91,22 @@
          vm_manager_helpers_[name].support_checker();
 }
 
+bool VmManager::ConfigureGpuMode(vsoc::CuttlefishConfig* config) {
+  auto it = vm_manager_helpers_.find(config->vm_manager());
+  if (it == vm_manager_helpers_.end()) {
+    return false;
+  }
+  return it->second.configure_gpu_mode(config);
+}
+
+void VmManager::ConfigureBootDevices(vsoc::CuttlefishConfig* config) {
+  auto it = vm_manager_helpers_.find(config->vm_manager());
+  if (it == vm_manager_helpers_.end()) {
+    return;
+  }
+  it->second.configure_boot_devices(config);
+}
+
 std::vector<std::string> VmManager::GetValidNames() {
   std::vector<std::string> ret = {};
   for (const auto& key_val: vm_manager_helpers_) {
diff --git a/host/libs/vm_manager/vm_manager.h b/host/libs/vm_manager/vm_manager.h
index 84bf77c..ac93e26 100644
--- a/host/libs/vm_manager/vm_manager.h
+++ b/host/libs/vm_manager/vm_manager.h
@@ -35,6 +35,8 @@
   static VmManager* Get(const std::string& vm_manager_name,
                         const vsoc::CuttlefishConfig* config);
   static bool IsValidName(const std::string& name);
+  static bool ConfigureGpuMode(vsoc::CuttlefishConfig* config);
+  static void ConfigureBootDevices(vsoc::CuttlefishConfig* config);
   static bool IsVmManagerSupported(const std::string& name);
   static std::vector<std::string> GetValidNames();
 
@@ -58,6 +60,8 @@
     std::function<VmManager*(const vsoc::CuttlefishConfig*)> builder;
     // Whether the host packages support this vm manager
     std::function<bool()> support_checker;
+    std::function<bool(vsoc::CuttlefishConfig*)> configure_gpu_mode;
+    std::function<void(vsoc::CuttlefishConfig*)> configure_boot_devices;
   };
   // Asociates a vm manager helper to every valid vm manager name
   static std::map<std::string, VmManagerHelper> vm_manager_helpers_;
diff --git a/tools/build-qemu-packages.sh b/tools/build-qemu-packages.sh
deleted file mode 100755
index 7d30541..0000000
--- a/tools/build-qemu-packages.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-VIRGL_PACKAGE=libvirglrenderer-dev
-
-sudo apt update
-sudo apt upgrade -y
-sudo apt install -y debhelper ubuntu-dev-tools equivs
-dpkg -l "${VIRGL_PACKAGE}" || (
-  # Try from the distribution
-  sudo apt install -y "${VIRGL_PACKAGE}"
-  dpkg -l "${VIRGL_PACKAGE}" || (
-    echo That failed. Building from source
-    curl -L -O http://http.debian.net/debian/pool/main/v/virglrenderer/virglrenderer_0.6.0-2.dsc
-    curl -L -O http://http.debian.net/debian/pool/main/v/virglrenderer/virglrenderer_0.6.0.orig.tar.bz2
-    curl -L -O http://http.debian.net/debian/pool/main/v/virglrenderer/virglrenderer_0.6.0-2.debian.tar.xz
-    sudo mk-build-deps -i virglrenderer_0.6.0-2.dsc -t "apt-get -y"
-    rm -f virglrenderer-build-deps_0.6.0-2_all.deb
-    dpkg-source -x virglrenderer_0.6.0-2.dsc
-    pushd virglrenderer*0
-    dpkg-buildpackage -uc -us
-    popd
-    sudo apt install -y ./*.deb
-  )
-)
-curl -L -O http://http.debian.net/debian/pool/main/q/qemu/qemu_2.12+dfsg.orig.tar.xz
-git clone https://salsa.debian.org/qemu-team/qemu.git
-pushd qemu
-debian/rules debian/control
-chmod +w debian/control
-popd
-sudo mk-build-deps -i qemu/debian/control  -t "apt-get -y"
-rm -f ./qemu-build-deps_2.12+dfsg-3_amd64.deb
-pushd qemu
-dpkg-buildpackage -uc -us --jobs=auto
-popd
diff --git a/tools/create_base_image_gce.sh b/tools/create_base_image_gce.sh
index 2438dab..237760e 100755
--- a/tools/create_base_image_gce.sh
+++ b/tools/create_base_image_gce.sh
@@ -33,22 +33,6 @@
 # Now gather all of the *.deb files to copy them into the image
 debs=(*.deb)
 
-# See if we are using a local build of qemu.
-if [[ -x build-qemu-packages.sh ]]; then
-  ./build-qemu-packages.sh
-  # We want only a subset of the debs that will be generated
-  for i in *.deb; do
-    case "$i" in
-      qemu-kvm_*) debs+=("$i") ;;
-      qemu-system-common_*) debs+=("$i") ;;
-      qemu-system-x86_*) debs+=("$i") ;;
-      qemu-utils_*) debs+=("$i") ;;
-      qemu-system-data_*) debs+=("$i") ;;
-      libvirglrenderer0*) debs+=("$i") ;;
-    esac
-  done                         
-fi
-
 tmp_debs=()
 for i in "${debs[@]}"; do
   tmp_debs+=(/tmp/"$(basename "$i")")
diff --git a/tools/create_base_image_hostlib.sh b/tools/create_base_image_hostlib.sh
index 26bf4f5..d8e583c 100755
--- a/tools/create_base_image_hostlib.sh
+++ b/tools/create_base_image_hostlib.sh
@@ -5,13 +5,21 @@
 # INTERNAL_extra_source may be set to a directory containing the source for
 # extra package to build.
 
+# INTERNAL_IP can be set to --internal-ip run on a GCE instance
+# The instance will need --scope compute-rw
+
 source "${ANDROID_BUILD_TOP}/external/shflags/src/shflags"
 
 DEFINE_string build_instance \
   "${USER}-build" "Instance name to create for the build" "i"
+DEFINE_string build_project "$(gcloud config get-value project)" \
+  "Project to use for scratch"
+DEFINE_string build_zone "$(gcloud config get-value compute/zone)" \
+  "Zone to use for scratch resources"
 DEFINE_string dest_image "vsoc-host-scratch-${USER}" "Image to create" "o"
 DEFINE_string dest_family "" "Image family to add the image to" "f"
-DEFINE_string dest_project "" "Project to use for the new image" "p"
+DEFINE_string dest_project "$(gcloud config get-value project)" \
+  "Project to use for the new image" "p"
 DEFINE_string launch_instance "" \
   "Name of the instance to launch with the new image" "l"
 DEFINE_string source_image_family debian-9 "Image familty to use as the base" \
@@ -26,11 +34,14 @@
 DEFINE_string variant master \
   "Variant to build: generally master or stable"
 
+
+SSH_FLAGS=(${INTERNAL_IP})
+
 wait_for_instance() {
   alive=""
   while [[ -z "${alive}" ]]; do
     sleep 5
-    alive="$(gcloud compute ssh "$@" -- uptime || true)"
+    alive="$(gcloud compute ssh "${SSH_FLAGS[@]}" "$@" -- uptime || true)"
   done
 }
 
@@ -50,11 +61,7 @@
 main() {
   set -o errexit
   set -x
-  if [[ -n "${FLAGS_dest_project}" ]]; then
-    dest_project_flag=("--project=${FLAGS_dest_project}")
-  else
-    dest_project_flag=()
-  fi
+  PZ=(--project=${FLAGS_build_project} --zone=${FLAGS_build_zone})
   if [[ -n "${FLAGS_dest_family}" ]]; then
     dest_family_flag=("--family=${FLAGS_dest_family}")
   else
@@ -69,9 +76,6 @@
     "${ANDROID_BUILD_TOP}/device/google/cuttlefish_common/tools/create_base_image_gce.sh"
     ${scratch_dir}/*
   )
-  if [[ "${FLAGS_variant}" == master ]]; then
-    source_files+=("${ANDROID_BUILD_TOP}/device/google/cuttlefish_common/tools/build-qemu-packages.sh")
-  fi
   if [[ -n "${INTERNAL_extra_source}" ]]; then
     source_files+=("${INTERNAL_extra_source}"/*)
   fi
@@ -81,50 +85,64 @@
     delete_instances+=("${FLAGS_launch_instance}")
   fi
   gcloud compute instances delete -q \
-    "${dest_project_flag[@]}" "${delete_instances[@]}" || \
+    "${PZ[@]}" "${delete_instances[@]}" || \
       echo Not running
   gcloud compute disks delete -q \
-    "${dest_project_flag[@]}" "${FLAGS_dest_image}" || echo No scratch disk
+    "${PZ[@]}" "${FLAGS_dest_image}" || echo No scratch disk
   gcloud compute images delete -q \
-    "${dest_project_flag[@]}" "${FLAGS_dest_image}" || echo Not respinning
+    --project="${FLAGS_build_project}" "${FLAGS_dest_image}" || echo Not respinning
   gcloud compute disks create \
-    "${dest_project_flag[@]}" \
+    "${PZ[@]}" \
     --image-family="${FLAGS_source_image_family}" \
     --image-project="${FLAGS_source_image_project}" \
     "${FLAGS_dest_image}"
   gcloud compute instances create \
-    "${dest_project_flag[@]}" \
+    "${PZ[@]}" \
     --machine-type=n1-standard-16 \
     --image-family="${FLAGS_source_image_family}" \
     --image-project="${FLAGS_source_image_project}" \
     --boot-disk-size=200GiB \
     "${FLAGS_build_instance}"
-  wait_for_instance "${dest_project_flag[@]}" "${FLAGS_build_instance}"
+  wait_for_instance "${PZ[@]}" "${FLAGS_build_instance}"
   # Ubuntu tends to mount the wrong disk as root, so help it by waiting until
   # it has booted before giving it access to the clean image disk
   gcloud compute instances attach-disk \
-      "${dest_project_flag[@]}" \
+      "${PZ[@]}" \
       "${FLAGS_build_instance}" --disk="${FLAGS_dest_image}"
-  gcloud compute scp "${dest_project_flag[@]}" \
+  # beta for the --internal-ip flag that may be passed via SSH_FLAGS
+  gcloud beta compute scp "${SSH_FLAGS[@]}" "${PZ[@]}" \
     "${source_files[@]}" \
     "${FLAGS_build_instance}:"
-  gcloud compute ssh \
-    "${dest_project_flag[@]}" "${FLAGS_build_instance}" -- \
+  gcloud compute ssh "${SSH_FLAGS[@]}" \
+    "${PZ[@]}" "${FLAGS_build_instance}" -- \
     ./create_base_image_gce.sh
   gcloud compute instances delete -q \
-    "${dest_project_flag[@]}" "${FLAGS_build_instance}"
-  gcloud compute images create "${dest_project_flag[@]}" \
+    "${PZ[@]}" "${FLAGS_build_instance}"
+  gcloud compute images create \
+    --project="${FLAGS_build_project}" \
     --source-disk="${FLAGS_dest_image}" \
+    --source-disk-zone="${FLAGS_build_zone}" \
     --licenses=https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx \
     "${dest_family_flag[@]}" \
     "${FLAGS_dest_image}"
-  gcloud compute disks delete -q "${dest_project_flag[@]}" \
+  gcloud compute disks delete -q "${PZ[@]}" \
     "${FLAGS_dest_image}"
   if [[ -n "${FLAGS_launch_instance}" ]]; then
-    gcloud compute instances create "${dest_project_flag[@]}" \
+    gcloud compute instances create "${PZ[@]}" \
+      --image-project="${FLAGS_build_project}" \
       --image="${FLAGS_dest_image}" \
       --machine-type=n1-standard-4 \
       --scopes storage-ro \
       "${FLAGS_launch_instance}"
   fi
+  cat <<EOF
+    echo Test and if this looks good, consider releasing it via:
+
+    gcloud compute images create \
+      --project="${FLAGS_dest_project}" \
+      --source-image="${FLAGS_dest_image}" \
+      --source-image-project="${FLAGS_build_project}" \
+      "${dest_family_flag[@]}" \
+      "${FLAGS_dest_image}"
+EOF
 }
diff --git a/tools/upload_to_gce_and_run.py b/tools/upload_to_gce_and_run.py
index 9d04b73..9ceee1f 100755
--- a/tools/upload_to_gce_and_run.py
+++ b/tools/upload_to_gce_and_run.py
@@ -9,21 +9,22 @@
 
 
 def upload_artifacts(args):
-  image_pat = os.path.join(args.dist_dir, '%s-img-*.zip' % args.product)
-  images = glob.glob(image_pat)
-  if len(images) == 0:
-    raise OSError('File not found: %s' + image_pat)
-  if len(images) > 1:
-    raise OSError('%s matches multiple images: %s' % (
-        image_pat, images))
-  subprocess.check_call(
-      'gcloud compute ssh %s@%s -- /usr/bin/install_zip.sh . < %s' % (
+  dir = os.getcwd()
+  try:
+    os.chdir(args.image_dir)
+    images = glob.glob('*.img')
+    if len(images) == 0:
+      raise OSError('File not found: %s' + image_pat)
+    subprocess.check_call(
+      'tar -c -f - --lzop -S ' + ' '.join(images) +
+        ' | gcloud compute ssh %s@%s -- tar -x -f - --lzop -S' % (
           args.user,
-          args.instance,
-          images[0]),
+          args.instance),
       shell=True)
+  finally:
+    os.chdir(dir)
 
-  host_package = os.path.join(args.dist_dir, 'cvd-host_package.tar.gz')
+  host_package = os.path.join(args.host_dir, 'cvd-host_package.tar.gz')
   # host_package
   subprocess.check_call(
       'gcloud compute ssh %s@%s -- tar -x -z -f - < %s' % (
@@ -63,20 +64,19 @@
   parser = argparse.ArgumentParser(
       description='Upload a local build to Google Compute Engine and run it')
   parser.add_argument(
-      '-dist_dir',
+      '-host_dir',
       type=str,
-      default=os.path.join(os.environ.get('ANDROID_BUILD_TOP', '.'),
-                           'out', 'dist'),
+      default=os.environ.get('ANDROID_HOST_OUT', '.'),
       help='path to the dist directory')
   parser.add_argument(
+      '-image_dir',
+      type=str,
+      default=os.environ.get('ANDROID_PRODUCT_OUT', '.'),
+      help='path to the img files')
+  parser.add_argument(
       '-instance', type=str, required=True,
       help='instance to update')
   parser.add_argument(
-      '-product',
-      type=str,
-      default=os.environ.get('TARGET_PRODUCT', 'cf_x86_phone'),
-      help='product to upload')
-  parser.add_argument(
       '-user', type=str, default='vsoc-01',
       help='user to update on the instance')
   parser.add_argument(
@@ -85,10 +85,15 @@
   parser.add_argument(
       '-blank-data-image-mb', type=int, default=4098,
       help='custom userdata image size in megabytes')
+  parser.add_argument(
+      '-launch', default=False,
+      action='store_true',
+      help='launch the device')
   args = parser.parse_args()
   stop_cvd(args)
   upload_artifacts(args)
-  launch_cvd(args)
+  if args.launch:
+    launch_cvd(args)
 
 
 if __name__ == '__main__':
diff --git a/tools/upload_via_ssh.py b/tools/upload_via_ssh.py
new file mode 100755
index 0000000..7b41aee
--- /dev/null
+++ b/tools/upload_via_ssh.py
@@ -0,0 +1,87 @@
+#!/usr/bin/python
+
+"""Upload a local build to Google Compute Engine and run it."""
+
+import argparse
+import glob
+import os
+import subprocess
+
+
+def upload_artifacts(args):
+  dir = os.getcwd()
+  try:
+    os.chdir(args.image_dir)
+    images = glob.glob('*.img')
+    if len(images) == 0:
+      raise OSError('File not found: %s' + image_pat)
+    subprocess.check_call(
+      'tar -c -f - --lzop -S ' + ' '.join(images) +
+        ' | ssh %s@%s -- tar -x -f - --lzop -S' % (
+          args.user,
+          args.ip),
+      shell=True)
+  finally:
+    os.chdir(dir)
+
+  host_package = os.path.join(args.host_dir, 'cvd-host_package.tar.gz')
+  # host_package
+  subprocess.check_call(
+      'ssh %s@%s -- tar -x -z -f - < %s' % (
+          args.user,
+          args.ip,
+          host_package),
+      shell=True)
+
+
+def launch_cvd(args):
+  subprocess.check_call(
+      'ssh %s@%s -- bin/launch_cvd %s' % (
+          args.user,
+          args.ip,
+          ' '.join(args.runner_args)
+      ),
+      shell=True)
+
+
+def stop_cvd(args):
+  subprocess.call(
+      'ssh %s@%s -- bin/stop_cvd' % (
+          args.user,
+          args.ip),
+      shell=True)
+
+
+def main():
+  parser = argparse.ArgumentParser(
+      description='Upload a local build to Google Compute Engine and run it')
+  parser.add_argument(
+      '-host_dir',
+      type=str,
+      default=os.environ.get('ANDROID_HOST_OUT', '.'),
+      help='path to the dist directory')
+  parser.add_argument(
+      '-image_dir',
+      type=str,
+      default=os.environ.get('ANDROID_PRODUCT_OUT', '.'),
+      help='path to the img files')
+  parser.add_argument(
+      '-user', type=str, default='vsoc-01',
+      help='user to update on the instance')
+  parser.add_argument(
+      '-ip', type=str,
+      help='ip address of the board')
+  parser.add_argument(
+      '-launch', default=False,
+      action='store_true',
+      help='launch the device')
+  parser.add_argument('runner_args', nargs='*', help='launch_cvd arguments')
+  args = parser.parse_args()
+  stop_cvd(args)
+  upload_artifacts(args)
+  if args.launch:
+    launch_cvd(args)
+
+
+if __name__ == '__main__':
+  main()