diff options
-rw-r--r-- | include/telephony/ril.h | 28 | ||||
-rw-r--r-- | include/telephony/ril_mnc.h | 149 | ||||
-rw-r--r-- | libril/ril_service.cpp | 19 |
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 = |