msm8974-common: libril: Encode the Number of MNC Digits in CellIdentity
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
This commit is contained in:
parent
7f220cbdb2
commit
e11fb2c255
@ -1376,14 +1376,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 */
|
||||
@ -1392,7 +1396,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 */
|
||||
@ -1400,7 +1406,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 */
|
||||
@ -1424,7 +1432,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 */
|
||||
@ -1432,7 +1442,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 */
|
||||
@ -1441,7 +1453,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 */
|
||||
|
149
ril/include/telephony/ril_mnc.h
Normal file
149
ril/include/telephony/ril_mnc.h
Normal file
@ -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) */
|
@ -26,6 +26,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;
|
||||
@ -8032,7 +8034,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 =
|
||||
@ -8056,7 +8058,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 =
|
||||
@ -8104,7 +8106,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 =
|
||||
@ -8134,7 +8136,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 =
|
||||
|
Loading…
Reference in New Issue
Block a user