Merge "Revert "reference-ril: fix emulator gateway""
diff --git a/include/libril/ril_ex.h b/include/libril/ril_ex.h
index 251e8ff..757bcf9 100644
--- a/include/libril/ril_ex.h
+++ b/include/libril/ril_ex.h
@@ -22,6 +22,8 @@
 
 #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);
 
diff --git a/include/telephony/ril.h b/include/telephony/ril.h
index d6a3aea..3d40b8f 100644
--- a/include/telephony/ril.h
+++ b/include/telephony/ril.h
@@ -757,6 +757,7 @@
   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.
@@ -2400,8 +2401,8 @@
  *  SUCCESS
  *  RADIO_NOT_AVAILABLE (radio resetting)
  *  PASSWORD_INCORRECT
- *  SIM_ABSENT
  *     (code is invalid)
+ *  SIM_ABSENT
  *  INTERNAL_ERR
  *  NO_MEMORY
  *  NO_RESOURCES
@@ -3054,7 +3055,7 @@
  *    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
+ *    SIM_ABSENT and CANCELLED
  *
  * See also: RIL_REQUEST_DEACTIVATE_DATA_CALL
  */
@@ -5116,7 +5117,6 @@
  *  INVALID_MODEM_STATE
  *  REQUEST_NOT_SUPPORTED
  *  SIM_ABSENT
- *
  */
 #define RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM 97
 
@@ -5235,7 +5235,6 @@
  *  CANCELLED
  *  REQUEST_NOT_SUPPORTED
  *  SIM_ABSENT
- *
  */
 #define RIL_REQUEST_SET_SMSC_ADDRESS 101
 
diff --git a/libril/Android.mk b/libril/Android.mk
index d4ed8f4..681e3c4 100644
--- a/libril/Android.mk
+++ b/libril/Android.mk
@@ -28,7 +28,7 @@
 LOCAL_STATIC_LIBRARIES := \
     libprotobuf-c-nano-enable_malloc \
 
-LOCAL_CFLAGS += -Wno-unused-parameter
+LOCAL_CFLAGS += -Wall -Wextra -Wno-unused-parameter -Werror
 
 ifeq ($(SIM_COUNT), 2)
     LOCAL_CFLAGS += -DANDROID_MULTI_SIM -DDSDA_RILD1
