Merge pie-platform-release to aosp-master - DO NOT MERGE

Change-Id: Ib170536902f7c88b2d9ca4005607e1080c79f5c7
diff --git a/include/telephony/ril.h b/include/telephony/ril.h
index c4add62..e189777 100644
--- a/include/telephony/ril.h
+++ b/include/telephony/ril.h
@@ -1360,14 +1360,18 @@
 
 typedef struct {
     int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */
-    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
     int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
     int cid;    /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown  */
 } RIL_CellIdentityGsm;
 
 typedef struct {
     int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown */
-    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
     int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
     int cid;    /* 16-bit GSM Cell Identity described in TS 27.007, 0..65535, INT_MAX if unknown  */
     int arfcn;  /* 16-bit GSM Absolute RF channel number; this value must be reported */
@@ -1376,7 +1380,9 @@
 
 typedef struct {
     int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
-    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
     int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
     int cid;    /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown  */
     int psc;    /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511, INT_MAX if unknown */
@@ -1384,7 +1390,9 @@
 
 typedef struct {
     int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
-    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
     int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
     int cid;    /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown  */
     int psc;    /* 9-bit UMTS Primary Scrambling Code described in TS 25.331, 0..511; this value must be reported */
@@ -1408,7 +1416,9 @@
 
 typedef struct {
     int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
-    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
     int ci;     /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */
     int pci;    /* physical cell id 0..503, INT_MAX if unknown  */
     int tac;    /* 16-bit tracking area code, INT_MAX if unknown  */
@@ -1416,7 +1426,9 @@
 
 typedef struct {
     int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
-    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
     int ci;     /* 28-bit Cell Identity described in TS ???, INT_MAX if unknown */
     int pci;    /* physical cell id 0..503; this value must be reported */
     int tac;    /* 16-bit tracking area code, INT_MAX if unknown  */
@@ -1425,7 +1437,9 @@
 
 typedef struct {
     int mcc;    /* 3-digit Mobile Country Code, 0..999, INT_MAX if unknown  */
-    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999, INT_MAX if unknown  */
+    int mnc;    /* 2 or 3-digit Mobile Network Code, 0..999;
+                   the most significant nibble encodes the number of digits - {2, 3, 0 (unset)};
+                   INT_MAX if unknown */
     int lac;    /* 16-bit Location Area Code, 0..65535, INT_MAX if unknown  */
     int cid;    /* 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, INT_MAX if unknown  */
     int cpid;    /* 8-bit Cell Parameters ID described in TS 25.331, 0..127, INT_MAX if unknown */
diff --git a/include/telephony/ril_mnc.h b/include/telephony/ril_mnc.h
new file mode 100644
index 0000000..fcbae99
--- /dev/null
+++ b/include/telephony/ril_mnc.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef RIL_MNC_H
+#define RIL_MNC_H
+
+#include <climits>
+#include <cstdio>
+#include <string>
+
+namespace ril {
+namespace util {
+namespace mnc {
+
+/**
+ * Decode an MNC with an optional length indicator provided in the most-significant nibble.
+ *
+ * @param mnc an encoded MNC value; if no encoding is provided, then the string is returned
+ *     as a minimum length string representing the provided integer.
+ *
+ * @return string representation of an encoded MNC or an empty string if the MNC is not a valid
+ *     MNC value.
+ */
+static inline std::string decode(int mnc) {
+    if (mnc == INT_MAX || mnc < 0) return "";
+    unsigned umnc = mnc;
+    char mncNumDigits = (umnc >> (sizeof(int) * 8 - 4)) & 0xF;
+
+    umnc = (umnc << 4) >> 4;
+    if (umnc > 999) return "";
+
+    char mncStr[4] = {0};
+    switch (mncNumDigits) {
+        case 0:
+            // Legacy MNC report hasn't set the number of digits; preserve current
+            // behavior and make a string of the minimum number of required digits.
+            return std::to_string(umnc);
+
+        case 2:
+            snprintf(mncStr, sizeof(mncStr), "%03.3u", umnc);
+            return mncStr + 1;
+
+        case 3:
+            snprintf(mncStr, sizeof(mncStr), "%03.3u", umnc);
+            return mncStr;
+
+        default:
+            // Error case
+            return "";
+    }
+
+}
+
+/**
+ * Encode an MNC of the given value and a given number of digits
+ *
+ * @param mnc an MNC value 0-999 or INT_MAX if unknown
+ * @param numDigits the number of MNC digits {2, 3} or 0 if unknown
+ *
+ * @return an encoded MNC with embedded length information
+ */
+static inline int encode(int mnc, int numDigits) {
+    if (mnc > 999 || mnc < 0) return INT_MAX;
+    switch (numDigits) {
+        case 0: // fall through
+        case 2: // fall through
+        case 3:
+            break;
+
+        default:
+            return INT_MAX;
+    };
+
+    return (numDigits << (sizeof(int) * 8 - 4)) | mnc;
+}
+
+/**
+ * Encode an MNC of the given value
+ *
+ * @param mnc the string representation of the MNC, with the length equal to the length of the
+ *     provided string.
+ *
+ * @return an encoded MNC with embedded length information
+ */
+static inline int encode(const std::string & mnc) {
+    return encode(std::stoi(mnc), mnc.length());
+}
+
+// echo -e "#include \"hardware/ril/include/telephony/ril_mnc.h\"\nint main()"\
+// "{ return ril::util::mnc::test(); }" > ril_test.cpp \
+// && g++ -o /tmp/ril_test -DTEST_RIL_MNC ril_test.cpp; \
+// rm ril_test.cpp; /tmp/ril_test && [ $? ] && echo "passed"
+#ifdef TEST_RIL_MNC
+static int test() {
+    const struct mnc_strings { const char * in; const char * out; } mncs[] = {
+        {"0001",""},
+        {"9999",""},
+        {"0",""},
+        {"9",""},
+        {"123","123"},
+        {"000","000"},
+        {"001","001"},
+        {"011","011"},
+        {"111","111"},
+        {"00","00"},
+        {"01","01"},
+        {"11","11"},
+        {"09","09"},
+        {"099","099"},
+        {"999", "999"}};
+
+    for (int i=0; i< sizeof(mncs) / sizeof(struct mnc_strings); i++) {
+        if (decode(encode(mncs[i].in)).compare(mncs[i].out)) return 1;
+    }
+
+    const struct mnc_ints { const int in; const char * out; } legacy_mncs[] = {
+        {INT_MAX, ""},
+        {1, "1"},
+        {11, "11"},
+        {111, "111"},
+        {0, "0"},
+        {9999, ""},
+    };
+
+    for (int i=0; i < sizeof(legacy_mncs) / sizeof(struct mnc_ints); i++) {
+        if (decode(legacy_mncs[i].in).compare(legacy_mncs[i].out)) return 1;
+    }
+
+    return 0;
+}
+#endif
+
+}
+}
+}
+#endif /* !defined(RIL_MNC_H) */
diff --git a/libril/ril.cpp b/libril/ril.cpp
index 514ac90..fbf7ee0 100644
--- a/libril/ril.cpp
+++ b/libril/ril.cpp
@@ -792,9 +792,11 @@
         assert(rwlockRet == 0);
     }
 
-    ret = s_unsolResponses[unsolResponseIndex].responseFunction(
-            (int) soc_id, responseType, 0, RIL_E_SUCCESS, const_cast<void*>(data),
-            datalen);
+    if (s_unsolResponses[unsolResponseIndex].responseFunction) {
+        ret = s_unsolResponses[unsolResponseIndex].responseFunction(
+                (int) soc_id, responseType, 0, RIL_E_SUCCESS, const_cast<void*>(data),
+                datalen);
+    }
 
     rwlockRet = pthread_rwlock_unlock(radioServiceRwlockPtr);
     assert(rwlockRet == 0);
diff --git a/libril/ril_service.cpp b/libril/ril_service.cpp
index 07fd49f..8e52b82 100644
--- a/libril/ril_service.cpp
+++ b/libril/ril_service.cpp
@@ -25,6 +25,8 @@
 
 #include <hwbinder/IPCThreadState.h>
 #include <hwbinder/ProcessState.h>
+#include <telephony/ril.h>
+#include <telephony/ril_mnc.h>
 #include <ril_service.h>
 #include <hidl/HidlTransportSupport.h>
 #include <utils/SystemClock.h>
@@ -501,7 +503,11 @@
 
 /**
  * Copies over src to dest. If memory allocation fails, responseFunction() is called for the
- * request with error RIL_E_NO_MEMORY.
+ * request with error RIL_E_NO_MEMORY. The size() method is used to determine the size of the
+ * destination buffer into which the HIDL string is copied. If there is a discrepancy between
+ * the string length reported by the size() method, and the length of the string returned by
+ * the c_str() method, the function will return false indicating a failure.
+ *
  * Returns true on success, and false on failure.
  */
 bool copyHidlStringToRil(char **dest, const hidl_string &src, RequestInfo *pRI, bool allowEmpty) {
@@ -516,7 +522,15 @@
         sendErrorResponse(pRI, RIL_E_NO_MEMORY);
         return false;
     }
-    strncpy(*dest, src.c_str(), len + 1);
+    if (strlcpy(*dest, src.c_str(), len + 1) >= (len + 1)) {
+        RLOGE("Copy of the HIDL string has been truncated, as "
+              "the string length reported by size() does not "
+              "match the length of string returned by c_str().");
+        free(*dest);
+        *dest = NULL;
+        sendErrorResponse(pRI, RIL_E_INTERNAL_ERR);
+        return false;
+    }
     return true;
 }
 
@@ -2626,7 +2640,7 @@
     rilRc.phase = (int) rc.phase;
     rilRc.rat = (int) rc.raf;
     rilRc.status = (int) rc.status;
-    strncpy(rilRc.logicalModemUuid, rc.logicalModemUuid.c_str(), MAX_UUID_LENGTH);
+    strlcpy(rilRc.logicalModemUuid, rc.logicalModemUuid.c_str(), sizeof(rilRc.logicalModemUuid));
 
     CALL_ONREQUEST(pRI->pCI->requestNumber, &rilRc, sizeof(rilRc), pRI, mSlotId);
 
@@ -3549,7 +3563,7 @@
             cellIdentity.cellIdentityGsm[0].mcc =
                     std::to_string(rilCellIdentity.cellIdentityGsm.mcc);
             cellIdentity.cellIdentityGsm[0].mnc =
-                    std::to_string(rilCellIdentity.cellIdentityGsm.mnc);
+                    ril::util::mnc::decode(rilCellIdentity.cellIdentityGsm.mnc);
             cellIdentity.cellIdentityGsm[0].lac = rilCellIdentity.cellIdentityGsm.lac;
             cellIdentity.cellIdentityGsm[0].cid = rilCellIdentity.cellIdentityGsm.cid;
             cellIdentity.cellIdentityGsm[0].arfcn = rilCellIdentity.cellIdentityGsm.arfcn;
@@ -3562,7 +3576,7 @@
             cellIdentity.cellIdentityWcdma[0].mcc =
                     std::to_string(rilCellIdentity.cellIdentityWcdma.mcc);
             cellIdentity.cellIdentityWcdma[0].mnc =
-                    std::to_string(rilCellIdentity.cellIdentityWcdma.mnc);
+                    ril::util::mnc::decode(rilCellIdentity.cellIdentityWcdma.mnc);
             cellIdentity.cellIdentityWcdma[0].lac = rilCellIdentity.cellIdentityWcdma.lac;
             cellIdentity.cellIdentityWcdma[0].cid = rilCellIdentity.cellIdentityWcdma.cid;
             cellIdentity.cellIdentityWcdma[0].psc = rilCellIdentity.cellIdentityWcdma.psc;
@@ -3586,7 +3600,7 @@
             cellIdentity.cellIdentityLte[0].mcc =
                     std::to_string(rilCellIdentity.cellIdentityLte.mcc);
             cellIdentity.cellIdentityLte[0].mnc =
-                    std::to_string(rilCellIdentity.cellIdentityLte.mnc);
+                    ril::util::mnc::decode(rilCellIdentity.cellIdentityLte.mnc);
             cellIdentity.cellIdentityLte[0].ci = rilCellIdentity.cellIdentityLte.ci;
             cellIdentity.cellIdentityLte[0].pci = rilCellIdentity.cellIdentityLte.pci;
             cellIdentity.cellIdentityLte[0].tac = rilCellIdentity.cellIdentityLte.tac;
@@ -3599,7 +3613,7 @@
             cellIdentity.cellIdentityTdscdma[0].mcc =
                     std::to_string(rilCellIdentity.cellIdentityTdscdma.mcc);
             cellIdentity.cellIdentityTdscdma[0].mnc =
-                    std::to_string(rilCellIdentity.cellIdentityTdscdma.mnc);
+                    ril::util::mnc::decode(rilCellIdentity.cellIdentityTdscdma.mnc);
             cellIdentity.cellIdentityTdscdma[0].lac = rilCellIdentity.cellIdentityTdscdma.lac;
             cellIdentity.cellIdentityTdscdma[0].cid = rilCellIdentity.cellIdentityTdscdma.cid;
             cellIdentity.cellIdentityTdscdma[0].cpid = rilCellIdentity.cellIdentityTdscdma.cpid;
@@ -7863,7 +7877,7 @@
                 cellInfoGsm->cellIdentityGsm.mcc =
                         std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mcc);
                 cellInfoGsm->cellIdentityGsm.mnc =
-                        std::to_string(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mnc);
+                        ril::util::mnc::decode(rillCellInfo->CellInfo.gsm.cellIdentityGsm.mnc);
                 cellInfoGsm->cellIdentityGsm.lac =
                         rillCellInfo->CellInfo.gsm.cellIdentityGsm.lac;
                 cellInfoGsm->cellIdentityGsm.cid =
@@ -7887,7 +7901,7 @@
                 cellInfoWcdma->cellIdentityWcdma.mcc =
                         std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mcc);
                 cellInfoWcdma->cellIdentityWcdma.mnc =
-                        std::to_string(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mnc);
+                        ril::util::mnc::decode(rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.mnc);
                 cellInfoWcdma->cellIdentityWcdma.lac =
                         rillCellInfo->CellInfo.wcdma.cellIdentityWcdma.lac;
                 cellInfoWcdma->cellIdentityWcdma.cid =
@@ -7935,7 +7949,7 @@
                 cellInfoLte->cellIdentityLte.mcc =
                         std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mcc);
                 cellInfoLte->cellIdentityLte.mnc =
-                        std::to_string(rillCellInfo->CellInfo.lte.cellIdentityLte.mnc);
+                        ril::util::mnc::decode(rillCellInfo->CellInfo.lte.cellIdentityLte.mnc);
                 cellInfoLte->cellIdentityLte.ci =
                         rillCellInfo->CellInfo.lte.cellIdentityLte.ci;
                 cellInfoLte->cellIdentityLte.pci =
@@ -7965,7 +7979,8 @@
                 cellInfoTdscdma->cellIdentityTdscdma.mcc =
                         std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mcc);
                 cellInfoTdscdma->cellIdentityTdscdma.mnc =
-                        std::to_string(rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
+                        ril::util::mnc::decode(
+                                rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.mnc);
                 cellInfoTdscdma->cellIdentityTdscdma.lac =
                         rillCellInfo->CellInfo.tdscdma.cellIdentityTdscdma.lac;
                 cellInfoTdscdma->cellIdentityTdscdma.cid =