Cleanup DATA_REG and VOICE_REG Location Info

The data registration and voice registration states contain
large swaths of location information. While it seemed at first
blush we could remove that information, having synchronized
knowledge of when a registration has resulted in a cell change
provides valuable infomation.  So cleaning up the same by using
the same cell location structure that is being used elsewhere
in the interface to ensure that this method
always keeps sufficiently up-to-date information, without the
need to increasingly bloat it. Note this also fixes subtle bugs
that existed due to the information previously being incomplete.

Bug: 32223344
Test: Tested updated qcril

Captured RILJ logs on different rats as follows

02-27 10:22:48.489 D/RILJ    ( 1483): [4169]< DATA_REGISTRATION_STATE
{.regState = REG_HOME, .rat = 14, .reasonDataDenied = -1, .maxDataCalls
= 20, .cellIdentity = {.cellInfoType = LTE, .cellIdentityGsm = [],
.cellIdentityWcdma = [], .cellIdentityCdma = [], .cellIdentityLte =
[{.mcc = -1, .mnc = -1, .ci = 56, .pci = 135, .tac = 13826, .earfcn =
-1}], .cellIdentityTdscdma = []}} [SUB0]

02-27 10:22:48.463 D/RILJ    ( 1483): [4166]< VOICE_REGISTRATION_STATE
{.regState = REG_HOME, .rat = 14, .cssSupported = true,
.roamingIndicator = 1, .systemIsInPrl = -1, .defaultRoamingIndicator =
-1, .reasonForDenial = 0, .cellIdentity = {.cellInfoType = LTE,
.cellIdentityGsm = [], .cellIdentityWcdma = [], .cellIdentityCdma = [],
.cellIdentityLte = [{.mcc = -1, .mnc = -1, .ci = 56, .pci = -1, .tac =
-1, .earfcn = -1}], .cellIdentityTdscdma = []}} [SUB

02-27 11:13:16.138 D/RILJ    ( 2110): [3992]< DATA_REGISTRATION_STATE
{.regState = REG_ROAMING, .rat = 13, .reasonDataDenied = -1,
.maxDataCalls = 20, .cellIdentity = {.cellInfoType = CDMA,
.cellIdentityGsm = [], .cellIdentityWcdma = [], .cellIdentityCdma =
[{.networkId = -1, .systemId = -1, .baseStationId = -1, .longitude = -1,
.latitude = -1}], .cellIdentityLte = [], .cellIdentityTdscdma = []}}
[SUB0]

02-27 11:13:16.136 D/RILJ    ( 2110): [3993]< VOICE_REGISTRATION_STATE
{.regState = NOT_REG_MT_SEARCHING_OP, .rat = 0, .cssSupported = false,
.roamingIndicator = 64, .systemIsInPrl = 1, .defaultRoamingIndicator =
-1, .reasonForDenial = 0, .cellIdentity = {.cellInfoType = 0x0,
.cellIdentityGsm = [], .cellIdentityWcdma = [], .cellIdentityCdma = [],
.cellIdentityLte = [], .cellIdentityTdscdma = []}} [SUB0]

02-27 11:23:21.875 D/RILJ    ( 2104): [4058]< VOICE_REGISTRATION_STATE
{.regState = REG_ROAMING, .rat = 6, .cssSupported = false,
.roamingIndicator = 64, .systemIsInPrl = 1, .defaultRoamingIndicator =
-1, .reasonForDenial = 0, .cellIdentity = {.cellInfoType = CDMA,
.cellIdentityGsm = [], .cellIdentityWcdma = [], .cellIdentityCdma =
[{.networkId = 54, .systemId = 4, .baseStationId = 7155, .longitude =
2147483647, .latitude = 0}], .cellIdentityLte = [], .cellIdentityTdscdma
= []}} [SUB0]

02-27 11:29:36.774 D/RILJ    ( 2157): [3925]< VOICE_REGISTRATION_STATE
{.regState = REG_HOME, .rat = 16, .cssSupported = false,
.roamingIndicator = 1, .systemIsInPrl = -1, .defaultRoamingIndicator =
-1, .reasonForDenial = 0, .cellIdentity = {.cellInfoType = GSM,
.cellIdentityGsm = [{.mcc = -1, .mnc = -1, .lac = 8, .cid = 0, .arfcn =
-1, .bsic = -1}], .cellIdentityWcdma = [], .cellIdentityCdma = [],
.cellIdentityLte = [], .cellIdentityTdscdma = []}} [SUB0]

02-27 11:29:36.768 D/RILJ    ( 2157): [3924]< DATA_REGISTRATION_STATE
{.regState = REG_HOME, .rat = 2, .reasonDataDenied = -1, .maxDataCalls =
20, .cellIdentity = {.cellInfoType = GSM, .cellIdentityGsm = [{.mcc =
-1, .mnc = -1, .lac = 8, .cid = 0, .arfcn = -1, .bsic = -1}],
.cellIdentityWcdma = [], .cellIdentityCdma = [], .cellIdentityLte = [],
.cellIdentityTdscdma = []}} [SUB0]

Merged-In: I62243cd0497bc742abf2fb58a24087698b25769d
Change-Id: I62243cd0497bc742abf2fb58a24087698b25769d
diff --git a/include/telephony/ril.h b/include/telephony/ril.h
index 212dd85..d3356b3 100644
--- a/include/telephony/ril.h
+++ b/include/telephony/ril.h
@@ -79,6 +79,10 @@
  *                    RIL_REQUEST_SET_SIM_CARD_POWER
  *                    The new parameters for RIL_REQUEST_SETUP_DATA_CALL,
  *                    Updated data structures: RIL_DataProfileInfo_v15, RIL_InitialAttachApn_v15
+ *                    New data structure RIL_DataRegistrationStateResponse,
+ *                    RIL_VoiceRegistrationStateResponse same is
+ *                    used in RIL_REQUEST_DATA_REGISTRATION_STATE and
+ *                    RIL_REQUEST_VOICE_REGISTRATION_STATE respectively.
  */
 #define RIL_VERSION 12
 #define LAST_IMPRECISE_RIL_VERSION 12 // Better self-documented name
@@ -1006,6 +1010,35 @@
   RIL_APPTYPE_ISIM    = 5
 } RIL_AppType;
 