diff --git a/libril/RilSapSocket.h b/libril/RilSapSocket.h
index 4f6316c..1a816c5 100644
--- a/libril/RilSapSocket.h
+++ b/libril/RilSapSocket.h
@@ -36,22 +36,6 @@
  */
 class RilSapSocket : public RilSocket {
     /**
-     * Function pointer to the ril initialization funtion.
-     *
-     * @param Ril environment variable with place request and
-     *        response handlers and timeout handler.
-     *
-     * @param Number of arguements for the initialization function.
-     *
-     * @param Arguements to the initialization function used to
-     *        generate instance id of the ril daemon.
-     *
-     * @return Radio functions with handlers for onRequest, onStateRequest,
-     *         supports, onCancel and getVersion.
-     */
-    RIL_RadioFunctions *(*UimInit)(const struct RIL_Env *, int argc, char **argv);
-
-    /**
      * Place holder for the radio functions returned by the initialization
      * function. Currenty only onRequest handler is being used.
      */
diff --git a/libril/ril.cpp b/libril/ril.cpp
index 8b2b538..52d574d 100644
--- a/libril/ril.cpp
+++ b/libril/ril.cpp
@@ -114,12 +114,8 @@
 static int s_registerCalled = 0;
 
 static pthread_t s_tid_dispatch;
-static pthread_t s_tid_reader;
 static int s_started = 0;
 
-static int s_fdDebug = -1;
-static int s_fdDebug_socket2 = -1;
-
 static int s_fdWakeupRead;
 static int s_fdWakeupWrite;
 
@@ -128,44 +124,30 @@
 static struct ril_event s_wakeupfd_event;
 
 static pthread_mutex_t s_pendingRequestsMutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t s_writeMutex = 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 pthread_mutex_t s_writeMutex_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 pthread_mutex_t s_writeMutex_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 pthread_mutex_t s_writeMutex_socket4            = PTHREAD_MUTEX_INITIALIZER;
 static RequestInfo *s_pendingRequests_socket4          = NULL;
 #endif
 
-static struct ril_event s_wake_timeout_event;
-static struct ril_event s_debug_event;
-
-
 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 pthread_mutex_t s_dispatchMutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t s_dispatchCond = PTHREAD_COND_INITIALIZER;
-
-static RequestInfo *s_toDispatchHead = NULL;
-static RequestInfo *s_toDispatchTail = NULL;
-
 static UserCallbackInfo *s_last_wake_timeout_info = NULL;
 
 static void *s_lastNITZTimeData = NULL;
@@ -430,9 +412,6 @@
 
 extern "C" void
 RIL_register (const RIL_RadioFunctions *callbacks) {
-    int ret;
-    int flags;
-
     RLOGI("SIM_COUNT: %d", SIM_COUNT);
 
     if (callbacks == NULL) {
@@ -568,9 +547,7 @@
 extern "C" void
 RIL_onRequestAck(RIL_Token t) {
     RequestInfo *pRI;
-    int ret;
 
-    size_t errorOffset;
     RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
 
     pRI = (RequestInfo *)t;
@@ -604,7 +581,6 @@
 RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen) {
     RequestInfo *pRI;
     int ret;
-    size_t errorOffset;
     RIL_SOCKET_ID socket_id = RIL_SOCKET_1;
 
     pRI = (RequestInfo *)t;
@@ -950,7 +926,7 @@
         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: "E_EMPTY_RECORD";
+        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";
diff --git a/libril/ril_commands.h b/libril/ril_commands.h
index de73936..94c2a26 100644
--- a/libril/ril_commands.h
+++ b/libril/ril_commands.h
@@ -158,3 +158,5 @@
     {RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, radio::setCarrierInfoForImsiEncryptionResponse},
     {RIL_REQUEST_START_NETWORK_SCAN, radio::startNetworkScanResponse},
     {RIL_REQUEST_STOP_NETWORK_SCAN, radio::stopNetworkScanResponse},
+    {RIL_REQUEST_START_KEEPALIVE, radio::startKeepaliveResponse},
+    {RIL_REQUEST_STOP_KEEPALIVE, radio::stopKeepaliveResponse},
diff --git a/libril/ril_service.cpp b/libril/ril_service.cpp
index c7e02c7..9b9b641 100644
--- a/libril/ril_service.cpp
+++ b/libril/ril_service.cpp
@@ -41,8 +41,6 @@
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::hidl_array;
-using ::android::hardware::radio::V1_1::NetworkScanRequest;
-using ::android::hardware::radio::V1_1::KeepaliveRequest;
 using ::android::hardware::Void;
 using android::CommandInfo;
 using android::RequestInfo;
@@ -248,7 +246,7 @@
 
     Return<void> getAvailableNetworks(int32_t serial);
 
-    Return<void> startNetworkScan(int32_t serial, const NetworkScanRequest& request);
+    Return<void> startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request);
 
     Return<void> stopNetworkScan(int32_t serial);
 
@@ -440,7 +438,7 @@
 
     Return<void> setIndicationFilter(int32_t serial, int32_t indicationFilter);
 
-    Return<void> startKeepalive(int32_t serial, const KeepaliveRequest& keepalive);
+    Return<void> startKeepalive(int32_t serial, const V1_1::KeepaliveRequest& keepalive);
 
     Return<void> stopKeepalive(int32_t serial, int32_t sessionHandle);
 
@@ -451,7 +449,7 @@
     Return<void> responseAcknowledgement();
 
     Return<void> setCarrierInfoForImsiEncryption(int32_t serial,
-            const ::android::hardware::radio::V1_1::ImsiEncryptionInfo& message);
+            const V1_1::ImsiEncryptionInfo& message);
 
     void checkReturnStatus(Return<void>& ret);
 };
@@ -498,9 +496,9 @@
  * request with error RIL_E_NO_MEMORY.
  * Returns true on success, and false on failure.
  */
-bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI) {
+bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI, bool allowEmpty) {
     size_t len = src.size();
-    if (len == 0) {
+    if (len == 0 && !allowEmpty) {
         *dest = NULL;
         return true;
     }
@@ -514,6 +512,10 @@
     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) {
@@ -549,7 +551,7 @@
     return true;
 }
 
-bool dispatchStrings(int serial, int slotId, int request, int countStrings, ...) {
+bool dispatchStrings(int serial, int slotId, int request, bool allowEmpty, int countStrings, ...) {
     RequestInfo *pRI = android::addRequestToList(serial, slotId, request);
     if (pRI == NULL) {
         return false;
@@ -566,7 +568,7 @@
     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)) {
+        if (!copyHidlStringToRil(&pStrings[i], hidl_string(str), pRI, allowEmpty)) {
             va_end(ap);
             for (int j = 0; j < i; j++) {
                 memsetAndFreeStrings(1, pStrings[j]);
@@ -819,7 +821,7 @@
 #if VDBG
     RLOGD("supplyIccPinForApp: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN, true,
             2, pin.c_str(), aid.c_str());
     return Void();
 }
@@ -829,7 +831,7 @@
 #if VDBG
     RLOGD("supplyIccPukForApp: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK, true,
             3, puk.c_str(), pin.c_str(), aid.c_str());
     return Void();
 }
@@ -839,7 +841,7 @@
 #if VDBG
     RLOGD("supplyIccPin2ForApp: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN2,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PIN2, true,
             2, pin2.c_str(), aid.c_str());
     return Void();
 }
@@ -849,7 +851,7 @@
 #if VDBG
     RLOGD("supplyIccPuk2ForApp: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK2,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_SIM_PUK2, true,
             3, puk2.c_str(), pin2.c_str(), aid.c_str());
     return Void();
 }
@@ -859,7 +861,7 @@
 #if VDBG
     RLOGD("changeIccPinForApp: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN, true,
             3, oldPin.c_str(), newPin.c_str(), aid.c_str());
     return Void();
 }
@@ -869,7 +871,7 @@
 #if VDBG
     RLOGD("changeIccPin2ForApp: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN2,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_SIM_PIN2, true,
             3, oldPin2.c_str(), newPin2.c_str(), aid.c_str());
     return Void();
 }
@@ -879,7 +881,7 @@
 #if VDBG
     RLOGD("supplyNetworkDepersonalization: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, true,
             1, netPin.c_str());
     return Void();
 }
@@ -938,7 +940,7 @@
 #if VDBG
     RLOGD("getImsiForApp: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_GET_IMSI,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_GET_IMSI, false,
             1, aid.c_str());
     return Void();
 }
@@ -1049,7 +1051,7 @@
 #if VDBG
     RLOGD("sendSms: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS, false,
             2, message.smscPdu.c_str(), message.pdu.c_str());
     return Void();
 }
@@ -1058,7 +1060,7 @@
 #if VDBG
     RLOGD("sendSMSExpectMore: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS_EXPECT_MORE,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_SEND_SMS_EXPECT_MORE, false,
             2, message.smscPdu.c_str(), message.pdu.c_str());
     return Void();
 }
@@ -1092,7 +1094,7 @@
     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, 7,
+        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(),
@@ -1110,7 +1112,7 @@
             }
             return Void();
         }
-        dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, 15,
+        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(),
@@ -1269,7 +1271,7 @@
 #if VDBG
     RLOGD("deactivateDataCall: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_DEACTIVATE_DATA_CALL,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_DEACTIVATE_DATA_CALL, false,
             2, (std::to_string(cid)).c_str(), reasonRadioShutDown ? "1" : "0");
     return Void();
 }
@@ -1280,7 +1282,7 @@
 #if VDBG
     RLOGD("getFacilityLockForApp: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_QUERY_FACILITY_LOCK,
+    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();
@@ -1292,7 +1294,7 @@
 #if VDBG
     RLOGD("setFacilityLockForApp: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_SET_FACILITY_LOCK,
+    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();
@@ -1304,7 +1306,7 @@
 #if VDBG
     RLOGD("setBarringPassword: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_BARRING_PASSWORD,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_CHANGE_BARRING_PASSWORD, true,
             3, facility.c_str(), oldPassword.c_str(), newPassword.c_str());
     return Void();
 }
@@ -1343,7 +1345,7 @@
     return Void();
 }
 
