mirror of
https://github.com/peterantypas/maiana.git
synced 2025-05-15 23:10:11 -07:00
120 lines
2.7 KiB
C++
120 lines
2.7 KiB
C++
// General helper functions for working with AIS and NMEA.
|
|
|
|
#include "ais.h"
|
|
|
|
extern "C" {
|
|
int LibAisVersionMajor() {
|
|
return LIBAIS_VERSION_MAJOR;
|
|
}
|
|
|
|
int LibAisVersionMinor() {
|
|
return LIBAIS_VERSION_MINOR;
|
|
}
|
|
} // extern "C"
|
|
|
|
namespace libais {
|
|
|
|
string GetNthField(const string &str, const size_t n,
|
|
const string &delim_str) {
|
|
assert(!delim_str.empty());
|
|
if (str.empty())
|
|
return "";
|
|
|
|
size_t prev = 0;
|
|
size_t off = str.find(delim_str);
|
|
size_t count = 0;
|
|
|
|
for (; off != string::npos && count != n;
|
|
off = str.find(delim_str, off + 1), count++) {
|
|
prev = off + delim_str.size();
|
|
}
|
|
|
|
if (count == n)
|
|
return str.substr(prev, off-prev);
|
|
|
|
return "";
|
|
}
|
|
|
|
int GetPad(const string &nmea_str) {
|
|
// -1 on error
|
|
const string chksum_block(GetNthField(nmea_str, 6, ","));
|
|
if (chksum_block.size() != 4 || chksum_block[1] != '*')
|
|
return -1;
|
|
const char pad = chksum_block[0];
|
|
if (pad < '0' || pad > '5')
|
|
return -1;
|
|
return static_cast<int>(pad - '0');
|
|
}
|
|
|
|
string GetBody(const string &nmea_str) {
|
|
return GetNthField(nmea_str, 5, ",");
|
|
}
|
|
|
|
// Note: Needs to be kept in sync with enum AIS_STATUS list in ais.h.
|
|
const char * const AIS_STATUS_STRINGS[AIS_STATUS_NUM_CODES] = {
|
|
"AIS_UNINITIALIZED",
|
|
"AIS_OK",
|
|
"AIS_ERR_BAD_BIT_COUNT",
|
|
"AIS_ERR_BAD_NMEA_CHR",
|
|
"AIS_ERR_BAD_PTR",
|
|
"AIS_ERR_UNKNOWN_MSG_TYPE",
|
|
"AIS_ERR_MSG_NOT_IMPLEMENTED",
|
|
"AIS_ERR_MSG_SUB_NOT_IMPLEMENTED",
|
|
"AIS_ERR_EXPECTED_STRING",
|
|
"AIS_ERR_BAD_MSG_CONTENT",
|
|
"AIS_ERR_MSG_TOO_LONG",
|
|
"AIS_ERR_BAD_SUB_MSG",
|
|
"AIS_ERR_BAD_SUB_SUB_MSG",
|
|
};
|
|
|
|
AisMsg::AisMsg(const char *nmea_payload, const size_t pad)
|
|
: message_id(0), repeat_indicator(0), mmsi(0), status(AIS_UNINITIALIZED),
|
|
num_chars(0), num_bits(0), bits() {
|
|
assert(nmea_payload);
|
|
assert(pad < 6);
|
|
|
|
const AIS_STATUS r = bits.ParseNmeaPayload(nmea_payload, pad);
|
|
if (r != AIS_OK) {
|
|
status = r;
|
|
return;
|
|
}
|
|
num_bits = bits.GetNumBits();
|
|
num_chars = bits.GetNumChars();
|
|
|
|
if (bits.GetNumBits() < 38) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
|
|
message_id = bits.ToUnsignedInt(0, 6);
|
|
repeat_indicator = bits.ToUnsignedInt(6, 2);
|
|
mmsi = bits.ToUnsignedInt(8, 30);
|
|
}
|
|
|
|
bool AisMsg::CheckStatus() const {
|
|
if (status == AIS_OK || status == AIS_UNINITIALIZED) {
|
|
return true;
|
|
}
|
|
#ifdef LIBAIS_DEBUG
|
|
std::cerr << "AisMsg::CheckStatus failed: "
|
|
<< AIS_STATUS_STRINGS[status]
|
|
<< std::endl;
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
AisPoint::AisPoint() : lng_deg(0), lat_deg(0) {
|
|
}
|
|
|
|
AisPoint::AisPoint(double lng_deg_, double lat_deg_)
|
|
: lng_deg(lng_deg_), lat_deg(lat_deg_) {
|
|
}
|
|
|
|
#if 0
|
|
ostream& operator<< (ostream &o, const AisPoint &position) {
|
|
return o << " (" << position.lng_deg << ", " << position.lat_deg << ")";
|
|
}
|
|
#endif
|
|
|
|
} // namespace libais
|