schwehr / libais

C++ decoder for Automatic Identification System for tracking ships and decoding maritime information
Other
215 stars 94 forks source link

Add parsing support for 8:367:23, 8:367:24, 8:367:25, 8:367:33. #219

Open andyvan-trabus opened 2 years ago

andyvan-trabus commented 2 years ago

This adds support for parsing the USCG 23, 24, 25, and 33 messages. I've tested this with live messages, and have added one each of those live messages as a test case.

schwehr commented 2 years ago

Please also make sure to link to the message specification in both the PR text and the code.

andyvan-trabus commented 2 years ago

Kurt, Since you only commented on this PR and not the cut-down version, I've removed the other messages from THIS PR, and I believe I have addressed your other comments.

schwehr commented 2 years ago

Using this PR is fine. I've merged a couple cleanup PRs. These are fixes to use unique_ptr and moving to always using std::

Also, I'd like to try to get away from putting the initializing in constructor switching to the default member initializer style (see data_members). I will be trying to do that for the whole of the library. So if you are up for doing that on this CL that would be very helpful. e.g.

class AisMsg {
 public:
  int message_id = 0;  // <-- default member initializer`
  int repeat_indicator = 0;
  int mmsi = 0;

  // TODO(schwehr): make status private and have accessors.
  bool had_error() const {  return status != AIS_OK;  }
  AIS_STATUS get_error() const { return status; }

  virtual ~AisMsg() {}

 protected:
  AIS_STATUS status = AIS_UNINITIALIZED;  // AIS_OK or error code
  int num_chars = 0;  // Number of characters in the nmea_payload.
  size_t num_bits = 0;  // Number of bits in the nmea_payload.
  AisBitset bits = {};  // Bitset that was constructed out of the nmea_payload.

  AisMsg() : status(AIS_UNINITIALIZED), num_chars(0), num_bits(0), bits() {}
  AisMsg(const char *nmea_payload, const size_t pad);

  // Returns true if the msg is in a good state "so far", i.e. either AIS_OK or
  // AIS_UNINITIALIZED.
  bool CheckStatus() const;
};

and

AisMsg::AisMsg(const char *nmea_payload, const size_t pad) {  // <-- Drop the initializer list
  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.num_bits();
  num_chars = bits.num_chars();

  if (num_bits < 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);
}