From 050834e3cdd0f5f56ba15b09ca568ac6312c7699 Mon Sep 17 00:00:00 2001 From: sdesai Date: Wed, 15 Mar 2023 15:22:04 -0500 Subject: GP-139:Support Portal Case #5086148: use Cellular Radio timeas alternative to GPS or NTP --- include/mts/MTS_IO_ICellularRadio.h | 2 +- include/mts/MTS_IO_QuectelRadio.h | 2 +- include/mts/MTS_IO_SequansRadio.h | 2 +- include/mts/MTS_IO_TelitRadio.h | 2 +- src/MTS_IO_CellularRadio.cpp | 57 ++++++++++++++++++++++++++++++------- src/MTS_IO_QuectelRadio.cpp | 25 ++++++++++++++++ src/MTS_IO_SequansRadio.cpp | 25 ++++++++++++++++ src/MTS_IO_TelitRadio.cpp | 36 +++++++++++++++++++++++ 8 files changed, 137 insertions(+), 14 deletions(-) diff --git a/include/mts/MTS_IO_ICellularRadio.h b/include/mts/MTS_IO_ICellularRadio.h index 0523236..da8e130 100644 --- a/include/mts/MTS_IO_ICellularRadio.h +++ b/include/mts/MTS_IO_ICellularRadio.h @@ -717,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 4315cb3..7015acb 100644 --- a/include/mts/MTS_IO_QuectelRadio.h +++ b/include/mts/MTS_IO_QuectelRadio.h @@ -86,7 +86,7 @@ namespace MTS { CODE setRxDiversity(const Json::Value& jArgs) override; const std::vector& 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 11f2c91..d61ae67 100644 --- a/include/mts/MTS_IO_SequansRadio.h +++ b/include/mts/MTS_IO_SequansRadio.h @@ -49,7 +49,7 @@ namespace MTS { CODE setRxDiversity(const Json::Value& jArgs) override; const std::vector getRegistrationCommands() override; - + CODE getTimeUTC(void) override; protected: SequansRadio(const std::string& sName, const std::string& sRadioPort); diff --git a/include/mts/MTS_IO_TelitRadio.h b/include/mts/MTS_IO_TelitRadio.h index d198969..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); diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index 1c385ae..8cdaf44 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -577,6 +577,13 @@ ICellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTi sDate = ""; sTime = ""; sTimeZone = ""; + std::vector 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); @@ -588,7 +595,7 @@ ICellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTi } 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,26 +606,56 @@ ICellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTi return FAILURE; } - std::vector 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; } - // Append "20" to the year. format is YYYY-MM-DD - sDate = "20" + vDateParts[0] + "-" + vDateParts[1] + "-" + vDateParts[2]; + // The format is YYYY-MM-DD + sDate = vDateParts[0] + "-" + vDateParts[1] + "-" + vDateParts[2]; + + 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 = "-"; + } - vParts = MTS::Text::split(vParts[1], '-'); - if(vParts.size() != 1) { - printWarning("%s| Unable to parse Time 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; } - sTime = vParts[0]; + + //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 + + if (iZonePartial < 0) { + //Remove negative sign from partial and clear sign component + iZonePartial *= -1; + sSign = ""; + } + std::stringstream ss; + ss << sSign << iZone; + if(iZonePartial != 0) { + ss << ":" << iZonePartial; + } + + sTimeZone = ss.str(); 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; diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp index 0c0c8ab..655fb38 100644 --- a/src/MTS_IO_QuectelRadio.cpp +++ b/src/MTS_IO_QuectelRadio.cpp @@ -1675,3 +1675,28 @@ const std::vector& 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 a48a309..33bd068 100644 --- a/src/MTS_IO_SequansRadio.cpp +++ b/src/MTS_IO_SequansRadio.cpp @@ -568,3 +568,28 @@ const std::vector& 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 21af65d..2c50208 100644 --- a/src/MTS_IO_TelitRadio.cpp +++ b/src/MTS_IO_TelitRadio.cpp @@ -1212,3 +1212,39 @@ const std::vector& 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 -- cgit v1.2.3