mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-02 02:48:51 -05:00
- Removed not used files from old implementations. - Renamed some classes to follow naming convention. - Renamed methods to use consistent styling. - Restructured code.
141 lines
4.3 KiB
C++
141 lines
4.3 KiB
C++
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include "ATURCStream.hpp"
|
|
#include "ATCommon.hpp"
|
|
|
|
#include <module-os/RTOSWrapper/include/ticks.hpp>
|
|
#include <cstring>
|
|
|
|
namespace at
|
|
{
|
|
|
|
/**
|
|
* Look for first possible urc begin \r\n+
|
|
* remove everything in front(should not happen but possible communication errors)
|
|
* @return true if have urc begin to process
|
|
*/
|
|
bool ATURCStream::search()
|
|
{
|
|
if (!urcBeginFound) {
|
|
auto pos = atBuffer.find(urcStart);
|
|
if (pos == std::string::npos) {
|
|
atBuffer = {};
|
|
return false;
|
|
}
|
|
|
|
urcBeginFound = true;
|
|
|
|
atBuffer.erase(0, pos);
|
|
return true;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* check that quotation mark is open or close in current buffer
|
|
* to wait for next chunk or if closed and urc is closed by \r\n ad to ready urc list
|
|
* @return true if found urc line
|
|
*/
|
|
bool ATURCStream::checkQuotation()
|
|
{
|
|
if (!openQuotationMark) {
|
|
auto posDelimiter = atBuffer.find(at::delimiter, posMark + 1);
|
|
if (posDelimiter != std::string::npos) {
|
|
auto posMark2 = atBuffer.find("\"", posMark + 1);
|
|
if ((posMark2 != std::string::npos) && (posDelimiter > posMark2)) {
|
|
posMark = posMark2;
|
|
openQuotationMark = !openQuotationMark;
|
|
return false;
|
|
}
|
|
|
|
urcList.push_back(atBuffer.substr(0, posDelimiter + std::strlen(at::delimiter)));
|
|
atBuffer.erase(0, posDelimiter + std::strlen(at::delimiter));
|
|
lookForNextURC = true;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check for next quotation and urc, in general could look like
|
|
* \r\n+URC: "literal \r\n...."\r\n\r\n+URC: "param",4,4\r\n ...
|
|
* or
|
|
* \r\nURC... \r\n
|
|
* @return true if found and we could look for next URCin buffer
|
|
*/
|
|
bool ATURCStream::lookForNext()
|
|
{
|
|
lookForNextURC = false;
|
|
openQuotationMark = false;
|
|
posMark = 0; /// start from \r\n(+) from search
|
|
do {
|
|
if (checkQuotation())
|
|
break;
|
|
|
|
openQuotationMark = !openQuotationMark;
|
|
posMark = atBuffer.find("\"", posMark + 1);
|
|
} while (posMark != std::string::npos);
|
|
|
|
return lookForNextURC;
|
|
}
|
|
/**
|
|
* try to find URC in current buffer,
|
|
* found results could be get by getURCList
|
|
*/
|
|
void ATURCStream::tryParse()
|
|
{
|
|
|
|
while (search()) {
|
|
|
|
if (!lookForNext()) {
|
|
urcBeginFound = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function reset buffer in case it is too big or too old.
|
|
* it is dictated only by the possibility related to transmission errors.
|
|
*/
|
|
void ATURCStream::fuse()
|
|
{
|
|
/**
|
|
* multiple frame have around hundreds char, so they should be delayed only by
|
|
* transmission time and for one URC should be (from experiment) around 1ms
|
|
* if frame delay is too long, there is a possibility that we have some transmission
|
|
* errors, eg.frames
|
|
* [1ms]Frame1: \r\n+URC: param,"long string .....
|
|
* [2ms]Frame2: error .... and some part without end of quotation mark ... \r\n
|
|
* [100ms] Frame3:\r\n+NextURC:ABC\r\n
|
|
*
|
|
* In case checking only data we omit NextURC, because we could also get URC which look like
|
|
* \r\n+URC: param,"\r\n+NextURC:ABC\r\n"\r\n
|
|
*/
|
|
|
|
if (atBuffer.empty())
|
|
return;
|
|
|
|
constexpr auto maxTimeout = 5;
|
|
constexpr auto maxSize = 2048;
|
|
uint32_t timeoutNeeded = lastWriteTime + maxTimeout;
|
|
uint32_t timeElapsed = cpp_freertos::Ticks::GetTicks();
|
|
if ((timeElapsed >= timeoutNeeded) || (atBuffer.length() > maxSize)) {
|
|
LOG_ERROR("AT URC Stream timeout ");
|
|
atBuffer = {};
|
|
}
|
|
}
|
|
|
|
bool ATURCStream::write(const std::string &buffer)
|
|
{
|
|
fuse();
|
|
lastWriteTime = cpp_freertos::Ticks::GetTicks();
|
|
atBuffer += buffer;
|
|
tryParse();
|
|
return true;
|
|
}
|
|
|
|
} // namespace at
|