summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/MTS_IO_QuectelRadio.cpp71
1 files changed, 48 insertions, 23 deletions
diff --git a/src/MTS_IO_QuectelRadio.cpp b/src/MTS_IO_QuectelRadio.cpp
index 942c0f7..a41e6fc 100644
--- a/src/MTS_IO_QuectelRadio.cpp
+++ b/src/MTS_IO_QuectelRadio.cpp
@@ -871,6 +871,9 @@ ICellularRadio::CODE QuectelRadio::setCellularMode(CELLULAR_MODES networks) {
}
ICellularRadio::CODE QuectelRadio::uploadFile(int fd, const std::string& sTargetFilename, ICellularRadio::UpdateCb& stepCb) {
+ const uint16_t uFileTimeout = 2; // s
+ const int32_t iUploadResultTimeout = uFileTimeout * 2 * 1000; // ms
+
size_t dPayloadLength;
size_t nChunks;
CODE rc;
@@ -888,7 +891,8 @@ ICellularRadio::CODE QuectelRadio::uploadFile(int fd, const std::string& sTarget
printTrace("File size: %d bytes and %d chunks", dPayloadLength, nChunks);
printTrace("Starting file upload...");
- rc = startFileUpload(sTargetFilename, dPayloadLength);
+ // Start file upload, set transmission timeouts and enable ACK mode
+ rc = startFileUpload(sTargetFilename, dPayloadLength, uFileTimeout, true);
if (rc != SUCCESS) {
return rc;
}
@@ -900,6 +904,20 @@ ICellularRadio::CODE QuectelRadio::uploadFile(int fd, const std::string& sTarget
size_t nChunksPerCent = (nChunks / 100) + 1;
size_t nFragmentLength = 0;
std::array<char, FILE_CHUNK_SIZE> vBuffer;
+ 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) {
+ // No data needed
+ rc = SUCCESS;
+ return false;
+ }
+
+ // We need more data
+ rc = NO_RESPONSE;
+ return true;
+ };
for (size_t iChunk = 1; iChunk < (nChunks + 1); iChunk++) {
@@ -914,6 +932,14 @@ ICellularRadio::CODE QuectelRadio::uploadFile(int fd, const std::string& sTarget
rc = sendData(vBuffer.data(), nFragmentLength);
if (rc != SUCCESS) {
+ // failed to send data
+ 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;
}
@@ -924,38 +950,28 @@ ICellularRadio::CODE QuectelRadio::uploadFile(int fd, const std::string& sTarget
}
- if (rc != SUCCESS) {
- // cancel upload and terminate
- callNextStep(stepCb, "FILE Error: Upload failed due to internal error");
- abortFileUpload();
- return rc;
- }
-
printTrace("Waiting for acknoledge from the radio");
std::string sExpectedResult = "+QFUPL: ";
sExpectedResult += MTS::Text::format(dPayloadLength);
sExpectedResult += ",";
sExpectedResult += MTS::Text::toLowerCase(MTS::Text::formatHex(dChecksum));
- // "send" empty string to read acknoledge string
- std::string sResult = sendCommand("", DEFAULT_BAIL_STRINGS, 10000, 0x00);
+ // Wait for confirmation of successful upload completion
+ sResponse += waitResponse(DEFAULT_BAIL_STRINGS, iUploadResultTimeout);
- if (sResult.find(sExpectedResult) != std::string::npos) {
- printDebug("Radio returned: [%s]", sResult.c_str());
+ if (sResponse.find(sExpectedResult) != std::string::npos) {
+ printDebug("Radio returned: [%s]", sResponse.c_str());
printTrace("Upload finished, checksum matched");
- } else {
- printError("Upload failed: checksum mismatch. Expected: [%s], Actual: [%s]", sExpectedResult.c_str(), sResult.c_str());
- abortFileUpload();
- rc = FAILURE;
- }
-
- if (rc == SUCCESS) {
callNextStep(stepCb, "FILE Info: Upload finished successfully");
- } else {
- callNextStep(stepCb, "FILE Error: Upload failed due to internal error");
+
+ return SUCCESS;
}
- return rc;
+ printError("Upload failed: checksum mismatch. Expected: [%s], Actual: [%s]", sExpectedResult.c_str(), sResponse.c_str());
+ callNextStep(stepCb, "FILE Error: Upload failed due to internal error");
+
+ abortFileUpload();
+ return FAILURE;
}
ICellularRadio::CODE QuectelRadio::removeFile(const std::string& sTargetFilename) {
@@ -1159,15 +1175,24 @@ std::string QuectelRadio::getFumoEarlyErrorCode(const std::string& sRadioInput)
return sResult;
}
-ICellularRadio::CODE QuectelRadio::startFileUpload(const std::string& sTargetFilename, size_t nBytes) {
+ICellularRadio::CODE QuectelRadio::startFileUpload(const std::string& sTargetFilename, size_t nBytes, uint16_t uRxTimeout, bool bAckEnabled) {
const std::vector<std::string> vBailStrings{ ICellularRadio::RSP_CONNECT, ICellularRadio::RSP_ERROR };
const int dTimeout = 1000; //ms
std::string sCommand, sResult;
+ // Format: AT+QFUPL=<filename>[,<file_size>[,<timeout>[,<ackmode>]]
+
sCommand = "AT+QFUPL=\"";
sCommand += sTargetFilename;
sCommand += "\",";
sCommand += MTS::Text::format(nBytes);
+ sCommand += ",";
+ sCommand += MTS::Text::format(uRxTimeout);
+
+ if (bAckEnabled) {
+ // ACK mode enabled
+ sCommand += ",1";
+ }
sResult = sendCommand(sCommand, vBailStrings, dTimeout);
if (sResult.find(ICellularRadio::RSP_CONNECT) == std::string::npos) {