summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Harold <nharold@google.com>2018-08-20 11:38:27 -0700
committerMichael Bestas <mkbestas@lineageos.org>2019-02-12 17:59:18 +0100
commitb475875975d1b576511df391f75125593b3353ac (patch)
tree455c53b1d66d6e4192b8d9bc90af6af0ab2d06af
parente3d006fa722c02fc26acdfcaa43a3f3a1378eba9 (diff)
downloadandroid_hardware_ril-lineage-16.0-caf.tar.gz
android_hardware_ril-lineage-16.0-caf.tar.bz2
android_hardware_ril-lineage-16.0-caf.zip
Encode the Number of MNC Digits in CellIdentitylineage-16.0-caf
Legacy RIL uses an integer to encode the number of MNC digits. Because the size is not fixed, leading zeroes result in ambiguity in the length of the mnc. This change adds support for passing the number of encoded digits in the most-significant nibble of the mnc integer (which is only 10 bits). Thus, on any implementation that is 16-bits or wider, the mnc info will be properly encoded and decoded with the correctly-sized string. Bug: 111971808 Test: ril::util::mnc::test Change-Id: I24aeba5328a63f80b0d6b25b068bd19160191dff Merged-In: I24aeba5328a63f80b0d6b25b068bd19160191dff (cherry picked from commit 98cfceefdf06d5e4ec3bfff3d1cd425baefb155e)
-rw-r--r--include/telephony/ril.h28
-rw-r--r--include/telephony/ril_mnc.h149
-rw-r--r--libril/ril_service.cpp19
3 files changed, 181 insertions, 15 deletions
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 {
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 {
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 {
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 {
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 {
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 {
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_service.cpp b/libril/ril_service.cpp
index 5fe4153..2e57bb5 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>
@@ -3572,7 +3574,7 @@ void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &
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;
@@ -3585,7 +3587,7 @@ void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &
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;
@@ -3609,7 +3611,7 @@ void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &
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;
@@ -3622,7 +3624,7 @@ void fillCellIdentityResponse(CellIdentity &cellIdentity, RIL_CellIdentity_v16 &
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;
@@ -8002,7 +8004,7 @@ void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<Ce
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 =
@@ -8026,7 +8028,7 @@ void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<Ce
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 =
@@ -8074,7 +8076,7 @@ void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<Ce
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 =
@@ -8104,7 +8106,8 @@ void convertRilCellInfoListToHal(void *response, size_t responseLen, hidl_vec<Ce
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 =