Skip to content

Commit

Permalink
Merge pull request #1 from ttlappalainen/master
Browse files Browse the repository at this point in the history
Updating my fork
  • Loading branch information
thomasonw authored Jun 25, 2016
2 parents 9dea0d5 + a804b96 commit 86b4662
Show file tree
Hide file tree
Showing 7 changed files with 646 additions and 11 deletions.
342 changes: 340 additions & 2 deletions N2kMessages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,115 @@ bool ParseN2kPGN129029(const tN2kMsg &N2kMsg, unsigned char &SID, uint16_t &Days

return true;
}


//*****************************************************************************
// AIS position report (class A 129038)
void SetN2kPGN129038(tN2kMsg &N2kMsg, uint8_t MessageID, tN2kAISRepeat Repeat, uint32_t UserID,
double Latitude, double Longitude, bool Accuracy, bool RAIM, uint8_t Seconds,
double COG, double SOG, double Heading, double ROT, tN2kAISNavStatus NavStatus)
{
N2kMsg.SetPGN(129038L);
N2kMsg.Priority=6;
N2kMsg.AddByte((Repeat & 0x03)<<6 | (MessageID & 0x3f));
N2kMsg.Add4ByteUInt(UserID);
N2kMsg.Add4ByteDouble(Longitude, 1e-07);
N2kMsg.Add4ByteDouble(Latitude, 1e-07);
N2kMsg.AddByte((Seconds & 0x3f)<<2 | (RAIM & 0x01)<<1 | (Accuracy & 0x01));
N2kMsg.Add2ByteUDouble(COG, 1e-04);
N2kMsg.Add2ByteUDouble(SOG, 0.01);
N2kMsg.AddByte(0xff); // Communication State (19 bits)
N2kMsg.AddByte(0xff);
N2kMsg.AddByte(0xff); // AIS transceiver information (5 bits)
N2kMsg.Add2ByteUDouble(Heading, 1e-04);
N2kMsg.Add2ByteDouble(ROT, ((1e-3/32.0) * 0.0001));
N2kMsg.AddByte(0xF0 | (NavStatus & 0x0f));
N2kMsg.AddByte(0xff); // Reserved
}

bool ParseN2kPGN129038(const tN2kMsg &N2kMsg, uint8_t &MessageID, tN2kAISRepeat &Repeat, uint32_t &UserID,
double &Latitude, double &Longitude, bool &Accuracy, bool &RAIM, uint8_t &Seconds,
double &COG, double &SOG, double &Heading, double &ROT, tN2kAISNavStatus &NavStatus)
{
if (N2kMsg.PGN!=129038L) return false;

int Index=0;
unsigned char vb;

vb=N2kMsg.GetByte(Index); MessageID=(vb & 0x3f); Repeat=(tN2kAISRepeat)(vb>>6 & 0x03);
UserID=N2kMsg.Get4ByteUInt(Index);
Longitude=N2kMsg.Get4ByteDouble(1e-07, Index);
Latitude=N2kMsg.Get4ByteDouble(1e-07, Index);
vb=N2kMsg.GetByte(Index); Accuracy=(vb & 0x01); RAIM=(vb>>1 & 0x01); Seconds=(vb>>2 & 0x3f);
COG=N2kMsg.Get2ByteUDouble(1e-04, Index);
SOG=N2kMsg.Get2ByteUDouble(0.01, Index);
vb=N2kMsg.GetByte(Index); // Communication State (19 bits)
vb=N2kMsg.GetByte(Index);
vb=N2kMsg.GetByte(Index); // AIS transceiver information (5 bits)
Heading=N2kMsg.Get2ByteUDouble(1e-04, Index);
ROT=N2kMsg.Get2ByteDouble(((1e-3/32.0) * 0.0001), Index);
vb=N2kMsg.GetByte(Index); NavStatus=(tN2kAISNavStatus)(vb & 0x0f);
vb=N2kMsg.GetByte(Index); // Reserved

return true;
}

