diff options
| -rw-r--r-- | include/mts/MTS_IO_QuectelRadio.h | 3 | ||||
| -rw-r--r-- | src/MTS_IO_QuectelRadio.cpp | 49 | 
2 files changed, 48 insertions, 4 deletions
| diff --git a/include/mts/MTS_IO_QuectelRadio.h b/include/mts/MTS_IO_QuectelRadio.h index 58e3d25..0f24db8 100644 --- a/include/mts/MTS_IO_QuectelRadio.h +++ b/include/mts/MTS_IO_QuectelRadio.h @@ -86,6 +86,9 @@ namespace MTS {                  CODE fumoWaitUpgradeFinished(UpdateCb& stepCb);                  CODE fumoWaitNewFirmware(UpdateCb& stepCb); +                /// Parse error code in early FUMO URC result received before the first attempt to flash the firmware +                std::string getFumoEarlyErrorCode(const std::string& sRadioInput); +                  /// Get value from container by its index, use default value if not found. Non-template version.                  const std::string& getByIndex(const std::vector<std::string>& vector, size_t index, const std::string& defaultValue) {                      if (index >= vector.size()) { diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp index 601674b..7d205e7 100644 --- a/src/MTS_IO_QuectelRadio.cpp +++ b/src/MTS_IO_QuectelRadio.cpp @@ -608,8 +608,12 @@ ICellularRadio::CODE QuectelRadio::fumoLocalCleanup() {  }  ICellularRadio::CODE QuectelRadio::fumoLocalApply(ICellularRadio::UpdateCb& stepCb) { +    const std::string sFotaUrcPrefix = "+QIND: \"FOTA\"";  // prefix for URC notification messages +    const std::vector<std::string> vFotaBailStrings{ sFotaUrcPrefix }; +      ICellularRadio::CODE rc;      std::string sCmd; +    std::string sResponse;      rc = getVendorFirmware(m_sQuectelFirmware);      if (rc != SUCCESS) { @@ -631,8 +635,8 @@ ICellularRadio::CODE QuectelRadio::fumoLocalApply(ICellularRadio::UpdateCb& step          return rc;      } -    const uint32_t duDetachTimeout = 10000;  // wait for 10 seconds for the radio to detach -    const uint32_t duAttachTimeout = 30000;  // wait for 30 seconds for the radio to attach +    const uint32_t duDetachTimeout = 15000;  // wait up to 15 seconds for the radio to detach +    const uint32_t duAttachTimeout = 30000;  // wait up to 30 seconds for the radio to attach      const int dMaxAttempts = 5;  // the radio makes 5 attempts to update the firmware      for (int i = 0; i < dMaxAttempts; i++) { @@ -640,8 +644,22 @@ ICellularRadio::CODE QuectelRadio::fumoLocalApply(ICellularRadio::UpdateCb& step          printInfo("Waiting for the radio to enter recovery mode");          callNextStep(stepCb, "FUMO Info: waiting for the radio to enter recovery mode"); -        // Wait for the radio to detach from the USB bus -        MTS::Thread::sleep(duDetachTimeout); +        // Wait for new FOTA responses. Exits preliminary if radio detached. +        sResponse = sendCommand("", vFotaBailStrings, duDetachTimeout, 0x00); +        printTrace("Radio response: [%s]", sResponse.c_str()); + +        if (i == 0 && sResponse.find(sFotaUrcPrefix) != std::string::npos) { +            // FOTA responce code received before radio detach, image can't be applied. +            // EG25-G radio prints a message in +QIND: "FOTA",ERR_CODE format in this case. +            std::string sErrorCode = getFumoEarlyErrorCode(sResponse); + +            printError("Preliminary termination of FUMO procedure: [%s]", sErrorCode.c_str()); +            callNextStep(stepCb, "FUMO Error: radio returned error code " + sErrorCode); + +            // We got a response from the radio but FOTA failed +            rc = FAILURE; +            break; +        }          // It's now detached. Try to reconnect          if (!resetConnection(duAttachTimeout)) { @@ -1116,6 +1134,29 @@ ICellularRadio::CODE QuectelRadio::fumoWaitNewFirmware(ICellularRadio::UpdateCb&      return rc;  } +std::string QuectelRadio::getFumoEarlyErrorCode(const std::string& sRadioInput) { +    const std::string sFotaPrefix = "+QIND: \"FOTA\","; +    const char cLineEnd = ICellularRadio::CR; + +    // sRadioInput may contain several lines. We need to find the line with '+QIND: "FOTA",' in it +    auto pLineStart = sRadioInput.find(sFotaPrefix); + +    if (pLineStart == std::string::npos) { +        // FOTA line not found at all +        return "-1"; +    } + +    // Parse the error code +    auto pErrorStart = pLineStart + sFotaPrefix.length(); +    auto pLineEnd = sRadioInput.find(cLineEnd, pErrorStart); + +    // Filter the error code +    std::string sSubString = sRadioInput.substr(pErrorStart, pLineEnd - pErrorStart); +    std::string sResult = MTS::Text::trim(sSubString); + +    return sResult; +} +  ICellularRadio::CODE QuectelRadio::startFileUpload(const std::string& sTargetFilename, size_t nBytes) {      const std::vector<std::string> vBailStrings{ ICellularRadio::RSP_CONNECT, ICellularRadio::RSP_ERROR };      const int dTimeout = 1000; //ms | 