-Return<void> RadioImpl::startNetworkScan(int32_t serial, const NetworkScanRequest& request) {
+Return<void> RadioImpl::startNetworkScan(int32_t serial, const V1_1::NetworkScanRequest& request) {
 #if VDBG
     RLOGD("startNetworkScan: serial %d", serial);
 #endif
@@ -1403,8 +1405,8 @@
         }
     }
 
-    s_vendorFunctions->onRequest(
-            RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI);
+    CALL_ONREQUEST(RIL_REQUEST_START_NETWORK_SCAN, &scan_request, sizeof(scan_request), pRI,
+            mSlotId);
 
     return Void();
 }
@@ -1503,7 +1505,6 @@
     RIL_SMS_WriteArgs args;
     args.status = (int) smsWriteArgs.status;
 
-    int len;
     if (!copyHidlStringToRil(&args.pdu, smsWriteArgs.pdu, pRI)) {
         return Void();
     }
@@ -1683,7 +1684,7 @@
 #if VDBG
     RLOGD("sendBurstDtmf: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_CDMA_BURST_DTMF,
+    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();
@@ -1952,7 +1953,7 @@
 #if VDBG
     RLOGD("acknowledgeIncomingGsmSmsWithPdu: serial %d", serial);
 #endif
-    dispatchStrings(serial, mSlotId, RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU,
+    dispatchStrings(serial, mSlotId, RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, false,
             2, success ? "1" : "0", ackPdu.c_str());
     return Void();
 }
@@ -2004,19 +2005,8 @@
     if (s_vendorFunctions->version <= 14) {
         RIL_InitialAttachApn iaa = {};
 
-        if (dataProfileInfo.apn.size() == 0) {
-            iaa.apn = (char *) calloc(1, sizeof(char));
-            if (iaa.apn == NULL) {
-                RLOGE("Memory allocation failed for request %s",
-                        requestToString(pRI->pCI->requestNumber));
-                sendErrorResponse(pRI, RIL_E_NO_MEMORY);
-                return Void();
-            }
-            iaa.apn[0] = '\0';
-        } else {
-            if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) {
-                return Void();
-            }
+        if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI, true)) {
+            return Void();
         }
 
         const hidl_string &protocol =
@@ -2042,19 +2032,8 @@
     } else {
         RIL_InitialAttachApn_v15 iaa = {};
 
-        if (dataProfileInfo.apn.size() == 0) {
-            iaa.apn = (char *) calloc(1, sizeof(char));
-            if (iaa.apn == NULL) {
-                RLOGE("Memory allocation failed for request %s",
-                        requestToString(pRI->pCI->requestNumber));
-                sendErrorResponse(pRI, RIL_E_NO_MEMORY);
-                return Void();
-            }
-            iaa.apn[0] = '\0';
-        } else {
-            if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI)) {
-                return Void();
-            }
+        if (!copyHidlStringToRil(&iaa.apn, dataProfileInfo.apn, pRI, true)) {
+            return Void();
         }
 
         if (!copyHidlStringToRil(&iaa.protocol, dataProfileInfo.protocol, pRI)) {
@@ -2166,9 +2145,13 @@
     return true;
 }
 
+struct ImsCdmaSms {
+    RIL_IMS_SMS_Message imsSms;
+    RIL_CDMA_SMS_Message cdmaSms;
+};
+
 bool dispatchImsCdmaSms(const ImsSmsMessage& message, RequestInfo *pRI) {
-    RIL_IMS_SMS_Message rism = {};
-    RIL_CDMA_SMS_Message rcsm = {};
+    ImsCdmaSms temp = {};
 
     if (message.cdmaMessage.size() != 1) {
         RLOGE("dispatchImsCdmaSms: Invalid len %s", requestToString(pRI->pCI->requestNumber));
@@ -2176,15 +2159,20 @@
         return false;
     }
 
-    rism.tech = RADIO_TECH_3GPP2;
-    rism.retry = BOOL_TO_INT(message.retry);
-    rism.messageRef = message.messageRef;
-    rism.message.cdmaMessage = &rcsm;
+    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(rcsm, message.cdmaMessage[0]);
+    constructCdmaSms(temp.cdmaSms, message.cdmaMessage[0]);
 
-    CALL_ONREQUEST(pRI->pCI->requestNumber, &rism, sizeof(RIL_RadioTechnologyFamily) +
-            sizeof(uint8_t) + sizeof(int32_t) + sizeof(rcsm), pRI, pRI->socket_id);
+    // 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;
 }
@@ -2387,7 +2375,6 @@
 
     pf.authContext = authContext;
 
-    int len;
     if (!copyHidlStringToRil(&pf.authData, authData, pRI)) {
         return Void();
     }
@@ -2475,20 +2462,21 @@
         for (size_t i = 0; i < num; i++) {
             dataProfilePtrs[i] = &dataProfiles[i];
 
-            success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI);
+            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)) {
+            if (success && !copyHidlStringToRil(&dataProfiles[i].protocol, protocol, pRI, true)) {
                 success = false;
             }
 
-            if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI)) {
+            if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI,
+                    true)) {
                 success = false;
             }
             if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password,
-                    pRI)) {
+                    pRI, true)) {
                 success = false;
             }
 
@@ -2538,24 +2526,25 @@
         for (size_t i = 0; i < num; i++) {
             dataProfilePtrs[i] = &dataProfiles[i];
 
-            success = copyHidlStringToRil(&dataProfiles[i].apn, profiles[i].apn, pRI);
+            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)) {
+                    profiles[i].roamingProtocol, pRI, true)) {
                 success = false;
             }
-            if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI)) {
+            if (success && !copyHidlStringToRil(&dataProfiles[i].user, profiles[i].user, pRI,
+                    true)) {
                 success = false;
             }
             if (success && !copyHidlStringToRil(&dataProfiles[i].password, profiles[i].password,
-                    pRI)) {
+                    pRI, true)) {
                 success = false;
             }
             if (success && !copyHidlStringToRil(&dataProfiles[i].mvnoMatchData,
-                    profiles[i].mvnoMatchData, pRI)) {
+                    profiles[i].mvnoMatchData, pRI, true)) {
                 success = false;
             }
 
