OSDN Git Service

Merge "Initialize the buffer" into mm-wireless-dev
authorRobert Greenwalt <rgreenwalt@google.com>
Thu, 21 Jan 2016 20:36:21 +0000 (20:36 +0000)
committerAndroid Partner Code Review <android-gerrit-partner@google.com>
Thu, 21 Jan 2016 20:36:21 +0000 (20:36 +0000)
include/telephony/ril.h
libril/RilSapSocket.cpp
libril/ril.cpp [changed mode: 0644->0755]

index 2e71367..c8b130f 100644 (file)
@@ -46,7 +46,26 @@ extern "C" {
 #define SIM_COUNT 1
 #endif
 
-#define RIL_VERSION 11     /* Current version */
+/*
+ * 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 = 11 : 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_VERSION = 12 : This version includes new wakelock semantics.
+ */
+#define RIL_VERSION 11
+#define LAST_IMPRECISE_RIL_VERSION 11 // Better self-documented name
 #define RIL_VERSION_MIN 6 /* Minimum RIL_VERSION supported */
 
 #define CDMA_ALPHA_INFO_BUFFER_LENGTH 64
@@ -591,10 +610,53 @@ typedef struct {
 /* 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,
@@ -613,7 +675,9 @@ typedef enum {
     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 */
-    CALL_FAIL_ERROR_UNSPECIFIED = 0xffff
+    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 {
@@ -632,6 +696,8 @@ typedef enum {
        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 */
@@ -644,10 +710,44 @@ typedef enum {
     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_PROTOCOL_ERRORS   = 0x6F,             /* no retry */
+    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,
 
     /* Not mentioned in the specification */
     PDP_FAIL_VOICE_REGISTRATION_FAIL = -1,
@@ -663,7 +763,8 @@ typedef enum {
                                              mode was up on same APN/data profile - no retry until
                                              tethered call is off */
 
-    PDP_FAIL_ERROR_UNSPECIFIED = 0xffff,  /* retry silently */
+    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 */
index e422f34..19457f4 100644 (file)
@@ -300,25 +300,26 @@ void RilSapSocket::onRequestComplete(RIL_Token t, RIL_Errno e, void *response,
     SapSocketRequest* request= (SapSocketRequest*)t;
     MsgHeader *hdr = request->curr;
 
-    if (response && response_len > 0) {
-        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 {
+    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("Token:%d, MessageId:%d", hdr->token, hdr->id);
+        RLOGE("Token:%d, MessageId:%d", hdr->token, hdr->id);
 
-            sendResponse(&rsp);
-            free(rsp.payload);
-        }
+        sendResponse(&rsp);
+        free(rsp.payload);
     }
 
     // Deallocate SapSocketRequest
old mode 100644 (file)
new mode 100755 (executable)
index 30b4220..97e35e4
@@ -30,6 +30,7 @@
 #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>
@@ -310,6 +311,8 @@ static RIL_RadioState processRadioState(RIL_RadioState newRadioState);
 
 static bool isServiceTypeCfQuery(RIL_SsServiceType serType, RIL_SsRequestType reqType);
 
+static bool isDebuggable();
+
 #ifdef RIL_SHLIB
 #if defined(ANDROID_MULTI_SIM)
 extern "C" void RIL_onUnsolicitedResponse(int unsolResponse, const void *data,
@@ -2506,69 +2509,84 @@ static int responseDataCallListV9(Parcel &p, void *response, size_t responselen)
     return 0;
 }
 
+static int responseDataCallListV11(Parcel &p, void *response, size_t responselen) {
+    if (response == NULL && responselen != 0) {
+                RLOGE("invalid response: NULL");
+                return RIL_ERRNO_INVALID_RESPONSE;
+    }
 
-static int responseDataCallList(Parcel &p, void *response, size_t responselen)
-{
-    if (s_callbacks.version < 5) {
-        RLOGD("responseDataCallList: v4");
-        return responseDataCallListV4(p, response, responselen);
-    } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
-        return responseDataCallListV6(p, response, responselen);
-    } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
-        return responseDataCallListV9(p, response, responselen);
-    } else {
-        if (response == NULL && responselen != 0) {
-            RLOGE("invalid response: NULL");
-            return RIL_ERRNO_INVALID_RESPONSE;
-        }
-
-        if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
-            RLOGE("invalid response length %d expected multiple of %d",
-                    (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
-            return RIL_ERRNO_INVALID_RESPONSE;
-        }
+    if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
+        RLOGE("invalid response length %d expected multiple of %d",
+        (int)responselen, (int)sizeof(RIL_Data_Call_Response_v11));
+        return RIL_ERRNO_INVALID_RESPONSE;
+    }
 
-        // Write version
-        p.writeInt32(11);
+    // Write version
+    p.writeInt32(11);
 
-        int num = responselen / sizeof(RIL_Data_Call_Response_v11);
-        p.writeInt32(num);
+    int num = responselen / sizeof(RIL_Data_Call_Response_v11);
+    p.writeInt32(num);
 
-        RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) response;
-        startResponse;
-        int i;
-        for (i = 0; i < num; i++) {
-            p.writeInt32((int)p_cur[i].status);
-            p.writeInt32(p_cur[i].suggestedRetryTime);
-            p.writeInt32(p_cur[i].cid);
-            p.writeInt32(p_cur[i].active);
-            writeStringToParcel(p, p_cur[i].type);
-            writeStringToParcel(p, p_cur[i].ifname);
-            writeStringToParcel(p, p_cur[i].addresses);
-            writeStringToParcel(p, p_cur[i].dnses);
-            writeStringToParcel(p, p_cur[i].gateways);
-            writeStringToParcel(p, p_cur[i].pcscf);
-            p.writeInt32(p_cur[i].mtu);
-            appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", printBuf,
-                p_cur[i].status,
-                p_cur[i].suggestedRetryTime,
-                p_cur[i].cid,
-                (p_cur[i].active==0)?"down":"up",
-                (char*)p_cur[i].type,
-                (char*)p_cur[i].ifname,
-                (char*)p_cur[i].addresses,
-                (char*)p_cur[i].dnses,
-                (char*)p_cur[i].gateways,
-                (char*)p_cur[i].pcscf,
-                p_cur[i].mtu);
-        }
-        removeLastChar;
-        closeResponse;
+    RIL_Data_Call_Response_v11 *p_cur = (RIL_Data_Call_Response_v11 *) response;
+    startResponse;
+    int i;
+    for (i = 0; i < num; i++) {
+        p.writeInt32((int)p_cur[i].status);
+        p.writeInt32(p_cur[i].suggestedRetryTime);
+        p.writeInt32(p_cur[i].cid);
+        p.writeInt32(p_cur[i].active);
+        writeStringToParcel(p, p_cur[i].type);
+        writeStringToParcel(p, p_cur[i].ifname);
+        writeStringToParcel(p, p_cur[i].addresses);
+        writeStringToParcel(p, p_cur[i].dnses);
+        writeStringToParcel(p, p_cur[i].gateways);
+        writeStringToParcel(p, p_cur[i].pcscf);
+        p.writeInt32(p_cur[i].mtu);
+        appendPrintBuf("%s[status=%d,retry=%d,cid=%d,%s,%s,%s,%s,%s,%s,%s,mtu=%d],", printBuf,
+        p_cur[i].status,
+        p_cur[i].suggestedRetryTime,
+        p_cur[i].cid,
+        (p_cur[i].active==0)?"down":"up",
+        (char*)p_cur[i].type,
+        (char*)p_cur[i].ifname,
+        (char*)p_cur[i].addresses,
+        (char*)p_cur[i].dnses,
+        (char*)p_cur[i].gateways,
+        (char*)p_cur[i].pcscf,
+        p_cur[i].mtu);
     }
+    removeLastChar;
+    closeResponse;
 
     return 0;
 }
 
+static int responseDataCallList(Parcel &p, void *response, size_t responselen)
+{
+    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+        if (s_callbacks.version < 5) {
+            RLOGD("responseDataCallList: v4");
+            return responseDataCallListV4(p, response, responselen);
+        } else if (responselen % sizeof(RIL_Data_Call_Response_v6) == 0) {
+            return responseDataCallListV6(p, response, responselen);
+        } else if (responselen % sizeof(RIL_Data_Call_Response_v9) == 0) {
+            return responseDataCallListV9(p, response, responselen);
+        } else {
+            return responseDataCallListV11(p, response, responselen);
+        }
+    } else { // RIL version >= 12
+        if (responselen % sizeof(RIL_Data_Call_Response_v11) != 0) {
+            RLOGE("Data structure expected is RIL_Data_Call_Response_v11");
+            if (!isDebuggable()) {
+                return RIL_ERRNO_INVALID_RESPONSE;
+            } else {
+                assert(0);
+            }
+        }
+        return responseDataCallListV11(p, response, responselen);
+    }
+}
+
 static int responseSetupDataCall(Parcel &p, void *response, size_t responselen)
 {
     if (s_callbacks.version < 5) {
@@ -2893,6 +2911,55 @@ static int responseCdmaInformationRecords(Parcel &p,
     return 0;
 }
 
+static void responseRilSignalStrengthV5(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
+    p.writeInt32(p_cur->GW_SignalStrength.signalStrength);
+    p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
+    p.writeInt32(p_cur->CDMA_SignalStrength.dbm);
+    p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
+    p.writeInt32(p_cur->EVDO_SignalStrength.dbm);
+    p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
+    p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
+}
+
+static void responseRilSignalStrengthV6Extra(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
+    /*
+     * Fixup LTE for backwards compatibility
+     */
+    // signalStrength: -1 -> 99
+    if (p_cur->LTE_SignalStrength.signalStrength == -1) {
+        p_cur->LTE_SignalStrength.signalStrength = 99;
+    }
+    // rsrp: -1 -> INT_MAX all other negative value to positive.
+    // So remap here
+    if (p_cur->LTE_SignalStrength.rsrp == -1) {
+        p_cur->LTE_SignalStrength.rsrp = INT_MAX;
+    } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
+        p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
+    }
+    // rsrq: -1 -> INT_MAX
+    if (p_cur->LTE_SignalStrength.rsrq == -1) {
+        p_cur->LTE_SignalStrength.rsrq = INT_MAX;
+    }
+    // Not remapping rssnr is already using INT_MAX
+
+    // cqi: -1 -> INT_MAX
+    if (p_cur->LTE_SignalStrength.cqi == -1) {
+        p_cur->LTE_SignalStrength.cqi = INT_MAX;
+    }
+
+    p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
+    p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
+    p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
+    p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
+    p.writeInt32(p_cur->LTE_SignalStrength.cqi);
+}
+
+static void responseRilSignalStrengthV10(Parcel &p, RIL_SignalStrength_v10 *p_cur) {
+    responseRilSignalStrengthV5(p, p_cur);
+    responseRilSignalStrengthV6Extra(p, p_cur);
+    p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
+}
+
 static int responseRilSignalStrength(Parcel &p,
                     void *response, size_t responselen) {
     if (response == NULL && responselen != 0) {
@@ -2900,90 +2967,65 @@ static int responseRilSignalStrength(Parcel &p,
         return RIL_ERRNO_INVALID_RESPONSE;
     }
 
-    if (responselen >= sizeof (RIL_SignalStrength_v5)) {
-        RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
+    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+        if (responselen >= sizeof (RIL_SignalStrength_v5)) {
+            RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
 
-        p.writeInt32(p_cur->GW_SignalStrength.signalStrength);
-        p.writeInt32(p_cur->GW_SignalStrength.bitErrorRate);
-        p.writeInt32(p_cur->CDMA_SignalStrength.dbm);
-        p.writeInt32(p_cur->CDMA_SignalStrength.ecio);
-        p.writeInt32(p_cur->EVDO_SignalStrength.dbm);
-        p.writeInt32(p_cur->EVDO_SignalStrength.ecio);
-        p.writeInt32(p_cur->EVDO_SignalStrength.signalNoiseRatio);
-        if (responselen >= sizeof (RIL_SignalStrength_v6)) {
-            /*
-             * Fixup LTE for backwards compatibility
-             */
-            if (s_callbacks.version <= 6) {
-                // signalStrength: -1 -> 99
-                if (p_cur->LTE_SignalStrength.signalStrength == -1) {
-                    p_cur->LTE_SignalStrength.signalStrength = 99;
-                }
-                // rsrp: -1 -> INT_MAX all other negative value to positive.
-                // So remap here
-                if (p_cur->LTE_SignalStrength.rsrp == -1) {
-                    p_cur->LTE_SignalStrength.rsrp = INT_MAX;
-                } else if (p_cur->LTE_SignalStrength.rsrp < -1) {
-                    p_cur->LTE_SignalStrength.rsrp = -p_cur->LTE_SignalStrength.rsrp;
-                }
-                // rsrq: -1 -> INT_MAX
-                if (p_cur->LTE_SignalStrength.rsrq == -1) {
-                    p_cur->LTE_SignalStrength.rsrq = INT_MAX;
-                }
-                // Not remapping rssnr is already using INT_MAX
+            responseRilSignalStrengthV5(p, p_cur);
 
-                // cqi: -1 -> INT_MAX
-                if (p_cur->LTE_SignalStrength.cqi == -1) {
-                    p_cur->LTE_SignalStrength.cqi = INT_MAX;
+            if (responselen >= sizeof (RIL_SignalStrength_v6)) {
+                responseRilSignalStrengthV6Extra(p, p_cur);
+                if (responselen >= sizeof (RIL_SignalStrength_v10)) {
+                    p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
+                } else {
+                    p.writeInt32(INT_MAX);
                 }
-            }
-            p.writeInt32(p_cur->LTE_SignalStrength.signalStrength);
-            p.writeInt32(p_cur->LTE_SignalStrength.rsrp);
-            p.writeInt32(p_cur->LTE_SignalStrength.rsrq);
-            p.writeInt32(p_cur->LTE_SignalStrength.rssnr);
-            p.writeInt32(p_cur->LTE_SignalStrength.cqi);
-            if (responselen >= sizeof (RIL_SignalStrength_v10)) {
-                p.writeInt32(p_cur->TD_SCDMA_SignalStrength.rscp);
             } else {
+                p.writeInt32(99);
+                p.writeInt32(INT_MAX);
+                p.writeInt32(INT_MAX);
+                p.writeInt32(INT_MAX);
+                p.writeInt32(INT_MAX);
                 p.writeInt32(INT_MAX);
             }
         } else {
-            p.writeInt32(99);
-            p.writeInt32(INT_MAX);
-            p.writeInt32(INT_MAX);
-            p.writeInt32(INT_MAX);
-            p.writeInt32(INT_MAX);
-            p.writeInt32(INT_MAX);
+            RLOGE("invalid response length");
+            return RIL_ERRNO_INVALID_RESPONSE;
         }
-
-        startResponse;
-        appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
-                CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
-                EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
-                EVDO_SS.signalNoiseRatio=%d,\
-                LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
-                LTE_SS.rssnr=%d,LTE_SS.cqi=%d,TDSCDMA_SS.rscp=%d]",
-                printBuf,
-                p_cur->GW_SignalStrength.signalStrength,
-                p_cur->GW_SignalStrength.bitErrorRate,
-                p_cur->CDMA_SignalStrength.dbm,
-                p_cur->CDMA_SignalStrength.ecio,
-                p_cur->EVDO_SignalStrength.dbm,
-                p_cur->EVDO_SignalStrength.ecio,
-                p_cur->EVDO_SignalStrength.signalNoiseRatio,
-                p_cur->LTE_SignalStrength.signalStrength,
-                p_cur->LTE_SignalStrength.rsrp,
-                p_cur->LTE_SignalStrength.rsrq,
-                p_cur->LTE_SignalStrength.rssnr,
-                p_cur->LTE_SignalStrength.cqi,
-                p_cur->TD_SCDMA_SignalStrength.rscp);
-        closeResponse;
-
-    } else {
-        RLOGE("invalid response length");
-        return RIL_ERRNO_INVALID_RESPONSE;
+    } else { // RIL version >= 12
+        if (responselen % sizeof(RIL_SignalStrength_v10) != 0) {
+            RLOGE("Data structure expected is RIL_SignalStrength_v10");
+            if (!isDebuggable()) {
+                return RIL_ERRNO_INVALID_RESPONSE;
+            } else {
+                assert(0);
+            }
+        }
+        RIL_SignalStrength_v10 *p_cur = ((RIL_SignalStrength_v10 *) response);
+        responseRilSignalStrengthV10(p, p_cur);
     }
-
+    startResponse;
+    appendPrintBuf("%s[signalStrength=%d,bitErrorRate=%d,\
+            CDMA_SS.dbm=%d,CDMA_SSecio=%d,\
+            EVDO_SS.dbm=%d,EVDO_SS.ecio=%d,\
+            EVDO_SS.signalNoiseRatio=%d,\
+            LTE_SS.signalStrength=%d,LTE_SS.rsrp=%d,LTE_SS.rsrq=%d,\
+            LTE_SS.rssnr=%d,LTE_SS.cqi=%d,TDSCDMA_SS.rscp=%d]",
+            printBuf,
+            p_cur->GW_SignalStrength.signalStrength,
+            p_cur->GW_SignalStrength.bitErrorRate,
+            p_cur->CDMA_SignalStrength.dbm,
+            p_cur->CDMA_SignalStrength.ecio,
+            p_cur->EVDO_SignalStrength.dbm,
+            p_cur->EVDO_SignalStrength.ecio,
+            p_cur->EVDO_SignalStrength.signalNoiseRatio,
+            p_cur->LTE_SignalStrength.signalStrength,
+            p_cur->LTE_SignalStrength.rsrp,
+            p_cur->LTE_SignalStrength.rsrq,
+            p_cur->LTE_SignalStrength.rssnr,
+            p_cur->LTE_SignalStrength.cqi,
+            p_cur->TD_SCDMA_SignalStrength.rscp);
+    closeResponse;
     return 0;
 }
 
@@ -3042,12 +3084,25 @@ static int responseCdmaCallWaiting(Parcel &p, void *response,
     writeStringToParcel(p, p_cur->name);
     marshallSignalInfoRecord(p, p_cur->signalInfoRecord);
 
-    if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
+    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+        if (responselen >= sizeof(RIL_CDMA_CallWaiting_v6)) {
+            p.writeInt32(p_cur->number_type);
+            p.writeInt32(p_cur->number_plan);
+        } else {
+            p.writeInt32(0);
+            p.writeInt32(0);
+        }
+    } else { // RIL version >= 12
+        if (responselen % sizeof(RIL_CDMA_CallWaiting_v6) != 0) {
+            RLOGE("Data structure expected is RIL_CDMA_CallWaiting_v6");
+            if (!isDebuggable()) {
+                return RIL_ERRNO_INVALID_RESPONSE;
+            } else {
+                assert(0);
+            }
+        }
         p.writeInt32(p_cur->number_type);
         p.writeInt32(p_cur->number_plan);
-    } else {
-        p.writeInt32(0);
-        p.writeInt32(0);
     }
 
     startResponse;
@@ -3069,6 +3124,20 @@ static int responseCdmaCallWaiting(Parcel &p, void *response,
     return 0;
 }
 
+static void responseSimRefreshV7(Parcel &p, void *response) {
+      RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
+      p.writeInt32(p_cur->result);
+      p.writeInt32(p_cur->ef_id);
+      writeStringToParcel(p, p_cur->aid);
+
+      appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
+            printBuf,
+            p_cur->result,
+            p_cur->ef_id,
+            p_cur->aid);
+
+}
+
 static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
     if (response == NULL && responselen != 0) {
         RLOGE("responseSimRefresh: invalid response: NULL");
@@ -3076,27 +3145,31 @@ static int responseSimRefresh(Parcel &p, void *response, size_t responselen) {
     }
 
     startResponse;
-    if (s_callbacks.version == 7) {
-        RIL_SimRefreshResponse_v7 *p_cur = ((RIL_SimRefreshResponse_v7 *) response);
-        p.writeInt32(p_cur->result);
-        p.writeInt32(p_cur->ef_id);
-        writeStringToParcel(p, p_cur->aid);
-
-        appendPrintBuf("%sresult=%d, ef_id=%d, aid=%s",
-                printBuf,
-                p_cur->result,
-                p_cur->ef_id,
-                p_cur->aid);
-    } else {
-        int *p_cur = ((int *) response);
-        p.writeInt32(p_cur[0]);
-        p.writeInt32(p_cur[1]);
-        writeStringToParcel(p, NULL);
+    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+        if (s_callbacks.version == 7) {
+            responseSimRefreshV7(p, response);
+        } else {
+            int *p_cur = ((int *) response);
+            p.writeInt32(p_cur[0]);
+            p.writeInt32(p_cur[1]);
+            writeStringToParcel(p, NULL);
+
+            appendPrintBuf("%sresult=%d, ef_id=%d",
+                    printBuf,
+                    p_cur[0],
+                    p_cur[1]);
+        }
+    } else { // RIL version >= 12
+        if (responselen % sizeof(RIL_SimRefreshResponse_v7) != 0) {
+            RLOGE("Data structure expected is RIL_SimRefreshResponse_v7");
+            if (!isDebuggable()) {
+                return RIL_ERRNO_INVALID_RESPONSE;
+            } else {
+                assert(0);
+            }
+        }
+        responseSimRefreshV7(p, response);
 
-        appendPrintBuf("%sresult=%d, ef_id=%d",
-                printBuf,
-                p_cur[0],
-                p_cur[1]);
     }
     closeResponse;
 
@@ -3459,6 +3532,29 @@ static void sendSimStatusAppInfo(Parcel &p, int num_apps, RIL_AppStatus appStatu
         closeResponse;
 }
 
+static void responseSimStatusV5(Parcel &p, void *response) {
+    RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
+
+    p.writeInt32(p_cur->card_state);
+    p.writeInt32(p_cur->universal_pin_state);
+    p.writeInt32(p_cur->gsm_umts_subscription_app_index);
+    p.writeInt32(p_cur->cdma_subscription_app_index);
+
+    sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
+}
+
+static void responseSimStatusV6(Parcel &p, void *response) {
+    RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
+
+    p.writeInt32(p_cur->card_state);
+    p.writeInt32(p_cur->universal_pin_state);
+    p.writeInt32(p_cur->gsm_umts_subscription_app_index);
+    p.writeInt32(p_cur->cdma_subscription_app_index);
+    p.writeInt32(p_cur->ims_subscription_app_index);
+
+    sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
+}
+
 static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
     int i;
 
@@ -3467,29 +3563,25 @@ static int responseSimStatus(Parcel &p, void *response, size_t responselen) {
         return RIL_ERRNO_INVALID_RESPONSE;
     }
 
-    if (responselen == sizeof (RIL_CardStatus_v6)) {
-        RIL_CardStatus_v6 *p_cur = ((RIL_CardStatus_v6 *) response);
-
-        p.writeInt32(p_cur->card_state);
-        p.writeInt32(p_cur->universal_pin_state);
-        p.writeInt32(p_cur->gsm_umts_subscription_app_index);
-        p.writeInt32(p_cur->cdma_subscription_app_index);
-        p.writeInt32(p_cur->ims_subscription_app_index);
-
-        sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
-    } else if (responselen == sizeof (RIL_CardStatus_v5)) {
-        RIL_CardStatus_v5 *p_cur = ((RIL_CardStatus_v5 *) response);
-
-        p.writeInt32(p_cur->card_state);
-        p.writeInt32(p_cur->universal_pin_state);
-        p.writeInt32(p_cur->gsm_umts_subscription_app_index);
-        p.writeInt32(p_cur->cdma_subscription_app_index);
-        p.writeInt32(-1);
-
-        sendSimStatusAppInfo(p, p_cur->num_applications, p_cur->applications);
-    } else {
-        RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
-        return RIL_ERRNO_INVALID_RESPONSE;
+    if (s_callbacks.version <= LAST_IMPRECISE_RIL_VERSION) {
+        if (responselen == sizeof (RIL_CardStatus_v6)) {
+            responseSimStatusV6(p, response);
+        } else if (responselen == sizeof (RIL_CardStatus_v5)) {
+            responseSimStatusV5(p, response);
+        } else {
+            RLOGE("responseSimStatus: A RilCardStatus_v6 or _v5 expected\n");
+            return RIL_ERRNO_INVALID_RESPONSE;
+        }
+    } else { // RIL version >= 12
+        if (responselen % sizeof(RIL_CardStatus_v6) != 0) {
+            RLOGE("Data structure expected is RIL_CardStatus_v6");
+            if (!isDebuggable()) {
+                return RIL_ERRNO_INVALID_RESPONSE;
+            } else {
+                assert(0);
+            }
+        }
+        responseSimStatusV6(p, response);
     }
 
     return 0;
@@ -4306,11 +4398,7 @@ RIL_register (const RIL_RadioFunctions *callbacks) {
              callbacks->version, RIL_VERSION_MIN);
         return;
     }
-    if (callbacks->version > RIL_VERSION) {
-        RLOGE("RIL_register: version %d is too new, max version is %d",
-             callbacks->version, RIL_VERSION);
-        return;
-    }
+
     RLOGE("RIL_register: RIL version %d", callbacks->version);
 
     if (s_registerCalled > 0) {
@@ -5096,6 +5184,7 @@ requestToString(int request) {
         case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU: return "RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
         case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS: return "RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS";
         case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH";
+        case RIL_REQUEST_WRITE_SMS_TO_SIM: return "WRITE_SMS_TO_SIM";
         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 "RIL_REQUEST_SET_INITIAL_ATTACH_APN";
@@ -5124,6 +5213,7 @@ requestToString(int request) {
         case RIL_UNSOL_ON_USSD_REQUEST: return "UNSOL_ON_USSD_REQUEST(obsolete)";
         case RIL_UNSOL_NITZ_TIME_RECEIVED: return "UNSOL_NITZ_TIME_RECEIVED";
         case RIL_UNSOL_SIGNAL_STRENGTH: return "UNSOL_SIGNAL_STRENGTH";
+        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";
@@ -5184,6 +5274,18 @@ rilSocketIdToString(RIL_SOCKET_ID socket_id)
     }
 }
 
+/*
+ * Returns true for a debuggable build.
+ */
+static bool isDebuggable() {
+    char debuggable[PROP_VALUE_MAX];
+    property_get("ro.debuggable", debuggable, "0");
+    if (strcmp(debuggable, "1") == 0) {
+        return true;
+    }
+    return false;
+}
+
 } /* namespace android */
 
 void rilEventAddWakeup_helper(struct ril_event *ev) {