//*****************************************************************************
// AIS position report (class B 129039)
void SetN2kPGN129039(tN2kMsg &N2kMsg, uint8_t MessageID, tN2kAISRepeat Repeat, uint32_t UserID,
double Latitude, double Longitude, bool Accuracy, bool RAIM,
uint8_t Seconds, double COG, double SOG, double Heading, tN2kAISUnit Unit,
bool Display, bool DSC, bool Band, bool Msg22, tN2kAISMode Mode, bool State)
{
N2kMsg.SetPGN(129039L);
N2kMsg.Priority=6;
N2kMsg.AddByte((Repeat & 0x03)<<6 | (MessageID & 0x3f));
N2kMsg.Add4ByteUInt(UserID);
N2kMsg.Add4ByteDouble(Longitude, 1e-07);
N2kMsg.Add4ByteDouble(Latitude, 1e-07);
N2kMsg.AddByte((Seconds & 0x3f)<<2 | (RAIM & 0x01)<<1 | (Accuracy & 0x01));
N2kMsg.Add2ByteUDouble(COG, 1e-04);
N2kMsg.Add2ByteUDouble(SOG, 0.01);
N2kMsg.AddByte(0xff); // Communication State (19 bits)
N2kMsg.AddByte(0xff);
N2kMsg.AddByte(0xff); // AIS transceiver information (5 bits)
N2kMsg.Add2ByteUDouble(Heading, 1e-04);
N2kMsg.AddByte(0xff); // Regional application
N2kMsg.AddByte((Mode & 0x01)<<7 | (Msg22 & 0x01)<<6 | (Band & 0x01)<<5 |
(DSC & 0x01)<<4 | (Display & 0x01)<<3 | (Unit & 0x01)<<2);
N2kMsg.AddByte(0xfe | (State & 0x01));
}


bool ParseN2kPGN129039(const tN2kMsg &N2kMsg, uint8_t &MessageID, tN2kAISRepeat &Repeat, uint32_t &UserID,
double &Latitude, double &Longitude, bool &Accuracy, bool &RAIM,
uint8_t &Seconds, double &COG, double &SOG, double &Heading, tN2kAISUnit &Unit,
bool &Display, bool &DSC, bool &Band, bool &Msg22, tN2kAISMode &Mode, bool &State)
{
if (N2kMsg.PGN!=129039L) return false;

int Index=0;
unsigned char vb;

vb=N2kMsg.GetByte(Index); MessageID=(vb & 0x3f); Repeat=(tN2kAISRepeat)(vb>>6 & 0x03);
UserID=N2kMsg.Get4ByteUInt(Index);
Longitude=N2kMsg.Get4ByteDouble(1e-07, Index);
Latitude=N2kMsg.Get4ByteDouble(1e-07, Index);
vb=N2kMsg.GetByte(Index); Accuracy=(vb & 0x01); RAIM=(vb>>1 & 0x01); Seconds=(vb>>2 & 0x3f);
COG=N2kMsg.Get2ByteUDouble(1e-04, Index);
SOG=N2kMsg.Get2ByteUDouble(0.01, Index);
vb=N2kMsg.GetByte(Index); // Communication State (19 bits)
vb=N2kMsg.GetByte(Index);
vb=N2kMsg.GetByte(Index); // AIS transceiver information (5 bits)
Heading=N2kMsg.Get2ByteUDouble(1e-04, Index);
vb=N2kMsg.GetByte(Index); // Regional application
vb=N2kMsg.GetByte(Index);
Unit=(tN2kAISUnit)(vb>>2 & 0x01); Display=(vb>>3 & 0x01); DSC=(vb>>4 & 0x01);
Band=(vb>>5 & 0x01); Msg22=(vb>>6 & 0x01); Mode=(tN2kAISMode)(vb>>7 & 0x01);
vb=N2kMsg.GetByte(Index); State=(vb & 0x01);

return true;
}