@@ -2793,6 +2782,102 @@
     return Void();
 }
 
+Return<void> RadioImpl::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::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::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::responseAcknowledgement() {
     android::releaseWakeLock();
     return Void();
@@ -2836,43 +2921,6 @@
     return Void();
 }
 
-Return<void> RadioImpl::setCarrierInfoForImsiEncryption(int32_t serial,
-        const ::android::hardware::radio::V1_1::ImsiEncryptionInfo& data) {
-    RLOGD("setCarrierInfoForImsiEncryption: serial %d", serial);
-    RequestInfo *pRI = android::addRequestToList(serial, mSlotId, RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION);
-    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();
-    }
-    int32_t lSize = data.carrierKey.size();
-    imsiEncryption.carrierKey = new uint8_t[lSize];
-    memcpy(imsiEncryption.carrierKey, data.carrierKey.data(), lSize);
-    imsiEncryption.expirationTime = data.expirationTime;
-    s_vendorFunctions->onRequest(pRI->pCI->requestNumber, &imsiEncryption, sizeof(RIL_CarrierInfoForImsiEncryption), pRI);
-    delete(imsiEncryption.carrierKey);
-    return Void();
-}
-
-Return<void> RadioImpl::startKeepalive(int32_t serial, const KeepaliveRequest& keepalive) {
-    RLOGD("startKeepalive: serial %d", serial);
-    return Void();
-}
-
-Return<void> RadioImpl::stopKeepalive(int32_t serial, int32_t sessionHandle) {
-    RLOGD("stopKeepalive: serial %d", serial);
-    return Void();
-}
-
-
 /***************************************************************************************************
  * RESPONSE FUNCTIONS
  * Functions above are used for requests going from framework to vendor code. The ones below are
@@ -3171,6 +3219,7 @@
                 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
@@ -4393,7 +4442,6 @@
         RadioResponseInfo responseInfo = {};
         populateResponseInfo(responseInfo, serial, responseType, e);
         bool manual = false;
-        int serviceClass;
         if (response == NULL || responseLen != sizeof(int)) {
             RLOGE("getNetworkSelectionModeResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
@@ -4628,7 +4676,6 @@
         RadioResponseInfo responseInfo = {};
         populateResponseInfo(responseInfo, serial, responseType, e);
         bool enable = false;
-        int serviceClass;
         if (response == NULL || responseLen != sizeof(int)) {
             RLOGE("getMuteResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
@@ -6598,6 +6645,60 @@
     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::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_1 == NULL) {
+        RLOGE("%s: radioService[%d]->mRadioResponseV1_1 == 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_1->startKeepaliveResponse(responseInfo, ks);
+    radioService[slotId]->checkReturnStatus(retStatus);
+    return 0;
+}
+
+int radio::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_1 == NULL) {
+        RLOGE("%s: radioService[%d]->mRadioResponseV1_1 == NULL", __FUNCTION__, slotId);
+        return 0;
+    }
+
+    Return<void> retStatus =
+            radioService[slotId]->mRadioResponseV1_1->stopKeepaliveResponse(responseInfo);
+    radioService[slotId]->checkReturnStatus(retStatus);
+    return 0;
+}
+
 int radio::sendRequestRawResponse(int slotId,
                                   int responseType, int serial, RIL_Errno e,
                                   void *response, size_t responseLen) {
@@ -6662,7 +6763,11 @@
     return 0;
 }
 
-// Radio Indication functions
+/***************************************************************************************************
+ * 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) :
@@ -8304,6 +8409,39 @@
     return 0;
 }
 
+int radio::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::oemHookRawInd(int slotId,
                          int indicationType, int token, RIL_Errno e, void *response,
                          size_t responseLen) {
diff --git a/libril/ril_service.h b/libril/ril_service.h
index be7cc2d..2240e2a 100644
--- a/libril/ril_service.h
+++ b/libril/ril_service.h
@@ -541,6 +541,14 @@
                               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,
@@ -713,6 +721,10 @@
                          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);
diff --git a/libril/sap_service.cpp b/libril/sap_service.cpp
index ab43ee8..b945174 100644
--- a/libril/sap_service.cpp
+++ b/libril/sap_service.cpp
@@ -532,7 +532,6 @@
 
 void *sapDecodeMessage(MsgId msgId, MsgType msgType, uint8_t *payloadPtr, size_t payloadLen) {
     void *responsePtr = NULL;
-    bool decodeStatus = false;
     pb_istream_t stream;
 
     /* Create the stream */
diff --git a/librilutils/Android.mk b/librilutils/Android.mk
index 0c6e9ea..62873e9 100644
--- a/librilutils/Android.mk
+++ b/librilutils/Android.mk
@@ -14,6 +14,8 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := \
     $(LOCAL_PATH)/../include
 
+LOCAL_CFLAGS := -Wall -Wextra -Werror
+
 LOCAL_PROTOC_OPTIMIZE_TYPE := nanopb-c-enable_malloc
 
 LOCAL_MODULE:= librilutils
@@ -37,6 +39,8 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := \
     $(LOCAL_PATH)/../include
 
+LOCAL_CFLAGS := -Wall -Wextra -Werror
+
 LOCAL_PROTOC_OPTIMIZE_TYPE := nanopb-c-enable_malloc
 
 LOCAL_MODULE:= librilutils_static
@@ -51,6 +55,7 @@
 src_proto := $(LOCAL_PATH)
 LOCAL_MODULE := sap-api-java-static
 LOCAL_SRC_FILES := proto/sap-api.proto
+LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_PROTOC_OPTIMIZE_TYPE := micro
 
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/reference-ril/Android.mk b/reference-ril/Android.mk
index 6d170c9..6afdbd3 100644
--- a/reference-ril/Android.mk
+++ b/reference-ril/Android.mk
@@ -14,8 +14,11 @@
 LOCAL_SHARED_LIBRARIES := \
     liblog libcutils libutils libril librilutils
 
+LOCAL_STATIC_LIBRARIES := libqemu_pipe libbase
+
 # for asprinf
 LOCAL_CFLAGS := -D_GNU_SOURCE