+/*
+ * Please note that registration state UNKNOWN is
+ * treated as "out of service" in the Android telephony.
+ * Registration state REG_DENIED must be returned if Location Update
+ * Reject (with cause 17 - Network Failure) is received
+ * repeatedly from the network, to facilitate
+ * "managed roaming"
+ */
+typedef enum {
+    RIL_NOT_REG_AND_NOT_SEARCHING = 0,           // Not registered, MT is not currently searching
+                                                 // a new operator to register
+    RIL_REG_HOME = 1,                            // Registered, home network
+    RIL_NOT_REG_AND_SEARCHING = 2,               // Not registered, but MT is currently searching
+                                                 // a new operator to register
+    RIL_REG_DENIED = 3,                          // Registration denied
+    RIL_UNKNOWN = 4,                             // Unknown
+    RIL_REG_ROAMING = 5,                         // Registered, roaming
+    RIL_NOT_REG_AND_EMERGENCY_AVAILABLE_AND_NOT_SEARCHING = 10,   // Same as
+                                                 // RIL_NOT_REG_AND_NOT_SEARCHING but indicates that
+                                                 // emergency calls are enabled.
+    RIL_NOT_REG_AND_EMERGENCY_AVAILABLE_AND_SEARCHING = 12,  // Same as RIL_NOT_REG_AND_SEARCHING
+                                                 // but indicates that
+                                                 // emergency calls are enabled.
+    RIL_REG_DENIED_AND_EMERGENCY_AVAILABLE = 13, // Same as REG_DENIED but indicates that
+                                                 // emergency calls are enabled.
+    RIL_UNKNOWN_AND_EMERGENCY_AVAILABLE = 14,    // Same as UNKNOWN but indicates that
+                                                 // emergency calls are enabled.
+} RIL_RegState;
+
 typedef struct
 {
   RIL_AppType      app_type;
@@ -1380,6 +1413,7 @@
 
 // Must be the same as CellInfo.TYPE_XXX
 typedef enum {
+  RIL_CELL_INFO_TYPE_NONE   = 0, /* indicates no cell information */
   RIL_CELL_INFO_TYPE_GSM    = 1,
   RIL_CELL_INFO_TYPE_CDMA   = 2,
   RIL_CELL_INFO_TYPE_LTE    = 3,
@@ -1424,6 +1458,100 @@
   } CellInfo;
 } RIL_CellInfo_v12;
 
