diff options
| -rw-r--r-- | include/mts/MTS_IO_CellularRadio.h | 4 | ||||
| -rw-r--r-- | include/mts/MTS_IO_QuectelRadio.h | 3 | ||||
| -rw-r--r-- | include/mts/MTS_IO_TelitRadio.h | 12 | ||||
| -rw-r--r-- | src/MTS_IO_CellularRadio.cpp | 72 | ||||
| -rw-r--r-- | src/MTS_IO_QuectelRadio.cpp | 75 | ||||
| -rw-r--r-- | src/MTS_IO_TelitRadio.cpp | 138 | 
6 files changed, 113 insertions, 191 deletions
| diff --git a/include/mts/MTS_IO_CellularRadio.h b/include/mts/MTS_IO_CellularRadio.h index e3941c3..6b23986 100644 --- a/include/mts/MTS_IO_CellularRadio.h +++ b/include/mts/MTS_IO_CellularRadio.h @@ -217,6 +217,10 @@ namespace MTS {                          std::string    m_sRadioType;                  }; +                static const size_t FILE_CHUNK_SIZE = 1024; +                static CODE getFileSize(int fd, size_t& nBytes, size_t& nFileChunks); +                static CODE readChunk(int fd, char* pChunk, size_t dChunkSize, size_t& nReadBytes); +              private:                  std::string m_sName;                  std::string m_sRadioPort; diff --git a/include/mts/MTS_IO_QuectelRadio.h b/include/mts/MTS_IO_QuectelRadio.h index d8228cb..2121f7c 100644 --- a/include/mts/MTS_IO_QuectelRadio.h +++ b/include/mts/MTS_IO_QuectelRadio.h @@ -67,7 +67,6 @@ namespace MTS {                  // private variable to save old firmware versions during FOTA                  std::string m_sQuectelFirmware; -                static const size_t FILE_CHUNK_SIZE;                  static const std::string CMD_ABORT_UPLOAD;                  static const std::string VALUE_MTS_DELTA_NAME;                  static const std::string VALUE_MTS_DELTA_PATH; @@ -85,8 +84,6 @@ namespace MTS {                  static uint16_t getQuectelChecksum(const void* data, size_t nBytes);                  static inline void updateQuectelChecksum(uint16_t& iChecksum, uint16_t iNewFragment);                  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 fumoWaitUpgradeFinished(UpdateCb& stepCb);                  CODE fumoWaitNewFirmware(UpdateCb& stepCb);          }; diff --git a/include/mts/MTS_IO_TelitRadio.h b/include/mts/MTS_IO_TelitRadio.h index 07a95de..fdf8a20 100644 --- a/include/mts/MTS_IO_TelitRadio.h +++ b/include/mts/MTS_IO_TelitRadio.h @@ -66,7 +66,8 @@ namespace MTS {                  };                  virtual FOTA_GROUP getFotaGroup(); -                virtual CODE uploadFile(int fd, UpdateCb& stepCb); +                virtual CODE fumoWriteGroupsABD(int fd, UpdateCb& stepCb); +                //virtual CODE fumoWriteGroupC(int fd, UpdateCb& stepCb);              private:                  virtual CODE getSimLockAttempts(int& iAttemptsPin, int& iAttemptsPuk, const std::string& sLockStatus); @@ -75,20 +76,17 @@ namespace MTS {                  // private variable to save old firmware versions during FOTA                  std::string m_sTelitFirmware; -                static const size_t FILE_CHUNK_SIZE;                  static const std::string CMD_ABORT_UPLOAD;                  CODE getTelitFirmware(std::string& sFirmware); -                CODE startFileUpload(); -                CODE abortFileUpload(); +                CODE startWrite(); +                CODE abortWrite();                  static inline void callNextStep(UpdateCb& stepCb, const char* csMessage);                  static inline void callNextStep(UpdateCb& stepCb, const std::string& sMessage); -                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 fumoWaitRadioBooted(UpdateCb& stepCb); +                CODE fumoWaitUpgradeFinished(UpdateCb& stepCb);                  CODE fumoCheckNewFirmware(UpdateCb& stepCb);          }; diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp index bb7cd40..0acf607 100644 --- a/src/MTS_IO_CellularRadio.cpp +++ b/src/MTS_IO_CellularRadio.cpp @@ -1262,3 +1262,75 @@ const char *CellularRadio::RadioBandMap::getRadioBandName(const std::string &cha      return band;  } + +ICellularRadio::CODE CellularRadio::getFileSize(int fd, size_t& nBytes, size_t& nChunks) { +    CODE rc = FAILURE; + +    do { +        ssize_t dScrollPos; +        dScrollPos = lseek(fd, 0, SEEK_SET); +        if (dScrollPos < 0) { +            printError("Failed to seek to the start of the file: %d", errno); +            break; +        } + +        dScrollPos = lseek(fd, 0, SEEK_END); +        if (dScrollPos < 0) { +            printError("Failed to determine the file size: %d", errno); +            break; +        } + +        nBytes = static_cast<size_t>(dScrollPos); +        nChunks = (nBytes + FILE_CHUNK_SIZE - 1) / FILE_CHUNK_SIZE;  // round up + +        rc = SUCCESS; + +    } while (false); + +    lseek(fd, 0, SEEK_SET); +    return rc; +} + +ICellularRadio::CODE CellularRadio::readChunk(int fd, char* pChunk, size_t dChunkSize, size_t& nReadBytes) { +    size_t nUsedBuffer = 0; +    CODE rc = FAILURE; + +    while (true) { + +        if (nUsedBuffer > dChunkSize) { +            printError("Internal pointer error, abort upload: %d", nUsedBuffer); +            rc = ERROR; +            break; +        } + +        if (nUsedBuffer == dChunkSize) { +            // full chunk received +            rc = SUCCESS; +            nReadBytes = dChunkSize; +            break; +        } + +        char* pData = pChunk + nUsedBuffer; +        size_t nFreeBuffer = dChunkSize - nUsedBuffer; + +        ssize_t dReadCount = read(fd, pData, nFreeBuffer); +        if (dReadCount < 0) { +            printError("Failed to read from the source file: %d", errno); +            rc = ERROR; +            break; +        } + +        size_t duReadCount = static_cast<size_t>(dReadCount); +        if (duReadCount == 0) { +            // EOF. Return what was already read +            nReadBytes = nUsedBuffer; +            rc = SUCCESS; +            break; +        } + +        nUsedBuffer += duReadCount; + +    } + +    return rc; +} diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp index 22374ee..bb81621 100644 --- a/src/MTS_IO_QuectelRadio.cpp +++ b/src/MTS_IO_QuectelRadio.cpp @@ -31,7 +31,6 @@  using namespace MTS::IO; -const size_t QuectelRadio::FILE_CHUNK_SIZE = 1024;  const std::string QuectelRadio::CMD_ABORT_UPLOAD = "+++";  // It is strongly recommended to use DOS 8.3 file name format for <filename>. @@ -603,7 +602,7 @@ ICellularRadio::CODE QuectelRadio::fumoLocalApply(ICellularRadio::UpdateCb& step      sCmd += VALUE_MTS_DELTA_PATH;      sCmd += "\""; -    rc = sendBasicCommand(sCmd, 1000); +    rc = sendBasicCommand(sCmd, 10000);      if (rc != SUCCESS) {          printError("FUMO failed, OK not received from the radio"); @@ -985,78 +984,6 @@ uint16_t QuectelRadio::getQuectelChecksum(const void* data, size_t nBytes) {      return iChecksum;  } -ICellularRadio::CODE QuectelRadio::getFileSize(int fd, size_t& nBytes, size_t& nChunks) { -    CODE rc = FAILURE; - -    do { -        ssize_t dScrollPos; -        dScrollPos = lseek(fd, 0, SEEK_SET); -        if (dScrollPos < 0) { -            printError("Failed to seek to the start of the file: %d", errno); -            break; -        } - -        dScrollPos = lseek(fd, 0, SEEK_END); -        if (dScrollPos < 0) { -            printError("Failed to determine the file size: %d", errno); -            break; -        } - -        nBytes = static_cast<size_t>(dScrollPos); -        nChunks = (nBytes + FILE_CHUNK_SIZE - 1) / FILE_CHUNK_SIZE;  // round up - -        rc = SUCCESS; - -    } while (false); - -    lseek(fd, 0, SEEK_SET); -    return rc; -} - -ICellularRadio::CODE QuectelRadio::readChunk(int fd, char* pChunk, size_t dChunkSize, size_t& nReadBytes) { -    size_t nUsedBuffer = 0; -    CODE rc = FAILURE; - -    while (true) { - -        if (nUsedBuffer > dChunkSize) { -            printError("Internal pointer error, abort upload: %d", nUsedBuffer); -            rc = ERROR; -            break; -        } - -        if (nUsedBuffer == dChunkSize) { -            // full chunk received -            rc = SUCCESS; -            nReadBytes = dChunkSize; -            break; -        } - -        char* pData = pChunk + nUsedBuffer; -        size_t nFreeBuffer = dChunkSize - nUsedBuffer; - -        ssize_t dReadCount = read(fd, pData, nFreeBuffer); -        if (dReadCount < 0) { -            printError("Failed to read from the source file: %d", errno); -            rc = ERROR; -            break; -        } - -        size_t duReadCount = static_cast<size_t>(dReadCount); -        if (duReadCount == 0) { -            // EOF. Return what was already read -            nReadBytes = nUsedBuffer; -            rc = SUCCESS; -            break; -        } - -        nUsedBuffer += duReadCount; - -    } - -    return rc; -} -  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 diff --git a/src/MTS_IO_TelitRadio.cpp b/src/MTS_IO_TelitRadio.cpp index 967baae..86c3565 100644 --- a/src/MTS_IO_TelitRadio.cpp +++ b/src/MTS_IO_TelitRadio.cpp @@ -28,7 +28,6 @@  using namespace MTS::IO; -const size_t TelitRadio::FILE_CHUNK_SIZE = 1024;  const std::string TelitRadio::CMD_ABORT_UPLOAD = "+++"; @@ -739,13 +738,6 @@ ICellularRadio::CODE TelitRadio::setCellularMode(CELLULAR_MODES networks) {  ICellularRadio::CODE TelitRadio::updateFumoLocal(int fd, ICellularRadio::UpdateCb& stepCb) {      CODE rc = FAILURE; -    FOTA_GROUP group = getFotaGroup(); - -    if (group == VALUE_UNKNOWN) { -        printError("Delta firmware upgrade is not supported for this type of radio modem"); -        callNextStep(stepCb, "FUMO Error: delta firmware upgrade is not supported for this type of radio modem"); -        return rc; -    }      rc = fumoLocalInject(fd, stepCb);      if (rc != SUCCESS) { @@ -765,16 +757,22 @@ ICellularRadio::CODE TelitRadio::fumoLocalInject(int fd, ICellularRadio::UpdateC          callNextStep(stepCb, "FUMO Info: downloading the firmware");          if ((group == VALUE_GROUP_A) || (group == VALUE_GROUP_B) || (group == VALUE_GROUP_D)) { -            rc = uploadFile(fd, stepCb); +            rc = fumoWriteGroupsABD(fd, stepCb);              if (rc != SUCCESS) {                  printError("Failed to inject the delta file.");                  callNextStep(stepCb, "FUMO Error: failed to download the firmware file");                  break;              }          } else if (group == VALUE_GROUP_C) { -            //TODO Not Implemented +            //TODO Not Implemented TelitRadio::fumoWriteGroupC              printError("Failed to inject the delta file.");              callNextStep(stepCb, "FUMO Error: not implemented"); +            rc = NOT_APPLICABLE; +            break; +        } else { +            printError("Delta firmware upgrade is not supported for this type of radio modem"); +            callNextStep(stepCb, "FUMO Error: delta firmware upgrade is not supported for this type of radio modem"); +            rc = NOT_APPLICABLE;              break;          } @@ -803,9 +801,13 @@ ICellularRadio::CODE TelitRadio::fumoLocalApply(ICellularRadio::UpdateCb& stepCb      } else if ((group == VALUE_GROUP_B) || (group == VALUE_GROUP_C)) {          // Send "AT#OTAUP=2" command to start the upgrade. OK response follows shortly.          sCmd  = "AT#OTAUP=2"; +    } else { +        printError("Delta firmware upgrade is not supported for this type of radio modem"); +        callNextStep(stepCb, "FUMO Error: delta firmware upgrade is not supported for this type of radio modem"); +        return NOT_APPLICABLE;      } -    rc = sendBasicCommand(sCmd, 2000); +    rc = sendBasicCommand(sCmd, 10000);      if (rc != SUCCESS) {          printError("FUMO failed, OK not received from the radio"); @@ -814,30 +816,15 @@ ICellularRadio::CODE TelitRadio::fumoLocalApply(ICellularRadio::UpdateCb& stepCb      }      const uint32_t duDetachTimeout = 10000;  // wait for 10 seconds for the radio to detach -    const uint32_t duAttachTimeout = 300000;  // wait for 300 seconds for the radio to attach      do { -        printInfo("Waiting for the radio to enter recovery mode"); -        callNextStep(stepCb, "FUMO Info: waiting for the radio to enter recovery mode"); +        printInfo("Applying the radio firmware"); +        callNextStep(stepCb, "FUMO Info: applying the radio firmware");          // Wait for the radio to detach from the USB bus          MTS::Thread::sleep(duDetachTimeout); -        printInfo("Firmware update in progress"); -        callNextStep(stepCb, "FUMO Info: firmware update in progress"); - -        // It's now detached. Try to reconnect -        if (!resetConnection(duAttachTimeout)) { -            printError("Can't connect to the radio in %d ms", (duAttachTimeout)); -            callNextStep(stepCb, "FUMO Error: unable to obtain radio after reset"); -            rc = ERROR; -            break; -        } - -        // Wait for the radio to finish update and reboot -        printTrace("Waiting for the radio to come up"); -        callNextStep(stepCb, "FUMO Info: waiting for the radio to enter normal mode"); -        rc = fumoWaitRadioBooted(stepCb); +        rc = fumoWaitUpgradeFinished(stepCb);          if (rc != SUCCESS) {              break; @@ -863,7 +850,7 @@ TelitRadio::FOTA_GROUP TelitRadio::getFotaGroup() {      return VALUE_UNKNOWN;  } -ICellularRadio::CODE TelitRadio::uploadFile(int fd, ICellularRadio::UpdateCb& stepCb) { +ICellularRadio::CODE TelitRadio::fumoWriteGroupsABD(int fd, ICellularRadio::UpdateCb& stepCb) {      size_t dPayloadLength;      size_t nChunks;      CODE rc; @@ -875,7 +862,7 @@ ICellularRadio::CODE TelitRadio::uploadFile(int fd, ICellularRadio::UpdateCb& st      printTrace("File size: %d bytes and %d chunks", dPayloadLength, nChunks);      printTrace("Starting file upload..."); -    rc = startFileUpload(); +    rc = startWrite();      if (rc != SUCCESS) {          return rc;      } @@ -912,83 +899,12 @@ ICellularRadio::CODE TelitRadio::uploadFile(int fd, ICellularRadio::UpdateCb& st      }      // send +++ -    abortFileUpload(); -    return rc; -} - -ICellularRadio::CODE TelitRadio::getFileSize(int fd, size_t& nBytes, size_t& nChunks) { -    CODE rc = FAILURE; - -    do { -        ssize_t dScrollPos; -        dScrollPos = lseek(fd, 0, SEEK_SET); -        if (dScrollPos < 0) { -            printError("Failed to seek to the start of the file: %d", errno); -            break; -        } - -        dScrollPos = lseek(fd, 0, SEEK_END); -        if (dScrollPos < 0) { -            printError("Failed to determine the file size: %d", errno); -            break; -        } - -        nBytes = static_cast<size_t>(dScrollPos); -        nChunks = (nBytes + FILE_CHUNK_SIZE - 1) / FILE_CHUNK_SIZE;  // round up - -        rc = SUCCESS; - -    } while (false); - -    lseek(fd, 0, SEEK_SET); +    abortWrite();      return rc;  } -ICellularRadio::CODE TelitRadio::readChunk(int fd, char* pChunk, size_t dChunkSize, size_t& nReadBytes) { -    size_t nUsedBuffer = 0; -    CODE rc = FAILURE; - -    while (true) { - -        if (nUsedBuffer > dChunkSize) { -            printError("Internal pointer error, abort upload: %d", nUsedBuffer); -            rc = ERROR; -            break; -        } - -        if (nUsedBuffer == dChunkSize) { -            // full chunk received -            rc = SUCCESS; -            nReadBytes = dChunkSize; -            break; -        } - -        char* pData = pChunk + nUsedBuffer; -        size_t nFreeBuffer = dChunkSize - nUsedBuffer; - -        ssize_t dReadCount = read(fd, pData, nFreeBuffer); -        if (dReadCount < 0) { -            printError("Failed to read from the source file: %d", errno); -            rc = ERROR; -            break; -        } - -        size_t duReadCount = static_cast<size_t>(dReadCount); -        if (duReadCount == 0) { -            // EOF. Return what was already read -            nReadBytes = nUsedBuffer; -            rc = SUCCESS; -            break; -        } - -        nUsedBuffer += duReadCount; -    } - -    return rc; -} - -ICellularRadio::CODE TelitRadio::startFileUpload() { +ICellularRadio::CODE TelitRadio::startWrite() {      const std::vector<std::string> vBailStrings{ ICellularRadio::RSP_CONNECT, ICellularRadio::RSP_ERROR };      const int dTimeout = 1000; //ms      std::string sCommand, sResult; @@ -1004,7 +920,7 @@ ICellularRadio::CODE TelitRadio::startFileUpload() {      return SUCCESS;  } -ICellularRadio::CODE TelitRadio::abortFileUpload() { +ICellularRadio::CODE TelitRadio::abortWrite() {      /*       * To prevent the “+++” from being mistaken for data, the following sequence should be followed:       * 1) Do not input any character within 1s or longer before inputting “+++”. @@ -1050,8 +966,9 @@ ICellularRadio::CODE TelitRadio::getTelitFirmware(std::string& sFirmware) {      return SUCCESS;  } -ICellularRadio::CODE TelitRadio::fumoWaitRadioBooted(ICellularRadio::UpdateCb& stepCb) { -    const uint32_t duUrcTimeout = 60 * 1000;       // wait for 1 minutes for the next URC message +ICellularRadio::CODE TelitRadio::fumoWaitUpgradeFinished(ICellularRadio::UpdateCb& stepCb) { +    const uint32_t duAttachTimeout = 300000;       // wait for 300 seconds for the radio to attach +	const uint32_t duUrcTimeout = 60 * 1000;       // wait for 1 minutes for the next URC message      const std::string sFotaUrcPrefix = "#OTAEV:";  // prefix for the URC notification messages      const std::string sFotaUrcEndSuccess = "Module Upgraded To New Fw";      const std::string sFotaUrcEndFailed = "OTA Fw Upgrade Failed"; @@ -1060,6 +977,13 @@ ICellularRadio::CODE TelitRadio::fumoWaitRadioBooted(ICellularRadio::UpdateCb& s      CODE rc = FAILURE;      std::string sResponse; +    // It's now detached. Try to reconnect +    if (!resetConnection(duAttachTimeout)) { +        printError("Can't connect to the radio in %d ms", (duAttachTimeout)); +        callNextStep(stepCb, "FUMO Error: unable to obtain radio after reset"); +        return ERROR; +    } +      while (true) {          sResponse = sendCommand("", vFotaBailStrings, duUrcTimeout, 0x00); | 