+LOCAL_CFLAGS += -Wall -Wextra -Wno-unused-variable -Wno-unused-function -Werror
 
 LOCAL_C_INCLUDES :=
 
diff --git a/reference-ril/reference-ril.c b/reference-ril/reference-ril.c
index c20fb81..3ab7bee 100644
--- a/reference-ril/reference-ril.c
+++ b/reference-ril/reference-ril.c
@@ -37,7 +37,7 @@
 #include <cutils/sockets.h>
 #include <sys/system_properties.h>
 #include <termios.h>
-#include <system/qemu_pipe.h>
+#include <qemu_pipe.h>
 
 #include "ril.h"
 
@@ -165,7 +165,13 @@
     RUIM_READY = 8,
     RUIM_PIN = 9,
     RUIM_PUK = 10,
-    RUIM_NETWORK_PERSONALIZATION = 11
+    RUIM_NETWORK_PERSONALIZATION = 11,
+    ISIM_ABSENT = 12,
+    ISIM_NOT_READY = 13,
+    ISIM_READY = 14,
+    ISIM_PIN = 15,
+    ISIM_PUK = 16,
+    ISIM_NETWORK_PERSONALIZATION = 17,
 } SIM_Status;
 
 static void onRequest (int request, void *data, size_t datalen, RIL_Token t);
@@ -394,7 +400,7 @@
 
     if (onOff == 0 && sState != RADIO_STATE_OFF) {
         err = at_send_command("AT+CFUN=0", &p_response);
-       if (err < 0 || p_response->success == 0) goto error;
+        if (err < 0 || p_response->success == 0) goto error;
         setRadioState(RADIO_STATE_OFF);
     } else if (onOff > 0 && sState == RADIO_STATE_OFF) {
         err = at_send_command("AT+CFUN=1", &p_response);
@@ -448,6 +454,60 @@
     requestOrSendDataCallList(&t);
 }
 
+// Hang up, reject, conference, call waiting
+static void requestCallSelection(
+                void *data __unused, size_t datalen __unused, RIL_Token t, int request)
+{
+    // 3GPP 22.030 6.5.5
+    static char hangupWaiting[]    = "AT+CHLD=0";
+    static char hangupForeground[] = "AT+CHLD=1";
+    static char switchWaiting[]    = "AT+CHLD=2";
+    static char conference[]       = "AT+CHLD=3";
+    static char reject[]           = "ATH";
+
+    char* atCommand;
+
+    if (getSIMStatus() == SIM_ABSENT) {
+        RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
+        return;
+    }
+
+    switch(request) {
+        case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
+            // "Releases all held calls or sets User Determined User Busy
+            //  (UDUB) for a waiting call."
+            atCommand = hangupWaiting;
+            break;
+        case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
+            // "Releases all active calls (if any exist) and accepts
+            //  the other (held or waiting) call."
+            atCommand = hangupForeground;
+            break;
+        case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
+            // "Places all active calls (if any exist) on hold and accepts
+            //  the other (held or waiting) call."
+            atCommand = switchWaiting;
+#ifdef WORKAROUND_ERRONEOUS_ANSWER
+            s_expectAnswer = 1;
+#endif /* WORKAROUND_ERRONEOUS_ANSWER */
+            break;
+        case RIL_REQUEST_CONFERENCE:
+            // "Adds a held call to the conversation"
+            atCommand = conference;
+            break;
+        case RIL_REQUEST_UDUB:
+            // User determined user busy (reject)
+            atCommand = reject;
+            break;
+        default:
+            assert(0);
+    }
+    at_send_command(atCommand, NULL);
+    // Success or failure is ignored by the upper layer here.
+    // It will call GET_CURRENT_CALLS and determine success that way.
+    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+}
+
 static void requestOrSendDataCallList(RIL_Token *t)
 {
     ATResponse *p_response;
@@ -802,9 +862,11 @@
     }
 
     return;
+#ifdef WORKAROUND_ERRONEOUS_ANSWER
 error:
     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
     at_response_free(p_response);
+#endif
 }
 
 static void requestDial(void *data, size_t datalen __unused, RIL_Token t)
@@ -842,6 +904,11 @@
     int err;
     ATResponse *p_response = NULL;
 
+    if (getSIMStatus() == SIM_ABSENT) {
+        RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
+        return;
+    }
+
     p_args = (RIL_SMS_WriteArgs *)data;
 
     length = strlen(p_args->pdu)/2;
@@ -867,6 +934,10 @@
     int ret;
     char *cmd;
 
+    if (getSIMStatus() == SIM_ABSENT) {
+        RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
+        return;
+    }
     p_line = (int *)data;
 
     // 3GPP 22.030 6.5.5
@@ -887,9 +958,13 @@
     ATResponse *p_response = NULL;
     int err;
     char *line;
-    int count =0;
-    int numofElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
-    int response[numofElements];
+    int count = 0;
+    // Accept a response that is at least v6, and up to v10
+    int minNumOfElements=sizeof(RIL_SignalStrength_v6)/sizeof(int);
+    int maxNumOfElements=sizeof(RIL_SignalStrength_v10)/sizeof(int);
+    int response[maxNumOfElements];
+
+    memset(response, 0, sizeof(response));
 
     err = at_send_command_singleline("AT+CSQ", "+CSQ:", &p_response);
 
@@ -903,9 +978,9 @@
     err = at_tok_start(&line);
     if (err < 0) goto error;
 
