diff --git a/lib/aisparser/ais_decoder.cpp b/lib/aisparser/ais_decoder.cpp index 6fece95..3c5dc00 100644 --- a/lib/aisparser/ais_decoder.cpp +++ b/lib/aisparser/ais_decoder.cpp @@ -627,7 +627,7 @@ void AisDecoder::decodeType21(PayloadBuffer &_buffer, unsigned int _uMsgType, in } // decode message fields (binary buffer has to go through all fields, but some fields are not used) - _buffer.getUnsignedValue(2); // repeatIndicator + auto repeat=_buffer.getUnsignedValue(2); // repeatIndicator auto mmsi = _buffer.getUnsignedValue(30); auto aidType = _buffer.getUnsignedValue(5); auto name = _buffer.getString(120); @@ -640,11 +640,11 @@ void AisDecoder::decodeType21(PayloadBuffer &_buffer, unsigned int _uMsgType, in auto toStarboard = _buffer.getUnsignedValue(6); _buffer.getUnsignedValue(4); // epfd type - _buffer.getUnsignedValue(6); // timestamp - _buffer.getBoolValue(); // off position + auto timestamp=_buffer.getUnsignedValue(6); // timestamp + auto offPosition=_buffer.getBoolValue(); // off position _buffer.getUnsignedValue(8); // reserved - _buffer.getBoolValue(); // RAIM - _buffer.getBoolValue(); // virtual aid + auto raim=_buffer.getBoolValue(); // RAIM + auto virtualAton=_buffer.getBoolValue(); // virtual aid _buffer.getBoolValue(); // assigned mode _buffer.getUnsignedValue(1); // spare @@ -654,7 +654,9 @@ void AisDecoder::decodeType21(PayloadBuffer &_buffer, unsigned int _uMsgType, in nameExt = _buffer.getString(88); } - onType21(mmsi, aidType, name + nameExt, posAccuracy, posLon, posLat, toBow, toStern, toPort, toStarboard); + onType21(mmsi, aidType, name + nameExt, posAccuracy, posLon, posLat, + toBow, toStern, toPort, toStarboard, + repeat,timestamp, raim, virtualAton, offPosition); } /* decode Voyage Report and Static Data (type nibble already pulled from buffer) */ diff --git a/lib/aisparser/ais_decoder.h b/lib/aisparser/ais_decoder.h index c908839..7872d3b 100644 --- a/lib/aisparser/ais_decoder.h +++ b/lib/aisparser/ais_decoder.h @@ -297,7 +297,8 @@ namespace AIS bool assigned, unsigned int repeat, bool raim) = 0; virtual void onType21(unsigned int _uMmsi, unsigned int _uAidType, const std::string &_strName, bool _bPosAccuracy, int _iPosLon, int _iPosLat, - unsigned int _uToBow, unsigned int _uToStern, unsigned int _uToPort, unsigned int _uToStarboard) = 0; + unsigned int _uToBow, unsigned int _uToStern, unsigned int _uToPort, unsigned int _uToStarboard, + unsigned int repeat,unsigned int timestamp, bool raim, bool virtualAton, bool offPosition) = 0; virtual void onType24A(unsigned int _uMsgType, unsigned int _repeat, unsigned int _uMmsi, const std::string &_strName) = 0; diff --git a/lib/nmea0183ton2k/NMEA0183AIStoNMEA2000.h b/lib/nmea0183ton2k/NMEA0183AIStoNMEA2000.h index 70ba754..5f4e5ee 100644 --- a/lib/nmea0183ton2k/NMEA0183AIStoNMEA2000.h +++ b/lib/nmea0183ton2k/NMEA0183AIStoNMEA2000.h @@ -84,25 +84,24 @@ class MyAisDecoder : public AIS::AisDecoder tN2kMsg N2kMsg; - // PGN129038 - - N2kMsg.SetPGN(129038L); - N2kMsg.Priority = 4; - N2kMsg.AddByte((_Repeat & 0x03) << 6 | (_uMsgType & 0x3f)); - N2kMsg.Add4ByteUInt(_uMmsi); - N2kMsg.Add4ByteDouble(_iPosLon / 600000.0, 1e-07); - N2kMsg.Add4ByteDouble(_iPosLat / 600000.0, 1e-07); - N2kMsg.AddByte((_timestamp & 0x3f) << 2 | (_Raim & 0x01) << 1 | (_bPosAccuracy & 0x01)); - N2kMsg.Add2ByteUDouble(decodeCog(_iCog), 1e-04); - N2kMsg.Add2ByteUDouble(_uSog * knToms/10.0, 0.01); - N2kMsg.AddByte(0x00); // Communication State (19 bits) - N2kMsg.AddByte(0x00); - N2kMsg.AddByte(0x00); // AIS transceiver information (5 bits) - N2kMsg.Add2ByteUDouble(decodeHeading(_iHeading), 1e-04); - N2kMsg.Add2ByteDouble(decodeRot(_iRot), 3.125E-05); // 1e-3/32.0 - N2kMsg.AddByte(0xF0 | (_uNavstatus & 0x0f)); - N2kMsg.AddByte(0xff); // Reserved - N2kMsg.AddByte(0xff); // SID (NA) + SetN2kPGN129038( + N2kMsg, + _uMsgType, + (tN2kAISRepeat)_Repeat, + _uMmsi, + _iPosLon/ 600000.0, + _iPosLat / 600000.0, + _bPosAccuracy, + _Raim, + _timestamp, + decodeCog(_iCog), + _uSog * knToms/10.0, + tN2kAISTransceiverInformation::N2kaischannel_A_VDL_reception, + decodeHeading(_iHeading), + decodeRot(_iRot), + (tN2kAISNavStatus)_uNavstatus, + 0xff + ); send(N2kMsg); } @@ -258,16 +257,14 @@ class MyAisDecoder : public AIS::AisDecoder } //mmsi, aidType, name + nameExt, posAccuracy, posLon, posLat, toBow, toStern, toPort, toStarboard - virtual void onType21(unsigned int mmsi , unsigned int aidType , const std::string & name, bool accuracy, int posLon, int posLat, unsigned int toBow, unsigned int toStern, unsigned int toPort, unsigned int toStarboard) override { + virtual void onType21(unsigned int mmsi , unsigned int aidType , const std::string & name, bool accuracy, int posLon, int posLat, unsigned int toBow, + unsigned int toStern, unsigned int toPort, unsigned int toStarboard, + unsigned int repeat,unsigned int timestamp, bool raim, bool virtualAton, bool offPosition) override { //Serial.println("21"); + //the name can be at most 120bit+88bit (35 byte) + termination -> 36 Byte //in principle we should use tN2kAISAtoNReportData to directly call the library //function for 129041. But this makes the conversion really complex. - int repeat=0; //TODO: should be part of the parameters - int seconds=0; - bool raim=false; - bool offPosition=false; bool assignedMode=false; - bool virtualAton=false; tN2kGNSStype gnssType=tN2kGNSStype::N2kGNSSt_GPS; //canboat considers 0 as undefined... tN2kAISTransceiverInformation transceiverInfo=tN2kAISTransceiverInformation::N2kaischannel_A_VDL_reception; tN2kMsg N2kMsg; @@ -277,7 +274,7 @@ class MyAisDecoder : public AIS::AisDecoder N2kMsg.Add4ByteUInt(mmsi); //N2kData.UserID N2kMsg.Add4ByteDouble(posLon / 600000.0, 1e-07); N2kMsg.Add4ByteDouble(posLat / 600000.0, 1e-07); - N2kMsg.AddByte((seconds & 0x3f)<<2 | boolbit(raim)<<1 | boolbit(accuracy)); + N2kMsg.AddByte((timestamp & 0x3f)<<2 | boolbit(raim)<<1 | boolbit(accuracy)); N2kMsg.Add2ByteUDouble(toBow+toStern, 0.1); N2kMsg.Add2ByteUDouble(toPort+toStarboard, 0.1); N2kMsg.Add2ByteUDouble(toStarboard, 0.1); @@ -289,6 +286,8 @@ class MyAisDecoder : public AIS::AisDecoder N2kMsg.AddByte((gnssType & 0x0F) << 1 | 0xe0); N2kMsg.AddByte(N2kUInt8NA); //status N2kMsg.AddByte((transceiverInfo & 0x1f) | 0xe0); + //bit offset 208 (see canboat/pgns.xml) -> 26 bytes from start + //as MaxDataLen is 223 and the string can be at most 36 bytes + 2 byte heading - no further check here N2kMsg.AddVarStr(name.c_str()); send(N2kMsg); }