summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 =