From e5e131de3faf1530cc977edc643e886a640d3bde Mon Sep 17 00:00:00 2001 From: Serhii Kostiuk Date: Sat, 29 May 2021 00:02:00 +0300 Subject: [GP-1111] mPower R. Apr 2021: +CEMODE shall be set to CEMODE=2 Extended the implementation of "getSimCarrierCode" to detect the carrier (home network) based on the MCC/MNC combination. Historically mPower used ICCIDs to detect the carrier and apply the carrier-specific settings. ICCIDs are known for Verizon and AT&T, but the list of known ICCIDs is not exhaustive. This change allows the firmware to detect more AT&T SIM cards by using the MCC/MNC combinations (PLMN IDs) when ICCID is not recognized. Limitation: The SIM shall be relatively new and report its MNC length, otherwise MCC/MNC can't be determined and so the carrier code. --- include/mts/MTS_IO_CellularRadio.h | 2 + src/MTS_IO_CellularRadio.cpp | 77 +++++++++++++++++++++++++++++++------- 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/include/mts/MTS_IO_CellularRadio.h b/include/mts/MTS_IO_CellularRadio.h index 3783705..daefcd1 100644 --- a/include/mts/MTS_IO_CellularRadio.h +++ b/include/mts/MTS_IO_CellularRadio.h @@ -185,6 +185,8 @@ namespace MTS { //! Get carrier code based on the SIM card ID (ICCID) virtual CODE getSimCarrierCode(const std::string& sIccid, std::string& sCarrierCode); + //! Get carrier code based on the SIM MCC/MNC + virtual CODE getSimCarrierCode(const std::string& sMcc, const std::string& sMnc, std::string& sCarrierCode); /** * @brief simAccessReadBinary - Read a string of bytes from the SIM Elementary File. diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index 5b6521f..03baf48 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -935,24 +935,49 @@ ICellularRadio::CODE CellularRadio::unlockSimCard(const Json::Value& jArgs) { } ICellularRadio::CODE CellularRadio::getSimCarrierCode(std::string& sCarrierCode) { - std::string sIccid; CODE rc; printTrace("%s| Get carrier code from the SIM card installed", m_sName.c_str()); - rc = getIccid(sIccid); - if (rc != SUCCESS) { - printError("%s| Unable to determine SIM carrier: Failed to fetch SIM identifier", m_sName.c_str()); - return rc; - } + do { + // Try to detect based on the ICCID + std::string sIccid; - printTrace("%s| Fetched ICCID: [%s]", m_sName.c_str(), sIccid.c_str()); + rc = getIccid(sIccid); + if (rc != SUCCESS) { + printError("%s| Unable to determine SIM carrier: Failed to fetch SIM identifier", m_sName.c_str()); + break; + } - rc = getSimCarrierCode(sIccid, sCarrierCode); - if (rc != SUCCESS) { - printError("%s| Unable to determine SIM carrier: Unable to extract carrier from the SIM identifier", m_sName.c_str()); - return rc; - } + printTrace("%s| Fetched ICCID: [%s]", m_sName.c_str(), sIccid.c_str()); + + rc = getSimCarrierCode(sIccid, sCarrierCode); + if (rc != SUCCESS) { + printError("%s| Unable to determine SIM carrier: Unable to extract carrier from the SIM identifier", m_sName.c_str()); + break; + } + + if (sCarrierCode != VALUE_UNKNOWN) { + rc = SUCCESS; + break; + } + + // Fallback to the MCC/MNC detection + std::string sMcc; + std::string sMnc; + + rc = getSimMccMnc(sMcc, sMnc); + if (rc != SUCCESS) { + printError("%s| Unable to determine SIM carrier: Failed to fetch MCC/MNC from the SIM", m_sName.c_str()); + break; + } + + rc = getSimCarrierCode(sMcc, sMnc, sCarrierCode); + if (rc != SUCCESS) { + printError("%s| Unable to determine SIM carrier: Unable to extract carrier from MCC/MNC of the SIM", m_sName.c_str()); + break; + } + } while(false); printTrace("%s| Detected carrier code: [%s]", m_sName.c_str(), sCarrierCode.c_str()); return rc; @@ -970,13 +995,39 @@ ICellularRadio::CODE CellularRadio::getSimCarrierCode(const std::string& sIccid, sCarrierCode = VALUE_CARRIER_CODE_ATT; } else { // All other carriers for which ICCID prefixes are not defined - printWarning("%s| Carrier is unknown for this SIM ID: [%s]", m_sName.c_str(), sIccid.c_str()); + printWarning("%s| Carrier code is unknown for this SIM ID: [%s]", m_sName.c_str(), sIccid.c_str()); sCarrierCode = VALUE_UNKNOWN; } return SUCCESS; // no error cases for now } +ICellularRadio::CODE CellularRadio::getSimCarrierCode(const std::string& sMcc, const std::string& sMnc, std::string& sCarrierCode) { + const Json::Value& jLookup = MccMncTable::getInstance()->lookup(sMcc, sMnc); + + do { + printTrace("%s| MCC-MNC Lookup: [%s][%s][%s]", m_sName.c_str(), + sMcc.c_str(), sMnc.c_str(), jLookup.toStyledString().c_str()); + + if (jLookup.isNull()) { + printWarning("%s| Carrier code is unknown for this MCC/NNC combination: [%s][%s]", m_sName.c_str(), sMcc.c_str(), sMnc.c_str()); + sCarrierCode = VALUE_UNKNOWN; + break; + } + + if (jLookup["carrierCode"].asString().empty()) { + printWarning("%s| Carrier code is unknown for this MCC/MNC combination: [%s][%s]", m_sName.c_str(), sMcc.c_str(), sMnc.c_str()); + sCarrierCode = VALUE_UNKNOWN; + break; + } + + sCarrierCode = jLookup["carrierCode"].asString(); + printTrace("%s| Detected carrier code by MCC/MNC: [%s]", m_sName.c_str(), sCarrierCode.c_str()); + } while (false); + + return CODE::SUCCESS; +} + ICellularRadio::CODE CellularRadio::simAccessReadBinary(uint16_t iFileId, uint8_t iP1, uint8_t iP2, uint8_t iLe, std::string& sResult) { printTrace("%s| Read binary from the SIM Elementary File", m_sName.c_str()); -- cgit v1.2.3