diff options
| author | Serhii Kostiuk <serhii.o.kostiuk@globallogic.com> | 2020-07-03 17:59:47 +0300 | 
|---|---|---|
| committer | Serhii Kostiuk <serhii.o.kostiuk@globallogic.com> | 2020-07-03 18:17:10 +0300 | 
| commit | 2c3296b5239b5d27f5df4d61a9609ace6d70904f (patch) | |
| tree | bf2d5e5c9a897af56868f4a793943b302fc288cc | |
| parent | d1798ea6a82c46b43e4caf27148189f34cc44ca5 (diff) | |
| download | libmts-io-2c3296b5239b5d27f5df4d61a9609ace6d70904f.tar.gz libmts-io-2c3296b5239b5d27f5df4d61a9609ace6d70904f.tar.bz2 libmts-io-2c3296b5239b5d27f5df4d61a9609ace6d70904f.zip | |
Quectel Delta Radio Firmware Upgrade support - libmts-io implementation
Started code cleanup before finishing the procedure.
Renamed functions related to the delta radio firmware upgrade to follow
established patterns:
- uploadDeltaFirmwareFile -> fumoLocalInject
- applyDeltaFirmwareFile  -> fumoLocalApply
- removeDeltaFirmwareFile -> fumoLocalCleanup
- new function: updateFumoLocal - encapsulates all the magic for radios
  that may not support separate stages for the delta upload and delta apply
