1 /*
2  * Driver for AIS messages.
3  *
4  * See the file AIVDM.txt on the GPSD website for documentation and references.
5  * AIVDM de-armoring is handled elsewhere; this is the binary-packet driver.
6  *
7  * Code for message types 1-15, 18-21, and 24 has been tested against
8  * live data with known-good decodings. Code for message types 16-17,
9  * 22-23, and 25-27 has not.
10  * For the special IMO messages (types 6 and 8), only the following have been
11  * tested against known-good decodings:
12  *  - IMO236 met/hydro message: Type=8, DAC=1, FI=11
13  *  - IMO289 met/hydro message: Type=8, DAC=1, FI=31
14  *
15  * This file is Copyright (c) 2010-2019 by the GPSD project
16  * SPDX-License-Identifier: BSD-2-clause
17  */
18 
19 #include "gpsd_config.h"  /* must be before all includes */
20 
21 #include <ctype.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include "gpsd.h"
26 #include "bits.h"
27 
28 /*
29  * Parse the data from the device
30  */
31 
from_sixbit_untrimmed(unsigned char * bitvec,unsigned int start,int count,char * to)32 static void from_sixbit_untrimmed(unsigned char *bitvec, unsigned int start,
33   int count, char *to)
34 /* beginning at bitvec bit start, unpack count sixbit characters */
35 {
36     const char sixchr[64] =
37 	"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_ !\"#$%&'()*+,-./0123456789:;<=>?";
38     int i;
39 
40     /* six-bit to ASCII */
41     for (i = 0; i < count; i++) {
42 	char newchar;
43 	newchar = sixchr[ubits(bitvec, start + 6 * i, 6U, false)];
44 	if (newchar == '@')
45 	    break;
46 	else
47 	    to[i] = newchar;
48     }
49     to[i] = '\0';
50 }
51 
trim_spaces_on_right_end(char * to)52 static void trim_spaces_on_right_end(char* to)
53 /* trim spaces on right end */
54 {
55     int i;
56     for (i = strlen(to) - 1; i >= 0; i--) {
57 	if (to[i] == ' ' || to[i] == '@') {
58 	    to[i] = '\0';
59 	} else {
60 	    break;
61 	}
62     }
63 }
64 
65 /* beginning at bitvec bit start, unpack count sixbit characters
66  * and remove trailing spaces */
from_sixbit(unsigned char * bitvec,unsigned int start,int count,char * to)67 static void from_sixbit(unsigned char *bitvec, unsigned int start, int count,
68                         char *to)
69 {
70        from_sixbit_untrimmed(bitvec, start, count, to);
71        trim_spaces_on_right_end(to);
72 }
73 
74 /* decode an AIS binary packet */
ais_binary_decode(const struct gpsd_errout_t * errout,struct ais_t * ais,const unsigned char * bits,size_t bitlen,struct ais_type24_queue_t * type24_queue)75 bool ais_binary_decode(const struct gpsd_errout_t *errout,
76 		       struct ais_t *ais,
77 		       const unsigned char *bits, size_t bitlen,
78 		       struct ais_type24_queue_t *type24_queue)
79 {
80     unsigned int u; int i;
81 
82 #define UBITS(s, l)	ubits((unsigned char *)bits, s, l, false)
83 #define SBITS(s, l)	sbits((signed char *)bits, s, l, false)
84 #define UCHARS(s, to)	from_sixbit((unsigned char *)bits, s, sizeof(to)-1, to)
85 #define ENDCHARS(s, to)	from_sixbit((unsigned char *)bits, s, (bitlen-(s))/6,to)
86     ais->type = UBITS(0, 6);
87     ais->repeat = UBITS(6, 2);
88     ais->mmsi = UBITS(8, 30);
89     GPSD_LOG(LOG_INF, errout, "AIVDM message type %d, MMSI %09d:\n",
90 	     ais->type, ais->mmsi);
91 
92 #define PERMISSIVE_LENGTH_CHECK(correct) \
93 	if (bitlen < correct) { \
94 	    GPSD_LOG(LOG_ERROR, errout, \
95 		     "AIVDM message type %d size < %d bits (%zd).\n",	\
96 		     ais->type, correct, bitlen);			\
97 	    return false; \
98 	} else if (bitlen > correct) { \
99 	    GPSD_LOG(LOG_WARN, errout, \
100 		     "AIVDM message type %d size > %d bits (%zd).\n",	\
101 		     ais->type, correct, bitlen);			\
102 	}
103 #define RANGE_CHECK(min, max) \
104 	if (bitlen < min || bitlen > max) { \
105 	    GPSD_LOG(LOG_ERROR, errout, \
106 		     "AIVDM message type %d size is out of range (%zd).\n", \
107 		     ais->type, bitlen);				\
108 	    return false; \
109 	}
110 
111     /*
112      * Something about the shape of this switch statement confuses
113      * GNU indent so badly that there is no point in trying to be
114      * finer-grained than leaving it all alone.
115      */
116     /* *INDENT-OFF* */
117     switch (ais->type) {
118     case 1:	/* Position Report */
119     case 2:
120     case 3:
121 	PERMISSIVE_LENGTH_CHECK(163)
122 	ais->type1.status	= UBITS(38, 4);
123 	ais->type1.turn		= SBITS(42, 8);
124 	ais->type1.speed	= UBITS(50, 10);
125 	ais->type1.accuracy	= UBITS(60, 1) != 0;
126 	ais->type1.lon		= SBITS(61, 28);
127 	ais->type1.lat		= SBITS(89, 27);
128 	ais->type1.course	= UBITS(116, 12);
129 	ais->type1.heading	= UBITS(128, 9);
130 	ais->type1.second	= UBITS(137, 6);
131 	ais->type1.maneuver	= UBITS(143, 2);
132 	//ais->type1.spare	= UBITS(145, 3);
133 	ais->type1.raim		= UBITS(148, 1) != 0;
134 	if(bitlen >= 168)
135 		ais->type1.radio	= UBITS(149, 19);
136 	if(bitlen < 168)
137 		ais->type1.radio	= UBITS(149, bitlen - 149);
138 	break;
139     case 4: 	/* Base Station Report */
140     case 11:	/* UTC/Date Response */
141 	PERMISSIVE_LENGTH_CHECK(168)
142 	ais->type4.year		= UBITS(38, 14);
143 	ais->type4.month	= UBITS(52, 4);
144 	ais->type4.day		= UBITS(56, 5);
145 	ais->type4.hour		= UBITS(61, 5);
146 	ais->type4.minute	= UBITS(66, 6);
147 	ais->type4.second	= UBITS(72, 6);
148 	ais->type4.accuracy	= UBITS(78, 1) != 0;
149 	ais->type4.lon		= SBITS(79, 28);
150 	ais->type4.lat		= SBITS(107, 27);
151 	ais->type4.epfd		= UBITS(134, 4);
152 	//ais->type4.spare	= UBITS(138, 10);
153 	ais->type4.raim		= UBITS(148, 1) != 0;
154 	ais->type4.radio	= UBITS(149, 19);
155 	break;
156     case 5: /* Ship static and voyage related data */
157 	if (bitlen != 424) {
158 	    GPSD_LOG(LOG_WARN, errout,
159 		     "AIVDM message type 5 size not 424 bits (%zd).\n",
160 		     bitlen);
161 	    /*
162 	     * For unknown reasons, a lot of transmitters in the wild ship
163 	     * with a length of 420 or 422.  This is a recoverable error.
164 	     */
165 	    if (bitlen < 420)
166 		return false;
167 	}
168 	ais->type5.ais_version  = UBITS(38, 2);
169 	ais->type5.imo          = UBITS(40, 30);
170 	UCHARS(70, ais->type5.callsign);
171 	UCHARS(112, ais->type5.shipname);
172 	ais->type5.shiptype     = UBITS(232, 8);
173 	ais->type5.to_bow       = UBITS(240, 9);
174 	ais->type5.to_stern     = UBITS(249, 9);
175 	ais->type5.to_port      = UBITS(258, 6);
176 	ais->type5.to_starboard = UBITS(264, 6);
177 	ais->type5.epfd         = UBITS(270, 4);
178 	ais->type5.month        = UBITS(274, 4);
179 	ais->type5.day          = UBITS(278, 5);
180 	ais->type5.hour         = UBITS(283, 5);
181 	ais->type5.minute       = UBITS(288, 6);
182 	ais->type5.draught      = UBITS(294, 8);
183 	UCHARS(302, ais->type5.destination);
184 	if (bitlen >= 423)
185 	    ais->type5.dte          = UBITS(422, 1);
186 	//ais->type5.spare        = UBITS(423, 1);
187 	break;
188     case 6: /* Addressed Binary Message */
189 	RANGE_CHECK(88, 1008);
190 	ais->type6.seqno          = UBITS(38, 2);
191 	ais->type6.dest_mmsi      = UBITS(40, 30);
192 	ais->type6.retransmit     = UBITS(70, 1) != 0;
193 	//ais->type6.spare        = UBITS(71, 1);
194 	ais->type6.dac            = UBITS(72, 10);
195 	ais->type6.fid            = UBITS(82, 6);
196 	ais->type6.bitcount       = bitlen - 88;
197 	/* not strictly required - helps stability in testing */
198 	(void)memset(ais->type6.bitdata, '\0', sizeof(ais->type6.bitdata));
199 	ais->type6.structured = false;
200 	/* Inland AIS */
201 	if (ais->type6.dac == 200) {
202 	    switch (ais->type6.fid) {
203 	    case 21:	/* ETA at lock/bridge/terminal */
204 		if (bitlen != 248)
205 		    break;
206 		UCHARS(88, ais->type6.dac200fid21.country);
207 		UCHARS(100, ais->type6.dac200fid21.locode);
208 		UCHARS(118, ais->type6.dac200fid21.section);
209 		UCHARS(148, ais->type6.dac200fid21.terminal);
210 		UCHARS(178, ais->type6.dac200fid21.hectometre);
211 		ais->type6.dac200fid21.month	= UBITS(208, 4);
212 		ais->type6.dac200fid21.day	= UBITS(212, 5);
213 		ais->type6.dac200fid21.hour	= UBITS(217, 5);
214 		ais->type6.dac200fid21.minute	= UBITS(222, 6);
215 		ais->type6.dac200fid21.tugs	= UBITS(228, 3);
216 		ais->type6.dac200fid21.airdraught	= UBITS(231, 12);
217 		/* skip 5 bits */
218 		ais->type6.structured = true;
219 		break;
220 	    case 22:	/* RTA at lock/bridge/terminal */
221 		if (bitlen != 232)
222 		    break;
223 		UCHARS(88, ais->type6.dac200fid22.country);
224 		UCHARS(100, ais->type6.dac200fid22.locode);
225 		UCHARS(118, ais->type6.dac200fid22.section);
226 		UCHARS(148, ais->type6.dac200fid22.terminal);
227 		UCHARS(178, ais->type6.dac200fid22.hectometre);
228 		ais->type6.dac200fid22.month	= UBITS(208, 4);
229 		ais->type6.dac200fid22.day	= UBITS(212, 5);
230 		ais->type6.dac200fid22.hour	= UBITS(217, 5);
231 		ais->type6.dac200fid22.minute	= UBITS(222, 6);
232 		ais->type6.dac200fid22.status	= UBITS(228, 2);
233 		/* skip 2 bits */
234 		ais->type6.structured = true;
235 		break;
236 	    case 55:	/* Number of Persons On Board */
237 		if (bitlen != 168)
238 		    break;
239 		ais->type6.dac200fid55.crew	  = UBITS(88, 8);
240 		ais->type6.dac200fid55.passengers = UBITS(96, 13);
241 		ais->type6.dac200fid55.personnel  = UBITS(109, 8);
242 		/* skip 51 bits */
243 		ais->type6.structured = true;
244 		break;
245 	    }
246 	}
247 	/* UK and Republic Of Ireland */
248 	else if (ais->type6.dac == 235 || ais->type6.dac == 250) {
249 	    switch (ais->type6.fid) {
250 	    case 10:	/* GLA - AtoN monitoring data */
251 		if (bitlen != 136)
252 		    break;
253 		ais->type6.dac235fid10.ana_int	= UBITS(88, 10);
254 		ais->type6.dac235fid10.ana_ext1	= UBITS(98, 10);
255 		ais->type6.dac235fid10.ana_ext2	= UBITS(108, 10);
256 		ais->type6.dac235fid10.racon    = UBITS(118, 2);
257 		ais->type6.dac235fid10.light    = UBITS(120, 2);
258 		ais->type6.dac235fid10.alarm    = UBITS(122, 1);
259 		ais->type6.dac235fid10.stat_ext	= UBITS(123, 8);
260 		ais->type6.dac235fid10.off_pos  = UBITS(131, 1);
261 		/* skip 4 bits */
262 		ais->type6.structured = true;
263 		break;
264 	    }
265 	}
266 	/* International */
267 	else if (ais->type6.dac == 1)
268 	    switch (ais->type6.fid) {
269 	    case 12:	/* IMO236 - Dangerous cargo indication */
270 		UCHARS(88, ais->type6.dac1fid12.lastport);
271 		ais->type6.dac1fid12.lmonth	= UBITS(118, 4);
272 		ais->type6.dac1fid12.lday	= UBITS(122, 5);
273 		ais->type6.dac1fid12.lhour	= UBITS(127, 5);
274 		ais->type6.dac1fid12.lminute	= UBITS(132, 6);
275 		UCHARS(138, ais->type6.dac1fid12.nextport);
276 		ais->type6.dac1fid12.nmonth	= UBITS(168, 4);
277 		ais->type6.dac1fid12.nday	= UBITS(172, 5);
278 		ais->type6.dac1fid12.nhour	= UBITS(177, 5);
279 		ais->type6.dac1fid12.nminute	= UBITS(182, 6);
280 		UCHARS(188, ais->type6.dac1fid12.dangerous);
281 		UCHARS(308, ais->type6.dac1fid12.imdcat);
282 		ais->type6.dac1fid12.unid	= UBITS(332, 13);
283 		ais->type6.dac1fid12.amount	= UBITS(345, 10);
284 		ais->type6.dac1fid12.unit	= UBITS(355, 2);
285 		/* skip 3 bits */
286 		ais->type6.structured = true;
287 		break;
288 	    case 14:	/* IMO236 - Tidal Window */
289 		ais->type6.dac1fid32.month	= UBITS(88, 4);
290 		ais->type6.dac1fid32.day	= UBITS(92, 5);
291 #define ARRAY_BASE 97
292 #define ELEMENT_SIZE 93
293 		for (u = 0; ARRAY_BASE + (ELEMENT_SIZE*u) <= bitlen; u++) {
294 		    int a = ARRAY_BASE + (ELEMENT_SIZE*u);
295 		    struct tidal_t *tp = &ais->type6.dac1fid32.tidals[u];
296 		    tp->lat	  = SBITS(a + 0, 27);
297 		    tp->lon	  = SBITS(a + 27, 28);
298 		    tp->from_hour = UBITS(a + 55, 5);
299 		    tp->from_min  = UBITS(a + 60, 6);
300 		    tp->to_hour   = UBITS(a + 66, 5);
301 		    tp->to_min    = UBITS(a + 71, 6);
302 		    tp->cdir      = UBITS(a + 77, 9);
303 		    tp->cspeed    = UBITS(a + 86, 7);
304 		}
305 		ais->type6.dac1fid32.ntidals = u;
306 #undef ARRAY_BASE
307 #undef ELEMENT_SIZE
308 		ais->type6.structured = true;
309 		break;
310 	    case 15:
311                 /* IMO236 - Extended Ship Static and Voyage Related Data */
312 		ais->type6.dac1fid15.airdraught	= UBITS(56, 11);
313 		ais->type6.structured = true;
314 		break;
315 	    case 16:	/* IMO236 - Number of persons on board */
316 		if (ais->type6.bitcount == 136)
317 		    ais->type6.dac1fid16.persons = UBITS(88, 13);  /* 289 */
318 		else
319 		    ais->type6.dac1fid16.persons = UBITS(55, 13);  /* 236 */
320 		ais->type6.structured = true;
321 		break;
322 	    case 18:	/* IMO289 - Clearance time to enter port */
323 		ais->type6.dac1fid18.linkage	= UBITS(88, 10);
324 		ais->type6.dac1fid18.month	= UBITS(98, 4);
325 		ais->type6.dac1fid18.day	= UBITS(102, 5);
326 		ais->type6.dac1fid18.hour	= UBITS(107, 5);
327 		ais->type6.dac1fid18.minute	= UBITS(112, 6);
328 		UCHARS(118, ais->type6.dac1fid18.portname);
329 		UCHARS(238, ais->type6.dac1fid18.destination);
330 		ais->type6.dac1fid18.lon	= SBITS(268, 25);
331 		ais->type6.dac1fid18.lat	= SBITS(293, 24);
332 		/* skip 43 bits */
333 		ais->type6.structured = true;
334 		break;
335 	    case 20:	/* IMO289 - Berthing data - addressed */
336 		ais->type6.dac1fid20.linkage      = UBITS(88, 10);
337 		ais->type6.dac1fid20.berth_length = UBITS(98, 9);
338 		ais->type6.dac1fid20.berth_depth  = UBITS(107, 8);
339 		ais->type6.dac1fid20.position     = UBITS(115, 3);
340 		ais->type6.dac1fid20.month	  = UBITS(118, 4);
341 		ais->type6.dac1fid20.day	  = UBITS(122, 5);
342 		ais->type6.dac1fid20.hour	  = UBITS(127, 5);
343 		ais->type6.dac1fid20.minute	  = UBITS(132, 6);
344 		ais->type6.dac1fid20.availability = UBITS(138, 1);
345 		ais->type6.dac1fid20.agent	  = UBITS(139, 2);
346 		ais->type6.dac1fid20.fuel	  = UBITS(141, 2);
347 		ais->type6.dac1fid20.chandler	  = UBITS(143, 2);
348 		ais->type6.dac1fid20.stevedore    = UBITS(145, 2);
349 		ais->type6.dac1fid20.electrical   = UBITS(147, 2);
350 		ais->type6.dac1fid20.water	  = UBITS(149, 2);
351 		ais->type6.dac1fid20.customs      = UBITS(151, 2);
352 		ais->type6.dac1fid20.cartage      = UBITS(153, 2);
353 		ais->type6.dac1fid20.crane	  = UBITS(155, 2);
354 		ais->type6.dac1fid20.lift	  = UBITS(157, 2);
355 		ais->type6.dac1fid20.medical      = UBITS(159, 2);
356 		ais->type6.dac1fid20.navrepair    = UBITS(161, 2);
357 		ais->type6.dac1fid20.provisions   = UBITS(163, 2);
358 		ais->type6.dac1fid20.shiprepair   = UBITS(165, 2);
359 		ais->type6.dac1fid20.surveyor     = UBITS(167, 2);
360 		ais->type6.dac1fid20.steam	  = UBITS(169, 2);
361 		ais->type6.dac1fid20.tugs	  = UBITS(171, 2);
362 		ais->type6.dac1fid20.solidwaste   = UBITS(173, 2);
363 		ais->type6.dac1fid20.liquidwaste  = UBITS(175, 2);
364 		ais->type6.dac1fid20.hazardouswaste = UBITS(177, 2);
365 		ais->type6.dac1fid20.ballast      = UBITS(179, 2);
366 		ais->type6.dac1fid20.additional   = UBITS(181, 2);
367 		ais->type6.dac1fid20.regional1    = UBITS(183, 2);
368 		ais->type6.dac1fid20.regional2    = UBITS(185, 2);
369 		ais->type6.dac1fid20.future1      = UBITS(187, 2);
370 		ais->type6.dac1fid20.future2      = UBITS(189, 2);
371 		UCHARS(191, ais->type6.dac1fid20.berth_name);
372 		ais->type6.dac1fid20.berth_lon    = SBITS(311, 25);
373 		ais->type6.dac1fid20.berth_lat    = SBITS(336, 24);
374 		ais->type6.structured = true;
375 		break;
376 	    case 23:        /* IMO289 - Area notice - addressed */
377 		break;
378 	    case 25:	/* IMO289 - Dangerous cargo indication */
379 		ais->type6.dac1fid25.unit 	= UBITS(88, 2);
380 		ais->type6.dac1fid25.amount	= UBITS(90, 10);
381 		for (u = 0; 100 + u*17 < bitlen; u++) {
382 		    ais->type6.dac1fid25.cargos[u].code =
383                         UBITS(100 + u * 17, 4);
384 		    ais->type6.dac1fid25.cargos[u].subtype =
385                         UBITS(104 + u * 17, 13);
386 		}
387 		ais->type6.dac1fid25.ncargos = u;
388 		ais->type6.structured = true;
389 		break;
390 	    case 28:	/* IMO289 - Route info - addressed */
391 		ais->type6.dac1fid28.linkage	= UBITS(88, 10);
392 		ais->type6.dac1fid28.sender	= UBITS(98, 3);
393 		ais->type6.dac1fid28.rtype	= UBITS(101, 5);
394 		ais->type6.dac1fid28.month	= UBITS(106, 4);
395 		ais->type6.dac1fid28.day	= UBITS(110, 5);
396 		ais->type6.dac1fid28.hour	= UBITS(115, 5);
397 		ais->type6.dac1fid28.minute	= UBITS(120, 6);
398 		ais->type6.dac1fid28.duration	= UBITS(126, 18);
399 		ais->type6.dac1fid28.waycount	= UBITS(144, 5);
400 #define ARRAY_BASE 149
401 #define ELEMENT_SIZE 55
402 		for (u = 0;
403                      u < (unsigned char)ais->type6.dac1fid28.waycount; u++) {
404 		    int a = ARRAY_BASE + (ELEMENT_SIZE*u);
405 		    ais->type6.dac1fid28.waypoints[u].lon = SBITS(a + 0, 28);
406 		    ais->type6.dac1fid28.waypoints[u].lat = SBITS(a + 28, 27);
407 		}
408 #undef ARRAY_BASE
409 #undef ELEMENT_SIZE
410 		ais->type6.structured = true;
411 		break;
412 	    case 30:	/* IMO289 - Text description - addressed */
413 		ais->type6.dac1fid30.linkage   = UBITS(88, 10);
414 		ENDCHARS(98, ais->type6.dac1fid30.text);
415 		ais->type6.structured = true;
416 		break;
417 	    case 32:	/* IMO289 - Tidal Window */
418 		ais->type6.dac1fid32.month	= UBITS(88, 4);
419 		ais->type6.dac1fid32.day	= UBITS(92, 5);
420 #define ARRAY_BASE 97
421 #define ELEMENT_SIZE 88
422 		for (u = 0; ARRAY_BASE + (ELEMENT_SIZE*u) <= bitlen; u++) {
423 		    int a = ARRAY_BASE + (ELEMENT_SIZE*u);
424 		    struct tidal_t *tp = &ais->type6.dac1fid32.tidals[u];
425 		    tp->lon       = SBITS(a + 0, 25);
426 		    tp->lat       = SBITS(a + 25, 24);
427 		    tp->from_hour = UBITS(a + 49, 5);
428 		    tp->from_min  = UBITS(a + 54, 6);
429 		    tp->to_hour   = UBITS(a + 60, 5);
430 		    tp->to_min    = UBITS(a + 65, 6);
431 		    tp->cdir      = UBITS(a + 71, 9);
432 		    tp->cspeed    = UBITS(a + 80, 8);
433 		}
434 		ais->type6.dac1fid32.ntidals = u;
435 #undef ARRAY_BASE
436 #undef ELEMENT_SIZE
437 		ais->type6.structured = true;
438 		break;
439 	    }
440 	if (!ais->type6.structured)
441 	    (void)memcpy(ais->type6.bitdata, (char *)bits + (88 / CHAR_BIT),
442 			 BITS_TO_BYTES(ais->type6.bitcount));
443 	break;
444     case 7: /* Binary acknowledge */
445     case 13: /* Safety Related Acknowledge */
446     {
447 	unsigned int mmsi[4];
448 	unsigned seqno[4];
449 	RANGE_CHECK(72, 168);
450 	for (u = 0; u < sizeof(mmsi)/sizeof(mmsi[0]); u++) {
451 	    if (bitlen > 40 + 32*u) {
452 		mmsi[u] = UBITS(40 + 32 * u, 30);
453 		seqno[u] = UBITS(72 + 32 * u, 2);
454 	    } else {
455 		mmsi[u] = 0;
456 		seqno[u] = 0;
457 	    }
458         }
459 	ais->type7.mmsi1 = mmsi[0];
460 	ais->type7.seqno1 = seqno[0];
461 	ais->type7.mmsi2 = mmsi[1];
462 	ais->type7.seqno2 = seqno[1];
463 	ais->type7.mmsi3 = mmsi[2];
464 	ais->type7.seqno2 = seqno[2];
465 	ais->type7.mmsi4 = mmsi[3];
466 	ais->type7.seqno3 = seqno[3];
467 	break;
468     }
469     case 8: /* Binary Broadcast Message */
470 	RANGE_CHECK(56, 1008);
471 	//ais->type8.spare        = UBITS(38, 2);
472 	ais->type8.dac            = UBITS(40, 10);
473 	ais->type8.fid            = UBITS(50, 6);
474 	ais->type8.bitcount       = bitlen - 56;
475 	/* not strictly required - helps stability in testing */
476 	(void)memset(ais->type8.bitdata, '\0', sizeof(ais->type8.bitdata));
477 	ais->type8.structured = false;
478 	if (ais->type8.dac == 1)
479 	    switch (ais->type8.fid) {
480 	    case 11:        /* IMO236 - Meteorological/Hydrological data */
481 		/* layout is almost identical to FID=31 from IMO289 */
482 		ais->type8.dac1fid11.lat	= SBITS(56, 24);
483 		ais->type8.dac1fid11.lon	= SBITS(80, 25);
484 		ais->type8.dac1fid11.day	= UBITS(105, 5);
485 		ais->type8.dac1fid11.hour	= UBITS(110, 5);
486 		ais->type8.dac1fid11.minute	= UBITS(115, 6);
487 		ais->type8.dac1fid11.wspeed	= UBITS(121, 7);
488 		ais->type8.dac1fid11.wgust	= UBITS(128, 7);
489 		ais->type8.dac1fid11.wdir	= UBITS(135, 9);
490 		ais->type8.dac1fid11.wgustdir	= UBITS(144, 9);
491 		ais->type8.dac1fid11.airtemp	= UBITS(153, 11);
492 		ais->type8.dac1fid11.humidity	= UBITS(164, 7);
493 		ais->type8.dac1fid11.dewpoint	= UBITS(171, 10);
494 		ais->type8.dac1fid11.pressure	= UBITS(181, 9);
495 		ais->type8.dac1fid11.pressuretend	= UBITS(190, 2);
496 		ais->type8.dac1fid11.visibility	= UBITS(192, 8);
497 		ais->type8.dac1fid11.waterlevel	= UBITS(200, 9);
498 		ais->type8.dac1fid11.leveltrend	= UBITS(209, 2);
499 		ais->type8.dac1fid11.cspeed	= UBITS(211, 8);
500 		ais->type8.dac1fid11.cdir	= UBITS(219, 9);
501 		ais->type8.dac1fid11.cspeed2	= UBITS(228, 8);
502 		ais->type8.dac1fid11.cdir2	= UBITS(236, 9);
503 		ais->type8.dac1fid11.cdepth2	= UBITS(245, 5);
504 		ais->type8.dac1fid11.cspeed3	= UBITS(250, 8);
505 		ais->type8.dac1fid11.cdir3	= UBITS(258, 9);
506 		ais->type8.dac1fid11.cdepth3	= UBITS(267, 5);
507 		ais->type8.dac1fid11.waveheight	= UBITS(272, 8);
508 		ais->type8.dac1fid11.waveperiod	= UBITS(280, 6);
509 		ais->type8.dac1fid11.wavedir	= UBITS(286, 9);
510 		ais->type8.dac1fid11.swellheight	= UBITS(295, 8);
511 		ais->type8.dac1fid11.swellperiod	= UBITS(303, 6);
512 		ais->type8.dac1fid11.swelldir	= UBITS(309, 9);
513 		ais->type8.dac1fid11.seastate	= UBITS(318, 4);
514 		ais->type8.dac1fid11.watertemp	= UBITS(322, 10);
515 		ais->type8.dac1fid11.preciptype	= UBITS(332, 3);
516 		ais->type8.dac1fid11.salinity	= UBITS(335, 9);
517 		ais->type8.dac1fid11.ice	= UBITS(344, 2);
518 		ais->type8.structured = true;
519 		break;
520 	    case 13:        /* IMO236 - Fairway closed */
521 		UCHARS(56, ais->type8.dac1fid13.reason);
522 		UCHARS(176, ais->type8.dac1fid13.closefrom);
523 		UCHARS(296, ais->type8.dac1fid13.closeto);
524 		ais->type8.dac1fid13.radius 	= UBITS(416, 10);
525 		ais->type8.dac1fid13.extunit	= UBITS(426, 2);
526 		ais->type8.dac1fid13.fday   	= UBITS(428, 5);
527 		ais->type8.dac1fid13.fmonth 	= UBITS(433, 4);
528 		ais->type8.dac1fid13.fhour  	= UBITS(437, 5);
529 		ais->type8.dac1fid13.fminute	= UBITS(442, 6);
530 		ais->type8.dac1fid13.tday   	= UBITS(448, 5);
531 		ais->type8.dac1fid13.tmonth 	= UBITS(453, 4);
532 		ais->type8.dac1fid13.thour  	= UBITS(457, 5);
533 		ais->type8.dac1fid13.tminute	= UBITS(462, 6);
534 		/* skip 4 bits */
535 		ais->type8.structured = true;
536 		break;
537 	    case 15:        /* IMO236 - Extended ship and voyage */
538 		ais->type8.dac1fid15.airdraught	= UBITS(56, 11);
539 		/* skip 5 bits */
540 		ais->type8.structured = true;
541 		break;
542 	    case 16:	    /* Number of Persons On Board */
543 		if (ais->type8.bitcount == 136) {
544 		    ais->type8.dac1fid16.persons = UBITS(88, 13);  /* 289 */
545 		    ais->type8.structured = true;
546 		} else if (ais->type8.bitcount == 72) {
547 		    ais->type8.dac1fid16.persons = UBITS(55, 13);  /* 236 */
548 		    ais->type8.structured = true;
549 		}
550 		break;
551 	    case 17:        /* IMO289 - VTS-generated/synthetic targets */
552 #define ARRAY_BASE 56
553 #define ELEMENT_SIZE 122
554 		for (u = 0; ARRAY_BASE + (ELEMENT_SIZE * u) <= bitlen; u++) {
555 		    struct target_t *tp = &ais->type8.dac1fid17.targets[u];
556 		    int a = ARRAY_BASE + (ELEMENT_SIZE * u);
557 		    tp->idtype = UBITS(a + 0, 2);
558 		    switch (tp->idtype) {
559 		    case DAC1FID17_IDTYPE_MMSI:
560 			tp->id.mmsi	= UBITS(a + 2, 42);
561 			break;
562 		    case DAC1FID17_IDTYPE_IMO:
563 			tp->id.imo	= UBITS(a + 2, 42);
564 			break;
565 		    case DAC1FID17_IDTYPE_CALLSIGN:
566 			UCHARS(a+2, tp->id.callsign);
567 			break;
568 		    default:
569 			UCHARS(a+2, tp->id.other);
570 			break;
571 		    }
572 		    /* skip 4 bits */
573 		    tp->lat	= SBITS(a + 48, 24);
574 		    tp->lon	= SBITS(a + 72, 25);
575 		    tp->course	= UBITS(a + 97, 9);
576 		    tp->second	= UBITS(a + 106, 6);
577 		    tp->speed	= UBITS(a + 112, 10);
578 		}
579 		ais->type8.dac1fid17.ntargets = u;
580 #undef ARRAY_BASE
581 #undef ELEMENT_SIZE
582 		ais->type8.structured = true;
583 		break;
584 	    case 19:        /* IMO289 - Marine Traffic Signal */
585 		ais->type8.dac1fid19.linkage	= UBITS(56, 10);
586 		UCHARS(66, ais->type8.dac1fid19.station);
587 		ais->type8.dac1fid19.lon	= SBITS(186, 25);
588 		ais->type8.dac1fid19.lat	= SBITS(211, 24);
589 		ais->type8.dac1fid19.status	= UBITS(235, 2);
590 		ais->type8.dac1fid19.signal	= UBITS(237, 5);
591 		ais->type8.dac1fid19.hour	= UBITS(242, 5);
592 		ais->type8.dac1fid19.minute	= UBITS(247, 6);
593 		ais->type8.dac1fid19.nextsignal	= UBITS(253, 5);
594 		/* skip 102 bits */
595 		ais->type8.structured = true;
596 		break;
597 	    case 21:        /* IMO289 - Weather obs. report from ship */
598 		break;
599 	    case 22:        /* IMO289 - Area notice - broadcast */
600 		break;
601 	    case 24:
602                 /* IMO289 - Extended ship static & voyage-related data */
603 		break;
604 	    case 26:        /* IMO289 - Environmental */
605 		break;
606 	    case 27:        /* IMO289 - Route information - broadcast */
607 		ais->type8.dac1fid27.linkage	= UBITS(56, 10);
608 		ais->type8.dac1fid27.sender	= UBITS(66, 3);
609 		ais->type8.dac1fid27.rtype	= UBITS(69, 5);
610 		ais->type8.dac1fid27.month	= UBITS(74, 4);
611 		ais->type8.dac1fid27.day	= UBITS(78, 5);
612 		ais->type8.dac1fid27.hour	= UBITS(83, 5);
613 		ais->type8.dac1fid27.minute	= UBITS(88, 6);
614 		ais->type8.dac1fid27.duration	= UBITS(94, 18);
615 		ais->type8.dac1fid27.waycount	= UBITS(112, 5);
616 #define ARRAY_BASE 117
617 #define ELEMENT_SIZE 55
618 		for (i = 0; i < ais->type8.dac1fid27.waycount; i++) {
619 		    int a = ARRAY_BASE + (ELEMENT_SIZE*i);
620 		    ais->type8.dac1fid27.waypoints[i].lon = SBITS(a + 0, 28);
621 		    ais->type8.dac1fid27.waypoints[i].lat = SBITS(a + 28, 27);
622 		}
623 #undef ARRAY_BASE
624 #undef ELEMENT_SIZE
625 		ais->type8.structured = true;
626 		break;
627 	    case 29:        /* IMO289 - Text Description - broadcast */
628 		ais->type8.dac1fid29.linkage   = UBITS(56, 10);
629 		ENDCHARS(66, ais->type8.dac1fid29.text);
630 		ais->type8.structured = true;
631 		break;
632 	    case 31:        /* IMO289 - Meteorological/Hydrological data */
633 		ais->type8.dac1fid31.lon	= SBITS(56, 25);
634 		ais->type8.dac1fid31.lat	= SBITS(81, 24);
635 		ais->type8.dac1fid31.accuracy   = (bool)UBITS(105, 1);
636 		ais->type8.dac1fid31.day	= UBITS(106, 5);
637 		ais->type8.dac1fid31.hour	= UBITS(111, 5);
638 		ais->type8.dac1fid31.minute	= UBITS(116, 6);
639 		ais->type8.dac1fid31.wspeed	= UBITS(122, 7);
640 		ais->type8.dac1fid31.wgust	= UBITS(129, 7);
641 		ais->type8.dac1fid31.wdir	= UBITS(136, 9);
642 		ais->type8.dac1fid31.wgustdir	= UBITS(145, 9);
643 		ais->type8.dac1fid31.airtemp	= SBITS(154, 11);
644 		ais->type8.dac1fid31.humidity	= UBITS(165, 7);
645 		ais->type8.dac1fid31.dewpoint	= SBITS(172, 10);
646 		ais->type8.dac1fid31.pressure	= UBITS(182, 9);
647 		ais->type8.dac1fid31.pressuretend	= UBITS(191, 2);
648 		ais->type8.dac1fid31.visgreater	= UBITS(193, 1);
649 		ais->type8.dac1fid31.visibility	= UBITS(194, 7);
650 		ais->type8.dac1fid31.waterlevel	= UBITS(201, 12);
651 		ais->type8.dac1fid31.leveltrend	= UBITS(213, 2);
652 		ais->type8.dac1fid31.cspeed	= UBITS(215, 8);
653 		ais->type8.dac1fid31.cdir	= UBITS(223, 9);
654 		ais->type8.dac1fid31.cspeed2	= UBITS(232, 8);
655 		ais->type8.dac1fid31.cdir2	= UBITS(240, 9);
656 		ais->type8.dac1fid31.cdepth2	= UBITS(249, 5);
657 		ais->type8.dac1fid31.cspeed3	= UBITS(254, 8);
658 		ais->type8.dac1fid31.cdir3	= UBITS(262, 9);
659 		ais->type8.dac1fid31.cdepth3	= UBITS(271, 5);
660 		ais->type8.dac1fid31.waveheight	= UBITS(276, 8);
661 		ais->type8.dac1fid31.waveperiod	= UBITS(284, 6);
662 		ais->type8.dac1fid31.wavedir	= UBITS(290, 9);
663 		ais->type8.dac1fid31.swellheight = UBITS(299, 8);
664 		ais->type8.dac1fid31.swellperiod = UBITS(307, 6);
665 		ais->type8.dac1fid31.swelldir	= UBITS(313, 9);
666 		ais->type8.dac1fid31.seastate	= UBITS(322, 4);
667 		ais->type8.dac1fid31.watertemp	= SBITS(326, 10);
668 		ais->type8.dac1fid31.preciptype	= UBITS(336, 3);
669 		ais->type8.dac1fid31.salinity	= UBITS(339, 9);
670 		ais->type8.dac1fid31.ice	= UBITS(348, 2);
671 		ais->type8.structured = true;
672 		break;
673 	    }
674 	else if (ais->type8.dac == 200) {
675 	    switch (ais->type8.fid) {
676 	    case 10:	/* Inland ship static and voyage related data */
677 		if (bitlen != 168)
678 		    break;
679 		UCHARS(56, ais->type8.dac200fid10.vin);
680 		ais->type8.dac200fid10.length	= UBITS(104, 13);
681 		ais->type8.dac200fid10.beam	= UBITS(117, 10);
682 		ais->type8.dac200fid10.shiptype	= UBITS(127, 14);
683 		ais->type8.dac200fid10.hazard	= UBITS(141, 3);
684 		ais->type8.dac200fid10.draught	= UBITS(144, 11);
685 		ais->type8.dac200fid10.loaded	= UBITS(155, 2);
686 		ais->type8.dac200fid10.speed_q	= (bool)UBITS(157, 1);
687 		ais->type8.dac200fid10.course_q	= (bool)UBITS(158, 1);
688 		ais->type8.dac200fid10.heading_q = (bool)UBITS(159, 1);
689 		/* skip 8 bits */
690 		/*
691 		 * Attempt to prevent false matches with this message type
692 		 * by range-checking certain fields.
693 		 */
694 		if (ais->type8.dac200fid10.hazard > DAC200FID10_HAZARD_MAX
695 		    || !isascii((int)ais->type8.dac200fid10.vin[0]))
696 		    ais->type8.structured = false;
697 		else
698 		    ais->type8.structured = true;
699 		break;
700 	    case 23:	/* EMMA warning */
701 		if (bitlen != 256)
702 		    break;
703 		ais->type8.dac200fid23.start_year	= UBITS(56, 8);
704 		ais->type8.dac200fid23.start_month	= UBITS(64, 4);
705 		ais->type8.dac200fid23.start_day	= UBITS(68, 5);
706 		ais->type8.dac200fid23.end_year	= UBITS(73, 8);
707 		ais->type8.dac200fid23.end_month	= UBITS(81, 4);
708 		ais->type8.dac200fid23.end_day	= UBITS(85, 5);
709 		ais->type8.dac200fid23.start_hour	= UBITS(90, 5);
710 		ais->type8.dac200fid23.start_minute	= UBITS(95, 6);
711 		ais->type8.dac200fid23.end_hour	= UBITS(101, 5);
712 		ais->type8.dac200fid23.end_minute	= UBITS(106, 6);
713 		ais->type8.dac200fid23.start_lon	= SBITS(112, 28);
714 		ais->type8.dac200fid23.start_lat	= SBITS(140, 27);
715 		ais->type8.dac200fid23.end_lon	= SBITS(167, 28);
716 		ais->type8.dac200fid23.end_lat	= SBITS(195, 27);
717 		ais->type8.dac200fid23.type	= UBITS(222, 4);
718 		ais->type8.dac200fid23.min	= SBITS(226, 9);
719 		ais->type8.dac200fid23.max	= SBITS(235, 9);
720 		ais->type8.dac200fid23.intensity	= UBITS(244, 2);
721 		ais->type8.dac200fid23.wind	= UBITS(246, 4);
722 		/* skip 6 bits */
723 		ais->type8.structured = true;
724 		break;
725 	    case 24:	/* Water level */
726 		if (bitlen != 168)
727 		    break;
728 		UCHARS(56, ais->type8.dac200fid24.country);
729 #define ARRAY_BASE 68
730 #define ELEMENT_SIZE 25
731 		for (i = 0; ARRAY_BASE + (ELEMENT_SIZE*i) < (int)bitlen; i++) {
732 		    int a = ARRAY_BASE + (ELEMENT_SIZE*i);
733 		    ais->type8.dac200fid24.gauges[i].id = UBITS(a + 0,  11);
734 		    ais->type8.dac200fid24.gauges[i].level = SBITS(a + 11, 14);
735 		}
736 		ais->type8.dac200fid24.ngauges = i;
737 #undef ARRAY_BASE
738 #undef ELEMENT_SIZE
739 		/* skip 6 bits */
740 		ais->type8.structured = true;
741 		break;
742 	    case 40:	/* Signal status */
743 		if (bitlen != 168)
744 		    break;
745 		ais->type8.dac200fid40.lon	= SBITS(56, 28);
746 		ais->type8.dac200fid40.lat	= SBITS(84, 27);
747 		ais->type8.dac200fid40.form	= UBITS(111, 4);
748 		ais->type8.dac200fid40.facing	= UBITS(115, 9);
749 		ais->type8.dac200fid40.direction	= UBITS(124, 3);
750 		ais->type8.dac200fid40.status	= UBITS(127, 30);
751 		/* skip 11 bits */
752 		ais->type8.structured = true;
753 		break;
754 	    }
755 	}
756 	/* land here if we failed to match a known DAC/FID */
757 	if (!ais->type8.structured) {
758 	    size_t number_of_bytes = BITS_TO_BYTES(ais->type8.bitcount);
759 	    (void)memcpy(ais->type8.bitdata, (char *)bits + (56 / CHAR_BIT),
760 			 number_of_bytes);
761 	    size_t valid_bits_in_last_byte = ais->type8.bitcount % CHAR_BIT;
762 	    if(valid_bits_in_last_byte > 0) {
763 		    ais->type8.bitdata[number_of_bytes - 1] &=
764                             (0xFF << (8 - valid_bits_in_last_byte));
765             }
766 	}
767 	break;
768     case 9: /* Standard SAR Aircraft Position Report */
769 	PERMISSIVE_LENGTH_CHECK(168);
770 	ais->type9.alt		= UBITS(38, 12);
771 	ais->type9.speed	= UBITS(50, 10);
772 	ais->type9.accuracy	= (bool)UBITS(60, 1);
773 	ais->type9.lon		= SBITS(61, 28);
774 	ais->type9.lat		= SBITS(89, 27);
775 	ais->type9.course	= UBITS(116, 12);
776 	ais->type9.second	= UBITS(128, 6);
777 	ais->type9.regional	= UBITS(134, 8);
778 	ais->type9.dte		= UBITS(142, 1);
779 	//ais->type9.spare	= UBITS(143, 3);
780 	ais->type9.assigned	= UBITS(146, 1) != 0;
781 	ais->type9.raim		= UBITS(147, 1) != 0;
782 	ais->type9.radio	= UBITS(148, 20);
783 	break;
784     case 10: /* UTC/Date inquiry */
785 	PERMISSIVE_LENGTH_CHECK(72);
786 	//ais->type10.spare        = UBITS(38, 2);
787 	ais->type10.dest_mmsi      = UBITS(40, 30);
788 	//ais->type10.spare2       = UBITS(70, 2);
789 	break;
790     case 12: /* Safety Related Message */
791 	RANGE_CHECK(72, 1008);
792 	ais->type12.seqno          = UBITS(38, 2);
793 	ais->type12.dest_mmsi      = UBITS(40, 30);
794 	ais->type12.retransmit     = (bool)UBITS(70, 1);
795 	//ais->type12.spare        = UBITS(71, 1);
796 	ENDCHARS(72, ais->type12.text);
797 	break;
798     case 14:	/* Safety Related Broadcast Message */
799 	RANGE_CHECK(40, 1008);
800 	//ais->type14.spare          = UBITS(38, 2);
801 	ENDCHARS(40, ais->type14.text);
802 	break;
803     case 15:	/* Interrogation */
804 	RANGE_CHECK(88, 168);
805 	(void)memset(&ais->type15, '\0', sizeof(ais->type15));
806 	//ais->type14.spare         = UBITS(38, 2);
807 	ais->type15.mmsi1	    = UBITS(40, 30);
808 	ais->type15.type1_1	    = UBITS(70, 6);
809 	ais->type15.type1_1	    = UBITS(70, 6);
810 	ais->type15.offset1_1	    = UBITS(76, 12);
811 	//ais->type14.spare2        = UBITS(88, 2);
812 	if (bitlen > 90) {
813 	    ais->type15.type1_2	      = UBITS(90, 6);
814 	    ais->type15.offset1_2     = UBITS(96, 12);
815 	    //ais->type14.spare3      = UBITS(108, 2);
816 	    if (bitlen > 110) {
817 		ais->type15.mmsi2	= UBITS(110, 30);
818 		ais->type15.type2_1	= UBITS(140, 6);
819 		ais->type15.offset2_1	= UBITS(146, 12);
820 		//ais->type14.spare4	= UBITS(158, 2);
821 	    }
822 	}
823 	break;
824     case 16:	/* Assigned Mode Command */
825 	RANGE_CHECK(96, 168);
826 	ais->type16.mmsi1	= UBITS(40, 30);
827 	ais->type16.offset1	= UBITS(70, 12);
828 	ais->type16.increment1	= UBITS(82, 10);
829 	if (bitlen < 144)
830 	    ais->type16.mmsi2=ais->type16.offset2=ais->type16.increment2 = 0;
831 	else {
832 	    ais->type16.mmsi2	= UBITS(92, 30);
833 	    ais->type16.offset2	= UBITS(122, 12);
834 	    ais->type16.increment2	= UBITS(134, 10);
835 	}
836 	break;
837     case 17:	/* GNSS Broadcast Binary Message */
838 	RANGE_CHECK(80, 816);
839 	//ais->type17.spare     = UBITS(38, 2);
840 	ais->type17.lon		= SBITS(40, 18);
841 	ais->type17.lat		= SBITS(58, 17);
842 	//ais->type17.spare	= UBITS(75, 5);
843 	ais->type17.bitcount    = bitlen - 80;
844 	(void)memcpy(ais->type17.bitdata, (char *)bits + (80 / CHAR_BIT),
845 		     BITS_TO_BYTES(ais->type17.bitcount));
846 	break;
847     case 18:	/* Standard Class B CS Position Report */
848 	PERMISSIVE_LENGTH_CHECK(168)
849 	ais->type18.reserved	= UBITS(38, 8);
850 	ais->type18.speed	= UBITS(46, 10);
851 	ais->type18.accuracy	= UBITS(56, 1) != 0;
852 	ais->type18.lon		= SBITS(57, 28);
853 	ais->type18.lat		= SBITS(85, 27);
854 	ais->type18.course	= UBITS(112, 12);
855 	ais->type18.heading	= UBITS(124, 9);
856 	ais->type18.second	= UBITS(133, 6);
857 	ais->type18.regional	= UBITS(139, 2);
858 	ais->type18.cs		= UBITS(141, 1) != 0;
859 	ais->type18.display 	= UBITS(142, 1) != 0;
860 	ais->type18.dsc     	= UBITS(143, 1) != 0;
861 	ais->type18.band    	= UBITS(144, 1) != 0;
862 	ais->type18.msg22   	= UBITS(145, 1) != 0;
863 	ais->type18.assigned	= UBITS(146, 1) != 0;
864 	ais->type18.raim	= UBITS(147, 1) != 0;
865 	ais->type18.radio	= UBITS(148, 20);
866 	break;
867     case 19:	/* Extended Class B CS Position Report */
868 	PERMISSIVE_LENGTH_CHECK(312)
869 	ais->type19.reserved     = UBITS(38, 8);
870 	ais->type19.speed        = UBITS(46, 10);
871 	ais->type19.accuracy     = UBITS(56, 1) != 0;
872 	ais->type19.lon          = SBITS(57, 28);
873 	ais->type19.lat          = SBITS(85, 27);
874 	ais->type19.course       = UBITS(112, 12);
875 	ais->type19.heading      = UBITS(124, 9);
876 	ais->type19.second       = UBITS(133, 6);
877 	ais->type19.regional     = UBITS(139, 4);
878 	UCHARS(143, ais->type19.shipname);
879 	ais->type19.shiptype     = UBITS(263, 8);
880 	ais->type19.to_bow       = UBITS(271, 9);
881 	ais->type19.to_stern     = UBITS(280, 9);
882 	ais->type19.to_port      = UBITS(289, 6);
883 	ais->type19.to_starboard = UBITS(295, 6);
884 	ais->type19.epfd         = UBITS(301, 4);
885 	ais->type19.raim         = UBITS(305, 1) != 0;
886 	ais->type19.dte          = UBITS(306, 1) != 0;
887 	ais->type19.assigned     = UBITS(307, 1) != 0;
888 	//ais->type19.spare      = UBITS(308, 4);
889 	break;
890     case 20:	/* Data Link Management Message */
891 	RANGE_CHECK(72, 186);
892 	//ais->type20.spare	= UBITS(38, 2);
893 	ais->type20.offset1	= UBITS(40, 12);
894 	ais->type20.number1	= UBITS(52, 4);
895 	ais->type20.timeout1	= UBITS(56, 3);
896 	ais->type20.increment1	= UBITS(59, 11);
897 	ais->type20.offset2	= UBITS(70, 12);
898 	ais->type20.number2	= UBITS(82, 4);
899 	ais->type20.timeout2	= UBITS(86, 3);
900 	ais->type20.increment2	= UBITS(89, 11);
901 	ais->type20.offset3	= UBITS(100, 12);
902 	ais->type20.number3	= UBITS(112, 4);
903 	ais->type20.timeout3	= UBITS(116, 3);
904 	ais->type20.increment3	= UBITS(119, 11);
905 	ais->type20.offset4	= UBITS(130, 12);
906 	ais->type20.number4	= UBITS(142, 4);
907 	ais->type20.timeout4	= UBITS(146, 3);
908 	ais->type20.increment4	= UBITS(149, 11);
909 	break;
910     case 21:	/* Aid-to-Navigation Report */
911 	RANGE_CHECK(272, 368);
912 	ais->type21.aid_type     = UBITS(38, 5);
913 	from_sixbit_untrimmed((unsigned char *)bits, 43, 20, ais->type21.name);
914 	ais->type21.accuracy     = UBITS(163, 1);
915 	ais->type21.lon          = SBITS(164, 28);
916 	ais->type21.lat          = SBITS(192, 27);
917 	ais->type21.to_bow       = UBITS(219, 9);
918 	ais->type21.to_stern     = UBITS(228, 9);
919 	ais->type21.to_port      = UBITS(237, 6);
920 	ais->type21.to_starboard = UBITS(243, 6);
921 	ais->type21.epfd         = UBITS(249, 4);
922 	ais->type21.second       = UBITS(253, 6);
923 	ais->type21.off_position = UBITS(259, 1)!= 0;
924 	ais->type21.regional     = UBITS(260, 8);
925 	ais->type21.raim         = UBITS(268, 1) != 0;
926 	ais->type21.virtual_aid  = UBITS(269, 1) != 0;
927 	ais->type21.assigned     = UBITS(270, 1) != 0;
928 	//ais->type21.spare      = UBITS(271, 1);
929 	if (strlen(ais->type21.name) == 20 && bitlen > 272)
930 	    ENDCHARS(272, ais->type21.name+20);
931         trim_spaces_on_right_end(ais->type21.name);
932 	break;
933     case 22:	/* Channel Management */
934 	PERMISSIVE_LENGTH_CHECK(168)
935 	ais->type22.channel_a    = UBITS(40, 12);
936 	ais->type22.channel_b    = UBITS(52, 12);
937 	ais->type22.txrx         = UBITS(64, 4);
938 	ais->type22.power        = UBITS(68, 1);
939 	ais->type22.addressed    = UBITS(139, 1);
940 	if (!ais->type22.addressed) {
941 	    ais->type22.area.ne_lon       = SBITS(69, 18);
942 	    ais->type22.area.ne_lat       = SBITS(87, 17);
943 	    ais->type22.area.sw_lon       = SBITS(104, 18);
944 	    ais->type22.area.sw_lat       = SBITS(122, 17);
945 	} else {
946 	    ais->type22.mmsi.dest1        = UBITS(69, 30);
947 	    ais->type22.mmsi.dest2        = UBITS(104, 30);
948 	}
949 	ais->type22.band_a       = UBITS(140, 1);
950 	ais->type22.band_b       = UBITS(141, 1);
951 	ais->type22.zonesize     = UBITS(142, 3);
952 	break;
953     case 23:	/* Group Assignment Command */
954 	PERMISSIVE_LENGTH_CHECK(160)
955 	ais->type23.ne_lon       = SBITS(40, 18);
956 	ais->type23.ne_lat       = SBITS(58, 17);
957 	ais->type23.sw_lon       = SBITS(75, 18);
958 	ais->type23.sw_lat       = SBITS(93, 17);
959 	ais->type23.stationtype  = UBITS(110, 4);
960 	ais->type23.shiptype     = UBITS(114, 8);
961 	ais->type23.txrx         = UBITS(144, 4);
962 	ais->type23.interval     = UBITS(146, 4);
963 	ais->type23.quiet        = UBITS(150, 4);
964 	break;
965     case 24:	/* Class B CS Static Data Report */
966 	switch (UBITS(38, 2)) {
967 	case 0:
968 	    RANGE_CHECK(160, 168);
969 	    /* save incoming 24A shipname/MMSI pairs in a circular queue */
970 	    {
971 		struct ais_type24a_t *saveptr =
972                         &type24_queue->ships[type24_queue->index];
973 
974 		GPSD_LOG(LOG_PROG, errout, "AIVDM: 24A from %09u stashed.\n",
975 			 ais->mmsi);
976 		saveptr->mmsi = ais->mmsi;
977 		UCHARS(40, saveptr->shipname);
978 		++type24_queue->index;
979 		type24_queue->index %= MAX_TYPE24_INTERLEAVE;
980 	    }
981 	    //ais->type24.a.spare	= UBITS(160, 8);
982 
983 	    UCHARS(40, ais->type24.shipname);
984 	    ais->type24.part = part_a;
985 	    return true;
986 	case 1:
987 	    PERMISSIVE_LENGTH_CHECK(168)
988 	    ais->type24.shiptype = UBITS(40, 8);
989 	    /*
990 	     * In ITU-R 1371-4, there are new model and serial fields
991 	     * carved out of the right-hand end of vendorid, which is
992 	     * reduced from 7 chars to 3.  To cope with older AIS
993 	     * implementations conforming to revision 3 and older,
994 	     * unpack the trailing bits *both* ways; truly
995 	     * revision-4-conformant implementations will have up to
996 	     * four characters of trailing garbage on the vendorid,
997 	     * and older implementations will have garbafe in the
998 	     * model and serial fields.
999 	     */
1000 	    UCHARS(48, ais->type24.vendorid);
1001 	    ais->type24.model = UBITS(66, 4);
1002 	    ais->type24.serial = UBITS(70, 20);
1003 	    UCHARS(90, ais->type24.callsign);
1004 	    if (AIS_AUXILIARY_MMSI(ais->mmsi)) {
1005 		ais->type24.mothership_mmsi   = UBITS(132, 30);
1006 	    } else {
1007 		ais->type24.dim.to_bow        = UBITS(132, 9);
1008 		ais->type24.dim.to_stern      = UBITS(141, 9);
1009 		ais->type24.dim.to_port       = UBITS(150, 6);
1010 		ais->type24.dim.to_starboard  = UBITS(156, 6);
1011 	    }
1012 	    //ais->type24.b.spare	    = UBITS(162, 8);
1013 
1014 	    /* search the 24A queue for a matching MMSI */
1015 	    for (i = 0; i < MAX_TYPE24_INTERLEAVE; i++) {
1016 		if (type24_queue->ships[i].mmsi == ais->mmsi) {
1017 		    (void)strlcpy(ais->type24.shipname,
1018 				  type24_queue->ships[i].shipname,
1019 				  sizeof(ais->type24.shipname));
1020 		    GPSD_LOG(LOG_PROG, errout,
1021 			     "AIVDM 24B from %09u matches a 24A.\n",
1022 			     ais->mmsi);
1023 		    /* prevent false match if a 24B is repeated */
1024 		    type24_queue->ships[i].mmsi = 0;
1025 		    ais->type24.part = both;
1026 		    return true;
1027 		}
1028 	    }
1029 
1030 	    /* no match, return Part B */
1031 	    ais->type24.part = part_b;
1032 	    return true;
1033 	default:
1034 	    GPSD_LOG(LOG_WARN, errout,
1035 		     "AIVDM message type 24 of subtype unknown.\n");
1036 	    return false;
1037 	}
1038 	// break;
1039     case 25:	/* Binary Message, Single Slot */
1040 	/* this check and the following one reject line noise */
1041 	if (bitlen < 40 || bitlen > 168) {
1042 	    GPSD_LOG(LOG_WARN, errout,
1043 		     "AIVDM message type 25 size not between "
1044                      "40 to 168 bits (%zd).\n", bitlen);
1045 	    return false;
1046 	}
1047 	ais->type25.addressed	= (bool)UBITS(38, 1);
1048 	ais->type25.structured	= (bool)UBITS(39, 1);
1049 	if (bitlen < (unsigned)(40 + (16 * ais->type25.structured) +
1050                                 (30 * ais->type25.addressed))) {
1051 	    GPSD_LOG(LOG_WARN, errout,
1052 		     "AIVDM message type 25 too short for mode.\n");
1053 	    return false;
1054 	}
1055 	if (ais->type25.addressed)
1056 	    ais->type25.dest_mmsi   = UBITS(40, 30);
1057 	if (ais->type25.structured)
1058 	    ais->type25.app_id      = UBITS(40 + ais->type25.addressed * 30,16);
1059 	ais->type25.bitcount        = bitlen - 40 - 16 * ais->type25.structured;
1060 	/* bit 40 is exactly 5 bytes in; 2 bytes is 16 bits */
1061 	(void)memcpy(ais->type25.bitdata,
1062 		     (char *)bits + 5 + 2 * ais->type25.structured,
1063 		     BITS_TO_BYTES(ais->type25.bitcount));
1064 	/* discard MMSI if addressed */
1065 	if (ais->type25.addressed) {
1066 	    shiftleft((unsigned char *)ais->type25.bitdata,
1067                       ais->type25.bitcount, 30);
1068 	    ais->type25.bitcount -= 30;
1069 	}
1070 	break;
1071     case 26:	/* Binary Message, Multiple Slot */
1072 	RANGE_CHECK(60, 1004);
1073 	ais->type26.addressed	= (bool)UBITS(38, 1);
1074 	ais->type26.structured	= (bool)UBITS(39, 1);
1075 	if ((signed)bitlen < 40 + 16 * ais->type26.structured +
1076                 30 * ais->type26.addressed + 20) {
1077 	    GPSD_LOG(LOG_WARN, errout,
1078 		     "AIVDM message type 26 too short for mode.\n");
1079 	    return false;
1080 	}
1081 	if (ais->type26.addressed)
1082 	    ais->type26.dest_mmsi = UBITS(40, 30);
1083 	if (ais->type26.structured)
1084 	    ais->type26.app_id    = UBITS(40 + ais->type26.addressed * 30, 16);
1085 	ais->type26.bitcount      = bitlen - 60 - 16 * ais->type26.structured;
1086 	(void)memcpy(ais->type26.bitdata,
1087 		     (unsigned char *)bits + 5 + 2 * ais->type26.structured,
1088 		     BITS_TO_BYTES(ais->type26.bitcount));
1089 	/* discard MMSI if addressed */
1090 	if (ais->type26.addressed) {
1091 	    shiftleft((unsigned char *)ais->type26.bitdata,
1092                       ais->type26.bitcount, 30);
1093 	    ais->type26.bitcount -= 30;
1094 	}
1095 	break;
1096     case 27:	/* Long Range AIS Broadcast message */
1097 	if (bitlen != 96 && bitlen != 168) {
1098 	    GPSD_LOG(LOG_WARN, errout,
1099 		     "unexpected AIVDM message type 27 (%zd).\n",
1100 		     bitlen);
1101 	    return false;
1102 	} if (bitlen == 168) {
1103 	    /*
1104 	     * This is an implementation error observed in the wild,
1105 	     * sending a full 168-bit slot rather than just 96 bits.
1106 	     */
1107 	    GPSD_LOG(LOG_WARN, errout,
1108 		     "oversized 169=8-bit AIVDM message type 27.\n");
1109 	}
1110 	ais->type27.accuracy    = (bool)UBITS(38, 1);
1111 	ais->type27.raim	= UBITS(39, 1) != 0;
1112 	ais->type27.status	= UBITS(40, 4);
1113 	ais->type27.lon		= SBITS(44, 18);
1114 	ais->type27.lat		= SBITS(62, 17);
1115 	ais->type27.speed	= UBITS(79, 6);
1116 	ais->type27.course	= UBITS(85, 9);
1117 	ais->type27.gnss        = (bool)UBITS(94, 1);
1118 	break;
1119     default:
1120 	GPSD_LOG(LOG_ERROR, errout,
1121 		 "Unparsed AIVDM message type %d.\n",ais->type);
1122 	return false;
1123     }
1124     /* *INDENT-ON* */
1125 #undef UCHARS
1126 #undef SBITS
1127 #undef UBITS
1128 
1129     /* data is fully decoded */
1130     return true;
1131 }
1132 
1133 /* driver_ais.c ends here */
1134