+typedef struct {
+  RIL_CellInfoType  cellInfoType;   /* cell type for selecting from union CellInfo */
+  union {
+    RIL_CellIdentityGsm_v12 cellIdentityGsm;
+    RIL_CellIdentityWcdma_v12 cellIdentityWcdma;
+    RIL_CellIdentityLte_v12 cellIdentityLte;
+    RIL_CellIdentityTdscdma cellIdentityTdscdma;
+    RIL_CellIdentityCdma cellIdentityCdma;
+  };
+}RIL_CellIdentity_v16;
+
+typedef struct {
+    RIL_RegState regState;                // Valid reg states are RIL_NOT_REG_AND_NOT_SEARCHING,
+                                          // REG_HOME, RIL_NOT_REG_AND_SEARCHING, REG_DENIED,
+                                          // UNKNOWN, REG_ROAMING defined in RegState
+    RIL_RadioTechnology rat;              // indicates the available voice radio technology,
+                                          // valid values as defined by RadioTechnology.
+    int32_t cssSupported;                 // concurrent services support indicator. if
+                                          // registered on a CDMA system.
+                                          // 0 - Concurrent services not supported,
+                                          // 1 - Concurrent services supported
+    int32_t roamingIndicator;             // TSB-58 Roaming Indicator if registered
+                                          // on a CDMA or EVDO system or -1 if not.
+                                          // Valid values are 0-255.
+    int32_t systemIsInPrl;                // indicates whether the current system is in the
+                                          // PRL if registered on a CDMA or EVDO system or -1 if
+                                          // not. 0=not in the PRL, 1=in the PRL
+    int32_t defaultRoamingIndicator;      // default Roaming Indicator from the PRL,
+                                          // if registered on a CDMA or EVDO system or -1 if not.
+                                          // Valid values are 0-255.
+    int32_t reasonForDenial;              // reasonForDenial if registration state is 3
+                                          // (Registration denied) this is an enumerated reason why
+                                          // registration was denied. See 3GPP TS 24.008,
+                                          // 10.5.3.6 and Annex G.
+                                          // 0 - General
+                                          // 1 - Authentication Failure
+                                          // 2 - IMSI unknown in HLR
+                                          // 3 - Illegal MS
+                                          // 4 - Illegal ME
+                                          // 5 - PLMN not allowed
+                                          // 6 - Location area not allowed
+                                          // 7 - Roaming not allowed
+                                          // 8 - No Suitable Cells in this Location Area
+                                          // 9 - Network failure
+                                          // 10 - Persistent location update reject
+                                          // 11 - PLMN not allowed
+                                          // 12 - Location area not allowed
+                                          // 13 - Roaming not allowed in this Location Area
+                                          // 15 - No Suitable Cells in this Location Area
+                                          // 17 - Network Failure
+                                          // 20 - MAC Failure
+                                          // 21 - Sync Failure
+                                          // 22 - Congestion
+                                          // 23 - GSM Authentication unacceptable
+                                          // 25 - Not Authorized for this CSG
+                                          // 32 - Service option not supported
+                                          // 33 - Requested service option not subscribed
+                                          // 34 - Service option temporarily out of order
+                                          // 38 - Call cannot be identified
+                                          // 48-63 - Retry upon entry into a new cell
+                                          // 95 - Semantically incorrect message
+                                          // 96 - Invalid mandatory information
+                                          // 97 - Message type non-existent or not implemented
+                                          // 98 - Message type not compatible with protocol state
+                                          // 99 - Information element non-existent or
+                                          //      not implemented
+                                          // 100 - Conditional IE error
+                                          // 101 - Message not compatible with protocol state;
+    RIL_CellIdentity_v16 cellIdentity;    // current cell information
+}RIL_VoiceRegistrationStateResponse;
+
+
+typedef struct {
+    RIL_RegState regState;                // Valid reg states are RIL_NOT_REG_AND_NOT_SEARCHING,
+                                          // REG_HOME, RIL_NOT_REG_AND_SEARCHING, REG_DENIED,
+                                          // UNKNOWN, REG_ROAMING defined in RegState
+    RIL_RadioTechnology rat;              // indicates the available data radio technology,
+                                          // valid values as defined by RadioTechnology.
+    int32_t reasonDataDenied;             // if registration state is 3 (Registration
+                                          // denied) this is an enumerated reason why
+                                          // registration was denied. See 3GPP TS 24.008,
+                                          // Annex G.6 "Additional cause codes for GMM".
+                                          // 7 == GPRS services not allowed
+                                          // 8 == GPRS services and non-GPRS services not allowed
+                                          // 9 == MS identity cannot be derived by the network
+                                          // 10 == Implicitly detached
+                                          // 14 == GPRS services not allowed in this PLMN
+                                          // 16 == MSC temporarily not reachable
+                                          // 40 == No PDP context activated
+    int32_t maxDataCalls;                 // The maximum number of simultaneous Data Calls that
+                                          // must be established using setupDataCall().
+    RIL_CellIdentity_v16 cellIdentity;    // Current cell information
+}RIL_DataRegistrationStateResponse;
+
 /* Names of the CDMA info records (C.S0005 section 3.7.5) */
 typedef enum {
   RIL_CDMA_DISPLAY_INFO_REC,
@@ -2328,119 +2456,7 @@
  * Request current registration state
  *
  * "data" is NULL
- * "response" is a "char **"
- * ((const char **)response)[0] is registration state 0-6,
- *              0 - Not registered, MT is not currently searching
- *                  a new operator to register
- *              1 - Registered, home network
- *              2 - Not registered, but MT is currently searching
- *                  a new operator to register
- *              3 - Registration denied
- *              4 - Unknown
- *              5 - Registered, roaming
- *             10 - Same as 0, but indicates that emergency calls
- *                  are enabled.
- *             12 - Same as 2, but indicates that emergency calls
- *                  are enabled.
- *             13 - Same as 3, but indicates that emergency calls
- *                  are enabled.
- *             14 - Same as 4, but indicates that emergency calls
- *                  are enabled.
- *
- * ((const char **)response)[1] is LAC if registered on a GSM/WCDMA system or
- *                              NULL if not.Valid LAC are 0x0000 - 0xffff
- * ((const char **)response)[2] is CID if registered on a * GSM/WCDMA or
- *                              NULL if not.
- *                                 Valid CID are 0x00000000 - 0xffffffff
- *                                    In GSM, CID is Cell ID (see TS 27.007)
- *                                            in 16 bits
- *                                    In UMTS, CID is UMTS Cell Identity
- *                                             (see TS 25.331) in 28 bits
- * ((const char **)response)[3] indicates the available voice radio technology,
- *                              valid values as defined by RIL_RadioTechnology.
- * ((const char **)response)[4] is Base Station ID if registered on a CDMA
- *                              system or NULL if not.  Base Station ID in
- *                              decimal format
- * ((const char **)response)[5] is Base Station latitude if registered on a
- *                              CDMA system or NULL if not. Base Station
- *                              latitude is a decimal number as specified in
- *                              3GPP2 C.S0005-A v6.0. It is represented in
- *                              units of 0.25 seconds and ranges from -1296000
- *                              to 1296000, both values inclusive (corresponding
- *                              to a range of -90 to +90 degrees).
- * ((const char **)response)[6] is Base Station longitude if registered on a
- *                              CDMA system or NULL if not. Base Station
- *                              longitude is a decimal number as specified in
- *                              3GPP2 C.S0005-A v6.0. It is represented in
- *                              units of 0.25 seconds and ranges from -2592000
- *                              to 2592000, both values inclusive (corresponding
- *                              to a range of -180 to +180 degrees).
- * ((const char **)response)[7] is concurrent services support indicator if
- *                              registered on a CDMA system 0-1.
- *                                   0 - Concurrent services not supported,
- *                                   1 - Concurrent services supported
- * ((const char **)response)[8] is System ID if registered on a CDMA system or
- *                              NULL if not. Valid System ID are 0 - 32767
- * ((const char **)response)[9] is Network ID if registered on a CDMA system or
- *                              NULL if not. Valid System ID are 0 - 65535
- * ((const char **)response)[10] is the TSB-58 Roaming Indicator if registered
- *                               on a CDMA or EVDO system or NULL if not. Valid values
- *                               are 0-255.
- * ((const char **)response)[11] indicates whether the current system is in the
- *                               PRL if registered on a CDMA or EVDO system or NULL if
- *                               not. 0=not in the PRL, 1=in the PRL
- * ((const char **)response)[12] is the default Roaming Indicator from the PRL,
- *                               if registered on a CDMA or EVDO system or NULL if not.
- *                               Valid values are 0-255.
- * ((const char **)response)[13] if registration state is 3 (Registration
- *                               denied) this is an enumerated reason why
- *                               registration was denied.  See 3GPP TS 24.008,
- *                               10.5.3.6 and Annex G.
- *                                 0 - General
- *                                 1 - Authentication Failure
- *                                 2 - IMSI unknown in HLR
- *                                 3 - Illegal MS
- *                                 4 - Illegal ME
- *                                 5 - PLMN not allowed
- *                                 6 - Location area not allowed
- *                                 7 - Roaming not allowed
- *                                 8 - No Suitable Cells in this Location Area
- *                                 9 - Network failure
- *                                10 - Persistent location update reject
- *                                11 - PLMN not allowed
- *                                12 - Location area not allowed
- *                                13 - Roaming not allowed in this Location Area
- *                                15 - No Suitable Cells in this Location Area
- *                                17 - Network Failure
- *                                20 - MAC Failure
- *                                21 - Sync Failure
- *                                22 - Congestion
- *                                23 - GSM Authentication unacceptable
- *                                25 - Not Authorized for this CSG
- *                                32 - Service option not supported
- *                                33 - Requested service option not subscribed
- *                                34 - Service option temporarily out of order
- *                                38 - Call cannot be identified
- *                                48-63 - Retry upon entry into a new cell
- *                                95 - Semantically incorrect message
- *                                96 - Invalid mandatory information
- *                                97 - Message type non-existent or not implemented
- *                                98 - Message type not compatible with protocol state
- *                                99 - Information element non-existent or not implemented
- *                               100 - Conditional IE error
- *                               101 - Message not compatible with protocol state
- *                               111 - Protocol error, unspecified
- * ((const char **)response)[14] is the Primary Scrambling Code of the current
- *                               cell as described in TS 25.331, in hexadecimal
- *                               format, or NULL if unknown or not registered
- *                               to a UMTS network.
- *
- * Please note that registration state 4 ("unknown") is treated
- * as "out of service" in the Android telephony system
- *
- * Registration state 3 can be returned if Location Update Reject
- * (with cause 17 - Network Failure) is received repeatedly from the network,
- * to facilitate "managed roaming"
+ * "response" is a const RIL_VoiceRegistrationStateResponse *
  *
  * Valid errors:
  *  SUCCESS
@@ -2455,41 +2471,7 @@
  * Request current DATA registration state
  *
  * "data" is NULL
- * "response" is a "char **"
- * ((const char **)response)[0] is registration state 0-5 from TS 27.007 10.1.20 AT+CGREG
- * ((const char **)response)[1] is LAC if registered or NULL if not
- * ((const char **)response)[2] is CID if registered or NULL if not
- * ((const char **)response)[3] indicates the available data radio technology,
- *                              valid values as defined by RIL_RadioTechnology.
- * ((const char **)response)[4] if registration state is 3 (Registration
- *                               denied) this is an enumerated reason why
- *                               registration was denied.  See 3GPP TS 24.008,
- *                               Annex G.6 "Additonal cause codes for GMM".
- *      7 == GPRS services not allowed
- *      8 == GPRS services and non-GPRS services not allowed
- *      9 == MS identity cannot be derived by the network
- *      10 == Implicitly detached
- *      14 == GPRS services not allowed in this PLMN
- *      16 == MSC temporarily not reachable
- *      40 == No PDP context activated
- * ((const char **)response)[5] The maximum number of simultaneous Data Calls that can be
- *                              established using RIL_REQUEST_SETUP_DATA_CALL.
- *
- * The values at offsets 6..10 are optional LTE location information in decimal.
- * If a value is unknown that value may be NULL. If all values are NULL,
- * none need to be present.
- *  ((const char **)response)[6] is TAC, a 16-bit Tracking Area Code.
- *  ((const char **)response)[7] is CID, a 0-503 Physical Cell Identifier.
- *  ((const char **)response)[8] is ECI, a 28-bit E-UTRAN Cell Identifier.
- *  ((const char **)response)[9] is CSGID, a 27-bit Closed Subscriber Group Identity.
- *  ((const char **)response)[10] is TADV, a 6-bit timing advance value.
- *
- * LAC and CID are in hexadecimal format.
- * valid LAC are 0x0000 - 0xffff
- * valid CID are 0x00000000 - 0x0fffffff
- *
- * Please note that registration state 4 ("unknown") is treated
- * as "out of service" in the Android telephony system
+ * "response" is a const RIL_DataRegistrationStateResponse *
  *
  * Valid errors:
  *  SUCCESS
diff --git a/libril/ril.cpp b/libril/ril.cpp
index 0f41368..e9392fe 100644
--- a/libril/ril.cpp
+++ b/libril/ril.cpp
@@ -2980,6 +2980,9 @@
                 p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
                 break;
             }
