summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsdesai <sdesai@multitech.com>2023-03-15 15:22:04 -0500
committerJohn Klug <john.klug@multitech.com>2023-04-26 17:29:28 -0500
commit576eb04e2d42e3b9c5fa40748d1d190a457fa1f8 (patch)
treecee3134469ec1e843dbe337dc65dda934b9728f3
parent0f15b7265be65cbd9f66a68f6d1685b58b13e501 (diff)
downloadlibmts-io-576eb04e2d42e3b9c5fa40748d1d190a457fa1f8.tar.gz
libmts-io-576eb04e2d42e3b9c5fa40748d1d190a457fa1f8.tar.bz2
libmts-io-576eb04e2d42e3b9c5fa40748d1d190a457fa1f8.zip
GP-139:Support Portal Case #5086148: use Cellular Radio timeas alternative to GPS or NTP
-rw-r--r--include/mts/MTS_IO_CellularRadio.h167
-rw-r--r--include/mts/MTS_IO_ICellularRadio.h53
-rw-r--r--include/mts/MTS_IO_QuectelRadio.h8
-rw-r--r--include/mts/MTS_IO_SequansRadio.h7
-rw-r--r--include/mts/MTS_IO_TelitRadio.h7
-rw-r--r--src/MTS_IO_CellularRadio.cpp353
-rw-r--r--src/MTS_IO_ICellularRadio.cpp11
-rw-r--r--src/MTS_IO_QuectelRadio.cpp133
-rw-r--r--src/MTS_IO_SequansRadio.cpp49
-rw-r--r--src/MTS_IO_TelitRadio.cpp139
10 files changed, 190 insertions, 737 deletions
diff --git a/include/mts/MTS_IO_CellularRadio.h b/include/mts/MTS_IO_CellularRadio.h
index 991dc47..68c1394 100644
--- a/include/mts/MTS_IO_CellularRadio.h
+++ b/include/mts/MTS_IO_CellularRadio.h
@@ -269,7 +269,6 @@ namespace MTS {
virtual CODE sendData(const char* pData, size_t nBytes);
virtual CODE sendBasicQuery(const std::string& sCmd, const std::string& sLabel, std::string& sResult, int32_t timeoutMillis = 100, const char& ESC = ICellularRadio::CR);
- virtual CODE isCommandSupported(const std::string& sCmd, bool& bIsSupported);
/**
* @brief getDiagCommands - returns the list of Cellular Diagnostics commands for this radio.
*
@@ -279,172 +278,6 @@ namespace MTS {
*/
virtual const std::vector<std::string>& getDiagCommands(bool bIsSimReady = true) = 0;
- struct PdpContextInfo {
- std::string sId;
- std::string sIpMode;
- std::string sApn;
- std::string sAuthType;
- std::string sUsername;
- std::string sPassword;
- };
-
- virtual std::vector<std::string> getSupportedPdpContextAuthTypes() const = 0;
- static CODE convertPdpContextAuthTypeToString(PDP_CONTEXT_AUTH_TYPE eAuthType, std::string& sAuthType);
- static CODE convertStringToPdpContextAuthType(const std::string& sAuthType, PDP_CONTEXT_AUTH_TYPE& eAuthType);
-
- /**
- * @brief checks if PDP context authentication is supported by the modem.
- *
- * @param isSupported - sets to "true" if PDP context authentication is supported, "false" otherwise.
- *
- * @return CODE::SUCCESS when the response from the radio is received
- * CODE::NO_RESPONSE when the modem doesn't respond,
- * CODE::FAILURE otherwise.
- */
- virtual CODE isPdpContextAuthSupported(bool& isSupported) = 0;
-
- /**
- * @brief Get the list of PDP contexts with the base info about them from the radio.
- *
- * @param jData - a JSON object to be filled with data.
- * {
- * "context_number : STRING": {
- * "apn" : "apn_value: STRING",
- * "ipMode" : "ip_mode_value: STRING",
- * }
- * }
- *
- * @return CODE::SUCCESS when fetched successfully,
- * CODE::NO_RESPONSE when the modem doesn't respond,
- * CODE::ERROR when the radio returns "ERROR",
- * CODE::FAILURE otherwise (unexpected response).
- */
- virtual CODE getPdpContextsBase(Json::Value& jData);
-
- /**
- * @brief fills jData with the information about PDP context authentication
- *
- * @param jData - a JSON object that is pre-filled with the list of PDP contexts:
- * {
- * "context_number : STRING": {
- * "apn" : "apn_value: STRING",
- * "ipMode" : "ip_mode_value: STRING",
- * }
- * }
- * On success the method will complement jData with the PDP context authentication fields:
- * {
- * "context_number : STRING": {
- * "apn" : "apn_value: STRING",
- * "authType" : "auth_type_value: STRING",
- * "ipMode" : "ip_mode_value: STRING",
- * "password" : "password_value (optional): STRING",
- * "username" : "username_value (optional): STRING"
- * }
- * }
- *
- * @return CODE::SUCCESS when fetched successfully,
- * CODE::NO_RESPONSE when the modem doesn't respond,
- * CODE::ERROR when the radio returns "ERROR",
- * CODE::FAILURE otherwise (unexpected response).
- */
- virtual CODE fillPdpContextAuthFields(Json::Value& jData) = 0;
-
- /**
- * @brief merges the current configuration of the PDP context with the one requested by user
- *
- * @param sId - ID of the PDP context to change.
- * @param jCurrentContext - a JSON object filled with current configuration data
- * {
- * "apn" : "apn_value (optional): STRING",
- * "authType" : "auth_type_value: STRING",
- * "ipMode" : "ip_mode_value: STRING",
- * "password" : "password_value (optional): STRING",
- * "username" : "username_value (optional): STRING"
- * }
- * @param jChanges - a JSON object filled with new configuration data
- * {
- * "apn" : "apn_value (optional): STRING",
- * "authType" : "auth_type_value (optional): STRING",
- * "ipMode" : "ip_mode_value (optional): STRING",
- * "password" : "password_value (optional): STRING",
- * "username" : "username_value (optional): STRING"
- * }
- * @param jResult - a JSON object to be filled with merged data
- * {
- * "apn" : "apn_value (optional): STRING",
- * "authType" : "auth_type_value (optional): STRING",
- * "id" : "ctx_id (optional): STRING",
- * "ipMode" : "ip_mode_value (optional): STRING",
- * "password" : "password_value (optional): STRING",
- * "username" : "username_value (optional): STRING"
- * }
- * @return CODE::SUCCESS.
- */
- virtual CODE mergePdpContexts(const std::string& sId, const Json::Value& jCurrentContext, const Json::Value& jChanges, Json::Value& jResult);
-
- /**
- * @brief fills a PdpContextInfo instance with the data from JSON
- * @param jData - a JSON object that contains:
- * {
- * "apn" : "apn_value: STRING",
- * "authType" : "auth_type_value: STRING",
- * "id" : "ctx_id: STRING",
- * "ipMode" : "ip_mode_value: STRING",
- * "password" : "password_value: STRING",
- * "username" : "username_value: STRING"
- * }
- * @param pdpContextResult - PdpContextInfo object to be filled with parameters.
- * @return CODE::SUCCESS if validated successfully,
- * CODE::INVALID_ARGS if validation failed.
- */
- virtual CODE initPdpContextInfo(const Json::Value& jConfig, PdpContextInfo& pdpContextResult);
-
- /**
- * @brief checks if PDP context authentication should be configured
- * @param jData - a JSON object that contains:
- * {
- * "apn" : "apn_value (optional): STRING",
- * "authType" : "auth_type_value: STRING",
- * "ipMode" : "ip_mode_value: STRING",
- * "password" : "password_value (optional): STRING",
- * "username" : "username_value (optional): STRING"
- * }
- * @param bIsAuthEditRequired - sets to "false" if there are no authType, username, and password fields in the json, otherwise sets to "true".
- * @return CODE::SUCCESS.
- */
- static CODE isPdpContextAuthEditRequired(const Json::Value& jConfig, bool& bIsAuthEditRequired);
-
- /**
- * @brief Sets the base PDP context parameters: IP Mode and APN
- * @param pdpContext - The new PDP context configuration
- * @return CODE::SUCCESS when set successfully,
- * CODE::NO_RESPONSE when the modem doesn't respond,
- * CODE::ERROR when the radio returns "ERROR",
- * CODE::FAILURE otherwise (unexpected response).
- */
- virtual CODE setPdpContextBase(const PdpContextInfo& pdpContext);
-
- /**
- * @brief Sets the Cellular Authentication parameters for this PDP context: Authentication Type, Username and Password.
- * NOTE: Some implementations (Quectel) override the current IP Mode and APN in addition to the authentication fields.
- * @param pdpContext - The new PDP context configuration
- * @return CODE::SUCCESS when set successfully,
- * CODE::NO_RESPONSE when the modem doesn't respond,
- * CODE::ERROR when the radio returns "ERROR",
- * CODE::FAILURE otherwise (unexpected response).
- */
- virtual CODE setPdpContextAuth(const PdpContextInfo& pdpContext) = 0;
-
- /**
- * @brief Delete the PDP context by its ID.
- * @param sId - PDP context ID
- * @return CODE::SUCCESS when delete successfully,
- * CODE::NO_RESPONSE when the modem doesn't respond,
- * CODE::ERROR when the radio returns "ERROR",
- * CODE::FAILURE otherwise (unexpected response).
- */
- virtual CODE deletePdpContext(const std::string& sId);
-
class RadioBandMap : public MTS::NonCopyable {
public:
RadioBandMap()
diff --git a/include/mts/MTS_IO_ICellularRadio.h b/include/mts/MTS_IO_ICellularRadio.h
index a698647..da8e130 100644
--- a/include/mts/MTS_IO_ICellularRadio.h
+++ b/include/mts/MTS_IO_ICellularRadio.h
@@ -78,13 +78,6 @@ namespace MTS {
CS_MODE2 // only non-EPS services are allowed, the usage is "data centric"
};
- enum PDP_CONTEXT_AUTH_TYPE : uint8_t {
- NONE = 0,
- PAP,
- CHAP,
- PAP_CHAP
- };
-
static CODE convertModelToType(const std::string& sModel, std::string& sType);
static CODE convertModelToMtsShortCode(const std::string& sModel, std::string& sCode, ICellularRadio *radioObj = NULL);
static CODE convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd);
@@ -213,19 +206,8 @@ namespace MTS {
static const char *KEY_ATTEMPTS_PUK; //!< The number of attempts left to unlock the SIM card using PUK code
//PDP Context
- static const char *KEY_PDP_CONTEXT_ID;
static const char *KEY_PDP_CONTEXT_APN;
static const char *KEY_PDP_CONTEXT_IPMODE;
- static const char *KEY_PDP_CONTEXT_AUTH_TYPE;
- static const char *KEY_PDP_CONTEXT_AUTH_USERNAME;
- static const char *KEY_PDP_CONTEXT_AUTH_PASSWORD;
- static const char *VALUE_PDP_CONTEXT_IP_MODE_IP;
- static const char *VALUE_PDP_CONTEXT_IP_MODE_IPV6;
- static const char *VALUE_PDP_CONTEXT_IP_MODE_IPV4V6;
- static const char *VALUE_PDP_CONTEXT_AUTH_TYPE_NONE;
- static const char *VALUE_PDP_CONTEXT_AUTH_TYPE_PAP;
- static const char *VALUE_PDP_CONTEXT_AUTH_TYPE_CHAP;
- static const char *VALUE_PDP_CONTEXT_AUTH_TYPE_PAP_CHAP;
//Values - Type
static const char *VALUE_TYPE_LTE;
@@ -680,18 +662,12 @@ namespace MTS {
/**
* @brief Get the list of PDP contexts from the radio
- * NOTE: authType, password and username are only present if the radio supports Cellular Authentication on
- * the PDP Context Level. “password” and “username” are only present if the current authentication type is
- * other than NONE. The “password” field is omitted on radios that do not allow reading the current password (i.e. on Telit LE910Cx).
*
* @param jData - an object to be filled with data.
* {
- * "context_number : STRING": {
- * "apn" : "apn_value: STRING",
- * "authType" : "auth_type_value: STRING",
- * "ipMode" : "ip_mode_value: STRING",
- * "password" : "password_value (optional): STRING",
- * "username" : "username_value (optional): STRING"
+ * "<context_number: str>": {
+ * "apn": "<apn_value: str>",
+ * "ipMode": "<ip_mode: str>"
* }
* }
*
@@ -703,27 +679,20 @@ namespace MTS {
virtual CODE getPdpContexts(Json::Value& jData) = 0;
/**
- * @brief Set the PDP context to the radio. If any of the fields are omitted,
- * the system re-uses the current configuration for such fields.
- * If all fields are omitted - the system deletes the context.
- * "username" and "password" are mandatory if "ipMode" is PAP, CHAP or PAP-CHAP.
- * "username", "password" and "authType" shall be omitted on radios that do NOT
- * support Cellular Authentication on the PDP Context Level.
+ * @brief Set the PDP context to the radio
*
- * @param sId - ID of the PDP context that should be edited.
- * @param jConfig - a JSON object that contains:
+ * @param sId - a string value that contains an ID of the PDP context to change.
+ * @param jConfig - a JSON-object that contains:
+ * an IP mode for the specified PDP context,
+ * an APN for the specified PDP context.
* {
- * "apn" : "apn_value (optional): STRING",
- * "authType" : "auth_type_value (optional): STRING",
- * "ipMode" : "ip_mode_value (optional): STRING",
- * "password" : "password_value (optional): STRING",
- * "username" : "username_value (optional): STRING"
+ * "apn": "<APN>",
+ * "ipMode": "<IP MODE>"
* }
*
* @return CODE::SUCCESS when fetched successfully,
* CODE::NO_RESPONSE when the modem doesn't respond,
* CODE::ERROR when the radio returns "ERROR",
- * CODE::INVALID_ARGS when one of the JSON object values is incorrect OR not supported by the current radio,
* CODE::FAILURE otherwise (unexpected response).
*/
virtual CODE setPdpContext(const std::string& sId, const Json::Value& jConfig) = 0;
@@ -748,7 +717,7 @@ namespace MTS {
* CODE::FAILURE otherwise.
*/
virtual CODE getDiagnostics(std::string& sDiagReport) = 0;
-
+ virtual CODE getTimeUTC(void) = 0;
};
}
}
diff --git a/include/mts/MTS_IO_QuectelRadio.h b/include/mts/MTS_IO_QuectelRadio.h
index b3881cb..7015acb 100644
--- a/include/mts/MTS_IO_QuectelRadio.h
+++ b/include/mts/MTS_IO_QuectelRadio.h
@@ -85,14 +85,8 @@ namespace MTS {
CODE setRxDiversity(const Json::Value& jArgs) override;
- std::vector<std::string> getSupportedPdpContextAuthTypes() const override;
- static CODE convertStringToPdpContextType(const std::string& sStringType, std::string& sIntType);
- CODE isPdpContextAuthSupported(bool& isSupported) override;
- CODE fillPdpContextAuthFields(Json::Value& jData) override;
- CODE setPdpContextAuth(const PdpContextInfo& pdpContext) override;
-
const std::vector<std::string>& getDiagCommands(bool bIsSimReady = true) override;
-
+ CODE getTimeUTC(void) override;
private:
// private variable to save old firmware versions during FOTA
std::string m_sQuectelFirmware;
diff --git a/include/mts/MTS_IO_SequansRadio.h b/include/mts/MTS_IO_SequansRadio.h
index b5a3a38..d61ae67 100644
--- a/include/mts/MTS_IO_SequansRadio.h
+++ b/include/mts/MTS_IO_SequansRadio.h
@@ -49,18 +49,13 @@ namespace MTS {
CODE setRxDiversity(const Json::Value& jArgs) override;
const std::vector<std::string> getRegistrationCommands() override;
-
+ CODE getTimeUTC(void) override;
protected:
SequansRadio(const std::string& sName, const std::string& sRadioPort);
CODE getIsSimInserted(bool& bData) override;
CODE getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk) override;
- std::vector<std::string> getSupportedPdpContextAuthTypes() const override;
- CODE isPdpContextAuthSupported(bool& isSupported) override;
- CODE fillPdpContextAuthFields(Json::Value& jData) override;
- CODE setPdpContextAuth(const PdpContextInfo& pdpContext) override;
-
const std::vector<std::string>& getDiagCommands(bool bIsSimReady = true) override;
private:
diff --git a/include/mts/MTS_IO_TelitRadio.h b/include/mts/MTS_IO_TelitRadio.h
index dc02755..01897ac 100644
--- a/include/mts/MTS_IO_TelitRadio.h
+++ b/include/mts/MTS_IO_TelitRadio.h
@@ -51,7 +51,7 @@ namespace MTS {
CODE fumoLocalApply(UpdateCb& stepCb) override;
CODE getSelectedBandsRaw(std::string& sRawBands) override;
-
+ CODE getTimeUTC(void) override;
protected:
TelitRadio(const std::string& sName, const std::string& sRadioPort);
@@ -73,11 +73,6 @@ namespace MTS {
virtual CODE fumoWriteGroupsABD(int fd, UpdateCb& stepCb);
//virtual CODE fumoWriteGroupC(int fd, UpdateCb& stepCb);
- std::vector<std::string> getSupportedPdpContextAuthTypes() const override;
- CODE isPdpContextAuthSupported(bool& isSupported) override;
- CODE fillPdpContextAuthFields(Json::Value &jData) override;
- CODE setPdpContextAuth(const PdpContextInfo& pdpContext) override;
-
const std::vector<std::string>& getDiagCommands(bool bIsSimReady = true) override;
static bool isContainsSignChar(const std::string& str);
diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp
index 7200658..8cdaf44 100644
--- a/src/MTS_IO_CellularRadio.cpp
+++ b/src/MTS_IO_CellularRadio.cpp
@@ -22,7 +22,6 @@
#include <unistd.h>
#include <sys/stat.h>
-#include <algorithm>
#include <mts/MTS_IO_MccMncTable.h>
#include <mts/MTS_Thread.h>
@@ -578,17 +577,25 @@ ICellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTi
sDate = "";
sTime = "";
sTimeZone = "";
+ std::vector<std::string> vTimeParts;
+ std::string sSign = "+";
+
+ if(getTimeUTC() == FAILURE) {
+ printWarning("%s| Unable to set Time Parameters for radio [%s]", m_sName.c_str());
+ return FAILURE;;
+ }
std::string sCmd("AT+CCLK?");
std::string sResult = sendCommand(sCmd);
size_t end = sResult.find(ICellularRadio::RSP_OK);
+
if (end == std::string::npos) {
printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
return FAILURE;
}
size_t start = sResult.find("CCLK: ");
- if(start != std::string::npos) {
+ if (start != std::string::npos) {
start += sizeof("CCLK: ");
std::string sValue = MTS::Text::trim(sResult.substr(start, end - start));
sValue = MTS::Text::strip(sValue, '"');
@@ -599,39 +606,47 @@ ICellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTi
return FAILURE;
}
-
std::vector<std::string> vDateParts = MTS::Text::split(vParts[0], '/');
if(vDateParts.size() != 3) {
- printWarning("%s| Unable to parse Date from response [%s]", m_sName.c_str(), sResult.c_str());
+ printWarning("%s| Unable to parse Date parts from response [%s]", m_sName.c_str(), sResult.c_str());
return FAILURE;
}
- //The Date format is YY/MM/DD -> Change to MM/DD/YY
- sDate = vDateParts[1] + "/" + vDateParts[2] + "/" + vDateParts[0];
+ // The format is YYYY-MM-DD
+ sDate = vDateParts[0] + "-" + vDateParts[1] + "-" + vDateParts[2];
- vParts = MTS::Text::split(vParts[1], '-');
- if(vParts.size() != 2) {
- printWarning("%s| Unable to parse Time from response [%s]", m_sName.c_str(), sResult.c_str());
- return FAILURE;
+ sTime = (vParts[1]);
+
+ //E.g. 20:39:34-16. Split time and zone with + or - sign.
+ size_t psign = sTime.find("+");
+ size_t nsign = sTime.find("-");
+
+ if (psign != std::string::npos) {
+ vTimeParts = MTS::Text::split(vParts[1], '+');
+ } else if (nsign != std::string::npos) {
+ vTimeParts = MTS::Text::split(vParts[1], '-');
+ sSign = "-";
}
- sTime = vParts[0];
- int32_t iZoneUnits; //the difference, expressed in quarters of an hour, between the local time and GMT
- if(!MTS::Text::parse(iZoneUnits, MTS::Text::strip(vParts[1], '+'))) {
- printWarning("%s| Unable to parse Time Zone from response [%s]", m_sName.c_str(), sResult.c_str());
+ if(vTimeParts.size() != 2) {
+ printWarning("%s| Unable to parse Time Zone from response [%s], size %d", m_sName.c_str(), sResult.c_str(),vTimeParts.size());
return FAILURE;
}
+ //Get just the UTC time without zone info
+ sTime = (vTimeParts[0]);
+
+ int32_t iZoneUnits = stoi(vTimeParts[1]); //the difference, expressed in quarters of an hour, between the local time and GMT
int32_t iZone = iZoneUnits/4; //Divide by 4 to get hours difference
int32_t iZonePartial = (iZoneUnits % 4) * 15; //Remainder in minutes
- std::string sPlusSign = "+";
- if(iZonePartial < 0) {
- //Remove negative sign from partial and clear plus sign component
+
+ if (iZonePartial < 0) {
+ //Remove negative sign from partial and clear sign component
iZonePartial *= -1;
- sPlusSign = "";
+ sSign = "";
}
std::stringstream ss;
- ss << sPlusSign << iZone;
+ ss << sSign << iZone;
if(iZonePartial != 0) {
ss << ":" << iZonePartial;
}
@@ -640,7 +655,7 @@ ICellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTi
return SUCCESS;
} else {
- printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
+ printWarning("%s| Unable to parse Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str());
}
return FAILURE;
@@ -1761,81 +1776,27 @@ ICellularRadio::CODE CellularRadio::sendBasicQuery(const std::string& sCmd, cons
return SUCCESS;
}
-ICellularRadio::CODE CellularRadio::isCommandSupported(const std::string& sCmd, bool& bIsSupported) {
- CODE rc;
- bIsSupported = false;
-
- rc = sendBasicCommand(sCmd);
-
- if (SUCCESS == rc) {
- bIsSupported = true;
- } else if (ERROR == rc) {
- // if not applicable
- rc = SUCCESS;
- }
-
- return rc;
-}
-
ICellularRadio::CODE CellularRadio::getSelectedBandsRaw(std::string& sRawBands)
{
printTrace("%s| Acquiring selected bands: not applicable", m_sName.c_str());
return NOT_APPLICABLE;
}
-ICellularRadio::CODE CellularRadio::convertPdpContextAuthTypeToString(PDP_CONTEXT_AUTH_TYPE eAuthType, std::string& sAuthType) {
- CODE rc = FAILURE;
-
- switch (eAuthType) {
- case NONE: sAuthType = VALUE_PDP_CONTEXT_AUTH_TYPE_NONE; rc = SUCCESS; break;
- case PAP: sAuthType = VALUE_PDP_CONTEXT_AUTH_TYPE_PAP; rc = SUCCESS; break;
- case CHAP: sAuthType = VALUE_PDP_CONTEXT_AUTH_TYPE_CHAP; rc = SUCCESS; break;
- case PAP_CHAP: sAuthType = VALUE_PDP_CONTEXT_AUTH_TYPE_PAP_CHAP; rc = SUCCESS; break;
- default: sAuthType = ICellularRadio::VALUE_UNKNOWN; break;
- }
- return rc;
-}
-
-ICellularRadio::CODE MTS::IO::CellularRadio::convertStringToPdpContextAuthType(const std::string& sAuthType, PDP_CONTEXT_AUTH_TYPE& eAuthType) {
- CODE rc = FAILURE;
- if (VALUE_PDP_CONTEXT_AUTH_TYPE_NONE == sAuthType) {
- eAuthType = PDP_CONTEXT_AUTH_TYPE::NONE;
- rc = SUCCESS;
- } else if (VALUE_PDP_CONTEXT_AUTH_TYPE_PAP == sAuthType) {
- eAuthType = PDP_CONTEXT_AUTH_TYPE::PAP;
- rc = SUCCESS;
- } else if (VALUE_PDP_CONTEXT_AUTH_TYPE_CHAP == sAuthType) {
- eAuthType = PDP_CONTEXT_AUTH_TYPE::CHAP;
- rc = SUCCESS;
- } else if (VALUE_PDP_CONTEXT_AUTH_TYPE_PAP_CHAP == sAuthType) {
- eAuthType = PDP_CONTEXT_AUTH_TYPE::PAP_CHAP;
- rc = SUCCESS;
- }
- return rc;
-}
-
-// When there are no defined contexts
-// Telit returns:
-// OK
-// Quectel returns:
-// +CGDCONT:
-//
-// OK
-ICellularRadio::CODE CellularRadio::getPdpContextsBase(Json::Value& jData) {
+ICellularRadio::CODE CellularRadio::getPdpContexts(Json::Value& jData) {
+ printTrace("%s| Fetching the list of PDP contexts from the radio", getName().c_str());
CODE rc;
const std::string sCommand = "AT+CGDCONT?";
const int dTimeout = 1000;
std::string sResult;
- jData = Json::objectValue;
-
rc = sendBasicQuery(sCommand, "", sResult, dTimeout);
if (rc != SUCCESS) {
return rc;
}
- std::vector<std::string> vContexts = MTS::Text::split(sResult, "+CGDCONT:");
+ std::vector<std::string> vContexts = MTS::Text::split(sResult, "+CGDCONT: ");
+ std::vector<std::string> vContextParams;
for (size_t i = 0; i < vContexts.size(); i++) {
vContexts[i] = MTS::Text::trim(vContexts[i]);
@@ -1844,7 +1805,7 @@ ICellularRadio::CODE CellularRadio::getPdpContextsBase(Json::Value& jData) {
continue;
}
- std::vector<std::string> vContextParams = MTS::Text::split(vContexts[i], ",", 4);
+ vContextParams = MTS::Text::split(vContexts[i], ",", 4);
if (vContextParams.size() < 3) {
return FAILURE;
@@ -1861,216 +1822,78 @@ ICellularRadio::CODE CellularRadio::getPdpContextsBase(Json::Value& jData) {
return SUCCESS;
}
-ICellularRadio::CODE CellularRadio::getPdpContexts(Json::Value& jData) {
- printTrace("%s| Fetching the list of PDP contexts from the radio", getName().c_str());
+ICellularRadio::CODE CellularRadio::setPdpContext(const std::string& sId, const Json::Value& jConfig) {
+ printTrace("%s| Setting context to the radio", getName().c_str());
CODE rc;
- bool bPdpAuthSupported;
- // check if pdp context authentication is applicable
- rc = isPdpContextAuthSupported(bPdpAuthSupported);
- if (SUCCESS != rc) {
- return rc;
+ if (sId.empty()) {
+ printError("%s| PDP Context ID is not specified", getName().c_str());
+ return FAILURE;
}
- rc = getPdpContextsBase(jData);
+ std::string sCommand = "AT+CGDCONT=" + sId;
+ const int dTimeout = 1000;
- if (SUCCESS != rc) {
- printError("%s| Failed to fetch the list of the defined PDP contexts from the radio", getName().c_str());
+ Json::Value jAllContexts;
+
+ rc = getPdpContexts(jAllContexts);
+ if (rc != SUCCESS) {
+ printError("%s| Failed to retrieve the current PDP context configuration: [%d]", getName().c_str(), rc);
return rc;
}
- if (bPdpAuthSupported) {
- rc = fillPdpContextAuthFields(jData);
-
- if (SUCCESS != rc) {
- printError("%s| Failed to fetch the authentication parameters for PDP contexts", getName().c_str());
+ // Remove the context if no parameters defined
+ if (!jConfig.isMember(ICellularRadio::KEY_PDP_CONTEXT_IPMODE) && !jConfig.isMember(ICellularRadio::KEY_PDP_CONTEXT_APN)) {
+ if (jAllContexts.isMember(sId)) {
+ rc = sendBasicCommand(sCommand, dTimeout);
return rc;
+ } else {
+ printError("%s| PDP Context [%s] does not exist", getName().c_str(), sId.c_str());
+ return FAILURE;
}
}
- return SUCCESS;
-}
-
-ICellularRadio::CODE CellularRadio::mergePdpContexts(const std::string& sId, const Json::Value& jCurrentContext, const Json::Value& jChanges, Json::Value& jResult) {
- jResult[KEY_PDP_CONTEXT_ID] = sId;
-
- if (jChanges.isMember(KEY_PDP_CONTEXT_IPMODE)) {
- jResult[KEY_PDP_CONTEXT_IPMODE] = jChanges[KEY_PDP_CONTEXT_IPMODE].asString();
- } else if (jCurrentContext.isMember(KEY_PDP_CONTEXT_IPMODE)) {
- printInfo("%s| Re-using IP Mode [%s] for PDP context [%s]", getName().c_str(), jCurrentContext[KEY_PDP_CONTEXT_IPMODE].asString().c_str(), sId.c_str());
- jResult[KEY_PDP_CONTEXT_IPMODE] = jCurrentContext[KEY_PDP_CONTEXT_IPMODE].asString();
- }
-
- if (jChanges.isMember(KEY_PDP_CONTEXT_APN)) {
- jResult[KEY_PDP_CONTEXT_APN] = jChanges[KEY_PDP_CONTEXT_APN].asString();
- } else if (jCurrentContext.isMember(KEY_PDP_CONTEXT_APN)) {
- printInfo("%s| Re-using APN [%s] for PDP context [%s]", getName().c_str(), jCurrentContext[KEY_PDP_CONTEXT_APN].asString().c_str(), sId.c_str());
- jResult[KEY_PDP_CONTEXT_APN] = jCurrentContext[KEY_PDP_CONTEXT_APN].asString();
- }
-
- if (jChanges.isMember(KEY_PDP_CONTEXT_AUTH_TYPE)) {
- jResult[KEY_PDP_CONTEXT_AUTH_TYPE] = jChanges[KEY_PDP_CONTEXT_AUTH_TYPE].asString();
- }
-
- if (jChanges.isMember(KEY_PDP_CONTEXT_AUTH_USERNAME)) {
- jResult[KEY_PDP_CONTEXT_AUTH_USERNAME] = jChanges[KEY_PDP_CONTEXT_AUTH_USERNAME].asString();
- }
-
- if (jChanges.isMember(KEY_PDP_CONTEXT_AUTH_PASSWORD)) {
- jResult[KEY_PDP_CONTEXT_AUTH_PASSWORD] = jChanges[KEY_PDP_CONTEXT_AUTH_PASSWORD].asString();
- }
-
- return SUCCESS;
-}
-
-ICellularRadio::CODE CellularRadio::initPdpContextInfo(const Json::Value& jConfig, PdpContextInfo& pdpContextResult) {
- // validate IP mode
- if (jConfig[KEY_PDP_CONTEXT_IPMODE].asString() != VALUE_PDP_CONTEXT_IP_MODE_IP &&
- jConfig[KEY_PDP_CONTEXT_IPMODE].asString() != VALUE_PDP_CONTEXT_IP_MODE_IPV6 &&
- jConfig[KEY_PDP_CONTEXT_IPMODE].asString() != VALUE_PDP_CONTEXT_IP_MODE_IPV4V6) {
- printError("%s| The PDP context IP mode value is invalid [%s]", getName().c_str(), jConfig[KEY_PDP_CONTEXT_IPMODE].asString().c_str());
- return INVALID_ARGS;
- }
-
- // validate authentication fields only if it is present
- if (jConfig.isMember(KEY_PDP_CONTEXT_AUTH_TYPE)) {
-
- // check if the PDP context authentication is supported by the radio
- const auto& sRequested = jConfig[KEY_PDP_CONTEXT_AUTH_TYPE].asString();
- const auto& vSupported = getSupportedPdpContextAuthTypes();
-
- auto supportCheck = [sRequested](const std::string& sElement) {
- return sRequested == sElement;
- };
+ std::string sIpMode;
- if (std::none_of(vSupported.begin(), vSupported.end(), supportCheck)) {
- printError("%s| PDP context parameters: authentication type [%s] is not supported", getName().c_str(), jConfig[KEY_PDP_CONTEXT_AUTH_TYPE].asString().c_str());
- return INVALID_ARGS;
+ if (jConfig.isMember(ICellularRadio::KEY_PDP_CONTEXT_IPMODE)) {
+ if (jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE] == "IP" || jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE] == "PPP" ||
+ jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE] == "IPV6" || jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE] == "IPV4V6") {
+ sIpMode = jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE].asString();
+ } else {
+ printError("%s| Invalid IP Mode defined: [%s]", getName().c_str(), jConfig[ICellularRadio::KEY_PDP_CONTEXT_IPMODE].asString().c_str());
+ return FAILURE;
}
+ } else if (jAllContexts.isMember(sId)) {
+ printInfo("%s| Re-using IP Mode [%s] for PDP context [%s]", getName().c_str(), jAllContexts[sId][ICellularRadio::KEY_PDP_CONTEXT_IPMODE].asString().c_str(), sId.c_str());
+ sIpMode = jAllContexts[sId][ICellularRadio::KEY_PDP_CONTEXT_IPMODE].asString();
+ } else {
+ printError("%s| Failed to edit PDP context [%s] - no such context defined", getName().c_str(), sId.c_str());
+ return FAILURE;
}
- if (! jConfig.isMember(KEY_PDP_CONTEXT_AUTH_TYPE) && (jConfig.isMember(KEY_PDP_CONTEXT_AUTH_USERNAME) || jConfig.isMember(KEY_PDP_CONTEXT_AUTH_PASSWORD))) {
- printError("%s| PDP context authentication type is not provided, but username or password are given", getName().c_str());
- return INVALID_ARGS;
- }
-
- if (jConfig.isMember(KEY_PDP_CONTEXT_AUTH_TYPE) && jConfig[KEY_PDP_CONTEXT_AUTH_TYPE].asString() != VALUE_PDP_CONTEXT_AUTH_TYPE_NONE &&
- ! (jConfig.isMember(KEY_PDP_CONTEXT_AUTH_USERNAME) && jConfig.isMember(KEY_PDP_CONTEXT_AUTH_PASSWORD))) {
- printError("%s| PDP context authentication type [%s]. The username or password are not provided", getName().c_str(), jConfig[KEY_PDP_CONTEXT_AUTH_TYPE].asString().c_str());
- return INVALID_ARGS;
- }
-
- // fills with empty string if there are no such fields
- pdpContextResult.sId = jConfig[KEY_PDP_CONTEXT_ID].asString();
- pdpContextResult.sIpMode = jConfig[KEY_PDP_CONTEXT_IPMODE].asString();
- pdpContextResult.sApn = jConfig[KEY_PDP_CONTEXT_APN].asString();
- pdpContextResult.sAuthType = jConfig[KEY_PDP_CONTEXT_AUTH_TYPE].asString();
- pdpContextResult.sUsername = jConfig[KEY_PDP_CONTEXT_AUTH_USERNAME].asString();
- pdpContextResult.sPassword = jConfig[KEY_PDP_CONTEXT_AUTH_PASSWORD].asString();
-
- return SUCCESS;
-}
-
-ICellularRadio::CODE CellularRadio::isPdpContextAuthEditRequired(const Json::Value& jConfig, bool& bIsAuthEditRequired) {
- bIsAuthEditRequired = false;
-
- if (jConfig.isMember(KEY_PDP_CONTEXT_AUTH_TYPE) ||
- jConfig.isMember(KEY_PDP_CONTEXT_AUTH_PASSWORD) ||
- jConfig.isMember(KEY_PDP_CONTEXT_AUTH_USERNAME)) {
- bIsAuthEditRequired = true;
- }
-
- return SUCCESS;
-}
-
-ICellularRadio::CODE CellularRadio::setPdpContextBase(const PdpContextInfo& pdpContext) {
- std::string sCommand = "AT+CGDCONT=";
- const int dTimeout = 1000;
-
- sCommand += pdpContext.sId;
sCommand += ",\"";
- sCommand += pdpContext.sIpMode;
- sCommand += "\",\"";
- sCommand += pdpContext.sApn;
+ sCommand += sIpMode;
sCommand += "\"";
- return sendBasicCommand(sCommand, dTimeout);
-}
-
-ICellularRadio::CODE CellularRadio::deletePdpContext(const std::string& sId) {
- std::string sCommand = "AT+CGDCONT=" + sId;
- const int dTimeout = 1000;
-
- return sendBasicCommand(sCommand, dTimeout);
-}
-
-ICellularRadio::CODE CellularRadio::setPdpContext(const std::string& sId, const Json::Value& jConfig) {
- printTrace("%s| Setting PDP context [%s] to the radio", getName().c_str(), sId.c_str());
-
- CODE rc;
- Json::Value jCurrentContexts;
- bool bPdpAuthSupported;
- bool bPdpAuthEditRequired;
- PdpContextInfo pdpContext;
-
- if (sId.empty()) {
- printError("%s| PDP Context ID is not specified", getName().c_str());
- return INVALID_ARGS;
- }
-
- rc = getPdpContexts(jCurrentContexts);
- if (SUCCESS != rc) {
- return rc;
- }
+ std::string sApn;
- // DELETE context
-
- if (jConfig.empty()) {
- rc = deletePdpContext(sId);
- if (SUCCESS != rc) {
- printError("%s| Failed to delete PDP context [%s]", getName().c_str(), sId.c_str());
- }
- return rc;
- }
-
- // ADD or EDIT context
-
- // check if PDP context authentication is applicable
-
- (void) isPdpContextAuthEditRequired(jConfig, bPdpAuthEditRequired);
-
- rc = isPdpContextAuthSupported(bPdpAuthSupported);
- if (SUCCESS != rc) {
- return rc;
- }
-
- if (! bPdpAuthSupported && bPdpAuthEditRequired) {
- printError("%s| PDP context authentication is not supported by this radio, but arguments are provided", getName().c_str());
- return INVALID_ARGS;
- }
-
- Json::Value jResult;
-
- // Edit - fetch missing arguments from the current state.
- (void) mergePdpContexts(sId, jCurrentContexts[sId], jConfig, jResult);
-
- // validate fields and create a PDP context structure to use in the commands
- rc = initPdpContextInfo(jResult, pdpContext);
- if (SUCCESS != rc) {
- return rc;
+ if (jConfig.isMember(ICellularRadio::KEY_PDP_CONTEXT_APN)) {
+ sApn = jConfig[ICellularRadio::KEY_PDP_CONTEXT_APN].asString();
+ } else if (jAllContexts.isMember(sId)) {
+ printInfo("%s| Re-using APN [%s] for PDP context [%s]", getName().c_str(), jAllContexts[sId][ICellularRadio::KEY_PDP_CONTEXT_APN].asString().c_str(), sId.c_str());
+ sApn = jAllContexts[sId][ICellularRadio::KEY_PDP_CONTEXT_APN].asString();
+ } else {
+ printError("%s| Failed to edit PDP context [%s] - no such context defined", getName().c_str(), sId.c_str());
+ return FAILURE;
}
- // setting context
- rc = setPdpContextBase(pdpContext);
- if (SUCCESS != rc) {
- return rc;
- }
+ sCommand += ",\"";
+ sCommand += sApn;
+ sCommand += "\"";
- if (bPdpAuthSupported && bPdpAuthEditRequired) {
- return setPdpContextAuth(pdpContext);
- }
+ rc = sendBasicCommand(sCommand, dTimeout);
- return SUCCESS;
+ return rc;
}
ICellularRadio::CODE CellularRadio::getDiagnostics(std::string& sReport) {
diff --git a/src/MTS_IO_ICellularRadio.cpp b/src/MTS_IO_ICellularRadio.cpp
index f93cb21..e42713d 100644
--- a/src/MTS_IO_ICellularRadio.cpp
+++ b/src/MTS_IO_ICellularRadio.cpp
@@ -97,19 +97,8 @@ const char *MTS::IO::ICellularRadio::KEY_MIP_REVTUN = "revTun";
const char *MTS::IO::ICellularRadio::KEY_MIP_MNAAASS = "mnAaaSs"; //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret
const char *MTS::IO::ICellularRadio::KEY_MIP_MNHASS = "mnHaSs"; //!< Mobile Node Home Agent Shared Secret
-const char *MTS::IO::ICellularRadio::KEY_PDP_CONTEXT_ID = "id";
const char *MTS::IO::ICellularRadio::KEY_PDP_CONTEXT_APN = "apn";
const char *MTS::IO::ICellularRadio::KEY_PDP_CONTEXT_IPMODE = "ipMode";
-const char *MTS::IO::ICellularRadio::KEY_PDP_CONTEXT_AUTH_TYPE = "authType";
-const char *MTS::IO::ICellularRadio::KEY_PDP_CONTEXT_AUTH_USERNAME = "username";
-const char *MTS::IO::ICellularRadio::KEY_PDP_CONTEXT_AUTH_PASSWORD = "password";
-const char *MTS::IO::ICellularRadio::VALUE_PDP_CONTEXT_IP_MODE_IP = "IP";
-const char *MTS::IO::ICellularRadio::VALUE_PDP_CONTEXT_IP_MODE_IPV6 = "IPV6";
-const char *MTS::IO::ICellularRadio::VALUE_PDP_CONTEXT_IP_MODE_IPV4V6 = "IPV4V6";
-const char *MTS::IO::ICellularRadio::VALUE_PDP_CONTEXT_AUTH_TYPE_NONE = "NONE";
-const char *MTS::IO::ICellularRadio::VALUE_PDP_CONTEXT_AUTH_TYPE_PAP = "PAP";
-const char *MTS::IO::ICellularRadio::VALUE_PDP_CONTEXT_AUTH_TYPE_CHAP = "CHAP";
-const char *MTS::IO::ICellularRadio::VALUE_PDP_CONTEXT_AUTH_TYPE_PAP_CHAP = "PAP-CHAP";
const char *MTS::IO::ICellularRadio::VALUE_TYPE_GSM = "GSM";
const char *MTS::IO::ICellularRadio::VALUE_TYPE_LTE = "LTE";
diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp
index b01bbb1..655fb38 100644
--- a/src/MTS_IO_QuectelRadio.cpp
+++ b/src/MTS_IO_QuectelRadio.cpp
@@ -1629,114 +1629,6 @@ ICellularRadio::CODE QuectelRadio::setRxDiversity(const Json::Value& jArgs) {
return SUCCESS;
}
-ICellularRadio::CODE QuectelRadio::convertStringToPdpContextType(const std::string& sStringType, std::string& sIntType) {
- CODE rc = FAILURE;
-
- if ("IP" == sStringType) {
- sIntType = "1";
- rc = SUCCESS;
- } else if ("IPV6" == sStringType) {
- sIntType = "2";
- rc = SUCCESS;
- } else if ("IPV4V6" == sStringType) {
- sIntType = "3";
- rc = SUCCESS;
- }
-
- return rc;
-}
-
-std::vector<std::string> QuectelRadio::getSupportedPdpContextAuthTypes() const {
- return {
- VALUE_PDP_CONTEXT_AUTH_TYPE_NONE,
- VALUE_PDP_CONTEXT_AUTH_TYPE_PAP,
- VALUE_PDP_CONTEXT_AUTH_TYPE_CHAP,
- VALUE_PDP_CONTEXT_AUTH_TYPE_PAP_CHAP
- };
-}
-
-ICellularRadio::CODE QuectelRadio::isPdpContextAuthSupported(bool& isSupported) {
- std::string sCmd("AT+QICSGP=?");
- return isCommandSupported(sCmd, isSupported);
-}
-
-ICellularRadio::CODE QuectelRadio::fillPdpContextAuthFields(Json::Value& jData) {
- CODE rc;
- std::string sCmd("AT+QICSGP=");
- std::string sResult;
- uint8_t iValue;
-
- // iterate over PDP contex IDs to get context settings
- for (std::string & sContextId : jData.getMemberNames()) {
- // +QICSGP: <context_type>,<APN>,<username>,<password>,<authentication>
- // +QICSGP: 0,"","","",0 -- if the context does not exist
-
- rc = sendBasicQuery(sCmd+sContextId, "+QICSGP:", sResult, 300);
-
- if (SUCCESS != rc) {
- return rc;
- }
-
- // 1,"test","login","password",1
- // [0] [1] [2] [3] [4]
- auto vAuthParams = MTS::Text::split(sResult, ",");
-
- if (vAuthParams.size() < 5) {
- printError("%s| Failed to parse PDP context authentication string [%s]", getName().c_str(), sResult.c_str());
- return FAILURE;
- }
-
- if (! MTS::Text::parse(iValue, vAuthParams[4])) {
- printError("%s| Failed to parse PDP context authentication type [%s]", getName().c_str(), vAuthParams[4].c_str());
- return FAILURE;
- }
-
- rc = convertPdpContextAuthTypeToString(static_cast<PDP_CONTEXT_AUTH_TYPE>(iValue), sResult);
- if (SUCCESS != rc) {
- return rc;
- }
-
- jData[sContextId][KEY_PDP_CONTEXT_AUTH_TYPE] = sResult;
-
- if (iValue != PDP_CONTEXT_AUTH_TYPE::NONE) {
- jData[sContextId][KEY_PDP_CONTEXT_AUTH_USERNAME] = MTS::Text::trim(vAuthParams[2], '"');
- jData[sContextId][KEY_PDP_CONTEXT_AUTH_PASSWORD] = MTS::Text::trim(vAuthParams[3], '"');
- }
- }
-
- return SUCCESS;
-}
-
-// AT+QICSGP=<contextID>[,<context_type>,<APN>[,<username>,<password>)[,<authentication>[,<cdma_pwd>]]]]
-ICellularRadio::CODE QuectelRadio::setPdpContextAuth(const PdpContextInfo& pdpContext) {
- printTrace("%s| Setting PDP context authentication to the radio", getName().c_str());
-
- CODE rc;
- std::string sContextType;
- std::string sCmd = "AT+QICSGP=";
- PDP_CONTEXT_AUTH_TYPE eAuthType;
-
- rc = convertStringToPdpContextType(pdpContext.sIpMode, sContextType);
- if (SUCCESS != rc) {
- return rc;
- }
-
- rc = convertStringToPdpContextAuthType(pdpContext.sAuthType, eAuthType);
- if (SUCCESS != rc) {
- return rc;
- }
-
- sCmd += pdpContext.sId + "," + sContextType + ",\"" + pdpContext.sApn + "\"";
-
- if (PDP_CONTEXT_AUTH_TYPE::NONE == eAuthType) {
- sCmd += ",\"\",\"\"," + std::to_string(eAuthType);
- } else {
- sCmd += ",\"" + pdpContext.sUsername + "\",\"" + pdpContext.sPassword +"\"," + std::to_string(eAuthType);
- }
-
- return sendBasicCommand(sCmd);
-}
-
const std::vector<std::string>& QuectelRadio::getDiagCommands(bool) {
// Declare as static to initialize only when used, but cache the results.
const static std::vector<std::string> vCommands {
@@ -1783,3 +1675,28 @@ const std::vector<std::string>& QuectelRadio::getDiagCommands(bool) {
return vCommands;
}
+
+ICellularRadio::CODE QuectelRadio::getTimeUTC(void) {
+ printTrace("%s| Get Time in UTC", getName().c_str());
+
+ // Set year format in YYYY first, in case it is in YY format to get accurate year
+ std::string sCmdCSDF("AT+CSDF=1,2");
+ std::string sRes = sendCommand(sCmdCSDF);
+ size_t endr = sRes.find(ICellularRadio::RSP_OK);
+
+ if (endr == std::string::npos) {
+ printWarning("%s| Unable to set year format for radio using command [%s]", getName().c_str(), sCmdCSDF.c_str());
+ return FAILURE;
+ }
+
+ // Set command enables/disables the automatic time zone update
+ std::string sCmdCTZU("AT+CTZU=1");
+ sRes = sendCommand(sCmdCTZU);
+ size_t endc = sRes.find(ICellularRadio::RSP_OK);
+
+ if (endc == std::string::npos) {
+ printWarning("%s| Unable to set automatic time zone update for radio using command [%s]", getName().c_str(), sCmdCTZU.c_str());
+ return FAILURE;
+ }
+ return SUCCESS;
+} \ No newline at end of file
diff --git a/src/MTS_IO_SequansRadio.cpp b/src/MTS_IO_SequansRadio.cpp
index 380dd80..33bd068 100644
--- a/src/MTS_IO_SequansRadio.cpp
+++ b/src/MTS_IO_SequansRadio.cpp
@@ -282,6 +282,7 @@ ICellularRadio::CODE SequansRadio::getNetworkStatusTxPower(Json::Value& jData, J
std::string sResult;
std::string sPrefix;
std::vector<std::string> vParts;
+ int iValue;
CODE rc;
sCmd = "AT+SQNQRUP?";
@@ -311,7 +312,7 @@ ICellularRadio::CODE SequansRadio::getNetworkStatusTxPower(Json::Value& jData, J
break; // invalid, not known or not detectable
}
if (fTxPow < -255 || fTxPow > 99) {
- printDebug("%s| Network Status command returned unexpected value of txPower: [%s][%f]", getName().c_str(), sCmd.c_str(), fTxPow);
+ printDebug("%s| Network Status command returned unexpected value of txPower: [%s][%d]", getName().c_str(), sCmd.c_str(), iValue);
break;
}
jDebug[ICellularRadio::KEY_TXPWR] = vParts[0];
@@ -533,27 +534,6 @@ ICellularRadio::CODE SequansRadio::getSimLockAttemptsByType(const std::string& s
return SUCCESS;
}
-std::vector<std::string> SequansRadio::getSupportedPdpContextAuthTypes() const {
- return {
- VALUE_PDP_CONTEXT_AUTH_TYPE_NONE,
- VALUE_PDP_CONTEXT_AUTH_TYPE_PAP,
- VALUE_PDP_CONTEXT_AUTH_TYPE_CHAP
- };
-}
-
-ICellularRadio::CODE SequansRadio::isPdpContextAuthSupported(bool& isSupported) {
- isSupported = false;
- return SUCCESS;
-}
-
-ICellularRadio::CODE SequansRadio::fillPdpContextAuthFields(Json::Value& jData) {
- return NOT_APPLICABLE;
-}
-
-ICellularRadio::CODE SequansRadio::setPdpContextAuth(const PdpContextInfo& pdpContext) {
- return NOT_APPLICABLE;
-}
-
const std::vector<std::string>& SequansRadio::getDiagCommands(bool) {
// Declare as static to initialize only when used, but cache the results.
const static std::vector<std::string> vCommands {
@@ -588,3 +568,28 @@ const std::vector<std::string>& SequansRadio::getDiagCommands(bool) {
return vCommands;
}
+
+ICellularRadio::CODE SequansRadio::getTimeUTC(void) {
+ printTrace("%s| Get Time in UTC", getName().c_str());
+
+ // Set year format in YYYY first, in case it is in YY format to get accurate year
+ std::string sCmdCSDF("AT+CSDF=1,2");
+ std::string sRes = sendCommand(sCmdCSDF);
+ size_t endr = sRes.find(ICellularRadio::RSP_OK);
+
+ if (endr == std::string::npos) {
+ printWarning("%s| Unable to set year format for radio using command [%s]", getName().c_str(), sCmdCSDF.c_str());
+ return FAILURE;
+ }
+
+ // Set year format in YYYY first, in case it is in YY format to get accurate year
+ std::string sCmdCTZU("AT+CTZU=1");
+ sRes = sendCommand(sCmdCTZU);
+ size_t endc = sRes.find(ICellularRadio::RSP_OK);
+
+ if (endc == std::string::npos) {
+ printWarning("%s| Unable to set automatic time zone update for radio using command [%s]", getName().c_str(), sCmdCTZU.c_str());
+ return FAILURE;
+ }
+ return SUCCESS;
+} \ No newline at end of file
diff --git a/src/MTS_IO_TelitRadio.cpp b/src/MTS_IO_TelitRadio.cpp
index 00c1686..2c50208 100644
--- a/src/MTS_IO_TelitRadio.cpp
+++ b/src/MTS_IO_TelitRadio.cpp
@@ -1178,109 +1178,6 @@ bool MTS::IO::TelitRadio::isContainsSignChar(const std::string& str) {
return true;
}
-std::vector<std::string> TelitRadio::getSupportedPdpContextAuthTypes() const {
- return {
- VALUE_PDP_CONTEXT_AUTH_TYPE_NONE,
- VALUE_PDP_CONTEXT_AUTH_TYPE_PAP,
- VALUE_PDP_CONTEXT_AUTH_TYPE_CHAP
- };
-}
-
-ICellularRadio::CODE TelitRadio::isPdpContextAuthSupported(bool& isSupported) {
- std::string sCmd("AT#PDPAUTH=?");
- return isCommandSupported(sCmd, isSupported);
-}
-
-ICellularRadio::CODE TelitRadio::fillPdpContextAuthFields(Json::Value& jData) {
- CODE rc;
- std::string sCmd("AT#PDPAUTH?");
- std::string sResult;
-
- // #PDPAUTH: 1,0
- // #PDPAUTH: 2,0
- // #PDPAUTH: 3,0
- // #PDPAUTH: 4,1,"admin"
- rc = sendBasicQuery(sCmd, "", sResult, 300);
-
- if (SUCCESS != rc) {
- return rc;
- }
-
- std::vector<std::string> vContexts = MTS::Text::split(sResult, "#PDPAUTH:");
- std::string sContextId;
-
- for (std::string& sLine : vContexts) {
- sLine = MTS::Text::trim(sLine);
-
- if (sLine.empty()) {
- continue;
- }
-
- // 4,1,"admin"
- // [0][1] [2]
- auto vAuthParams = MTS::Text::split(sLine, ",");
-
- // Contains 2 elements when the authentication type is NONE, contains 3 elements in other cases
- if (vAuthParams.size() < 2) {
- printError("%s| Failed to parse PDP context authentication string [%s]", getName().c_str(), sLine.c_str());
- return FAILURE;
- }
-
- sContextId = vAuthParams[0];
-
- uint8_t iValue;
- if (! MTS::Text::parse(iValue, vAuthParams[1])) {
- printError("%s| Failed to parse PDP context authentication type [%s]", getName().c_str(), vAuthParams[1].c_str());
- return FAILURE;
- }
-
- rc = convertPdpContextAuthTypeToString(static_cast<PDP_CONTEXT_AUTH_TYPE>(iValue), sResult);
- if (SUCCESS != rc) {
- printError("%s| Failed to convert PDP context authentication type to string [%d]", getName().c_str(), iValue);
- return rc;
- }
-
- jData[sContextId][KEY_PDP_CONTEXT_AUTH_TYPE] = sResult;
-
- if (iValue == PDP_CONTEXT_AUTH_TYPE::NONE) {
- continue;
- }
-
- if (vAuthParams.size() < 3) {
- printError("%s| Failed to parse PDP context authentication string [%s]", getName().c_str(), sLine.c_str());
- return FAILURE;
- }
-
- jData[sContextId][KEY_PDP_CONTEXT_AUTH_USERNAME] = MTS::Text::trim(vAuthParams[2], '"');
- }
-
- return SUCCESS;
-}
-
-ICellularRadio::CODE TelitRadio::setPdpContextAuth(const PdpContextInfo& pdpContext) {
- printTrace("%s| Setting PDP context authentication to the radio", getName().c_str());
-
- CODE rc;
- std::string sCmd = "AT#PDPAUTH=";
- PDP_CONTEXT_AUTH_TYPE eAuthType;
-
- sCmd += pdpContext.sId + ",";
-
- rc = convertStringToPdpContextAuthType(pdpContext.sAuthType, eAuthType);
-
- if (SUCCESS != rc) {
- return rc;
- }
-
- sCmd += std::to_string(eAuthType);
-
- if (PDP_CONTEXT_AUTH_TYPE::NONE != eAuthType) {
- sCmd += "," + pdpContext.sUsername + "," + pdpContext.sPassword;
- }
-
- return sendBasicCommand(sCmd);
-}
-
const std::vector<std::string>& TelitRadio::getDiagCommands(bool) {
// Declare as static to initialize only when used, but cache the results.
const static std::vector<std::string> vCommands {
@@ -1315,3 +1212,39 @@ const std::vector<std::string>& TelitRadio::getDiagCommands(bool) {
return vCommands;
}
+
+ICellularRadio::CODE TelitRadio::getTimeUTC(void) {
+ printTrace("%s| Get Time in UTC", getName().c_str());
+
+ // Set year format in YYYY first, in case it is in YY format to get accurate year
+ std::string sCmdCSDF("AT+CSDF=1,2");
+ std::string sRes = sendCommand(sCmdCSDF);
+ size_t endr = sRes.find(ICellularRadio::RSP_OK);
+
+ if (endr == std::string::npos) {
+ printWarning("%s| Unable to set year format for radio using command [%s]", getName().c_str(), sCmdCSDF.c_str());
+ return FAILURE;
+ }
+
+ // Set command enables/disables the automatic time zone update via NITZ.
+ std::string sCmdCTZU("AT+CTZU=1");
+ sRes = sendCommand(sCmdCTZU);
+ size_t endc = sRes.find(ICellularRadio::RSP_OK);
+
+ if (endc == std::string::npos) {
+ printWarning("%s| Unable to set year format for radio using command [%s]", getName().c_str(), sCmdCTZU.c_str());
+ return FAILURE;
+ }
+
+ //Enables/disables the automatic date/time updating and the
+ //Full Network Name applying. It enables also the #NITZ URC in the format.
+ std::string sCmdNITZ("AT#NITZ");
+ sRes = sendCommand(sCmdNITZ);
+ size_t endn = sRes.find(ICellularRadio::RSP_OK);
+
+ if (endn == std::string::npos) {
+ printWarning("%s| Unable to set automatic time zone update for radio using command [%s]", getName().c_str(), sCmdNITZ.c_str());
+ return FAILURE;
+ }
+ return SUCCESS;
+} \ No newline at end of file