// IMO Circ 289 - Clearance time to enter port Ais6_1_18::Ais6_1_18(const char *nmea_payload, const size_t pad) : Ais6(nmea_payload, pad), link_id(0), utc_month(0), utc_day(0), utc_hour(0), utc_min(0), spare2() { assert(dac == 1); assert(fi == 18); if (num_bits != 360) { status = AIS_ERR_BAD_BIT_COUNT; return; } AisBitset bs; const AIS_STATUS r = bs.ParseNmeaPayload(nmea_payload, pad); if (r != AIS_OK) { status = r; return; } link_id = bs.ToUnsignedInt(88, 10); utc_month = bs.ToUnsignedInt(98, 4); utc_day = bs.ToUnsignedInt(102, 5); utc_hour = bs.ToUnsignedInt(107, 5); utc_min = bs.ToUnsignedInt(112, 6); port_berth = bs.ToString(118, 120); dest = bs.ToString(238, 30); position = bs.ToAisPoint(268, 49); spare2[0] = bs.ToUnsignedInt(317, 32); spare2[1] = bs.ToUnsignedInt(349, 11); assert(bs.GetRemaining() == 0); status = AIS_OK; }
Ais8_1_26_Location::Ais8_1_26_Location(const AisBitset &bits, const size_t offset) { position = bits.ToAisPoint(offset, 55); z = bits.ToUnsignedInt(offset + 55, 11) / 10.; owner = bits.ToUnsignedInt(offset + 66, 4); timeout = bits.ToUnsignedInt(offset + 70, 3); spare = bits.ToUnsignedInt(offset + 73, 12); }
Ais8_366_22_Sector::Ais8_366_22_Sector(const AisBitset &bits, const size_t offset) { const int scale_factor = bits.ToUnsignedInt(offset + 3, 2); position = bits.ToAisPoint(offset + 5, 55); radius_m = bits.ToUnsignedInt(offset + 60, 12) * scale_multipliers[scale_factor]; left_bound_deg = bits.ToUnsignedInt(offset + 72, 9); right_bound_deg = bits.ToUnsignedInt(offset + 81, 9); }
Ais8_366_22_Rect::Ais8_366_22_Rect(const AisBitset &bs, const size_t offset) { const int scale_factor = bs.ToUnsignedInt(offset + 3, 2); position = bs.ToAisPoint(offset + 5, 55); e_dim_m = bs.ToUnsignedInt(offset + 60, 8) * scale_multipliers[scale_factor]; n_dim_m = bs.ToUnsignedInt(offset + 68, 8) * scale_multipliers[scale_factor]; orient_deg = bs.ToUnsignedInt(offset + 76, 9); spare = bs.ToUnsignedInt(offset + 85, 5); }
Ais8_366_22_Circle::Ais8_366_22_Circle(const AisBitset &bits, const size_t offset) { const int scale_factor = bits.ToUnsignedInt(offset + 3, 2); position = bits.ToAisPoint(offset + 5, 55); // TODO(schwehr): precision? And bit counts for radius and spare? // TODO(schwehr): collapse these numbers radius_m = bits.ToUnsignedInt(offset + 60, 12) * scale_multipliers[scale_factor]; spare = bits.ToUnsignedInt(offset + 72, 16); }
// IMO Circ 289 - Berthing data Ais6_1_20::Ais6_1_20(const char *nmea_payload, const size_t pad) : Ais6(nmea_payload, pad), link_id(0), length(0), depth(0.0), mooring_position(0), utc_month(0), utc_day(0), utc_hour(0), utc_min(0), services_known(false), services() { assert(dac == 1); assert(fi == 20); if (num_bits != 360) { status = AIS_ERR_BAD_BIT_COUNT; return; } AisBitset bs; const AIS_STATUS r = bs.ParseNmeaPayload(nmea_payload, pad); if (r != AIS_OK) { status = r; return; } bs.SeekTo(88); link_id = bs.ToUnsignedInt(88, 10); length = bs.ToUnsignedInt(98, 9); depth = bs.ToUnsignedInt(107, 8); mooring_position = bs.ToUnsignedInt(115, 3); utc_month = bs.ToUnsignedInt(118, 4); utc_day = bs.ToUnsignedInt(122, 5); utc_hour = bs.ToUnsignedInt(127, 5); utc_min = bs.ToUnsignedInt(132, 6); services_known = bs[138]; for (size_t serv_num = 0; serv_num < 26; serv_num++) { // TODO(schwehr): const int val = bs.ToUnsignedInt(139 + 2*serv_num, 2); services[serv_num] = static_cast<int>(bs.ToUnsignedInt(139 + 2*serv_num, 2)); } name = bs.ToString(191, 120); position = bs.ToAisPoint(311, 49); assert(bs.GetRemaining() == 0); status = AIS_OK; }
// IMO Circ 289 - Tidal window // See also Circ 236 Ais6_1_32::Ais6_1_32(const char *nmea_payload, const size_t pad) : Ais6(nmea_payload, pad), utc_month(0), utc_day(0) { assert(dac == 1); assert(fi == 32); // TODO(schwehr): might get messages with not all windows if (num_bits != 350) { status = AIS_ERR_BAD_BIT_COUNT; return; } AisBitset bs; const AIS_STATUS r = bs.ParseNmeaPayload(nmea_payload, pad); if (r != AIS_OK) { status = r; return; } bs.SeekTo(88); utc_month = bs.ToUnsignedInt(88, 4); utc_day = bs.ToUnsignedInt(92, 5); for (size_t window_num = 0; window_num < 3; window_num++) { Ais6_1_32_Window w; const size_t start = 97 + 88*window_num; w.position = bs.ToAisPoint(start, 49); w.from_utc_hour = bs.ToUnsignedInt(start + 49, 5); w.from_utc_min = bs.ToUnsignedInt(start + 54, 6); w.to_utc_hour = bs.ToUnsignedInt(start + 60, 5); w.to_utc_min = bs.ToUnsignedInt(start + 65, 6); w.cur_dir = bs.ToUnsignedInt(start + 71, 9); w.cur_speed = bs.ToUnsignedInt(start + 80, 8) / 10.; windows.push_back(w); } assert(bs.GetRemaining() == 0); status = AIS_OK; }
Ais23::Ais23(const char *nmea_payload, const size_t pad) : AisMsg(nmea_payload, pad), spare(0), station_type(0), type_and_cargo(0), spare2(3), txrx_mode(0), interval_raw(0), quiet(0), spare3(0) { assert(message_id == 23); if (pad != 2 || num_chars != 27) { status = AIS_ERR_BAD_BIT_COUNT; return; } AisBitset bs; const AIS_STATUS r = bs.ParseNmeaPayload(nmea_payload, pad); if (r != AIS_OK) { status = r; return; } bs.SeekTo(38); spare = bs.ToUnsignedInt(38, 2); position1 = bs.ToAisPoint(40, 35); position2 = bs.ToAisPoint(75, 35); station_type = bs.ToUnsignedInt(110, 4); type_and_cargo = bs.ToUnsignedInt(114, 8); spare2 = bs.ToUnsignedInt(122, 22); txrx_mode = bs.ToUnsignedInt(144, 2); interval_raw = bs.ToUnsignedInt(146, 4); quiet = bs.ToUnsignedInt(150, 4); spare3 = bs.ToUnsignedInt(154, 6); assert(bs.GetRemaining() == 0); status = AIS_OK; }
Ais18::Ais18(const char *nmea_payload, const size_t pad) : AisMsg(nmea_payload, pad), spare(0), sog(0.0), position_accuracy(0), cog(0.0), true_heading(0), timestamp(0), spare2(0), unit_flag(0), display_flag(0), dsc_flag(0), band_flag(0), m22_flag(0), mode_flag(0), raim(false), 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(0), commstate_cs_fill_valid(false), commstate_cs_fill(0) { assert(message_id == 18); if (pad != 0 || num_chars != 28) { status = AIS_ERR_BAD_BIT_COUNT; return; } AisBitset bs; const AIS_STATUS r = bs.ParseNmeaPayload(nmea_payload, pad); if (r != AIS_OK) { status = r; return; } bs.SeekTo(38); spare = bs.ToUnsignedInt(38, 8); sog = bs.ToUnsignedInt(46, 10) / 10.; position_accuracy = bs[56]; position = bs.ToAisPoint(57, 55); cog = bs.ToUnsignedInt(112, 12) / 10.; true_heading = bs.ToUnsignedInt(124, 9); timestamp = bs.ToUnsignedInt(133, 6); spare2 = bs.ToUnsignedInt(139, 2); unit_flag = bs[141]; display_flag = bs[142]; dsc_flag = bs[143]; band_flag = bs[144]; m22_flag = bs[145]; mode_flag = bs[146]; raim = bs[147]; commstate_flag = bs[148]; // 0 SOTDMA, 1 ITDMA if (unit_flag == 0) { sync_state = bs.ToUnsignedInt(149, 2); if (commstate_flag == 0) { // SOTDMA slot_timeout = bs.ToUnsignedInt(151, 3); slot_timeout_valid = true; switch (slot_timeout) { case 0: slot_offset = bs.ToUnsignedInt(154, 14); slot_offset_valid = true; break; case 1: utc_hour = bs.ToUnsignedInt(154, 5); utc_min = bs.ToUnsignedInt(159, 7); utc_spare = bs.ToUnsignedInt(166, 2); utc_valid = true; break; case 2: // FALLTHROUGH case 4: // FALLTHROUGH case 6: slot_number = bs.ToUnsignedInt(154, 14); slot_number_valid = true; break; case 3: // FALLTHROUGH case 5: // FALLTHROUGH case 7: received_stations = bs.ToUnsignedInt(154, 14); received_stations_valid = true; break; default: assert(false); } } else { // ITDMA slot_increment = bs.ToUnsignedInt(151, 13); slot_increment_valid = true; slots_to_allocate = bs.ToUnsignedInt(164, 3); slots_to_allocate_valid = true; keep_flag = bs[167]; keep_flag_valid = true; } } else { // Carrier Sense (CS) with unit_flag of 1. commstate_cs_fill = bs.ToUnsignedInt(149, 19); commstate_cs_fill_valid = true; } assert(bs.GetRemaining() == 0); status = AIS_OK; }