+            default: {
+                break;
+            }
         }
         p_cur += 1;
     }
@@ -3076,6 +3079,9 @@
                 p.writeInt32(p_cur->CellInfo.tdscdma.signalStrengthTdscdma.rscp);
                 break;
             }
+            default: {
+                break;
+            }
         }
         p_cur += 1;
     }
diff --git a/libril/ril_service.cpp b/libril/ril_service.cpp
index 1ffee5e..4fd8e0c 100644
--- a/libril/ril_service.cpp
+++ b/libril/ril_service.cpp
@@ -2853,6 +2853,254 @@
     return 0;
 }
 
+RIL_CellInfoType getCellInfoTypeRadioTechnology(char *rat) {
+    if (rat == NULL) {
+        return RIL_CELL_INFO_TYPE_NONE;
+    }
+
+    int radioTech = atoi(rat);
+
+    switch(radioTech) {
+
+        case RADIO_TECH_GPRS:
+        case RADIO_TECH_EDGE:
+        case RADIO_TECH_GSM: {
+            return RIL_CELL_INFO_TYPE_GSM;
+        }
+
+        case RADIO_TECH_UMTS:
+        case RADIO_TECH_HSDPA:
+        case RADIO_TECH_HSUPA:
+        case RADIO_TECH_HSPA:
+        case RADIO_TECH_HSPAP: {
+            return RIL_CELL_INFO_TYPE_WCDMA;
+        }
+
+        case RADIO_TECH_IS95A:
+        case RADIO_TECH_IS95B:
+        case RADIO_TECH_1xRTT:
+        case RADIO_TECH_EVDO_0:
+        case RADIO_TECH_EVDO_A:
+        case RADIO_TECH_EVDO_B:
+        case RADIO_TECH_EHRPD: {
+            return RIL_CELL_INFO_TYPE_CDMA;
+        }
+
+        case RADIO_TECH_LTE:
+        case RADIO_TECH_LTE_CA: {
+            return RIL_CELL_INFO_TYPE_LTE;
+        }
+
+        case RADIO_TECH_TD_SCDMA: {
+            return RIL_CELL_INFO_TYPE_TD_SCDMA;
+        }
+
+        default: {
+            break;
+        }
+    }
+
+    return RIL_CELL_INFO_TYPE_NONE;
+
+}
+
+void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &rilCellIdentity) {
+
+    cellIdentity.cellIdentityGsm.resize(0);
+    cellIdentity.cellIdentityWcdma.resize(0);
+    cellIdentity.cellIdentityCdma.resize(0);
+    cellIdentity.cellIdentityTdscdma.resize(0);
+    cellIdentity.cellIdentityLte.resize(0);
+    cellIdentity.cellInfoType = (CellInfoType)rilCellIdentity.cellInfoType;
+    switch(rilCellIdentity.cellInfoType) {
+
+        case RIL_CELL_INFO_TYPE_GSM: {
+            cellIdentity.cellIdentityGsm.resize(1);
+            cellIdentity.cellIdentityGsm[0].mcc =
+                    std::to_string(rilCellIdentity.cellIdentityGsm.mcc);
+            cellIdentity.cellIdentityGsm[0].mnc =
+                    std::to_string(rilCellIdentity.cellIdentityGsm.mnc);
+            cellIdentity.cellIdentityGsm[0].lac = rilCellIdentity.cellIdentityGsm.lac;
+            cellIdentity.cellIdentityGsm[0].cid = rilCellIdentity.cellIdentityGsm.cid;
+            cellIdentity.cellIdentityGsm[0].arfcn = rilCellIdentity.cellIdentityGsm.arfcn;
+            cellIdentity.cellIdentityGsm[0].bsic = rilCellIdentity.cellIdentityGsm.bsic;
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_WCDMA: {
+            cellIdentity.cellIdentityWcdma.resize(1);
+            cellIdentity.cellIdentityWcdma[0].mcc =
+                    std::to_string(rilCellIdentity.cellIdentityWcdma.mcc);
+            cellIdentity.cellIdentityWcdma[0].mnc =
+                    std::to_string(rilCellIdentity.cellIdentityWcdma.mnc);
+            cellIdentity.cellIdentityWcdma[0].lac = rilCellIdentity.cellIdentityWcdma.lac;
+            cellIdentity.cellIdentityWcdma[0].cid = rilCellIdentity.cellIdentityWcdma.cid;
+            cellIdentity.cellIdentityWcdma[0].psc = rilCellIdentity.cellIdentityWcdma.psc;
+            cellIdentity.cellIdentityWcdma[0].uarfcn = rilCellIdentity.cellIdentityWcdma.uarfcn;
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_CDMA: {
+            cellIdentity.cellIdentityCdma.resize(1);
+            cellIdentity.cellIdentityCdma[0].networkId = rilCellIdentity.cellIdentityCdma.networkId;
+            cellIdentity.cellIdentityCdma[0].systemId = rilCellIdentity.cellIdentityCdma.systemId;
+            cellIdentity.cellIdentityCdma[0].baseStationId =
+                    rilCellIdentity.cellIdentityCdma.basestationId;
+            cellIdentity.cellIdentityCdma[0].longitude = rilCellIdentity.cellIdentityCdma.longitude;
+            cellIdentity.cellIdentityCdma[0].latitude = rilCellIdentity.cellIdentityCdma.latitude;
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_LTE: {
+            cellIdentity.cellIdentityLte.resize(1);
+            cellIdentity.cellIdentityLte[0].mcc =
+                    std::to_string(rilCellIdentity.cellIdentityLte.mcc);
+            cellIdentity.cellIdentityLte[0].mnc =
+                    std::to_string(rilCellIdentity.cellIdentityLte.mnc);
+            cellIdentity.cellIdentityLte[0].ci = rilCellIdentity.cellIdentityLte.ci;
+            cellIdentity.cellIdentityLte[0].pci = rilCellIdentity.cellIdentityLte.pci;
+            cellIdentity.cellIdentityLte[0].tac = rilCellIdentity.cellIdentityLte.tac;
+            cellIdentity.cellIdentityLte[0].earfcn = rilCellIdentity.cellIdentityLte.earfcn;
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_TD_SCDMA: {
+            cellIdentity.cellIdentityTdscdma.resize(1);
+            cellIdentity.cellIdentityTdscdma[0].mcc =
+                    std::to_string(rilCellIdentity.cellIdentityTdscdma.mcc);
+            cellIdentity.cellIdentityTdscdma[0].mnc =
+                    std::to_string(rilCellIdentity.cellIdentityTdscdma.mnc);
+            cellIdentity.cellIdentityTdscdma[0].lac = rilCellIdentity.cellIdentityTdscdma.lac;
+            cellIdentity.cellIdentityTdscdma[0].cid = rilCellIdentity.cellIdentityTdscdma.cid;
+            cellIdentity.cellIdentityTdscdma[0].cpid = rilCellIdentity.cellIdentityTdscdma.cpid;
+            break;
+        }
+
+        default: {
+            break;
+        }
+    }
+}
+
+int convertResponseStringEntryToInt(char **response, int index, int numStrings) {
+    if ((response != NULL) &&  (numStrings > index) && (response[index] != NULL)) {
+        return atoi(response[index]);
+    }
+
+    return -1;
+}
+
+void fillCellIdentityFromVoiceRegStateResponseString(CellIdentity &cellIdentity,
+        int numStrings, char** response) {
+
+    RIL_CellIdentity_v16 rilCellIdentity;
+    int32_t *tmp = (int32_t*)&rilCellIdentity;
+
+    for (int i = 0; i < sizeof(RIL_CellIdentity_v16)/sizeof(int32_t); i++) {
+        tmp[i] = -1;
+    }
+
+    rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]);
+    switch(rilCellIdentity.cellInfoType) {
+
+        case RIL_CELL_INFO_TYPE_GSM: {
+            rilCellIdentity.cellIdentityGsm.lac =
+                    convertResponseStringEntryToInt(response, 1, numStrings);
+            rilCellIdentity.cellIdentityGsm.cid =
+                    convertResponseStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_WCDMA: {
+            rilCellIdentity.cellIdentityWcdma.lac =
+                    convertResponseStringEntryToInt(response, 1, numStrings);
+            rilCellIdentity.cellIdentityWcdma.cid =
+                    convertResponseStringEntryToInt(response, 2, numStrings);
+            rilCellIdentity.cellIdentityWcdma.psc =
+                    convertResponseStringEntryToInt(response, 14, numStrings);
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_TD_SCDMA:{
+            rilCellIdentity.cellIdentityTdscdma.lac =
+                    convertResponseStringEntryToInt(response, 1, numStrings);
+            rilCellIdentity.cellIdentityTdscdma.cid =
+                    convertResponseStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+
+        case RIL_CELL_INFO_TYPE_CDMA:{
+            rilCellIdentity.cellIdentityCdma.basestationId =
+                    convertResponseStringEntryToInt(response, 4, numStrings);
+            rilCellIdentity.cellIdentityCdma.longitude =
+                    convertResponseStringEntryToInt(response, 5, numStrings);
+            rilCellIdentity.cellIdentityCdma.latitude =
+                    convertResponseStringEntryToInt(response, 6, numStrings);
+            rilCellIdentity.cellIdentityCdma.systemId =
+                    convertResponseStringEntryToInt(response, 8, numStrings);
+            rilCellIdentity.cellIdentityCdma.networkId =
+                    convertResponseStringEntryToInt(response, 9, numStrings);
+            break;
+        }
+
+        default: {
+            break;
+        }
+    }
+
+    fillCellIdentityResponse(cellIdentity, rilCellIdentity);
+}
+
+void fillCellIdentityFromDataRegStateResponseString(CellIdentity &cellIdentity,
+        int numStrings, char** response) {
+
+    RIL_CellIdentity_v16 rilCellIdentity;
+    int32_t *tmp = (int32_t*)&rilCellIdentity;
+
+    for (int i = 0; i < sizeof(RIL_CellIdentity_v16)/sizeof(int32_t); i++) {
+        tmp[i] = -1;
+    }
+
+    rilCellIdentity.cellInfoType = getCellInfoTypeRadioTechnology(response[3]);
+    switch(rilCellIdentity.cellInfoType) {
+        case RIL_CELL_INFO_TYPE_GSM: {
+            rilCellIdentity.cellIdentityGsm.lac =
+                    convertResponseStringEntryToInt(response, 1, numStrings);
+            rilCellIdentity.cellIdentityGsm.cid =
+                    convertResponseStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_WCDMA: {
+            rilCellIdentity.cellIdentityWcdma.lac =
+                    convertResponseStringEntryToInt(response, 1, numStrings);
+            rilCellIdentity.cellIdentityWcdma.cid =
+                    convertResponseStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_TD_SCDMA:{
+            rilCellIdentity.cellIdentityTdscdma.lac =
+                    convertResponseStringEntryToInt(response, 1, numStrings);
+            rilCellIdentity.cellIdentityTdscdma.cid =
+                    convertResponseStringEntryToInt(response, 2, numStrings);
+            break;
+        }
+        case RIL_CELL_INFO_TYPE_LTE: {
+            rilCellIdentity.cellIdentityLte.tac =
+                    convertResponseStringEntryToInt(response, 6, numStrings);
+            rilCellIdentity.cellIdentityLte.pci =
+                    convertResponseStringEntryToInt(response, 7, numStrings);
+            rilCellIdentity.cellIdentityLte.ci =
+                    convertResponseStringEntryToInt(response, 8, numStrings);
+            break;
+        }
+        default: {
+            break;
+        }
+    }
+
+    fillCellIdentityResponse(cellIdentity, rilCellIdentity);
+}
+
 int radio::getVoiceRegistrationStateResponse(android::Parcel &p, int slotId, int requestNumber,
                                             int responseType, int serial, RIL_Errno e,
                                             void *response, size_t responseLen) {
@@ -2863,29 +3111,44 @@
         populateResponseInfo(responseInfo, serial, responseType, e);
 
         VoiceRegStateResult voiceRegResponse = {};
-
         int numStrings = responseLen / sizeof(char *);
-
-        if (response == NULL || numStrings != 15) {
-            RLOGE("radio::getVoiceRegistrationStateResponse Invalid response: NULL");
-            if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        if (response == NULL) {
+               RLOGE("radio::getVoiceRegistrationStateResponse Invalid response: NULL");
+               if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else if (s_vendorFunctions->version <= 14) {
+            if (numStrings != 15) {
+                RLOGE("radio::getVoiceRegistrationStateResponse Invalid response: NULL");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            } else {
+                char **resp = (char **) response;
+                voiceRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4);
+                voiceRegResponse.rat = ATOI_NULL_HANDLED(resp[3]);
+                voiceRegResponse.cssSupported = ATOI_NULL_HANDLED_DEF(resp[7], 0);
+                voiceRegResponse.roamingIndicator = ATOI_NULL_HANDLED(resp[10]);
+                voiceRegResponse.systemIsInPrl = ATOI_NULL_HANDLED_DEF(resp[11], 0);
+                voiceRegResponse.defaultRoamingIndicator = ATOI_NULL_HANDLED_DEF(resp[12], 0);
+                voiceRegResponse.reasonForDenial = ATOI_NULL_HANDLED_DEF(resp[13], 0);
+                fillCellIdentityFromVoiceRegStateResponseString(voiceRegResponse.cellIdentity,
+                        numStrings, resp);
+            }
         } else {
-            char **resp = (char **) response;
-            voiceRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4);
-            voiceRegResponse.lac = ATOI_NULL_HANDLED(resp[1]);
-            voiceRegResponse.cid = ATOI_NULL_HANDLED(resp[2]);
-            voiceRegResponse.rat = ATOI_NULL_HANDLED(resp[3]);
-            voiceRegResponse.baseStationId = ATOI_NULL_HANDLED(resp[4]);
-            voiceRegResponse.baseStationLatitude = ATOI_NULL_HANDLED_DEF(resp[5], INT_MAX);
-            voiceRegResponse.baseStationLongitude = ATOI_NULL_HANDLED_DEF(resp[6], INT_MAX);
-            voiceRegResponse.cssSupported = ATOI_NULL_HANDLED_DEF(resp[7], 0);
-            voiceRegResponse.systemId = ATOI_NULL_HANDLED_DEF(resp[8], 0);
-            voiceRegResponse.networkId = ATOI_NULL_HANDLED_DEF(resp[9], 0);
-            voiceRegResponse.roamingIndicator = ATOI_NULL_HANDLED(resp[10]);
-            voiceRegResponse.systemIsInPrl = ATOI_NULL_HANDLED_DEF(resp[11], 0);
-            voiceRegResponse.defaultRoamingIndicator = ATOI_NULL_HANDLED_DEF(resp[12], 0);
-            voiceRegResponse.reasonForDenial = ATOI_NULL_HANDLED_DEF(resp[13], 0);
-            voiceRegResponse.psc = ATOI_NULL_HANDLED(resp[14]);
+            RIL_VoiceRegistrationStateResponse *voiceRegState =
+                    (RIL_VoiceRegistrationStateResponse *)response;
+
+            if (responseLen != sizeof(RIL_VoiceRegistrationStateResponse)) {
+                RLOGE("radio::getVoiceRegistrationStateResponse Invalid response: NULL");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            } else {
+                voiceRegResponse.regState = (RegState) voiceRegState->regState;
+                voiceRegResponse.rat = voiceRegState->rat;;
+                voiceRegResponse.cssSupported = voiceRegState->cssSupported;
+                voiceRegResponse.roamingIndicator = voiceRegState->roamingIndicator;
+                voiceRegResponse.systemIsInPrl = voiceRegState->systemIsInPrl;
+                voiceRegResponse.defaultRoamingIndicator = voiceRegState->defaultRoamingIndicator;
+                voiceRegResponse.reasonForDenial = voiceRegState->reasonForDenial;
+                fillCellIdentityResponse(voiceRegResponse.cellIdentity,
+                        voiceRegState->cellIdentity);
+            }
         }
 
         Return<void> retStatus =
@@ -2909,24 +3172,36 @@
         RadioResponseInfo responseInfo = {};
         populateResponseInfo(responseInfo, serial, responseType, e);
         DataRegStateResult dataRegResponse = {};
-        int numStrings = responseLen / sizeof(char *);
-        if (response == NULL || (numStrings != 6 && numStrings != 11)) {
+        if (response == NULL) {
             RLOGE("radio::getDataRegistrationStateResponse Invalid response: NULL");
             if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+        } else if (s_vendorFunctions->version <= 14) {
+            int numStrings = responseLen / sizeof(char *);
+            if ((numStrings != 6) && (numStrings != 11)) {
+                RLOGE("radio::getDataRegistrationStateResponse Invalid response: NULL");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            } else {
+                char **resp = (char **) response;
+                dataRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4);
+                dataRegResponse.rat =  ATOI_NULL_HANDLED_DEF(resp[3], 0);
+                dataRegResponse.reasonDataDenied =  ATOI_NULL_HANDLED(resp[4]);
+                dataRegResponse.maxDataCalls =  ATOI_NULL_HANDLED_DEF(resp[5], 1);
+                fillCellIdentityFromDataRegStateResponseString(dataRegResponse.cellIdentity,
+                        numStrings, resp);
+            }
         } else {
-            char **resp = (char **) response;
-            dataRegResponse.regState = (RegState) ATOI_NULL_HANDLED_DEF(resp[0], 4);
-            dataRegResponse.lac =  ATOI_NULL_HANDLED(resp[1]);
-            dataRegResponse.cid =  ATOI_NULL_HANDLED(resp[2]);
-            dataRegResponse.rat =  ATOI_NULL_HANDLED_DEF(resp[3], 0);
-            dataRegResponse.reasonDataDenied =  ATOI_NULL_HANDLED(resp[4]);
-            dataRegResponse.maxDataCalls =  ATOI_NULL_HANDLED_DEF(resp[5], 1);
-            if (numStrings == 11) {
-                dataRegResponse.tac = ATOI_NULL_HANDLED(resp[6]);
-                dataRegResponse.phyCid = ATOI_NULL_HANDLED(resp[7]);
-                dataRegResponse.eci = ATOI_NULL_HANDLED(resp[8]);
-                dataRegResponse.csgid = ATOI_NULL_HANDLED(resp[9]);
-                dataRegResponse.tadv = ATOI_NULL_HANDLED(resp[10]);
+            RIL_DataRegistrationStateResponse *dataRegState =
+                    (RIL_DataRegistrationStateResponse *)response;
+
+            if (responseLen != sizeof(RIL_DataRegistrationStateResponse)) {
+                RLOGE("radio::getDataRegistrationStateResponse Invalid response: NULL");
+                if (e == RIL_E_SUCCESS) responseInfo.error = RadioError::INVALID_RESPONSE;
+            } else {
+                dataRegResponse.regState = (RegState) dataRegState->regState;
+                dataRegResponse.rat = dataRegState->rat;;
+                dataRegResponse.reasonDataDenied = dataRegState->reasonDataDenied;
+                dataRegResponse.maxDataCalls = dataRegState->maxDataCalls;
+                fillCellIdentityResponse(dataRegResponse.cellIdentity, dataRegState->cellIdentity);
             }
         }
 
@@ -6579,6 +6854,9 @@
                         rillCellInfo->CellInfo.tdscdma.signalStrengthTdscdma.rscp;
                 break;
             }
+            default: {
+                break;
+            }
         }
         rillCellInfo += 1;
     }