| -rw-r--r-- | include/mts/MTS_IO_CellularRadio.h | 7 | ||||
| -rw-r--r-- | include/mts/MTS_IO_ICellularRadio.h | 55 | ||||
| -rw-r--r-- | include/mts/MTS_IO_QuectelRadio.h | 12 | ||||
| -rw-r--r-- | src/MTS_IO_CellularRadio.cpp | 18 | ||||
| -rw-r--r-- | src/MTS_IO_QuectelRadio.cpp | 121 | 
5 files changed, 116 insertions, 97 deletions
| diff --git a/include/mts/MTS_IO_CellularRadio.h b/include/mts/MTS_IO_CellularRadio.h index e65e7cd..e3941c3 100644 --- a/include/mts/MTS_IO_CellularRadio.h +++ b/include/mts/MTS_IO_CellularRadio.h @@ -99,9 +99,10 @@ namespace MTS {                  CODE updateDc(const Json::Value& jArgs, UpdateCb& stepCb) override;                  CODE updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) override;                  CODE updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) override; -                CODE uploadDeltaFirmwareFile(int fd, UpdateCb& stepCb) override; -                CODE removeDeltaFirmwareFile() override; -                CODE applyDeltaFirmwareFile(UpdateCb& stepCb) override; +                CODE updateFumoLocal(int fd, UpdateCb& stepCb) override; +                CODE fumoLocalInject(int fd, UpdateCb& stepCb) override; +                CODE fumoLocalApply(UpdateCb& stepCb) override; +                CODE fumoLocalCleanup() override;                  CODE resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) override;                  CODE activate(const Json::Value& jArgs, UpdateCb& stepCb) override;                  CODE startOmaDm(UpdateCb& stepCb) override; diff --git a/include/mts/MTS_IO_ICellularRadio.h b/include/mts/MTS_IO_ICellularRadio.h index 3259041..e1edbcd 100644 --- a/include/mts/MTS_IO_ICellularRadio.h +++ b/include/mts/MTS_IO_ICellularRadio.h @@ -429,54 +429,69 @@ namespace MTS {                  virtual CODE updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) = 0;                  /** -                 * @brief uploadDeltaFirmwareFile - upload delta file to the radio's internal memory. +                 * @brief updateFumoLocal - Performs the radio firmware upgrade using local firmware image.                   * -                 * This command uploads (injects) the whole delta firmware image to some place that -                 * can be later used by the radio to perform the Delta Radio Firmware Upgrade. -                 * -                 * This delta firmware image is NOT validated on the firmware image upload step. +                 * This command uploads (injects) the whole delta firmware image to the radio, performs the +                 * upgrade and waits for it to complete.                   * -                 * @param fd - file sescriptor of a file that shall be uploaded to the radio. -                 * @param stepCb - the callback to receive status updates during the upload. -                 * @return CODE::SUCCESS when the file was successfully uploaded, +                 * @param fd - file descriptor of a file that shall be injected to the radio. +                 * @param stepCb - callback to receive status updates during the firmware upgrade. +                 * @return CODE::SUCCESS when the firmware upgrade was successful,                   *         CODE::INVALID_ARGS when the file can't be opened for reading, +                 *         CODE::FAILURE when upgrade failed on the radio side,                   *         CODE::NOT_APPLICABLE when not supported by this radio,                   *         CODE::ERROR otherwise.                   */ -                virtual CODE uploadDeltaFirmwareFile(int fd, UpdateCb& stepCb) = 0; +                virtual CODE updateFumoLocal(int fd, UpdateCb& stepCb) = 0;                  /** -                 * @brief removeDeltaFirmwareFile - remove the delta file from the radio's internal memory. +                 * @brief fumoLocalInject - upload delta file to the radio's internal memory.                   * -                 * This command allows to remove the old delta firmware image from the radio's internal -                 * memory for cases when it's no longer needed. +                 * This command uploads (injects) the whole delta firmware image to some place that +                 * can be later used by the radio to perform the Delta Radio Firmware Upgrade. +                 * +                 * This delta firmware image is NOT validated on the firmware image upload step.                   *                   * @param fd - file sescriptor of a file that shall be uploaded to the radio. -                 * @return CODE::SUCCESS when the file was successfully deleted, -                 *         CODE::FAILURE when the file can't be deleted (i.e. no such file), +                 * @param stepCb - callback to receive status updates during the upload. +                 * @return CODE::SUCCESS when the file was successfully uploaded, +                 *         CODE::INVALID_ARGS when the file can't be opened for reading,                   *         CODE::NOT_APPLICABLE when not supported by this radio,                   *         CODE::ERROR otherwise.                   */ -                virtual CODE removeDeltaFirmwareFile() = 0; +                virtual CODE fumoLocalInject(int fd, UpdateCb& stepCb) = 0;                  /** -                 * @brief applyDeltaFirmwareFile - apply the delta file that was previously uploaded. +                 * @brief fumoLocalApply - apply the delta file that was previously uploaded.                   *                   * This commands initializes and tracks the progress of the delta firmware upgrade                   * procedure using the delta firmware image file that was previously uploaded -                 * into internal radio's memory. +                 * into internal memory of the radio.                   * -                 * See ICellularRadio::removeDeltaFirmwareFile to upload the file and prepare +                 * See ICellularRadio::fumoLocalInject to upload the file and prepare                   * for the upgrade.                   * -                 * @param fd - file sescriptor of a file that shall be uploaded to the radio. +                 * @param fd - file descriptor of a file that shall be uploaded to the radio.                   * @param stepCb - the callback to receive status updates during the upgrade. +                 * @return CODE::SUCCESS when the firmware upgrade was successful, +                 *         CODE::FAILURE when upgrade failed on the radio side, +                 *         CODE::NOT_APPLICABLE when not supported by this radio, +                 *         CODE::ERROR otherwise. +                 */ +                virtual CODE fumoLocalApply(UpdateCb& stepCb) = 0; + +                /** +                 * @brief fumoLocalCleanup - remove the delta file from the radio's internal memory. +                 * +                 * This command allows to remove the old delta firmware image from the radio's internal +                 * memory for cases when it's no longer needed. +                 *                   * @return CODE::SUCCESS when the file was successfully deleted,                   *         CODE::FAILURE when the file can't be deleted (i.e. no such file),                   *         CODE::NOT_APPLICABLE when not supported by this radio,                   *         CODE::ERROR otherwise.                   */ -                virtual CODE applyDeltaFirmwareFile(UpdateCb& stepCb) = 0; +                virtual CODE fumoLocalCleanup() = 0;                  /*                   * jArgs = { diff --git a/include/mts/MTS_IO_QuectelRadio.h b/include/mts/MTS_IO_QuectelRadio.h index cb455d8..b805ed8 100644 --- a/include/mts/MTS_IO_QuectelRadio.h +++ b/include/mts/MTS_IO_QuectelRadio.h @@ -45,9 +45,10 @@ namespace MTS {                  CODE setCellularMode(CELLULAR_MODES networks) override; -                CODE uploadDeltaFirmwareFile(int fd, UpdateCb& stepCb) override; -                CODE removeDeltaFirmwareFile() override; -                CODE applyDeltaFirmwareFile(UpdateCb& stepCb) override; +                CODE updateFumoLocal(int fd, UpdateCb& stepCb) override; +                CODE fumoLocalInject(int fd, UpdateCb& stepCb) override; +                CODE fumoLocalCleanup() override; +                CODE fumoLocalApply(UpdateCb& stepCb) override;              protected:                  QuectelRadio(const std::string& sName, const std::string& sRadioPort); @@ -76,9 +77,8 @@ namespace MTS {                  static inline uint16_t bytesToUint16(uint8_t high, uint8_t low);                  static CODE getFileSize(int fd, size_t& nBytes, size_t& nFileChunks);                  static CODE readChunk(int fd, char* pChunk, size_t dChunkSize, size_t& nReadBytes); -                CODE waitApplyDeltaFirmware(UpdateCb& stepCb); -                CODE waitFotaFinish(UpdateCb& stepCb); -                CODE waitNewFirmware(UpdateCb& stepCb); +                CODE fumoWaitUpgradeFinished(UpdateCb& stepCb); +                CODE fumoWaitNewFirmware(UpdateCb& stepCb);          };      }  } diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index 55f719f..bb7cd40 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -1051,20 +1051,26 @@ ICellularRadio::CODE CellularRadio::updateFumo(const Json::Value&, UpdateCb&) {      return NOT_APPLICABLE;  } -ICellularRadio::CODE CellularRadio::uploadDeltaFirmwareFile(int, ICellularRadio::UpdateCb&) { -    printTrace("%s| Upload Delta Firmware Upgrade File: not applicable", m_sName.c_str()); +ICellularRadio::CODE CellularRadio::updateFumoLocal(int, ICellularRadio::UpdateCb&) { +    printTrace("%s| Update Local Firmware Update Management Object", m_sName.c_str());      return NOT_APPLICABLE;  } -ICellularRadio::CODE CellularRadio::removeDeltaFirmwareFile() { -    printTrace("%s| Remove Delta Firmware Upgrade File: not applicable", m_sName.c_str()); +ICellularRadio::CODE CellularRadio::fumoLocalInject(int, ICellularRadio::UpdateCb&) { +    printTrace("%s| Inject Delta Firmware Image File: not applicable", m_sName.c_str());      return NOT_APPLICABLE;  } -ICellularRadio::CODE CellularRadio::applyDeltaFirmwareFile(ICellularRadio::UpdateCb&) { -    printTrace("%s| Apply Delta Firmware Upgrade File: not applicable", m_sName.c_str()); +ICellularRadio::CODE CellularRadio::fumoLocalApply(ICellularRadio::UpdateCb&) { +    printTrace("%s| Apply Delta Firmware Image File: not applicable", m_sName.c_str()); + +    return NOT_APPLICABLE; +} + +ICellularRadio::CODE CellularRadio::fumoLocalCleanup() { +    printTrace("%s| Cleanup Delta Firmware Image File: not applicable", m_sName.c_str());      return NOT_APPLICABLE;  } diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp index 25d2a30..7b67431 100644 --- a/src/MTS_IO_QuectelRadio.cpp +++ b/src/MTS_IO_QuectelRadio.cpp @@ -540,7 +540,21 @@ ICellularRadio::CODE QuectelRadio::startOmaDm(ICellularRadio::UpdateCb& stepCb)      return eCode;  } -ICellularRadio::CODE QuectelRadio::uploadDeltaFirmwareFile(int fd, ICellularRadio::UpdateCb& stepCb) { +ICellularRadio::CODE QuectelRadio::updateFumoLocal(int fd, ICellularRadio::UpdateCb& stepCb) { +    CODE rc; + +    rc = fumoLocalInject(fd, stepCb); +    if (rc != SUCCESS) { +        return rc; +    } + +    rc = fumoLocalApply(stepCb); +    (void)fumoLocalCleanup();  // try to cleanup the injected file but cleanup errors are not fatal + +    return rc; +} + +ICellularRadio::CODE QuectelRadio::fumoLocalInject(int fd, ICellularRadio::UpdateCb& stepCb) {      CODE rc = FAILURE;      bool bIsFilePresent = false; @@ -552,7 +566,7 @@ ICellularRadio::CODE QuectelRadio::uploadDeltaFirmwareFile(int fd, ICellularRadi          }          if (bIsFilePresent) { -            rc = removeDeltaFirmwareFile(); +            rc = fumoLocalCleanup();          }          if (rc != SUCCESS) { @@ -571,16 +585,16 @@ ICellularRadio::CODE QuectelRadio::uploadDeltaFirmwareFile(int fd, ICellularRadi      return rc;  } -ICellularRadio::CODE QuectelRadio::removeDeltaFirmwareFile() { +ICellularRadio::CODE QuectelRadio::fumoLocalCleanup() {      printTrace("Removing the delta upgrade file: %s", VALUE_MTS_DELTA_NAME.c_str());      return removeFile(VALUE_MTS_DELTA_NAME);  } -ICellularRadio::CODE QuectelRadio::applyDeltaFirmwareFile(ICellularRadio::UpdateCb& stepCb) { +ICellularRadio::CODE QuectelRadio::fumoLocalApply(ICellularRadio::UpdateCb& stepCb) {      ICellularRadio::CODE rc;      std::string sCmd; -    // Send "AT+QFOTADL" command to start the upgrade. OK responce follows shortly. +    // Send "AT+QFOTADL" command to start the upgrade. OK response follows shortly.      sCmd  = "AT+QFOTADL=\"";      sCmd += VALUE_MTS_DELTA_PATH;      sCmd += "\""; @@ -594,16 +608,48 @@ ICellularRadio::CODE QuectelRadio::applyDeltaFirmwareFile(ICellularRadio::Update          return rc;      } -    rc = waitApplyDeltaFirmware(stepCb); -    if (rc != SUCCESS) { +    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 int dMaxAttempts = 5;  // the radio makes 5 attempts to update the firmware + +    for (int i = 0; i < dMaxAttempts; i++) { + +        printInfo("Waiting for the radio to enter recovery mode");          if(stepCb) { -            stepCb(Json::Value("FUMO Error: failed to apply the firmware")); +            stepCb(Json::Value("FUMO Info: waiting for the radio to enter recovery mode"));          } -        //return rc; -    } -    // TODO: Check the new firmware version +        // Wait for the radio to detach from the USB bus +        MTS::Thread::sleep(duDetachTimeout); + +        // It's now detached. Try to reconnect +        if (!resetConnection(duAttachTimeout)) { +            printError("Can't connect to the radio in %d ms", (duAttachTimeout)); + +            if(stepCb) { +                stepCb(Json::Value("FUMO error: failed to connect to the radio in recovery mode")); +            } +            break; +        } + +        // It's now back on the bus. Wait for the URC messages. +        rc = fumoWaitUpgradeFinished(stepCb); +        if (rc == ERROR) { +            // unrecoverable error +            break; +        } + +        if (rc != SUCCESS) { +            // attempt failed, radio reboots and starts its next attempt +            continue; +        } + +        // attempt finished +        break; +    } +    // Wait for the radio to finish update and reboot +    rc = fumoWaitNewFirmware(stepCb);      return rc;  } @@ -979,56 +1025,7 @@ ICellularRadio::CODE QuectelRadio::readChunk(int fd, char* pChunk, size_t dChunk      return rc;  } -ICellularRadio::CODE QuectelRadio::waitApplyDeltaFirmware(ICellularRadio::UpdateCb& stepCb) { -    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 int dMaxAttempts = 5;  // the radio makes 5 attempts to update the firmware - -    CODE rc = FAILURE; -    std::string sResponse; - -    for (int i = 0; i < dMaxAttempts; i++) { - -        printInfo("Waiting for the radio to enter recovery mode"); -        if(stepCb) { -            stepCb(Json::Value("FUMO Info: waiting for the radio to enter recovery mode")); -        } - -        // Wait for the radio to detach from the USB bus -        MTS::Thread::sleep(duDetachTimeout); - -        // It's now detached. Try to reconnect -        if (!resetConnection(duAttachTimeout)) { -            printError("Can't connect to the radio in %d ms", (duAttachTimeout)); - -            if(stepCb) { -                stepCb(Json::Value("FUMO error: failed to connect to the radio in recovery mode")); -            } -            break; -        } - -        // It's now back on the bus. Wait for the URC messages. -        rc = waitFotaFinish(stepCb); -        if (rc == ERROR) { -            // unrecoverable error -            break; -        } - -        if (rc != SUCCESS) { -            // attempt failed, radio reboots and starts its next attempt -            continue; -        } - -        // attempt finished -        break; -    } - -    // Wait for the radio to finish update and reboot -    rc = waitNewFirmware(stepCb); -    return rc; -} - -ICellularRadio::CODE QuectelRadio::waitFotaFinish(ICellularRadio::UpdateCb& stepCb) { +ICellularRadio::CODE QuectelRadio::fumoWaitUpgradeFinished(ICellularRadio::UpdateCb& stepCb) {      const uint32_t duUrcTimeout = 4 * 60 * 1000;  // wait for 4 minutes for the next URC message      const std::string sFotaUrcPrefix = "+QIND: \"FOTA\"";  // prefix for the URC notification messages      const std::string sFotaUrcStart = "\"START\""; @@ -1082,7 +1079,7 @@ ICellularRadio::CODE QuectelRadio::waitFotaFinish(ICellularRadio::UpdateCb& step      return rc;  } -ICellularRadio::CODE QuectelRadio::waitNewFirmware(ICellularRadio::UpdateCb& stepCb) { +ICellularRadio::CODE QuectelRadio::fumoWaitNewFirmware(ICellularRadio::UpdateCb& stepCb) {      MTS::Timer oTimer;      oTimer.start();      std::string sFirmware; | 
