summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhii Kostiuk <serhii.o.kostiuk@globallogic.com>2020-06-30 17:43:11 +0300
committerSerhii Kostiuk <serhii.o.kostiuk@globallogic.com>2020-06-30 17:43:11 +0300
commit69d7eb13bdda92a92b381f58a8ba9ec6fc29888f (patch)
tree342c06babde7a1e1aa355e0aab12f794af845224
parent24ed390ceb584fadfd428a6e9019371550931094 (diff)
parent343e662b6224cf03fea5ebfd419c7cf990528b53 (diff)
downloadlibmts-io-69d7eb13bdda92a92b381f58a8ba9ec6fc29888f.tar.gz
libmts-io-69d7eb13bdda92a92b381f58a8ba9ec6fc29888f.tar.bz2
libmts-io-69d7eb13bdda92a92b381f58a8ba9ec6fc29888f.zip
Merge remote-tracking branch 'origin/master' into sk/quectel-delta-fwu
-rw-r--r--include/mts/MTS_IO_CellularRadio.h5
-rw-r--r--include/mts/MTS_IO_ICellularRadio.h25
-rw-r--r--include/mts/MTS_IO_QuectelRadio.h1
-rw-r--r--src/MTS_IO_CellularRadio.cpp49
-rw-r--r--src/MTS_IO_ICellularRadio.cpp5
-rw-r--r--src/MTS_IO_QuectelRadio.cpp92
6 files changed, 176 insertions, 1 deletions
diff --git a/include/mts/MTS_IO_CellularRadio.h b/include/mts/MTS_IO_CellularRadio.h
index 92df561..e65e7cd 100644
--- a/include/mts/MTS_IO_CellularRadio.h
+++ b/include/mts/MTS_IO_CellularRadio.h
@@ -81,6 +81,7 @@ namespace MTS {
CODE convertCellModesToString(CELLULAR_MODES eCellModes, std::string& sCellModes) override;
CODE unlockSimCard(const Json::Value& jArgs) override;
+ CODE getSimCarrierCode(std::string& sCarrierCode) override;
CODE getMipProfile(Json::Value& jMipProfile) override;
CODE validateMsl(const Json::Value& jArgs) override;
@@ -103,6 +104,7 @@ namespace MTS {
CODE applyDeltaFirmwareFile(UpdateCb& stepCb) override;
CODE resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) override;
CODE activate(const Json::Value& jArgs, UpdateCb& stepCb) override;
+ CODE startOmaDm(UpdateCb& stepCb) override;
CODE setActiveFirmware(const Json::Value& jArgs) override;
CODE getActiveFirmware(std::string& sFwId) override;
CODE getEcho(bool& bEnabled) override;
@@ -166,6 +168,9 @@ namespace MTS {
*/
virtual CODE getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk) = 0;
+ //! Get carrier code based on the SIM card ID (ICCID)
+ virtual CODE getSimCarrierCode(const std::string& sIccid, std::string& sCarrierCode);
+
void initMipProfile(Json::Value& jData);
bool splitAndAssign(const std::string& sLine, const std::string& sKey, Json::Value& jParent, const std::string& sJsonKey, Json::ValueType eType = Json::ValueType::stringValue);
diff --git a/include/mts/MTS_IO_ICellularRadio.h b/include/mts/MTS_IO_ICellularRadio.h
index 7ad69c7..3259041 100644
--- a/include/mts/MTS_IO_ICellularRadio.h
+++ b/include/mts/MTS_IO_ICellularRadio.h
@@ -128,6 +128,7 @@ namespace MTS {
static const char *KEY_ICCID; //!< Integrated Circuit Card Identifier
static const char *KEY_MSL; //!< Master Subsidy Lock
static const char *KEY_SUPPORTED_CELL_MODES; //!< Comma-separated list of all supported cellular modes (2g,3g,4g)
+ static const char *KEY_SIM_CARRIER_CODE; //!< Unique carrier identifier based on the SIM card information.
//Network Status Data
@@ -201,6 +202,10 @@ namespace MTS {
static const char *VALUE_ABND_DCS_1800;
static const char *VALUE_ABND_PCS_1900;
+ //Values - Carrier code; abstraction over PLMN IDs, IINs and other identifiers
+ static const char *VALUE_CARRIER_CODE_VERIZON;
+ static const char *VALUE_CARRIER_CODE_ATT;
+
static const std::vector<std::string> DEFAULT_BAIL_STRINGS;
virtual ~ICellularRadio() = 0;
@@ -291,6 +296,23 @@ namespace MTS {
*/
virtual CODE unlockSimCard(const Json::Value& jArgs) = 0;
+ /**
+ * @brief getSimCarrierCode - get unique carrier identifier based on
+ * the SIM card information.
+ *
+ * @param sCarrier - a string to be populated with one of the carrier codes:
+ *
+ * - VALUE_CARRIER_CODE_VERIZON - Verizon
+ * - VALUE_CARRIER_CODE_ATT - AT&T
+ * - VALUE_UNKNOWN - Unknown carrier
+ * - other values may be defined in the future
+ *
+ * @return CODE::SUCCESS when carrier code retrieved,
+ * CODE::ERROR otherwise (i.e. when modem is not responding,
+ * when SIM card is removed or on any other error).
+ */
+ virtual CODE getSimCarrierCode(std::string& sCarrierCode) = 0;
+
//! Gather details of the radio's Mobile IP Profile
/*!
\param Json::Value object that will be populated with MIP data
@@ -482,6 +504,9 @@ namespace MTS {
* "fwid" : "Firmware Image To Be Enabled: STRING"
* }
*/
+
+ virtual CODE startOmaDm(UpdateCb& stepCb) = 0;
+
virtual CODE setActiveFirmware(const Json::Value& jArgs) = 0;
virtual CODE getActiveFirmware(std::string& sFwId) = 0;
diff --git a/include/mts/MTS_IO_QuectelRadio.h b/include/mts/MTS_IO_QuectelRadio.h
index c55b224..506b21b 100644
--- a/include/mts/MTS_IO_QuectelRadio.h
+++ b/include/mts/MTS_IO_QuectelRadio.h
@@ -41,6 +41,7 @@ namespace MTS {
CODE convertdBmToSignalStrength(const int32_t& dBm, int32_t& iRssi) override;
CODE setMdn(const Json::Value& jArgs) override;
+ CODE startOmaDm(ICellularRadio::UpdateCb& stepCb) override;
CODE setCellularMode(CELLULAR_MODES networks) override;
diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp
index 26d9f43..55f719f 100644
--- a/src/MTS_IO_CellularRadio.cpp
+++ b/src/MTS_IO_CellularRadio.cpp
@@ -912,6 +912,49 @@ ICellularRadio::CODE CellularRadio::unlockSimCard(const Json::Value& jArgs) {
return SUCCESS;
}
+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;
+ }
+
+ 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());
+ return rc;
+ }
+
+ printTrace("%s| Detected carrier code: [%s]", m_sName.c_str(), sCarrierCode.c_str());
+ return rc;
+}
+
+ICellularRadio::CODE CellularRadio::getSimCarrierCode(const std::string& sIccid, std::string& sCarrierCode) {
+ const char* ICCID_PREFIX_VZW = "891480";
+ const char* ICCID_PREFIX_ATT = "8901410";
+
+ if (sIccid.find(ICCID_PREFIX_VZW) == 0) {
+ printTrace("%s| Verizon SIM detected", m_sName.c_str());
+ sCarrierCode = VALUE_CARRIER_CODE_VERIZON;
+ } else if (sIccid.find(ICCID_PREFIX_ATT) == 0) {
+ printTrace("%s| AT&T SIM detected", m_sName.c_str());
+ 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());
+ sCarrierCode = VALUE_UNKNOWN;
+ }
+
+ return SUCCESS; // no error cases for now
+}
+
ICellularRadio::CODE CellularRadio::validateMsl(const Json::Value&) {
printTrace("%s| Validate MSL", m_sName.c_str());
@@ -1038,6 +1081,12 @@ ICellularRadio::CODE CellularRadio::activate(const Json::Value&, UpdateCb&) {
return NOT_APPLICABLE;
}
+ICellularRadio::CODE CellularRadio::startOmaDm(ICellularRadio::UpdateCb&) {
+ printTrace("%s| Start OMA DM procedure: not applicable", m_sName.c_str());
+
+ return NOT_APPLICABLE;
+}
+
ICellularRadio::CODE CellularRadio::setActiveFirmware(const Json::Value&) {
printTrace("%s| Set Active Firmware Image Number: not applicable", m_sName.c_str());
diff --git a/src/MTS_IO_ICellularRadio.cpp b/src/MTS_IO_ICellularRadio.cpp
index b84fa3f..4b58189 100644
--- a/src/MTS_IO_ICellularRadio.cpp
+++ b/src/MTS_IO_ICellularRadio.cpp
@@ -50,7 +50,7 @@ const char *MTS::IO::ICellularRadio::KEY_MDN = "mdn"; //!< Mobile Dir
const char *MTS::IO::ICellularRadio::KEY_ICCID = "iccid"; //!< Integrated Circuit Card Identifier
const char *MTS::IO::ICellularRadio::KEY_MSL = "msl"; //!< Master Subsidy Lock
const char *MTS::IO::ICellularRadio::KEY_SUPPORTED_CELL_MODES = "supportedCellularModes"; //!< Comma-separated list of all supported cellular modes (2g,3g,4g)
-
+const char *MTS::IO::ICellularRadio::KEY_SIM_CARRIER_CODE = "simCarrierCode"; //!< Unique carrier identifier based on the SIM card information.
//Dynamic Data
const char *MTS::IO::ICellularRadio::KEY_ROAMING = "roaming"; //!< Indicates whether or not using Home Network
const char *MTS::IO::ICellularRadio::KEY_DATETIME = "datetime"; //!< Date and Time from tower
@@ -112,6 +112,9 @@ const char *MTS::IO::ICellularRadio::VALUE_ABND_GSM_900 = "GSM 900";
const char *MTS::IO::ICellularRadio::VALUE_ABND_DCS_1800 = "DCS 1800";
const char *MTS::IO::ICellularRadio::VALUE_ABND_PCS_1900 = "PCS 1900";
+const char *MTS::IO::ICellularRadio::VALUE_CARRIER_CODE_VERIZON = "vz";
+const char *MTS::IO::ICellularRadio::VALUE_CARRIER_CODE_ATT = "att";
+
const std::vector<std::string> MTS::IO::ICellularRadio::DEFAULT_BAIL_STRINGS = { MTS::IO::ICellularRadio::RSP_OK, MTS::IO::ICellularRadio::RSP_ERROR };
MTS::IO::ICellularRadio::~ICellularRadio()
diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp
index a8986f4..2ed11b0 100644
--- a/src/MTS_IO_QuectelRadio.cpp
+++ b/src/MTS_IO_QuectelRadio.cpp
@@ -447,6 +447,98 @@ ICellularRadio::CODE QuectelRadio::setMdn(const Json::Value& jArgs) {
return NOT_APPLICABLE;
}
+ICellularRadio::CODE QuectelRadio::startOmaDm(ICellularRadio::UpdateCb& stepCb) {
+ printTrace("%s| Start OMA DM procedure", getName().c_str());
+
+ // TODO: All the timeout values below are empirically defined.
+ // Feel free to update them if you get any verified information.
+ const int32_t iTimeoutOk = 3 * 1000; // 3 seconds
+ const int32_t iTimeoutStart = 5 * 1000; // 5 seconds
+ const int32_t iTimeoutEnd = 160 * 1000; // 2 minutes 40 seconds
+ const int32_t iTimeoutAbort = 3 * 1000; // 3 seconds
+
+ const std::string sCmdOdmStart = "AT+QODM=\"dme\",2,\"ui\"";
+ const std::string sCmdOdmAbort = "AT+QODM=\"dme\",2,\"kill\"";
+
+ const std::string sOdmStarted = "DM Start";
+ const std::string sOdmFinished = "DM End";
+ const std::string sOdmAbnormal = "DME Abnormal";
+
+ const std::vector<std::string> vOdmStartedStrings{ sOdmStarted };
+ const std::vector<std::string> vOdmFinishedStrings{ sOdmFinished, sOdmAbnormal };
+
+ CODE eCode;
+
+ do {
+
+ // Send command and expect "OK" in iTimeoutOk milliseconds
+ eCode = sendBasicCommand(sCmdOdmStart, iTimeoutOk);
+ if (eCode != SUCCESS) {
+ printError("%s| OMA DM procedure can not be started", getName().c_str());
+ if (stepCb) {
+ stepCb(Json::Value("OMA DM Error: OMA DM can not be started"));
+ }
+ break;
+ }
+
+ // Wait for the "Start" response
+ std::string sResponse = sendCommand("", vOdmStartedStrings, iTimeoutStart, 0x00);
+ printDebug("%s| Radio returned: [%s]", getName().c_str(), sResponse.c_str());
+
+ // Received something unexpected or nothing at all?
+ if (sResponse.find(sOdmStarted) == std::string::npos) {
+ printError("%s| OMA DM procedure failed due to timeout", getName().c_str());
+ if (stepCb) {
+ stepCb(Json::Value("OMA DM Error: OMA DM failed due to timeout"));
+ }
+ eCode = FAILURE;
+ break;
+ }
+
+ // Got "DM Started" message from the radio
+ printTrace("%s| OMA DM started", getName().c_str());
+ if (stepCb) {
+ stepCb(Json::Value("OMA DM Info: OMA DM started"));
+ }
+
+ // Wait for the "End" or "Abnormal" response
+ sResponse = sendCommand("", vOdmFinishedStrings, iTimeoutEnd, 0x00);
+ printDebug("%s| Radio returned: [%s]", getName().c_str(), sResponse.c_str());
+
+ // Received "Abnormal"?
+ if (sResponse.find(sOdmAbnormal) != std::string::npos) {
+ printError("%s| OMA DM procedure failed due to internal error: [%s]", getName().c_str(), sResponse.c_str());
+ if (stepCb) {
+ stepCb(Json::Value("OMA DM Error: OMA DM failed due to internal error"));
+ }
+ eCode = FAILURE;
+ break;
+ }
+
+ // Received something unexpected or nothing at all?
+ if (sResponse.find(sOdmFinished) == std::string::npos) {
+ printError("%s| OMA DM procedure failed due to timeout", getName().c_str());
+ if (stepCb) {
+ stepCb(Json::Value("OMA DM Error: OMA DM failed due to timeout"));
+ }
+ sendBasicCommand(sCmdOdmAbort, iTimeoutAbort); // abort the procedure
+ eCode = FAILURE;
+ break;
+ }
+
+ // Got "DM End" message from the radio
+ printTrace("%s| OMA DM finished", getName().c_str());
+ if (stepCb) {
+ stepCb(Json::Value("OMA DM Info: OMA DM finished"));
+ }
+
+ eCode = SUCCESS;
+
+ } while (false);
+
+ return eCode;
+}
+
ICellularRadio::CODE QuectelRadio::uploadDeltaFirmwareFile(int fd, ICellularRadio::UpdateCb& stepCb) {
CODE rc = FAILURE;
bool bIsFilePresent = false;