-    for (count =0; count < numofElements; count ++) {
+    for (count = 0; count < maxNumOfElements; count++) {
         err = at_tok_nextint(&line, &(response[count]));
-        if (err < 0) goto error;
+        if (err < 0 && count < minNumOfElements) goto error;
     }
 
     RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
@@ -1074,12 +1149,6 @@
 
     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
     at_response_free(p_response);
-
-    return;
-error:
-    RLOGE("requestCdmaDeviceIdentity must never return an error when radio is on");
-    at_response_free(p_response);
-    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
 }
 
 static void requestCdmaGetSubscriptionSource(int request __unused, void *data,
@@ -1168,11 +1237,6 @@
     responseStr[3] = "8587777777"; // MIN
     responseStr[4] = "1"; // PRL Version
     RIL_onRequestComplete(t, RIL_E_SUCCESS, responseStr, count*sizeof(char*));
-
-    return;
-error:
-    RLOGE("requestRegistrationState must never return an error when radio is on");
-    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
 }
 
 static void requestCdmaGetRoamingPreference(int request __unused, void *data __unused,
@@ -1195,7 +1259,7 @@
     res = at_tok_nextint(&line, &roaming_pref);
     if (res < 0) goto error;
 
-     RIL_onRequestComplete(t, RIL_E_SUCCESS, &roaming_pref, sizeof(roaming_pref));
+    RIL_onRequestComplete(t, RIL_E_SUCCESS, &roaming_pref, sizeof(roaming_pref));
     return;
 error:
     RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
@@ -1535,6 +1599,11 @@
     RIL_SMS_Response response;
     RIL_CDMA_SMS_Message* rcsm;
 
+    if (getSIMStatus() == SIM_ABSENT) {
+        RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
+        return;
+    }
+
     RLOGD("requestCdmaSendSMS datalen=%zu, sizeof(RIL_CDMA_SMS_Message)=%zu",
             datalen, sizeof(RIL_CDMA_SMS_Message));
 
@@ -1573,6 +1642,11 @@
     RIL_SMS_Response response;
     ATResponse *p_response = NULL;
 
+    if (getSIMStatus() == SIM_ABSENT) {
+        RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
+        return;
+    }
+
     memset(&response, 0, sizeof(response));
     RLOGD("requestSendSMS datalen =%zu", datalen);
 
@@ -1616,7 +1690,7 @@
     RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
     at_response_free(p_response);
     return;
-    }
+}
 
 static void requestImsSendSMS(void *data, size_t datalen, RIL_Token t)
 {
@@ -1904,6 +1978,11 @@
     int ackSuccess;
     int err;
 
+    if (getSIMStatus() == SIM_ABSENT) {
+        RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
+        return;
+    }
+
     ackSuccess = ((int *)data)[0];
 
     if (ackSuccess == 1) {
@@ -2105,6 +2184,47 @@
    RIL_onRequestComplete(t, RIL_E_SUCCESS, &hwCfg, sizeof(hwCfg));
 }
 
+static void requestGetTtyMode(void *data, size_t datalen, RIL_Token t)
+{
+   int  ttyModeResponse;
+
+   RIL_UNUSED_PARM(data);
+   RIL_UNUSED_PARM(datalen);
+
+   ttyModeResponse = (getSIMStatus() == SIM_READY) ? 1  // TTY Full
+                                                   : 0; // TTY Off
+
+   RIL_onRequestComplete(t, RIL_E_SUCCESS, &ttyModeResponse, sizeof(ttyModeResponse));
+}
+
+static void requestGetRadioCapability(void *data, size_t datalen, RIL_Token t)
+{
+   RIL_RadioCapability radioCapability;
+
+   RIL_UNUSED_PARM(data);
+   RIL_UNUSED_PARM(datalen);
+
+   radioCapability.version = RIL_RADIO_CAPABILITY_VERSION;
+   radioCapability.session = 0;
+   radioCapability.phase   = 0;
+   radioCapability.rat     = 0;
+   radioCapability.logicalModemUuid[0] = '\0';
+   radioCapability.status  = RC_STATUS_SUCCESS;
+
+   RIL_onRequestComplete(t, RIL_E_SUCCESS, &radioCapability, sizeof(radioCapability));
+}
+
+static void requestGetMute(void *data, size_t datalen, RIL_Token t)
+{
+   int  muteResponse;
+
+   RIL_UNUSED_PARM(data);
+   RIL_UNUSED_PARM(datalen);
+
+   muteResponse = 0; // Mute disabled
+
+   RIL_onRequestComplete(t, RIL_E_SUCCESS, &muteResponse, sizeof(muteResponse));
+}
 
 /*** Callback methods from the RIL library to us ***/
 
@@ -2141,12 +2261,47 @@
     /* Ignore all non-power requests when RADIO_STATE_OFF
      * (except RIL_REQUEST_GET_SIM_STATUS)
      */
-    if (sState == RADIO_STATE_OFF
-        && !(request == RIL_REQUEST_RADIO_POWER
-            || request == RIL_REQUEST_GET_SIM_STATUS)
-    ) {
-        RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
-        return;
+    if (sState == RADIO_STATE_OFF) {
+        switch(request) {
+            case RIL_REQUEST_BASEBAND_VERSION:
+            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
+            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
+            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
+            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
+            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
+            case RIL_REQUEST_CDMA_SUBSCRIPTION:
+            case RIL_REQUEST_DEVICE_IDENTITY:
+            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
+            case RIL_REQUEST_GET_ACTIVITY_INFO:
+            case RIL_REQUEST_GET_CARRIER_RESTRICTIONS:
+            case RIL_REQUEST_GET_CURRENT_CALLS:
+            case RIL_REQUEST_GET_IMEI:
+            case RIL_REQUEST_GET_MUTE:
+            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
+            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
+            case RIL_REQUEST_GET_RADIO_CAPABILITY:
+            case RIL_REQUEST_GET_SIM_STATUS:
+            case RIL_REQUEST_NV_RESET_CONFIG:
+            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
+            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
+            case RIL_REQUEST_QUERY_TTY_MODE:
+            case RIL_REQUEST_RADIO_POWER:
+            case RIL_REQUEST_SET_BAND_MODE:
+            case RIL_REQUEST_SET_CARRIER_RESTRICTIONS:
+            case RIL_REQUEST_SET_LOCATION_UPDATES:
+            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
+            case RIL_REQUEST_SET_TTY_MODE:
+            case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
+            case RIL_REQUEST_STOP_LCE:
+            case RIL_REQUEST_VOICE_RADIO_TECH:
+                // Process all the above, even though the radio is off
+                break;
+
+            default:
+                // For all others, say NOT_AVAILABLE because the radio is off
+                RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
+                return;
+        }
     }
 
     switch (request) {
@@ -2177,39 +2332,12 @@
             requestHangup(data, datalen, t);
             break;
         case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
-            // 3GPP 22.030 6.5.5
-            // "Releases all held calls or sets User Determined User Busy
-            //  (UDUB) for a waiting call."
-            at_send_command("AT+CHLD=0", NULL);
-
-            /* success or failure is ignored by the upper layer here.
-               it will call GET_CURRENT_CALLS and determine success that way */
-            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
-            break;
         case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
-            // 3GPP 22.030 6.5.5
-            // "Releases all active calls (if any exist) and accepts
-            //  the other (held or waiting) call."
-            at_send_command("AT+CHLD=1", NULL);
-
-            /* success or failure is ignored by the upper layer here.
-               it will call GET_CURRENT_CALLS and determine success that way */
-            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
-            break;
         case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
-            // 3GPP 22.030 6.5.5
-            // "Places all active calls (if any exist) on hold and accepts
-            //  the other (held or waiting) call."
-            at_send_command("AT+CHLD=2", NULL);
-
-#ifdef WORKAROUND_ERRONEOUS_ANSWER
-            s_expectAnswer = 1;
-#endif /* WORKAROUND_ERRONEOUS_ANSWER */
-
-            /* success or failure is ignored by the upper layer here.
-               it will call GET_CURRENT_CALLS and determine success that way */
-            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
-            break;
+        case RIL_REQUEST_CONFERENCE:
+        case RIL_REQUEST_UDUB:
+             requestCallSelection(data, datalen, t, request);
+             break;
         case RIL_REQUEST_ANSWER:
             at_send_command("ATA", NULL);
 
@@ -2217,27 +2345,13 @@
             s_expectAnswer = 1;
 #endif /* WORKAROUND_ERRONEOUS_ANSWER */
 
-            /* success or failure is ignored by the upper layer here.
-               it will call GET_CURRENT_CALLS and determine success that way */
-            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
-            break;
-        case RIL_REQUEST_CONFERENCE:
-            // 3GPP 22.030 6.5.5
-            // "Adds a held call to the conversation"
-            at_send_command("AT+CHLD=3", NULL);
-
-            /* success or failure is ignored by the upper layer here.
-               it will call GET_CURRENT_CALLS and determine success that way */
-            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
-            break;
-        case RIL_REQUEST_UDUB:
-            /* user determined user busy */
-            /* sometimes used: ATH */
-            at_send_command("ATH", NULL);
-
-            /* success or failure is ignored by the upper layer here.
-               it will call GET_CURRENT_CALLS and determine success that way */
-            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+            if (getSIMStatus() != SIM_READY) {
+                RIL_onRequestComplete(t, RIL_E_MODEM_ERR, NULL, 0);
+            } else {
+                // Success or failure is ignored by the upper layer here.
+                // It will call GET_CURRENT_CALLS and determine success that way.
+                RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+            }
             break;
 
         case RIL_REQUEST_SEPARATE_CONNECTION:
@@ -2245,6 +2359,10 @@
                 char  cmd[12];
                 int   party = ((int*)data)[0];
 
+                if (getSIMStatus() == SIM_ABSENT) {
+                    RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
+                    return;
+                }
                 // Make sure that party is in a valid range.
                 // (Note: The Telephony middle layer imposes a range of 1 to 7.
                 // It's sufficient for us to just make sure it's single digit.)
@@ -2341,6 +2459,10 @@
             break;
 
         case RIL_REQUEST_CANCEL_USSD:
+            if (getSIMStatus() == SIM_ABSENT) {
+                RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
+                return;
+            }
             p_response = NULL;
             err = at_send_command_numeric("AT+CUSD=2", &p_response);
 
@@ -2354,7 +2476,11 @@
             break;
 
         case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
-            at_send_command("AT+COPS=0", NULL);
+            if (getSIMStatus() == SIM_ABSENT) {
+                RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
+            } else {
+                at_send_command("AT+COPS=0", NULL);
+            }
             break;
 
         case RIL_REQUEST_DATA_CALL_LIST:
@@ -2470,54 +2596,92 @@
             requestShutdown(t);
             break;
 
-        /* CDMA Specific Requests */
+        case RIL_REQUEST_QUERY_TTY_MODE:
+            requestGetTtyMode(data, datalen, t);
+            break;
+
+        case RIL_REQUEST_GET_RADIO_CAPABILITY:
+            requestGetRadioCapability(data, datalen, t);
+            break;
+
+        case RIL_REQUEST_GET_MUTE:
+            requestGetMute(data, datalen, t);
+            break;
+
+        case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
+        case RIL_REQUEST_ALLOW_DATA:
+        case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
+        case RIL_REQUEST_SET_CLIR:
+        case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
+        case RIL_REQUEST_SET_BAND_MODE:
+        case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
+        case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
+        case RIL_REQUEST_SET_LOCATION_UPDATES:
+        case RIL_REQUEST_SET_TTY_MODE:
+        case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
+            RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+            break;
+
         case RIL_REQUEST_BASEBAND_VERSION:
-            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
-                requestCdmaBaseBandVersion(request, data, datalen, t);
-                break;
-            } // Fall-through if tech is not cdma
+            requestCdmaBaseBandVersion(request, data, datalen, t);
+            break;
 
         case RIL_REQUEST_DEVICE_IDENTITY:
-            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
-                requestCdmaDeviceIdentity(request, data, datalen, t);
-                break;
-            } // Fall-through if tech is not cdma
+            requestCdmaDeviceIdentity(request, data, datalen, t);
+            break;
 
         case RIL_REQUEST_CDMA_SUBSCRIPTION:
-            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
-                requestCdmaSubscription(request, data, datalen, t);
-                break;
-            } // Fall-through if tech is not cdma
-
-        case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
-            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
-                requestCdmaSetSubscriptionSource(request, data, datalen, t);
-                break;
-            } // Fall-through if tech is not cdma
+            requestCdmaSubscription(request, data, datalen, t);
+            break;
 
         case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
