From 2f72253be9a6de623b0b28d77f29998414558326 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 10 Nov 2013 14:00:30 -0500 Subject: Make interpretation of the split24 flag propperly per-subscriber. This involved moving some out of the AIS driver. There is a related small change in behavior; now, if split24 is on, the Type B half of a matched pair will be shipped with type 'both'. All regression tests pass. PPS is live. --- driver_ais.c | 78 +++++++++++++++++++++++++----------------------------------- drivers.c | 5 ++-- gpsd.c | 6 +++++ gpsdecode.c | 8 ++++++- 4 files changed, 48 insertions(+), 49 deletions(-) diff --git a/driver_ais.c b/driver_ais.c index d006780f..e2a17f8d 100644 --- a/driver_ais.c +++ b/driver_ais.c @@ -989,29 +989,24 @@ bool ais_binary_decode(const int debug, bitlen); return false; } - if (type24_queue != NULL) - { - /* save incoming 24A shipname/MMSI pairs in a circular queue */ - { - struct ais_type24a_t *saveptr = &type24_queue->ships[type24_queue->index]; - gpsd_report(debug, LOG_PROG, - "AIVDM: 24A from %09u stashed.\n", - ais->mmsi); - saveptr->mmsi = ais->mmsi; - UCHARS(40, saveptr->shipname); - ++type24_queue->index; - type24_queue->index %= MAX_TYPE24_INTERLEAVE; - } - //ais->type24.a.spare = UBITS(160, 8); - return false; /* data only partially decoded */ - } - else + /* save incoming 24A shipname/MMSI pairs in a circular queue */ { - UCHARS(40, ais->type24.shipname); - ais->type24.part = part_a; - return true; + struct ais_type24a_t *saveptr = &type24_queue->ships[type24_queue->index]; + + gpsd_report(debug, LOG_PROG, + "AIVDM: 24A from %09u stashed.\n", + ais->mmsi); + saveptr->mmsi = ais->mmsi; + UCHARS(40, saveptr->shipname); + ++type24_queue->index; + type24_queue->index %= MAX_TYPE24_INTERLEAVE; } + //ais->type24.a.spare = UBITS(160, 8); + + UCHARS(40, ais->type24.shipname); + ais->type24.part = part_a; + return true; case 1: if (bitlen != 168) { gpsd_report(debug, LOG_WARN, @@ -1044,33 +1039,26 @@ bool ais_binary_decode(const int debug, ais->type24.dim.to_starboard = UBITS(156, 6); } //ais->type24.b.spare = UBITS(162, 8); - if (type24_queue != NULL) - { - /* search the 24A queue for a matching MMSI */ - for (i = 0; i < MAX_TYPE24_INTERLEAVE; i++) { - if (type24_queue->ships[i].mmsi == ais->mmsi) { - (void)strlcpy(ais->type24.shipname, - type24_queue->ships[i].shipname, - sizeof(type24_queue->ships[i].shipname)); - gpsd_report(debug, LOG_PROG, - "AIVDM 24B from %09u matches a 24A.\n", - ais->mmsi); - /* prevent false match if a 24B is repeated */ - type24_queue->ships[i].mmsi = 0; - return true; - } + + /* search the 24A queue for a matching MMSI */ + for (i = 0; i < MAX_TYPE24_INTERLEAVE; i++) { + if (type24_queue->ships[i].mmsi == ais->mmsi) { + (void)strlcpy(ais->type24.shipname, + type24_queue->ships[i].shipname, + sizeof(type24_queue->ships[i].shipname)); + gpsd_report(debug, LOG_PROG, + "AIVDM 24B from %09u matches a 24A.\n", + ais->mmsi); + /* prevent false match if a 24B is repeated */ + type24_queue->ships[i].mmsi = 0; + ais->type24.part = both; + return true; } - gpsd_report(debug, LOG_WARN, - "AIVDM 24B from %09u can't be matched to a 24A.\n", - ais->mmsi); - ais->type24.part = both; - return false; - } - else - { - ais->type24.part = part_b; - return true; } + + /* no match, return Part B */ + ais->type24.part = part_b; + return true; default: gpsd_report(debug, LOG_WARN, "AIVDM message type 24 of subtype unknown.\n"); diff --git a/drivers.c b/drivers.c index 050a8602..a2e07bf9 100644 --- a/drivers.c +++ b/drivers.c @@ -1154,7 +1154,7 @@ const struct gps_type_t mtk3301 = { static bool aivdm_decode(const char *buf, size_t buflen, struct gps_device_t *session, struct ais_t *ais, - bool split24, int debug) + int debug) { #ifdef __UNUSED_DEBUG__ char *sixbits[64] = { @@ -1325,7 +1325,7 @@ static bool aivdm_decode(const char *buf, size_t buflen, ais, ais_context->bits, ais_context->bitlen, - split24 ? NULL : &ais_context->type24_queue); + &ais_context->type24_queue); } /* we're still waiting on another sentence */ @@ -1340,7 +1340,6 @@ static gps_mask_t aivdm_analyze(struct gps_device_t *session) if (aivdm_decode ((char *)session->packet.outbuffer, session->packet.outbuflen, session, &session->gpsdata.ais, - session->gpsdata.policy.split24, session->context->debug)) { return ONLINE_SET | AIS_SET; } else diff --git a/gpsd.c b/gpsd.c index 338857d9..c8c19362 100644 --- a/gpsd.c +++ b/gpsd.c @@ -1633,6 +1633,12 @@ static void all_reports(struct gps_device_t *device, gps_mask_t changed) { char buf[GPS_JSON_RESPONSE_MAX * 4]; + if ((changed & AIS_SET) != 0) + if (device->gpsdata.ais.type == 24 + && device->gpsdata.ais.type24.part != both + && !sub->policy.split24) + continue; + json_data_report(changed, device, &sub->policy, buf, sizeof(buf)); diff --git a/gpsdecode.c b/gpsdecode.c index 35b5cc7f..22238817 100644 --- a/gpsdecode.c +++ b/gpsdecode.c @@ -51,6 +51,7 @@ static void aivdm_csv_dump(struct ais_t *ais, char *buf, size_t buflen) { char scratchbuf[MAX_PACKET_LENGTH*2+1]; bool imo = false; + (void)snprintf(buf, buflen, "%u|%u|%09u|", ais->type, ais->repeat, ais->mmsi); /*@ -formatcode @*/ @@ -548,7 +549,6 @@ static void decode(FILE *fpin, FILE*fpout) gpsd_clear(&session); session.gpsdata.gps_fd = fileno(fpin); session.gpsdata.dev.baudrate = 38400; /* hack to enable subframes */ - session.gpsdata.policy.split24 = split24; (void)strlcpy(session.gpsdata.dev.path, "stdin", sizeof(session.gpsdata.dev.path)); @@ -574,6 +574,10 @@ static void decode(FILE *fpin, FILE*fpout) } #ifdef SOCKET_EXPORT_ENABLE else { + if ((changed & AIS_SET)!=0) { + if (session.gpsdata.ais.type == 24 && session.gpsdata.ais.type24.part != both && !split24) + continue; + } json_data_report(changed, &session, &policy, buf, sizeof(buf)); @@ -583,6 +587,8 @@ static void decode(FILE *fpin, FILE*fpout) #ifdef AIVDM_ENABLE } else if (session.packet.type == AIVDM_PACKET) { if ((changed & AIS_SET)!=0) { + if (session.gpsdata.ais.type == 24 && session.gpsdata.ais.type24.part != both && !split24) + continue; aivdm_csv_dump(&session.gpsdata.ais, buf, sizeof(buf)); (void)fputs(buf, fpout); } -- cgit v1.2.1