driver_ais.c 53 KB

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