From da53c2f6955e748862066f727997965f7b9c6849 Mon Sep 17 00:00:00 2001 From: Serhii Kostiuk Date: Sat, 22 Jun 2019 10:51:06 +0300 Subject: [MTS-MTQ] SIM status and PIN unlock procedures Defined the JSON object fields for SIM Status Summary data --- src/MTS_IO_ICellularRadio.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/MTS_IO_ICellularRadio.cpp b/src/MTS_IO_ICellularRadio.cpp index 7f216d0..4e7809e 100644 --- a/src/MTS_IO_ICellularRadio.cpp +++ b/src/MTS_IO_ICellularRadio.cpp @@ -94,6 +94,12 @@ const char *MTS::IO::ICellularRadio::VALUE_TYPE_GSM = "GSM"; const char *MTS::IO::ICellularRadio::VALUE_TYPE_LTE = "LTE"; const char *MTS::IO::ICellularRadio::VALUE_TYPE_CDMA = "CDMA"; +const char *MTS::IO::ICellularRadio::KEY_IS_SIM_INSERTED = "isSimInserted"; //!< SIM card insertion indicator. True when a SIM card is inserted +const char *MTS::IO::ICellularRadio::KEY_IS_SIM_LOCKED = "isSimLocked"; //!< SIM card lock status indicator. True when a SIM card is locked by PIN / PUK / other code +const char *MTS::IO::ICellularRadio::KEY_SIM_LOCK_STATUS = "lockStatus"; //!< SIM card lock status string. Either "READY", "SIM PIN", "SIM PUK" or other state +const char *MTS::IO::ICellularRadio::KEY_ATTEMPTS_PIN = "attemptsPin"; //!< The number of attempts left to unlock the SIM card using PIN code +const char *MTS::IO::ICellularRadio::KEY_ATTEMPTS_PUK = "attemptsPuk"; //!< The number of attempts left to unlock the SIM card using PUK code + const char *MTS::IO::ICellularRadio::VALUE_SD_NO_SERVICE = "NO SERVICE"; const char *MTS::IO::ICellularRadio::VALUE_SD_CS_ONLY = "CS ONLY"; const char *MTS::IO::ICellularRadio::VALUE_SD_PS_ONLY = "PS ONLY"; -- cgit v1.2.3 From a7673be0a434243c2011d809cc0a3a01441470fb Mon Sep 17 00:00:00 2001 From: Serhii Kostiuk Date: Sat, 22 Jun 2019 10:57:44 +0300 Subject: [MTS-MTQ] SIM status and PIN unlock procedures Added a common implementation for the CellularRadio::getSimStatusSummary method --- src/MTS_IO_CellularRadio.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'src') diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index dbb64a5..8c4c75b 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -285,6 +285,50 @@ CellularRadio::CODE CellularRadio::getSimStatus(std::string& sSimStatus) { return FAILURE; } +CellularRadio::CODE CellularRadio::getSimStatusSummary(Json::Value& jData) { + bool bIsSimInserted = false; + bool bIsSimLocked = true; + int iAttemptsPin = 0; + int iAttemptsPuk = 0; + std::string sSimLockStatus; + CODE retCode; + + do { + retCode = getIsSimInserted(bIsSimInserted); + if (retCode != SUCCESS) { + break; + } + + if (!bIsSimInserted) { + // There is no left much to do. Return one field only. + jData[KEY_IS_SIM_INSERTED] = bIsSimInserted; + break; + } + + // The following code assumes that the SIM card is inserted + retCode = getSimLockStatus(sSimLockStatus); + if (retCode != SUCCESS) { + break; + } + + bIsSimLocked = (sSimLockStatus != "READY"); // SIM PIN, SIM PUK or other values + + retCode = getSimLockAttempts(iAttemptsPin, iAttemptsPuk); + if (retCode != SUCCESS) { + break; + } + + // Everything fetched successfully. Populate the jData object + jData[KEY_IS_SIM_INSERTED] = bIsSimInserted; + jData[KEY_IS_SIM_LOCKED] = bIsSimLocked; + jData[KEY_SIM_LOCK_STATUS] = sSimLockStatus; + jData[KEY_ATTEMPTS_PIN] = iAttemptsPin; + jData[KEY_ATTEMPTS_PUK] = iAttemptsPuk; + } while (false); + + return retCode; +} + CellularRadio::CODE CellularRadio::getLac(std::string& sLac) { Json::Value jData; -- cgit v1.2.3 From d9024556c684f2c157d472eee814e01ff2496ff9 Mon Sep 17 00:00:00 2001 From: Serhii Kostiuk Date: Sat, 22 Jun 2019 11:24:51 +0300 Subject: [MTS-MTQ] SIM status and PIN unlock procedures Added common implementations for CellularRadio::unlockSimCard and CellularRadio::getSimLockStatus --- src/MTS_IO_CellularRadio.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'src') diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index 8c4c75b..df1303c 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -760,6 +760,31 @@ void CellularRadio::getCommonNetworkStats(Json::Value& jData) { } } +CellularRadio::CODE CellularRadio::getSimLockStatus(std::string& sData) +{ + printTrace("%s| Get SIM lock status", m_sName.c_str()); + std::string sCmd("AT+CPIN?"); + std::string sResult = sendCommand(sCmd); + + const std::string sPrefix = "+CPIN: "; + size_t start = sResult.find(sPrefix); + size_t end = sResult.rfind(ICellularRadio::RSP_OK); + + if (start == std::string::npos || end == std::string::npos) { + printWarning("%s| Unable to get SIM lock status from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + start += sPrefix.size(); + sData = MTS::Text::trim(sResult.substr(start, end-start)); + if(sData.size() == 0) { + printWarning("%s| Unable to get SIM lock status from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + void CellularRadio::initMipProfile(Json::Value& jData) { jData[ICellularRadio::KEY_MIP_ID] = 0; jData[ICellularRadio::KEY_MIP_ENABLED] = false; @@ -821,6 +846,25 @@ CellularRadio::CODE CellularRadio::convertRegistrationToString(REGISTRATION eReg return eCode; } +CellularRadio::CODE CellularRadio::unlockSimCard(const Json::Value& jArgs) { + printTrace("%s| Unlock the SIM card using PIN code", m_sName.c_str()); + + if(!jArgs["pin"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd = "AT+CPIN=" + jArgs["pin"].asString(); + std::string sResult = sendCommand(sCmd); + + size_t pos = sResult.find(ICellularRadio::RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Failed to unlock the SIM card using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + CellularRadio::CODE CellularRadio::validateMsl(const Json::Value&) { printTrace("%s| Validate MSL", m_sName.c_str()); -- cgit v1.2.3 From 25bbcb7482dbbb93c9edfc3e1de415cfa4c260d0 Mon Sep 17 00:00:00 2001 From: Serhii Kostiuk Date: Sat, 22 Jun 2019 12:03:17 +0300 Subject: [MTS-MTQ] SIM status and PIN unlock procedures Added Telit-specific implementation of the CellularRadio::getIsSimInserted and CellularRadio::getSimLockAttempts utility methods --- src/MTS_IO_TelitRadio.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) (limited to 'src') diff --git a/src/MTS_IO_TelitRadio.cpp b/src/MTS_IO_TelitRadio.cpp index 4fcf836..8a21b46 100644 --- a/src/MTS_IO_TelitRadio.cpp +++ b/src/MTS_IO_TelitRadio.cpp @@ -537,3 +537,94 @@ bool TelitRadio::getHardwareVersionFromFirmware(const std::string& sFirmware, st return bResult; } + +CellularRadio::CODE TelitRadio::getIsSimInserted(bool& bData) { + printTrace("%s| Get SIM insertion status", getName().c_str()); + std::string sCmd("AT#SIMDET?"); + std::string sResult = sendCommand(sCmd); + + const std::string sPrefix = "#SIMDET: "; + size_t start = sResult.find(sPrefix); + size_t end = sResult.rfind(ICellularRadio::RSP_OK); + + if (end == std::string::npos) { + printWarning("%s| Unable to get SIM insertion status from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + if (start == std::string::npos) { + printDebug("%s| AT#SIMDET? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str()); + return FAILURE; + } + + // #SIMDET: , + start += sPrefix.size(); + std::vector vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start, end-start)), ','); + + if(vParts.size() != 2) { + printWarning("%s| Unable to parse SIM insertion status from response [%s]", getName().c_str(), sResult.c_str()); + return FAILURE; + } + + if (vParts[1] == "1") { // + bData = true; + } else { + bData = false; + } + + return SUCCESS; +} + +CellularRadio::CODE TelitRadio::getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk) { + std::string sLockStatus; + CODE retCode; + + retCode = getSimLockStatus(sLockStatus); + if (retCode != SUCCESS) { + printWarning("%s| Unable determine the number of SIM unlock attempts: SIM lock status is unavailable [%s]", getName().c_str(), sLockStatus.c_str()); + return retCode; + } + + return getSimLockAttempts(iAttemptsPin, iAttemptsPuk, sLockStatus); +} + +CellularRadio::CODE TelitRadio::getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk, const std::string& sLockStatus) { + printTrace("%s| Get SIM unlock attempts left", getName().c_str()); + std::string sCmd("AT#PCT?"); + std::string sResult = sendCommand(sCmd); + std::string sValue; + int iValue; + + const std::string sPrefix = "#PCT: "; + size_t start = sResult.find(sPrefix); + size_t end = sResult.rfind(ICellularRadio::RSP_OK); + + if (end == std::string::npos) { + printWarning("%s| Unable to get SIM unlock attempts from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + if (start == std::string::npos) { + printDebug("%s| AT#PCT? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str()); + return FAILURE; + } + + // #PCT: + start += sPrefix.size(); + sValue = MTS::Text::trim(sResult.substr(start, end-start)); + + if (!MTS::Text::parse(iValue, sValue)) { + printWarning("%s| Unable to parse SIM unlock attempts from response [%s]", getName().c_str(), sResult.c_str()); + return FAILURE; + } + + if (sLockStatus == "READY" || sLockStatus == "SIM PIN") { + iAttemptsPin = iValue; // Some PIN attempts left, maximum PUK attempts left + iAttemptsPuk = 10; + } else { + iAttemptsPin = 0; // No PIN attempts left + iAttemptsPuk = iValue; + } + + return SUCCESS; +} -- cgit v1.2.3 From 1cb0265df2b2e2171a874a52a782de3ecc6620fa Mon Sep 17 00:00:00 2001 From: Serhii Kostiuk Date: Sat, 22 Jun 2019 12:03:17 +0300 Subject: [MTS-MTQ] SIM status and PIN unlock procedures Added Quectel-specific implementation of the CellularRadio::getIsSimInserted and CellularRadio::getSimLockAttempts utility methods --- src/MTS_IO_QuectelRadio.cpp | 79 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'src') diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp index 2f3c9b5..0a054ff 100644 --- a/src/MTS_IO_QuectelRadio.cpp +++ b/src/MTS_IO_QuectelRadio.cpp @@ -478,6 +478,85 @@ bool QuectelRadio::getHardwareVersionFromFirmware(const std::string& sFirmware, return false; } +CellularRadio::CODE QuectelRadio::getIsSimInserted(bool& bData) { + printTrace("%s| Get SIM insertion status", getName().c_str()); + std::string sCmd("AT+QSIMSTAT?"); + std::string sResult = sendCommand(sCmd); + + const std::string sPrefix = "+QSIMSTAT: "; + size_t start = sResult.find(sPrefix); + size_t end = sResult.rfind(ICellularRadio::RSP_OK); + + if (end == std::string::npos) { + printWarning("%s| Unable to get SIM insertion status from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + if (start == std::string::npos) { + printDebug("%s| AT+QSIMSTAT? returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str()); + return FAILURE; + } + + // +QSIMSTAT: , + start += sPrefix.size(); + std::vector vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start, end-start)), ','); + + if(vParts.size() != 2) { + printWarning("%s| Unable to parse SIM insertion status from response [%s]", getName().c_str(), sResult.c_str()); + return FAILURE; + } + + if (vParts[1] == "1") { // Inserted + bData = true; + } else { // Removed or Unknown, before (U)SIM initialization + bData = false; + } + + return SUCCESS; +} + +CellularRadio::CODE QuectelRadio::getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk) { + printTrace("%s| Get SIM unlock attempts left", getName().c_str()); + std::string sCmd("AT+QPINC=\"SC\""); + std::string sResult = sendCommand(sCmd); + + const std::string sPrefix = "+QPINC: \"SC\","; + size_t start = sResult.find(sPrefix); + size_t end = sResult.rfind(ICellularRadio::RSP_OK); + + if (end == std::string::npos) { + printWarning("%s| Unable to get SIM unlock attempts from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + if (start == std::string::npos) { + printDebug("%s| AT+QPINC returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str()); + return FAILURE; + } + + // +QPINC: ,, + // [x] ,[0] ,[1] + start += sPrefix.size(); + std::vector vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start, end-start)), ','); + + if(vParts.size() != 2) { + printWarning("%s| Unable to parse SIM unlock attempts left from response [%s]", getName().c_str(), sResult.c_str()); + return FAILURE; + } + + if (!MTS::Text::parse(iAttemptsPin, vParts[0])) { + printWarning("%s| Unable to parse SIM PIM unlock attempts from response [%s]", getName().c_str(), sResult.c_str()); + return FAILURE; + } + + if (!MTS::Text::parse(iAttemptsPuk, vParts[1])) { + printWarning("%s| Unable to parse SIM PUK unlock attempts from response [%s]", getName().c_str(), sResult.c_str()); + return FAILURE; + } + + return SUCCESS; +} + CellularRadio::CODE QuectelRadio::convertToActiveBand(const std::string& sQuectelBand, ICellularRadio::ACTIVEBAND& band) { int iQuectelBand = -1; -- cgit v1.2.3 From 28ce5eaaa648670a2c83d583ebff2dc517af002e Mon Sep 17 00:00:00 2001 From: Serhii Kostiuk Date: Sat, 22 Jun 2019 14:39:31 +0300 Subject: [MTS-MTQ] SIM status and PIN unlock procedures Fixed a tiny issue with Telit implementation of CellularRadio::getSimLockAttempts --- src/MTS_IO_TelitRadio.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/MTS_IO_TelitRadio.cpp b/src/MTS_IO_TelitRadio.cpp index 8a21b46..ae885e9 100644 --- a/src/MTS_IO_TelitRadio.cpp +++ b/src/MTS_IO_TelitRadio.cpp @@ -590,7 +590,7 @@ CellularRadio::CODE TelitRadio::getSimLockAttempts(int& iAttemptsPin, int& iAtte CellularRadio::CODE TelitRadio::getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk, const std::string& sLockStatus) { printTrace("%s| Get SIM unlock attempts left", getName().c_str()); - std::string sCmd("AT#PCT?"); + std::string sCmd("AT#PCT"); std::string sResult = sendCommand(sCmd); std::string sValue; int iValue; -- cgit v1.2.3