summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mts/MTS_IO_CellularRadio.h4
-rw-r--r--include/mts/MTS_IO_QuectelRadio.h3
-rw-r--r--include/mts/MTS_IO_TelitRadio.h12
-rw-r--r--src/MTS_IO_CellularRadio.cpp72
-rw-r--r--src/MTS_IO_QuectelRadio.cpp75
-rw-r--r--src/MTS_IO_TelitRadio.cpp138
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);