From cb4e2bf0e1902ef91fe10fe6e6aa9c91e04d7c90 Mon Sep 17 00:00:00 2001 From: Serhii Kostiuk Date: Thu, 23 Jul 2020 16:03:09 +0300 Subject: Quectel Delta Radio Firmware Upgrade support - libmts-io implementation During testing it was discovered that rarely CellularRadio::sendCommand implementation returns not one line with URC output but multiple lines. It happened once during testing and development. But is likely to happen again under increased CPU load and/or when CPU does not keep pace with the serial data flow. --- src/MTS_IO_QuectelRadio.cpp | 68 ++++++++++++++++++++++++++++++--------------- 1 file changed, 46 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp index 59170fe..8656973 100644 --- a/src/MTS_IO_QuectelRadio.cpp +++ b/src/MTS_IO_QuectelRadio.cpp @@ -1001,10 +1001,11 @@ ICellularRadio::CODE QuectelRadio::fumoWaitUpgradeFinished(ICellularRadio::Updat const std::string sFotaUrcEnd = "\"END\""; const std::vector vFotaBailStrings{ sFotaUrcPrefix }; + bool bFinished = false; CODE rc = FAILURE; std::string sResponse; - while (true) { // breaks on "FOTA","END" + while (!bFinished) { // breaks on "FOTA","END" sResponse = sendCommand("", vFotaBailStrings, duUrcTimeout, 0x00); printTrace("Radio response: [%s]", sResponse.c_str()); @@ -1015,31 +1016,54 @@ ICellularRadio::CODE QuectelRadio::fumoWaitUpgradeFinished(ICellularRadio::Updat break; } - const auto vParts = MTS::Text::split(MTS::Text::trim(sResponse), ',', 3); - const std::string& sStage = getByIndex(vParts, 1, "NOT_DEFINED"); + // Occasionally sendCommand returns multiple lines in one chunk. + // Handle each line separately for such cases. + const auto vLines = MTS::Text::split(sResponse, '\r'); - if (sStage == sFotaUrcEnd) { - // FOTA finished - printTrace("Got FOTA END message"); - const std::string& sCode = getByIndex(vParts, 2, "-1"); + for (const auto& sLine : vLines) { + const auto& sTrimmedLine = MTS::Text::trim(sLine); - if (sCode == "0") { - // finished successfully - rc = SUCCESS; + if (sTrimmedLine.empty()) { + // whitespace characters only, ignore + continue; + } + + printTrace("Processing line: [%s]", sTrimmedLine.c_str()); + + if (sTrimmedLine.find(sFotaUrcPrefix) == std::string::npos) { + printDebug("URC message not found, line skipped"); + continue; + } + + const auto vParts = MTS::Text::split(sTrimmedLine, ',', 3); + const std::string& sStage = getByIndex(vParts, 1, "NOT_DEFINED"); + + if (sStage == sFotaUrcEnd) { + // FOTA finished + printTrace("Got FOTA END message"); + const std::string& sCode = getByIndex(vParts, 2, "-1"); + + if (sCode == "0") { + // finished successfully + rc = SUCCESS; + bFinished = true; + break; + } + + // attempt failed, the radio attempts to recover + callNextStep(stepCb, "FUMO Error: radio returned error code " + sCode); + bFinished = true; break; + } else if (sStage == sFotaUrcStart) { + printTrace("Got FOTA START message"); + } else if (sStage == sFotaUrcProgress) { + printTrace("Got FOTA progress message"); + const std::string& sPercents = getByIndex(vParts, 2, "0"); + printInfo("FOTA progress: [%s]", sPercents.c_str()); + callNextStep(stepCb, "FUMO Info: firmware apply progress " + sPercents); + } else { + printInfo("FOTA unexpected URC code: [%s]", sLine.c_str()); } - // attempt failed, the radio attempts to recover - callNextStep(stepCb, "FUMO Error: radio returned error code " + sCode); - break; - } else if (sStage == sFotaUrcStart) { - printTrace("Got FOTA START message"); - } else if (sStage == sFotaUrcProgress) { - printTrace("Got FOTA progress message"); - const std::string& sPercents = getByIndex(vParts, 2, "0"); - printInfo("FOTA progress: [%s]", sPercents.c_str()); - callNextStep(stepCb, "FUMO Info: firmware apply progress " + sPercents); - } else { - printInfo("FOTA unexpected URC code: [%s]", sResponse.c_str()); } } -- cgit v1.2.3