-            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
-                requestCdmaGetSubscriptionSource(request, data, datalen, t);
-                break;
-            } // Fall-through if tech is not cdma
+            requestCdmaGetSubscriptionSource(request, data, datalen, t);
+            break;
+
+        case RIL_REQUEST_START_LCE:
+        case RIL_REQUEST_STOP_LCE:
+        case RIL_REQUEST_PULL_LCEDATA:
+            if (getSIMStatus() == SIM_ABSENT) {
+                RIL_onRequestComplete(t, RIL_E_SIM_ABSENT, NULL, 0);
+            } else {
+                RIL_onRequestComplete(t, RIL_E_LCE_NOT_SUPPORTED, NULL, 0);
+            }
+            break;
 
         case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
                 requestCdmaGetRoamingPreference(request, data, datalen, t);
-                break;
-            } // Fall-through if tech is not cdma
+            } else {
+                RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
+            }
+            break;
+
+        case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
+            if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
+                requestCdmaSetSubscriptionSource(request, data, datalen, t);
+            } else {
+                // VTS tests expect us to silently do nothing
+                RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+            }
+            break;
 
         case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
                 requestCdmaSetRoamingPreference(request, data, datalen, t);
-                break;
-            } // Fall-through if tech is not cdma
+            } else {
+                // VTS tests expect us to silently do nothing
+                RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+            }
+            break;
 
         case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
             if (TECH_BIT(sMdmInfo) == MDM_CDMA) {
                 requestExitEmergencyMode(data, datalen, t);
-                break;
-            } // Fall-through if tech is not cdma
+            } else {
+                // VTS tests expect us to silently do nothing
+                RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+            }
+            break;
 
         default:
             RLOGD("Request not supported. Tech: %d",TECH(sMdmInfo));
