SeaTalk: message 54 added.
[marnav.git] / src / marnav / seatalk / message_51.cpp
blobb21e94e1d1a8d59c837a8119a5309d5fdfba5045
1 #include "message_51.hpp"
3 namespace marnav
5 namespace seatalk
8 message_51::message_51()
9 : message(ID)
13 std::unique_ptr<message> message_51::parse(const raw & data)
15 if (data.size() != 5)
16 throw std::invalid_argument{"invalid number of bytes in message_51::parse"};
17 if ((data[1] & 0x0f) != 0x02)
18 throw std::invalid_argument{"invalid size specified in message"};
20 std::unique_ptr<message> result = utils::make_unique<message_51>();
21 message_51 & msg = static_cast<message_51 &>(*result);
23 // 51 Z2 XX YY YY
24 // raw 1 2 3 4
26 const uint32_t degrees = data[2];
27 uint32_t m = 0;
28 m += data[3];
29 m <<= 8;
30 m += data[4];
32 const uint32_t minutes = (m & 0x7fff) / 100;
33 const uint32_t seconds = (((m & 0x7fff) % 100) * 60) / 100;
34 const geo::longitude::hemisphere hemisphere
35 = (m & 0x8000) ? geo::longitude::hemisphere::EAST : geo::longitude::hemisphere::WEST;
37 msg.lon = geo::longitude{degrees, minutes, seconds, hemisphere};
39 // deliberately ignored 'Z'
41 return result;
44 raw message_51::get_data() const
46 uint16_t m = 0;
47 m += lon.minutes() * 100;
48 m += (lon.seconds() * 100) / 60;
49 if (lon.hem() == geo::longitude::hemisphere::EAST)
50 m |= 0x8000;
52 return raw{static_cast<uint8_t>(ID), 0x02, static_cast<uint8_t>(lon.degrees() & 0xff),
53 static_cast<uint8_t>((m >> 8) & 0xff), static_cast<uint8_t>((m >> 0) & 0xff)};