34static bool Is0183ChecksumOk(
const std::string& sentence) {
35 const size_t cs_start = sentence.find(
'*');
36 if (cs_start == std::string::npos || cs_start > sentence.size() - 3)
39 const std::string cs_str = sentence.substr(cs_start + 1, 2);
40 const unsigned long checksum = strtol(cs_str.c_str(),
nullptr, 16);
41 if (checksum == 0L && cs_str !=
"00")
return false;
43 unsigned char calculated_checksum = 0;
44 for (
const char c : sentence.substr(1, cs_start - 1))
45 calculated_checksum ^= static_cast<unsigned char>(c);
46 return calculated_checksum == checksum;
55static std::string GetPayloadSentence(
const std::string& sentence) {
56 size_t start_pos = sentence.find(
'$');
57 if (start_pos == std::string::npos) start_pos = sentence.find(
'!');
58 if (start_pos == std::string::npos)
return "";
59 if (sentence.size() < start_pos + 6)
return "";
60 return sentence.substr(start_pos);
65CommDriverN0183::CommDriverN0183(NavAddr::Bus,
const std::string& s)
68CommDriverN0183::~CommDriverN0183() =
default;
73 const std::string sentence = GetPayloadSentence(payload);
74 if (sentence.empty())
return;
75 assert(sentence[0] ==
'$' || sentence[0] ==
'!');
76 assert(sentence.size() >= 6);
78 const bool is_garbage =
79 sentence.size() > 128 ||
80 std::any_of(sentence.begin(), sentence.end(),
81 [](
char c) { return !isprint(c) && c !=
'\n' && c !=
'\r'; });
82 const bool has_checksum =
83 sentence.find(
'*', sentence.size() - 6) != std::string::npos;
87 state = NavMsg::State::kCannotParse;
88 else if (!params.SentencePassesFilter(sentence, FILTER_INPUT))
89 state = NavMsg::State::kFiltered;
90 else if (has_checksum && !Is0183ChecksumOk(sentence))
91 state = NavMsg::State::kBadChecksum;
93 state = NavMsg::State::kOk;
96 auto msg = std::make_shared<const Nmea0183Msg>(
"TRASH", payload,
98 listener.
Notify(std::move(msg));
101 const std::string
id = sentence.substr(1, 5);
103 std::make_shared<const Nmea0183Msg>(
id, sentence, GetAddress(), state);
104 listener.
Notify(std::move(msg));
Common interface for all drivers.
void SendToListener(const std::string &payload, DriverListener &listener, const ConnectionParams ¶ms)
Wrap argument string in NavMsg pointer, forward to listener.
Interface for handling incoming messages.
virtual void Notify(std::shared_ptr< const NavMsg > message)=0
Handle a received message.
Where messages are sent to or received from.
NMEA0183 drivers common base.