Each of the aismsg_XX parsing functions expect to be passed a pointer to a ais_sate structure containing the raw 6-bit data and a pointer to the aismsg_XX structure to place the parsed information into.
All aismsg_XX structures are cleared by their respecive parsers, except for parse_ais_24() which stores 2 messages into a single structure.
Data like the ship's name and callsign are converted to ASCII before being stored. Positions are converted to signed long values, and other fields like course over ground, speed, heading, etc. are left for further decoding. 1/1000 minute positions are converted to 1/10000 minute positions to make comparisons easier.
Not all of these parsers have been fully tested with live data. Here is a list of the ones that have been tested so far: 1,3,4,5,7,12,15,20
If you have valid data for other message ids and would like to contribute them please email them to bcl@brianlane.com
Example:
ais_state ais; aismsg_1 msg_1; char buf[256]; memset( &state, 0, sizeof(state) ); // Process incoming packets from some source while( message_source_active ) { // Get your messages from your source, whatever that may be fill_buf( buf, 255); // Is there a complete message available? if (assemble_vdm( &ais, buf ) == 0) { // Get the 6 bit message id ais.msgid = (unsigned char) get_6bit( &ais.six_state, 6 ); // process message with appropriate parser switch( ais.msgid ) { case 1: if( parse_ais_1( &ais, &msg_1 ) == 0 ) { // Successfully parsed a message 1 into msg_1 struct } break; } } }
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "portable.h"
#include "nmea.h"
#include "sixbit.h"
#include "vdm_parse.h"
Functions | |
| int __stdcall | get_timetag (sixbit *state, timetag *datetime) |
| Get 20 bit ETA, Seaway and IMO Timetag. | |
| void __stdcall | conv_sign (unsigned int sign_bit, int *value) |
| Convert a 2's complement value to a signed integer value. | |
| char __stdcall | ais2ascii (char value) |
| Convert a AIS 6-bit character to ASCII. | |
| int __stdcall | pos2ddd (long latitude, long longitude, double *lat_dd, double *long_ddd) |
| Convert 1/10000 minute position to signed DD.DDDDDD format. | |
| int __stdcall | pos2dmm (long latitude, long longitude, short *lat_dd, double *lat_min, short *long_ddd, double *long_min) |
| Convert 1/10000 minute position to signed DD MM.MMMM format. | |
| int __stdcall | conv_pos (long *latitude, long *longitude) |
| Convert unsigned 1/10000 minute position to signed. | |
| int __stdcall | assemble_vdm (ais_state *state, char *str) |
| Assemble AIVDM/VDO sentences. | |
| int __stdcall | parse_ais_1 (ais_state *state, aismsg_1 *result) |
| Parse an AIS message 1 into an aismsg_1 structure. | |
| int __stdcall | parse_ais_2 (ais_state *state, aismsg_2 *result) |
| Parse an AIS message 2 into an aismsg_2 structure. | |
| int __stdcall | parse_ais_3 (ais_state *state, aismsg_3 *result) |
| Parse an AIS message 3 into an aismsg_3 structure. | |
| int __stdcall | parse_ais_4 (ais_state *state, aismsg_4 *result) |
| Parse an AIS message 4 into an aismsg_4 structure. | |
| int __stdcall | parse_ais_5 (ais_state *state, aismsg_5 *result) |
| Parse an AIS message 5 into an aismsg_5 structure. | |
| int __stdcall | parse_ais_6 (ais_state *state, aismsg_6 *result) |
| Parse an AIS message 6 into an aismsg_6 structure. | |
| int __stdcall | parse_ais_7 (ais_state *state, aismsg_7 *result) |
| Parse an AIS message 7 into an aismsg_7 structure. | |
| int __stdcall | parse_ais_8 (ais_state *state, aismsg_8 *result) |
| Parse an AIS message 8 into an aismsg_8 structure. | |
| int __stdcall | parse_ais_9 (ais_state *state, aismsg_9 *result) |
| Parse an AIS message 9 into an aismsg_9 structure. | |
| int __stdcall | parse_ais_10 (ais_state *state, aismsg_10 *result) |
| Parse an AIS message 10 into an aismsg_10 structure. | |
| int __stdcall | parse_ais_11 (ais_state *state, aismsg_11 *result) |
| Parse an AIS message 11 into an aismsg_11 structure. | |
| int __stdcall | parse_ais_12 (ais_state *state, aismsg_12 *result) |
| Parse an AIS message 12 into an aismsg_12 structure. | |
| int __stdcall | parse_ais_13 (ais_state *state, aismsg_13 *result) |
| Parse an AIS message 13 into an aismsg_13 structure. | |
| int __stdcall | parse_ais_14 (ais_state *state, aismsg_14 *result) |
| Parse an AIS message 14 into an aismsg_14 structure. | |
| int __stdcall | parse_ais_15 (ais_state *state, aismsg_15 *result) |
| Parse an AIS message 15 into an aismsg_15 structure. | |
| int __stdcall | parse_ais_16 (ais_state *state, aismsg_16 *result) |
| Parse an AIS message 16 into an aismsg_16 structure. | |
| int __stdcall | parse_ais_17 (ais_state *state, aismsg_17 *result) |
| Parse an AIS message 17 into an aismsg_17 structure. | |
| int __stdcall | parse_ais_18 (ais_state *state, aismsg_18 *result) |
| Parse an AIS message 18 into an aismsg_18 structure. | |
| int __stdcall | parse_ais_19 (ais_state *state, aismsg_19 *result) |
| Parse an AIS message 19 into an aismsg_19 structure. | |
| int __stdcall | parse_ais_20 (ais_state *state, aismsg_20 *result) |
| Parse an AIS message 20 into an aismsg_20 structure. | |
| int __stdcall | parse_ais_21 (ais_state *state, aismsg_21 *result) |
| Parse an AIS message 21 into an aismsg_21 structure. | |
| int __stdcall | parse_ais_22 (ais_state *state, aismsg_22 *result) |
| Parse an AIS message 22 into an aismsg_22 structure. | |
| int __stdcall | parse_ais_23 (ais_state *state, aismsg_23 *result) |
| Parse an AIS message 23 into an aismsg_23 structure. | |
| int __stdcall | parse_ais_24 (ais_state *state, aismsg_24 *result) |
| Parse an AIS message 24 into an aismsg_24 structure. | |
| char __stdcall ais2ascii | ( | char | value | ) |
Convert a AIS 6-bit character to ASCII.
| value | 6-bit value to be converted |
This function is used to convert binary data to ASCII. This is different from the 6-bit ASCII to binary conversion for VDM messages; it is used for strings within the datastream itself. eg. Ship Name and Destination.
| int __stdcall assemble_vdm | ( | ais_state * | state, | |
| char * | str | |||
| ) |
Assemble AIVDM/VDO sentences.
This function handles re-assembly and extraction of the 6-bit data from AIVDM/AIVDO sentences.
Because the NMEA standard limits the length of a line to 80 characters some AIS messages, such as message 5, are output as a multipart VDM messages. This routine collects the 6-bit encoded data from these parts and returns a 1 when all pieces have been reassembled.
It expects the sentences to:
It will return an error if it receives a piece out of order or from a new sequence before the previous one is finished.
Returns
Example:
ais_state state; char buf[3][255] = { "!AIVDM,1,1,,B,19NS7Sp02wo?HETKA2K6mUM20<L=,0*27\r\n", "!AIVDM,2,1,9,A,55Mf@6P00001MUS;7GQL4hh61L4hh6222222220t41H,0*49\r\n", "!AIVDM,2,2,9,A,==40HtI4i@E531H1QDTVH51DSCS0,2*16\r\n" }; memset( &state, 0, sizeof(state) ); assemble_vdm( &state, buf[0] ) state.six_state now has the 6-bit data from the message assemble_vdm( &state, buf[1] ); This returns a 1 because not all the pieces have been received. assemble_vdm( &state, buf[2] ); This returns a 0 and state.six_state has the complete 6-bit data for the message 5.
| int __stdcall conv_pos | ( | long * | latitude, | |
| long * | longitude | |||
| ) |
Convert unsigned 1/10000 minute position to signed.
| latitude | pointer to an unsigned latitude | |
| longitude | pointer to an unsigned longitude |
| void __stdcall conv_sign | ( | unsigned int | sign_bit, | |
| int * | value | |||
| ) |
Convert a 2's complement value to a signed integer value.
| sign_bit | ||
| value | pointer to value |
Get 20 bit ETA, Seaway and IMO Timetag.
| state | pointer to parser state | |
| datetime | pointer to timetag result struct |
Parse an AIS message 1 into an aismsg_1 structure.
Ship Position report with SOTDMA Communication state
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the latitude and longitude are converted to signed values before being returned.
Parse an AIS message 12 into an aismsg_12 structure.
Addressed Safety Related Message
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
The safety message is converted to ASCII before storage in the result->message field.
Parse an AIS message 13 into an aismsg_13 structure.
Safety Related Acknowledge
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Depending on the length of the message some of the fields may be 0. result->num_acks has the number of acks received.
Parse an AIS message 14 into an aismsg_14 structure.
Safety Related Broadcast
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
The safety message is converted to ASCII before storage in the result->message field.
Parse an AIS message 15 into an aismsg_15 structure.
Interrogation
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Depending on the length of the message some if the fields may be 0. result->num_reqs has the number of interrogation requests.
Parse an AIS message 16 into an aismsg_16 structure.
Assigned mode command
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Depending on the length of the message some of the fields may be 0. result->num_cmds has the number of commands received.
Parse an AIS message 17 into an aismsg_17 structure.
GNSS Binary Broadcast Message
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note: the binary payload of the message is left in its 6-bit ASCII form when stored into result->data. This allows the data to be passed to the sixbit module for parsing.
Parse an AIS message 18 into an aismsg_18 structure.
Class B Position Report
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the latitude and longitude are converted to signed values before being returned.
Parse an AIS message 19 into an aismsg_19 structure.
Extended Class B Position Report
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the latitude and longitude are converted to signed values before being returned. And the ship's name is converted to ASCII before being stored.
Parse an AIS message 2 into an aismsg_2 structure.
Ship Position report with SOTDMA Communication state
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the latitude and longitude are converted to signed values before being returned.
Parse an AIS message 20 into an aismsg_20 structure.
Data link management message
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Depending on the length of the message some fields may be 0. result->num_cmds will have the number of commands received.
Parse an AIS message 21 into an aismsg_21 structure.
Aids To Navigation position report (AtoN)
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the latitude and longitude are converted to signed values before being returned. And the AtoN name and extended name are converted to ASCII before storage.
Parse an AIS message 22 into an aismsg_22 structure.
Channel Management
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Check the addressed flag to decide whether to use the positions in NE and SW or the addresses in addressed_1 and addressed_2
Note that the latitudes and longitudes are converted to signed values before being returned and that they are converted to 1/10000 minute format from 1/1000 minute as received.
Parse an AIS message 23 into an aismsg_23 structure.
Group Assignment Command
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the latitudes and longitudes are converted to signed values before being returned and that they are converted to 1/10000 minute format from 1/1000 minute as received.
Parse an AIS message 24 into an aismsg_24 structure.
Class B"CS" Static Data Report
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled. |
NOTE! The result structure needs to be cleared before use. Because message 24 is a 2 part message the parse function doesn't clear the structure before filling it. You should do this:
memset( result, 0, sizeof( aismsg_24 ));
before passing a message 24A to the parse_ais_24() function.
Message 24 is a 2 part message. The first part only contains the MMSI and the ship name. The second message contains the ship dimensions, etc.
Check the result->part_number field to determine which message this is. The same structure is used for both messages and the result->flags field will have a 0x03 in it when both messages have been parsed.
The ship name, vendor id and callsign are all converted to ASCII before storage.
Parse an AIS message 3 into an aismsg_3 structure.
Ship Position report with ITDMA Communication state
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the latitude and longitude are converted to signed values before being returned.
Parse an AIS message 4 into an aismsg_4 structure.
Base Station Report
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the latitude and longitude are converted to signed values before being returned.
Parse an AIS message 5 into an aismsg_5 structure.
Ship Static and Voyage Data
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the ship's callsign, name and destination are converted to ASCII before storage.
Parse an AIS message 6 into an aismsg_6 structure.
Addressed Binary Message
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note: the binary payload of the message is left in its 6-bit ASCII form when stored into result->data. This allows the data to be passed to the sixbit module for parsing.
Parse an AIS message 7 into an aismsg_7 structure.
Binary acknowledge
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Depending on the length of the message some of the fields may be 0. result->num_acks has the number of acks received.
Parse an AIS message 8 into an aismsg_8 structure.
Binary Broadcast Message
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note: the binary payload of the message is left in its 6-bit ASCII form when stored into result->data. This allows the data to be passed to the sixbit module for parsing.
Parse an AIS message 9 into an aismsg_9 structure.
Search And Rescue(SAR) position report
| state | pointer to ais_state | |
| result | pointer to parsed message result structure to be filled |
Note that the latitude and longitude are converted to signed values before being returned.
| int __stdcall pos2ddd | ( | long | latitude, | |
| long | longitude, | |||
| double * | lat_dd, | |||
| double * | long_ddd | |||
| ) |
Convert 1/10000 minute position to signed DD.DDDDDD format.
| latitude | signed latitude in 1/10000 minute format | |
| longitude | signed longitude in 1/10000 minute format | |
| lat_dd | pointer to hold signed latitude in DD.DDDDDD format | |
| long_ddd | pointer to hold signed longitude in DD.DDDDDD format |
| int __stdcall pos2dmm | ( | long | latitude, | |
| long | longitude, | |||
| short * | lat_dd, | |||
| double * | lat_min, | |||
| short * | long_ddd, | |||
| double * | long_min | |||
| ) |
Convert 1/10000 minute position to signed DD MM.MMMM format.
| latitude | signed latitude in 1/10000 minute format | |
| longitude | signed longitude in 1/10000 minute format | |
| lat_dd | pointer to hold signed latitude in DD format | |
| lat_min | pointer to hold minutes in mm.mmmm format | |
| long_ddd | pointer to hold signed longitude in DDD format | |
| long_min | pointer to hold minutes in mm.mmmm format |
1.5.2