mirror of
https://github.com/peterantypas/maiana.git
synced 2025-05-15 23:10:11 -07:00
111 lines
3.2 KiB
C++
111 lines
3.2 KiB
C++
// 'J' - Multi slot binary message with comm state
|
|
// TODO(schwehr): handle payload
|
|
// BAD: the comm-state is after the veriable payload. This is a bad design.
|
|
|
|
// See also: http://www.e-navigation.nl/asm
|
|
|
|
#include "ais.h"
|
|
|
|
namespace libais {
|
|
|
|
Ais26::Ais26(const char *nmea_payload, const size_t pad)
|
|
: AisMsg(nmea_payload, pad), use_app_id(false), dest_mmsi_valid(false),
|
|
dest_mmsi(0), dac(0), fi(0), commstate_flag(0), sync_state(0),
|
|
slot_timeout_valid(false), slot_timeout(0),
|
|
received_stations_valid(false), received_stations(0),
|
|
slot_number_valid(false), slot_number(0),
|
|
utc_valid(false), utc_hour(0), utc_min(0), utc_spare(0),
|
|
slot_offset_valid(false), slot_offset(0),
|
|
slot_increment_valid(false), slot_increment(0),
|
|
slots_to_allocate_valid(false), slots_to_allocate(0),
|
|
keep_flag_valid(false), keep_flag(false) {
|
|
if (!CheckStatus()) {
|
|
return;
|
|
}
|
|
|
|
// TODO(schwehr): Check for off by one.
|
|
const size_t comm_flag_offset = num_bits - 20;
|
|
|
|
if (num_bits < 52 || num_bits > 1064) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
|
|
assert(message_id == 26);
|
|
|
|
bits.SeekTo(38);
|
|
const bool addressed = bits[38];
|
|
use_app_id = bits[39];
|
|
if (addressed) {
|
|
dest_mmsi_valid = true;
|
|
dest_mmsi = bits.ToUnsignedInt(40, 30);
|
|
if (use_app_id) {
|
|
if (num_bits < 86) {
|
|
status = AIS_ERR_BAD_BIT_COUNT;
|
|
return;
|
|
}
|
|
dac = bits.ToUnsignedInt(70, 10);
|
|
fi = bits.ToUnsignedInt(80, 6);
|
|
}
|
|
// TODO(schwehr): Handle the payload.
|
|
} else {
|
|
// broadcast
|
|
if (use_app_id) {
|
|
dac = bits.ToUnsignedInt(40, 10);
|
|
fi = bits.ToUnsignedInt(50, 6);
|
|
}
|
|
// TODO(schwehr): Handle the payload.
|
|
}
|
|
|
|
bits.SeekTo(comm_flag_offset);
|
|
commstate_flag = bits[comm_flag_offset];
|
|
sync_state = bits.ToUnsignedInt(comm_flag_offset + 1, 2); // SOTDMA and TDMA.
|
|
|
|
if (!commstate_flag) {
|
|
// SOTDMA
|
|
slot_timeout = bits.ToUnsignedInt(comm_flag_offset + 3, 3);
|
|
slot_timeout_valid = true;
|
|
switch (slot_timeout) {
|
|
case 0:
|
|
slot_offset = bits.ToUnsignedInt(comm_flag_offset + 6, 14);
|
|
slot_offset_valid = true;
|
|
break;
|
|
case 1:
|
|
utc_hour = bits.ToUnsignedInt(comm_flag_offset + 6, 5);
|
|
utc_min = bits.ToUnsignedInt(comm_flag_offset + 11, 7);
|
|
utc_spare = bits.ToUnsignedInt(comm_flag_offset + 18, 2);
|
|
utc_valid = true;
|
|
break;
|
|
case 2: // FALLTHROUGH
|
|
case 4: // FALLTHROUGH
|
|
case 6:
|
|
slot_number = bits.ToUnsignedInt(comm_flag_offset + 6, 14);
|
|
slot_number_valid = true;
|
|
break;
|
|
case 3: // FALLTHROUGH
|
|
case 5: // FALLTHROUGH
|
|
case 7:
|
|
received_stations = bits.ToUnsignedInt(comm_flag_offset + 6, 14);
|
|
received_stations_valid = true;
|
|
break;
|
|
default:
|
|
assert(false);
|
|
}
|
|
} else {
|
|
// ITDMA
|
|
slot_increment = bits.ToUnsignedInt(comm_flag_offset + 3, 13);
|
|
slot_increment_valid = true;
|
|
|
|
slots_to_allocate = bits.ToUnsignedInt(comm_flag_offset + 16, 3);
|
|
slots_to_allocate_valid = true;
|
|
|
|
keep_flag = bits[comm_flag_offset + 19];
|
|
keep_flag_valid = true;
|
|
}
|
|
|
|
// TODO(schwehr): Add assert(bits.GetRemaining() == 0);
|
|
status = AIS_OK;
|
|
}
|
|
|
|
} // namespace libais
|