//*****************************************************************************
// Cross Track Error
void SetN2kPGN129283(tN2kMsg &N2kMsg, unsigned char SID, tN2kXTEMode XTEMode, bool NavigationTerminated, double XTE) {
Expand All @@ -557,6 +665,8 @@ void SetN2kPGN129283(tN2kMsg &N2kMsg, unsigned char SID, tN2kXTEMode XTEMode, bo
N2kMsg.AddByte(SID);
N2kMsg.AddByte((char)XTEMode | (NavigationTerminated?0x40:0));
N2kMsg.Add4ByteDouble(XTE,0.01);
N2kMsg.AddByte(0xff); // Reserved
N2kMsg.AddByte(0xff); // Reserved
}

//*****************************************************************************
Expand All @@ -582,9 +692,237 @@ void SetN2kPGN129284(tN2kMsg &N2kMsg, unsigned char SID, double DistanceToWaypoi
N2kMsg.Add2ByteDouble(WaypointClosingVelocity,0.01);
}

//*****************************************************************************
// Waypoint list
void SetN2kPGN129285(tN2kMsg &N2kMsg, uint16_t Start, uint16_t Database, uint16_t Route,
bool NavDirection, bool SupplementaryData, char* RouteName) {
unsigned int i;
N2kMsg.SetPGN(129285L);
N2kMsg.Priority=6;
N2kMsg.Add2ByteUInt(Start);
N2kMsg.Add2ByteUInt(0); // number of items initially 0
N2kMsg.Add2ByteUInt(Database);
N2kMsg.Add2ByteUInt(Route);
N2kMsg.AddByte(0xC0 | (SupplementaryData & 0x03)<<4 | (NavDirection & 0x0F));
if (strlen(RouteName) == 0) {
N2kMsg.AddByte(0x03);N2kMsg.AddByte(0x01);N2kMsg.AddByte(0x00);
} else {
N2kMsg.AddByte(strlen(RouteName)+2);N2kMsg.AddByte(0x01);
for (i=0; i<strlen(RouteName); i++)
N2kMsg.AddByte(RouteName[i]);
}
N2kMsg.AddByte(0xff); // reserved
}

bool AppendN2kPGN129285(tN2kMsg &N2kMsg, uint16_t ID, char* Name, double Latitude, double Longitude) {
if (N2kMsg.PGN!=129285L) return false;

unsigned int i;
int NumItemsIdx, len;
uint16_t NumItems;

if (strlen(Name) > 0)
len = 12 + strlen(Name);
else
len = 13;

if (N2kMsg.DataLen + len < N2kMsg.MaxDataLen) {
NumItemsIdx = 2;
NumItems = N2kMsg.Get2ByteUInt(NumItemsIdx); // get and increment the number of items
NumItemsIdx = 2;
N2kMsg.Set2ByteUInt(++NumItems, NumItemsIdx); // increment the number of items
N2kMsg.Add2ByteUInt(ID); // add the new item
if (strlen(Name) == 0) {
N2kMsg.AddByte(0x03);N2kMsg.AddByte(0x01);N2kMsg.AddByte(0x00);
} else {
N2kMsg.AddByte(strlen(Name)+2);N2kMsg.AddByte(0x01);
for (i=0; i<strlen(Name); i++)
N2kMsg.AddByte(Name[i]);
}
N2kMsg.Add4ByteDouble(Latitude,1e-07);
N2kMsg.Add4ByteDouble(Longitude,1e-07);
return true;
} else
return false;
}

//*****************************************************************************
// AIS static data A
void SetN2kPGN129794(tN2kMsg &N2kMsg, uint8_t MessageID, tN2kAISRepeat Repeat, uint32_t UserID,
uint32_t IMOnumber, char *Callsign, char *Name, uint8_t VesselType, double Length,
double Beam, double PosRefStbd, double PosRefBow, uint16_t ETAdate, double ETAtime,
double Draught, char *Destination, tN2kAISVersion AISversion, tN2kGNSStype GNSStype,
tN2kAISDTE DTE, tN2kAISTranceiverInfo AISinfo)
{
N2kMsg.SetPGN(129794L);
N2kMsg.Priority=6;
N2kMsg.AddByte((Repeat & 0x03)<<6 | (MessageID & 0x3f));
N2kMsg.Add4ByteUInt(UserID);
N2kMsg.Add4ByteUInt(IMOnumber);
N2kMsg.AddStr(Callsign, 7);
N2kMsg.AddStr(Name, 20);
N2kMsg.AddByte(VesselType);
N2kMsg.Add2ByteDouble(Length, 0.1);
N2kMsg.Add2ByteDouble(Beam, 0.1);
N2kMsg.Add2ByteDouble(PosRefStbd, 0.1);
N2kMsg.Add2ByteDouble(PosRefBow, 0.1);
N2kMsg.Add2ByteUInt(ETAdate);
N2kMsg.Add4ByteUDouble(ETAtime, 0.0001);
N2kMsg.Add2ByteDouble(Draught, 0.01);
N2kMsg.AddStr(Destination, 20);
N2kMsg.AddByte((DTE & 0x01)<<6 | (GNSStype & 0x0f)<<2 | (AISversion & 0x03));
N2kMsg.AddByte(AISinfo & 0x1f);
}

bool ParseN2kPGN129794(const tN2kMsg &N2kMsg, uint8_t &MessageID, tN2kAISRepeat &Repeat, uint32_t &UserID,
uint32_t &IMOnumber, char *Callsign, char *Name, uint8_t &VesselType, double &Length,
double &Beam, double &PosRefStbd, double &PosRefBow, uint16_t &ETAdate, double &ETAtime,
double &Draught, char *Destination, tN2kAISVersion &AISversion, tN2kGNSStype &GNSStype,
tN2kAISDTE &DTE, tN2kAISTranceiverInfo &AISinfo)
{
if (N2kMsg.PGN!=129794L) return false;

int Index=0;
unsigned char vb;

vb=N2kMsg.GetByte(Index); MessageID=(vb & 0x3f); Repeat=(tN2kAISRepeat)(vb>>6 & 0x03);
UserID=N2kMsg.Get4ByteUInt(Index);
IMOnumber=N2kMsg.Get4ByteUInt(Index);
N2kMsg.GetStr(Callsign, 7, Index);
N2kMsg.GetStr(Name, 20, Index);
VesselType=N2kMsg.GetByte(Index);
Length=N2kMsg.Get2ByteDouble(0.1, Index);
Beam=N2kMsg.Get2ByteDouble(0.1, Index);
PosRefStbd=N2kMsg.Get2ByteDouble(0.1, Index);
PosRefBow=N2kMsg.Get2ByteDouble(0.1, Index);
ETAdate=N2kMsg.Get2ByteUInt(Index);
ETAtime=N2kMsg.Get4ByteUDouble(0.0001, Index);
Draught=N2kMsg.Get2ByteDouble(0.01, Index);
N2kMsg.GetStr(Destination, 20, Index);
vb=N2kMsg.GetByte(Index); AISversion=(tN2kAISVersion)(vb & 0x03); GNSStype=(tN2kGNSStype)(vb>>2 & 0x0f); DTE=(tN2kAISDTE)(vb>>6 & 0x01);
vb=N2kMsg.GetByte(Index); AISinfo=(tN2kAISTranceiverInfo)(vb & 0x1f);

return true;
}

//*****************************************************************************
// AIS static data class B part A
void SetN2kPGN129809(tN2kMsg &N2kMsg, uint8_t MessageID, tN2kAISRepeat Repeat, uint32_t UserID, char *Name)
{
N2kMsg.SetPGN(129809L);
N2kMsg.Priority=6;
N2kMsg.AddByte((Repeat & 0x03)<<6 | (MessageID & 0x3f));
N2kMsg.Add4ByteUInt(UserID);
N2kMsg.AddStr(Name, 20);
}

bool ParseN2kPGN129809(const tN2kMsg &N2kMsg, uint8_t &MessageID, tN2kAISRepeat &Repeat, uint32_t &UserID, char *Name)
{
if (N2kMsg.PGN!=129809L) return false;

int Index=0;
unsigned char vb;

vb=N2kMsg.GetByte(Index); MessageID=(vb & 0x3f); Repeat=(tN2kAISRepeat)(vb>>6 & 0x03);
UserID=N2kMsg.Get4ByteUInt(Index);
N2kMsg.GetStr(Name, 20, Index);

return true;
}

//*****************************************************************************
// AIS static data class B part B
void SetN2kPGN129810(tN2kMsg &N2kMsg, uint8_t MessageID, tN2kAISRepeat Repeat, uint32_t UserID,
uint8_t VesselType, char *Vendor, char *Callsign, double Length, double Beam,
double PosRefStbd, double PosRefBow, uint32_t MothershipID)
{
N2kMsg.SetPGN(129810L);
N2kMsg.Priority=6;
N2kMsg.AddByte((Repeat & 0x03)<<6 | (MessageID & 0x3f));
N2kMsg.Add4ByteUInt(UserID);
N2kMsg.AddByte(VesselType);
N2kMsg.AddStr(Vendor, 7);
N2kMsg.AddStr(Callsign, 7);
N2kMsg.Add2ByteUDouble(Length, 0.1);
N2kMsg.Add2ByteUDouble(Beam, 0.1);
N2kMsg.Add2ByteUDouble(PosRefStbd, 0.1);
N2kMsg.Add2ByteUDouble(PosRefBow, 0.1);
N2kMsg.Add4ByteUInt(MothershipID);
N2kMsg.AddByte(0xff); // Reserved
}

bool ParseN2kPGN129810(const tN2kMsg &N2kMsg, uint8_t &MessageID, tN2kAISRepeat &Repeat, uint32_t &UserID,
uint8_t &VesselType, char *Vendor, char *Callsign, double &Length, double &Beam,
double &PosRefStbd, double &PosRefBow, uint32_t &MothershipID)
{
if (N2kMsg.PGN!=129810L) return false;

int Index=0;
unsigned char vb;

vb=N2kMsg.GetByte(Index); MessageID=(vb & 0x3f); Repeat=(tN2kAISRepeat)(vb>>6 & 0x03);
UserID=N2kMsg.Get4ByteUInt(Index);
VesselType=N2kMsg.GetByte(Index);
N2kMsg.GetStr(Vendor, 7, Index);
N2kMsg.GetStr(Callsign, 7, Index);
Length = N2kMsg.Get2ByteUDouble(0.1, Index);
Beam = N2kMsg.Get2ByteUDouble(0.1, Index);
PosRefStbd = N2kMsg.Get2ByteUDouble(0.1, Index);
PosRefBow = N2kMsg.Get2ByteUDouble(0.1, Index);
MothershipID = N2kMsg.Get4ByteUInt(Index);

return true;
}

//*****************************************************************************
// Waypoint list
void SetN2kPGN130074(tN2kMsg &N2kMsg, uint16_t Start, uint16_t NumWaypoints, uint16_t Database) {
N2kMsg.SetPGN(130074L);
N2kMsg.Priority=6;
N2kMsg.Add2ByteUInt(Start);
N2kMsg.Add2ByteUInt(0); // set number of items to 0 initially
N2kMsg.Add2ByteUInt(NumWaypoints);
N2kMsg.Add2ByteUInt(Database);
N2kMsg.AddByte(0xff); // Reserved
N2kMsg.AddByte(0xff); // Reserved
}

bool AppendN2kPGN130074(tN2kMsg &N2kMsg, uint16_t ID, char* Name, double Latitude, double Longitude) {
if (N2kMsg.PGN!=130074L) return false;

unsigned int i;
int NumItemsIdx, len;
uint16_t NumItems;

if (strlen(Name) > 0)
len = 12 + strlen(Name);
else
len = 13;

if (N2kMsg.DataLen + len < N2kMsg.MaxDataLen) {
NumItemsIdx = 2;
NumItems = N2kMsg.Get2ByteUInt(NumItemsIdx); // get and increment the number of items
NumItemsIdx = 2;
N2kMsg.Set2ByteUInt(++NumItems, NumItemsIdx); // increment the number of items

N2kMsg.Add2ByteUInt(ID);
if (strlen(Name) == 0) {
N2kMsg.AddByte(0x03);N2kMsg.AddByte(0x01);N2kMsg.AddByte(0x00);
} else {
N2kMsg.AddByte(strlen(Name)+2);N2kMsg.AddByte(0x01);
for (i=0; i<strlen(Name); i++)
N2kMsg.AddByte(Name[i]);
}
N2kMsg.Add4ByteDouble(Latitude,1e-07);
N2kMsg.Add4ByteDouble(Longitude,1e-07);
return true;
} else
return false;
}

//*****************************************************************************
// Wind Speed
void SetN2kPGN130306 (tN2kMsg &N2kMsg, unsigned char SID, double WindSpeed, double WindAngle, tN2kWindReference WindReference) {
void SetN2kPGN130306(tN2kMsg &N2kMsg, unsigned char SID, double WindSpeed, double WindAngle, tN2kWindReference WindReference) {
N2kMsg.SetPGN(130306L);
N2kMsg.Priority=6;
N2kMsg.AddByte(SID);
Expand Down
Loading

0 comments on commit 86b4662

Please sign in to comment.