diff options
author | Teemu Ikonen <tpikonen@mailbox.org> | 2021-10-26 14:03:34 +0300 |
---|---|---|
committer | Zeeshan Ali <zeenix@gmail.com> | 2021-11-07 20:31:35 +0000 |
commit | 91c9974bc6c44e6b3069533a2f2b889e1025b984 (patch) | |
tree | 648d16893024c9d6ad6f8fe15a78cf46bf3c8a9c | |
parent | b89187e77147b797e317977579fc6486d05fdb65 (diff) |
nmea-source: Use multiple NMEA sentences for location
Read lines from the NMEA socket source in on_read_nmea_sentence as long
as new lines are available. Store the last received GGA and RMC
sentences to static buffers and pass them to
gclue_location_create_from_nmeas to create a new location.
-rw-r--r-- | src/gclue-nmea-source.c | 90 |
1 files changed, 62 insertions, 28 deletions
diff --git a/src/gclue-nmea-source.c b/src/gclue-nmea-source.c index f7ac644..af294b4 100644 --- a/src/gclue-nmea-source.c +++ b/src/gclue-nmea-source.c @@ -448,6 +448,7 @@ browse_callback (AvahiServiceBrowser *service_browser, } } +#define NMEA_STR_LEN 128 static void on_read_nmea_sentence (GObject *object, GAsyncResult *result, @@ -460,44 +461,74 @@ on_read_nmea_sentence (GObject *object, GClueLocation *location; gsize data_size = 0 ; char *message; + gint i; + static const gchar *sentences[3] = { 0 }; + static gchar gga[NMEA_STR_LEN] = { 0 }; + static gchar rmc[NMEA_STR_LEN] = { 0 }; + message = g_data_input_stream_read_line_finish (data_input_stream, result, &data_size, &error); - if (message == NULL) { - if (error != NULL) { - if (error->code == G_IO_ERROR_CLOSED) - g_debug ("Socket closed."); - else if (error->code != G_IO_ERROR_CANCELLED) - g_warning ("Error when receiving message: %s", - error->message); - g_error_free (error); - } else { - g_debug ("Nothing to read"); + do { + if (message == NULL) { + if (error != NULL) { + if (error->code == G_IO_ERROR_CLOSED) + g_debug ("Socket closed."); + else if (error->code != G_IO_ERROR_CANCELLED) + g_warning ("Error when receiving message: %s", + error->message); + g_error_free (error); + } else { + g_debug ("Nothing to read"); + } + g_object_unref (data_input_stream); + + if (source->priv->active_service != NULL) + /* In case service did not advertise it exiting + * or we failed to receive it's notification. + */ + remove_service (source, source->priv->active_service); + + gga[0] = '\0'; + rmc[0] = '\0'; + return; } - g_object_unref (data_input_stream); + g_debug ("Network source sent: \"%s\"", message); - if (source->priv->active_service != NULL) - /* In case service did not advertise it exiting - * or we failed to receive it's notification. - */ - remove_service (source, source->priv->active_service); + if (gclue_nmea_is_gga (message)) { + g_strlcpy (gga, message, NMEA_STR_LEN); + } else if (gclue_nmea_is_rmc (message)) { + g_strlcpy (rmc, message, NMEA_STR_LEN); + } else { + g_debug ("Ignoring NMEA sentence, as it's neither GGA or RMC: %s", message); + } - return; - } - g_debug ("Network source sent: \"%s\"", message); + message = (char *) g_buffered_input_stream_peek_buffer + (G_BUFFERED_INPUT_STREAM (data_input_stream), + &data_size); + if (g_strstr_len (message, data_size, "\n")) { + message = g_data_input_stream_read_line + (data_input_stream, &data_size, NULL, &error); + } else { + break; + } + } while (TRUE); - if (!gclue_nmea_is_nmea (message)) { - g_debug ("Ignoring NMEA sentence, as it's niether GGA or RMC: %s", message); - goto READ_NEXT_LINE; - } + i = 0; + if (gga[0]) + sentences[i++] = gga; + if (rmc[0]) + sentences[i++] = rmc; + sentences[i] = NULL; - prev_location = gclue_location_source_get_location (GCLUE_LOCATION_SOURCE (source)); - location = gclue_location_create_from_nmea (message, - prev_location, - &error); + prev_location = gclue_location_source_get_location + (GCLUE_LOCATION_SOURCE (source)); + location = gclue_location_create_from_nmeas (sentences, + prev_location, + &error); if (error != NULL) { g_warning ("Error: %s", error->message); @@ -507,7 +538,10 @@ on_read_nmea_sentence (GObject *object, (GCLUE_LOCATION_SOURCE (source), location); } -READ_NEXT_LINE: + gga[0] = '\0'; + rmc[0] = '\0'; + sentences[0] = NULL; + g_data_input_stream_read_line_async (data_input_stream, G_PRIORITY_DEFAULT, source->priv->cancellable, |