summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhii Kostiuk <serhii.o.kostiuk@globallogic.com>2020-08-07 11:07:48 +0300
committerSerhii Kostiuk <serhii.o.kostiuk@globallogic.com>2020-08-07 15:52:54 +0300
commit5c529e115394ba3d04c7531d046776293e2bf06c (patch)
tree941cad881b989f1dee19a27889c4aff0c953ceaa
parentc1a58778eecd0115d746afbca1079683b244b672 (diff)
downloadlibmts-io-5c529e115394ba3d04c7531d046776293e2bf06c.tar.gz
libmts-io-5c529e115394ba3d04c7531d046776293e2bf06c.tar.bz2
libmts-io-5c529e115394ba3d04c7531d046776293e2bf06c.zip
Quectel EG25-G Delta Radio Firmware Upgrade support - libmts-io implementation
This commit fixes additional issue discrovered after implementation of ACK mode. When a single 1024 bytes long chunk of data is sent to the radio - the radio reports that it received nothing. Which is a lie according to Wireshark USB logs, data is actually sent over USB and looks like radio acknowledged it in USB packet. This issue is reproducible when chunk size is set to 1024 or 512 bytes. This issue is not reproducible with chunk size of 256 bytes. When 1025 or 2048 bytes are sent to the radio - all bytes are received just fine and we get an ACK string for each 1024 bytes of data. This commit allows to send 2048 bytes long chunks of data, wait for two ACK strings from the radio and finish transmission successfully.
-rw-r--r--src/MTS_IO_QuectelRadio.cpp26
1 files changed, 17 insertions, 9 deletions
diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp
index a41e6fc..67a8d71 100644
--- a/src/MTS_IO_QuectelRadio.cpp
+++ b/src/MTS_IO_QuectelRadio.cpp
@@ -31,7 +31,7 @@
using namespace MTS::IO;
-const size_t QuectelRadio::FILE_CHUNK_SIZE = 1024;
+const size_t QuectelRadio::FILE_CHUNK_SIZE = 2048;
const std::string QuectelRadio::CMD_ABORT_UPLOAD = "+++";
// It is strongly recommended to use DOS 8.3 file name format for <filename>.
@@ -874,6 +874,11 @@ ICellularRadio::CODE QuectelRadio::uploadFile(int fd, const std::string& sTarget
const uint16_t uFileTimeout = 2; // s
const int32_t iUploadResultTimeout = uFileTimeout * 2 * 1000; // ms
+ // Quectel radios return ACK string every 1024 bytes
+ const size_t nChunksPerAck = std::max(static_cast<size_t>(1), (1024 / FILE_CHUNK_SIZE));
+ const size_t nAcksPerChunk = std::max(static_cast<size_t>(1), (FILE_CHUNK_SIZE / 1024));
+ const std::string sAckString(nAcksPerChunk, 'A');
+
size_t dPayloadLength;
size_t nChunks;
CODE rc;
@@ -907,8 +912,8 @@ ICellularRadio::CODE QuectelRadio::uploadFile(int fd, const std::string& sTarget
std::string sResponse;
// ACK waiter callback - wait for ACK and populate result code
- IsNeedMoreData waitAck = [&rc](const std::string& iterationData, const std::string&/*allData*/)->bool {
- if (iterationData.find('A') != std::string::npos) {
+ IsNeedMoreData waitAck = [&rc, &sAckString](const std::string& /*iterationData*/, const std::string& allData)->bool {
+ if (allData.find(sAckString) != std::string::npos) {
// No data needed
rc = SUCCESS;
return false;
@@ -919,7 +924,7 @@ ICellularRadio::CODE QuectelRadio::uploadFile(int fd, const std::string& sTarget
return true;
};
- for (size_t iChunk = 1; iChunk < (nChunks + 1); iChunk++) {
+ for (size_t iChunk = 0; iChunk < nChunks; iChunk++) {
rc = readChunk(fd, vBuffer.data(), vBuffer.size(), nFragmentLength);
if (rc != SUCCESS) {
@@ -936,11 +941,14 @@ ICellularRadio::CODE QuectelRadio::uploadFile(int fd, const std::string& sTarget
break;
}
- // Wait for ACK for up to 1 second and populate rc variable
- sResponse = waitResponse(waitAck, 1000);
- if (rc != SUCCESS) {
- // timeout or end of execution - check later
- break;
+ // Every 1024 bytes
+ if ((iChunk) && (iChunk % nChunksPerAck == 0)) {
+ // Wait for ACK for up to 1 second and populate rc variable
+ sResponse = waitResponse(waitAck, 1000);
+ if (rc != SUCCESS) {
+ // timeout or end of execution - check later
+ break;
+ }
}
if (stepCb && ((iChunk % nChunksPerCent) == 0)) {