@@ -2716,11 +2880,6 @@
     char *cpinResult;
 
     RLOGD("getSIMStatus(). sState: %d",sState);
-    if (sState == RADIO_STATE_OFF || sState == RADIO_STATE_UNAVAILABLE) {
-        ret = SIM_NOT_READY;
-        goto done;
-    }
-
     err = at_send_command_singleline("AT+CPIN?", "+CPIN:", &p_response);
 
     if (err != 0) {
@@ -2776,7 +2935,7 @@
     p_response = NULL;
     cpinResult = NULL;
 
-    ret = SIM_READY;
+    ret = (sState == RADIO_STATE_ON) ? SIM_READY : SIM_NOT_READY;
 
 done:
     at_response_free(p_response);
@@ -2827,7 +2986,26 @@
           NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
         // RUIM_NETWORK_PERSONALIZATION = 11
         { RIL_APPTYPE_RUIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
-           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN }
+           NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
+        // ISIM_ABSENT = 12
+        { RIL_APPTYPE_UNKNOWN, RIL_APPSTATE_UNKNOWN, RIL_PERSOSUBSTATE_UNKNOWN,
+          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
+        // ISIM_NOT_READY = 13
+        { RIL_APPTYPE_ISIM, RIL_APPSTATE_DETECTED, RIL_PERSOSUBSTATE_UNKNOWN,
+          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
+        // ISIM_READY = 14
+        { RIL_APPTYPE_ISIM, RIL_APPSTATE_READY, RIL_PERSOSUBSTATE_READY,
+          NULL, NULL, 0, RIL_PINSTATE_UNKNOWN, RIL_PINSTATE_UNKNOWN },
+        // ISIM_PIN = 15
+        { RIL_APPTYPE_ISIM, RIL_APPSTATE_PIN, RIL_PERSOSUBSTATE_UNKNOWN,
+          NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
+        // ISIM_PUK = 16
+        { RIL_APPTYPE_ISIM, RIL_APPSTATE_PUK, RIL_PERSOSUBSTATE_UNKNOWN,
+          NULL, NULL, 0, RIL_PINSTATE_ENABLED_BLOCKED, RIL_PINSTATE_UNKNOWN },
+        // ISIM_NETWORK_PERSONALIZATION = 17
+        { RIL_APPTYPE_ISIM, RIL_APPSTATE_SUBSCRIPTION_PERSO, RIL_PERSOSUBSTATE_SIM_NETWORK,
+          NULL, NULL, 0, RIL_PINSTATE_ENABLED_NOT_VERIFIED, RIL_PINSTATE_UNKNOWN },
+
     };
     RIL_CardState card_state;
     int num_apps;
@@ -2838,7 +3016,7 @@
         num_apps = 0;
     } else {
         card_state = RIL_CARDSTATE_PRESENT;
-        num_apps = 2;
+        num_apps = 3;
     }
 
     // Allocate and initialize base card status.
@@ -2859,14 +3037,15 @@
     // Pickup the appropriate application status
     // that reflects sim_status for gsm.
     if (num_apps != 0) {
-        // Only support one app, gsm
-        p_card_status->num_applications = 2;
+        p_card_status->num_applications = 3;
         p_card_status->gsm_umts_subscription_app_index = 0;
         p_card_status->cdma_subscription_app_index = 1;
+        p_card_status->ims_subscription_app_index = 2;
 
         // Get the correct app status
         p_card_status->applications[0] = app_status_array[sim_status];
         p_card_status->applications[1] = app_status_array[sim_status + RUIM_ABSENT];
+        p_card_status->applications[2] = app_status_array[sim_status + ISIM_ABSENT];
     }
 
     *pp_card_status = p_card_status;
diff --git a/rild/Android.mk b/rild/Android.mk
index 4f5802b..7ac505c 100644
--- a/rild/Android.mk
+++ b/rild/Android.mk
@@ -17,6 +17,7 @@
 	librilutils_static
 
 LOCAL_CFLAGS := -DRIL_SHLIB
+LOCAL_CFLAGS += -Wall -Wextra -Werror
 
 ifeq ($(SIM_COUNT), 2)
     LOCAL_CFLAGS += -DANDROID_MULTI_SIM
diff --git a/rild/rild.c b/rild/rild.c
index dbd925d..685ef70 100644
--- a/rild/rild.c
+++ b/rild/rild.c
@@ -144,8 +144,8 @@
         exit(0);
     }
     if (strncmp(clientId, "0", MAX_CLIENT_ID_LENGTH)) {
-        strncpy(ril_service_name, ril_service_name_base, MAX_SERVICE_NAME_LENGTH);
-        strncat(ril_service_name, clientId, MAX_SERVICE_NAME_LENGTH);
+        snprintf(ril_service_name, sizeof(ril_service_name), "%s%s", ril_service_name_base,
+                 clientId);
     }
 
     if (rilLibPath == NULL) {