Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
76a8235
DUNE/Hardware/HayesModem: wait for expected string until the end of t…
Bernardo-Gabriel Oct 6, 2025
71d80bb
DUNE/Hardware/BasicModem: prevention for infinite waiForItems.
Bernardo-Gabriel Oct 6, 2025
e3b5f0a
Transports/IridiumSBD: added parameter to specify driver timeout.
Bernardo-Gabriel Oct 6, 2025
9133da7
Transports/Evologics: added parameter to specify driver timeout.
Bernardo-Gabriel Oct 6, 2025
e3a05a5
Transports/IridiumSBD: code style standardization.
Bernardo-Gabriel Oct 7, 2025
af13060
DUNE/Hardware/BasicModem: change c_timeout scope.
Bernardo-Gabriel Oct 20, 2025
f32245d
DUNE/Hardware/HayesModem: added method to wait for a specific reply.
Bernardo-Gabriel Oct 20, 2025
42a45bd
DUNE/Hardware/HayesModem: added method to send a command and wait for…
Bernardo-Gabriel Oct 20, 2025
83d3e16
Transports/IridiumSBD/Driver: more appropriate name for constant.
Bernardo-Gabriel Oct 20, 2025
3ab9edd
Transports/IridiumSBD/Driver: added constant for CSQ command default …
Bernardo-Gabriel Oct 20, 2025
bb551ef
Transports/IridiumSBD/Driver: added constant for SBDIX[A] command def…
Bernardo-Gabriel Oct 20, 2025
8778cc3
Transports/IridiumSBD/Driver: SBDIX is no longer handled as unsolicited.
Bernardo-Gabriel Oct 20, 2025
4b2818e
Transports/IridiumSBD/Driver: use new method to send command and wait…
Bernardo-Gabriel Oct 20, 2025
e266457
Transports/IridiumSBD/Driver: use internal method for buffer clearing.
Bernardo-Gabriel Oct 20, 2025
6ee77b4
DUNE/Hardware/BasicModem: refactor if case to a switch case.
Bernardo-Gabriel Oct 21, 2025
a260af1
DUNE/Hardware/BasicModem: add a function to handle incoming characters.
Bernardo-Gabriel Oct 21, 2025
0ab0954
DUNE/Hardware/BasicModem: code style standardization.
Bernardo-Gabriel Oct 21, 2025
f15aaff
DUNE/Hardware/BasicModem: refactor if case to a switch case.
Bernardo-Gabriel Oct 21, 2025
4c3de7a
DUNE/Hardware/BasicModem: prevent redundant mode setting in read mode.
Bernardo-Gabriel Oct 23, 2025
1b07efc
DUNE/Hardware/BasicModem: remove whitespace.
Bernardo-Gabriel Oct 23, 2025
63aa9ed
DUNE/Hardware/BasicModem: add functions to ingest incoming data for r…
Bernardo-Gabriel Oct 23, 2025
2196463
DUNE/Hardware/BasicModem: implement mutex for data ingestion and refa…
Bernardo-Gabriel Oct 23, 2025
f679aa6
DUNE/Hardware/HayesModem: add error reply handling with isErrorReply …
Bernardo-Gabriel Oct 23, 2025
02ab31f
Transports/IridiumSBD: add error reply string and integrate with Driv…
Bernardo-Gabriel Oct 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 139 additions & 66 deletions src/DUNE/Hardware/BasicModem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ namespace DUNE
{
namespace Hardware
{
//! Default command timeout.
static const double c_timeout = 5.0;
//! Default input line termination.
static std::string c_line_term_in = "\r\n";
//! Default output line termination.
Expand Down Expand Up @@ -176,52 +174,31 @@ namespace DUNE
{
{
Concurrency::ScopedMutex l(m_mutex);

if (m_read_mode == mode)
return;

m_read_mode = mode;
}

if (mode == READ_MODE_LINE)
switch (mode)
{
if (m_bytes.size() > 0)
{ // if have bytes in queue, transfer to lines
getTask()->spew("There are %d bytes in the queue bytes. Convert to queue of lines.",
m_bytes.size());
while (m_bytes.size() > 0)
{
uint8_t byte = 0;
m_bytes.pop(byte);
m_chars.push(byte);
}
std::string line = "";
while (!m_chars.empty())
{
if (!processInput(line))
continue;

if (line.empty())
continue;

if (!handleUnsolicited(line))
{
m_lines.push(line);
line = "";
}
}
}
}
else
case READ_MODE_LINE:
{
if (m_lines.size())
{
getTask()->war("[BasicModem]:There are %d lines in the queue. Convert to queue of bytes.",
m_lines.size());
while (m_lines.size() > 0)
{
std::string line = m_lines.pop();
getTask()->war("[BasicModem]:line: %s", line.c_str());
for (size_t i = 0; i < line.size(); ++i)
m_bytes.push(line[i]);
}
}
if (!converBytesToLines())
break;

std::string line;
handleIncomingCharacters(line);
break;
}

case READ_MODE_RAW:
convertLinesToBytes();
break;

default:
break;
}
}

Expand Down Expand Up @@ -295,6 +272,8 @@ namespace DUNE
bool
BasicModem::processInput(std::string& str)
{
Concurrency::ScopedMutex l(m_ingestion_mtx);

bool got_line = false;

while (!m_chars.empty())
Expand Down Expand Up @@ -368,7 +347,14 @@ namespace DUNE
std::string
BasicModem::readLine(Time::Counter<double>& timer)
{
if (m_lines.waitForItems(timer.getRemaining()))
const auto remaining = timer.getRemaining();
if (remaining <= 0)
{
getTask()->war("[BasicModem]:timeout while reading line");
throw ReadTimeout();
}

if (m_lines.waitForItems(remaining))
{
std::string line = m_lines.pop();
if (line != m_last_cmd)
Expand All @@ -386,6 +372,96 @@ namespace DUNE
m_handle->flushInput();
}

void
BasicModem::handleIncomingCharacters(std::string& str)
{
while (!incomingCharsQueueEmpty())
{
if (!processInput(str))
continue;

if (str.empty())
continue;

if (!handleUnsolicited(str))
pushLine(str);

str = "";
}
}

void
BasicModem::ingestIncomingDataRaw(const char* data, const size_t len)
{
Concurrency::ScopedMutex l(m_ingestion_mtx);
for (size_t i = 0; i < len; ++i)
m_bytes.push(data[i]);
}

void
BasicModem::ingestIncomingDataLine(const char* data, const size_t len)
{
Concurrency::ScopedMutex l(m_ingestion_mtx);
for (size_t i = 0; i < len; ++i)
m_chars.push(data[i]);
}

void
BasicModem::pushLine(const std::string& line)
{
Concurrency::ScopedMutex l(m_ingestion_mtx);
m_lines.push(line);
}

bool
BasicModem::incomingCharsQueueEmpty(void)
{
Concurrency::ScopedMutex l(m_ingestion_mtx);
return m_chars.empty();
}

bool
BasicModem::converBytesToLines(void)
{
Concurrency::ScopedMutex l(m_ingestion_mtx);

if (m_bytes.size() <= 0)
return false;

// if have bytes in queue, transfer to lines
getTask()->spew("There are %u bytes in the queue bytes. Convert to queue of lines.",
m_bytes.size());
while (m_bytes.size() > 0)
{
uint8_t byte = 0;
m_bytes.pop(byte);
m_chars.push(byte);
}

return true;
}

bool
BasicModem::convertLinesToBytes(void)
{
Concurrency::ScopedMutex l(m_ingestion_mtx);

if (m_lines.size() <= 0)
return false;

getTask()->war("[BasicModem]:There are %u lines in the queue. Convert to queue of bytes.",
m_lines.size());
while (m_lines.size() > 0)
{
std::string line = m_lines.pop();
getTask()->war("[BasicModem]:line: %s", line.c_str());
for (const auto& c: line)
m_bytes.push(c);
}

return true;
}

void
BasicModem::run(void)
{
Expand All @@ -401,7 +477,9 @@ namespace DUNE
try
{
rv = m_handle->read(bfr, sizeof(bfr));
} catch (std::runtime_error &e) {
}
catch (std::runtime_error& e)
{
m_task->war("[BasicModem]:%s: %s", Status::getString(Status::CODE_IO_ERROR), e.what());
break;
}
Expand All @@ -417,32 +495,27 @@ namespace DUNE
break;
}

if (getReadMode() == READ_MODE_RAW)
const auto mode = getReadMode();

switch (mode)
{
case READ_MODE_RAW:
{
for (size_t i = 0; i < rv; ++i)
m_bytes.push(bfr[i]);
ingestIncomingDataRaw(bfr, rv);
break;
}
else

case READ_MODE_LINE:
{
bfr[rv] = 0;
m_task->spew("%s", Streams::sanitize(bfr).c_str());

for (size_t i = 0; i < rv; ++i)
{
m_chars.push(bfr[i]);
}

while (!m_chars.empty())
{
if (!processInput(line))
continue;

if (line.empty())
continue;

if (!handleUnsolicited(line))
m_lines.push(line);
}
ingestIncomingDataLine(bfr, rv);
handleIncomingCharacters(line);
break;
}

default:
break;
}
}
}
Expand Down
28 changes: 28 additions & 0 deletions src/DUNE/Hardware/BasicModem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ namespace DUNE
setBusy(bool value);

protected:
//! Default command timeout.
static constexpr double c_timeout = 5.0;

//! Read mode.
enum ReadMode
{
Expand All @@ -113,6 +116,8 @@ namespace DUNE

//! Concurrency lock.
Concurrency::Mutex m_mutex;
//! Lock for data ingestion.
Concurrency::Mutex m_ingestion_mtx;

//! Handle unsolicited or asynchronous commands.
//! @param[in] str command string.
Expand Down Expand Up @@ -223,6 +228,29 @@ namespace DUNE
//! True to trim white-space.
bool m_line_trim;



void
handleIncomingCharacters(std::string& str);

void
ingestIncomingDataRaw(const char* data, const size_t len);

void
ingestIncomingDataLine(const char* data, const size_t len);

void
pushLine(const std::string& line);

bool
incomingCharsQueueEmpty(void);

bool
converBytesToLines(void);

bool
convertLinesToBytes(void);

bool
processInput(std::string& str);

Expand Down
61 changes: 57 additions & 4 deletions src/DUNE/Hardware/HayesModem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,36 @@ namespace DUNE
return str;
}

std::string
HayesModem::readValue(const std::string& cmd, const std::string& rly, const double tmt)
{
sendAT(cmd);
std::string str = waitForReply(rly, tmt);
expectOK();
return str;
}

std::string
HayesModem::waitForReply(const std::string& rly, const double tmt)
{
Time::Counter<double> timer(tmt);
std::string str;

do
{
str = readLine(timer);

if (Utils::String::startsWith(str, rly))
return str;
}
while(!timer.overflow());

if (str.empty())
throw ReadTimeout();
else
throw UnexpectedReply(rly, str);
}

void
HayesModem::sendAT(const std::string& str)
{
Expand All @@ -175,11 +205,22 @@ namespace DUNE
}

void
HayesModem::expect(const std::string& str)
HayesModem::expect(const std::string& str, const bool persistent)
{
std::string rv = readLine();
if (rv != str)
throw UnexpectedReply(str, rv);
Time::Counter<double> timer(getTimeout());

do
{
std::string rv = readLine(timer);
if (rv == str)
return;
else if (!persistent || isErrorReply(rv))
throw UnexpectedReply(str, rv);
}
while (!timer.overflow());

getTask()->war("[BasicModem]:timeout while reading line");
throw ReadTimeout();
}

void
Expand All @@ -193,5 +234,17 @@ namespace DUNE
{
expect("READY");
}

bool
HayesModem::isErrorReply(const std::string& str)
{
return m_error_replies.find(str) != m_error_replies.end();
}

void
HayesModem::addErrorReply(const std::string& str)
{
m_error_replies.insert(str);
}
}
}
Loading