diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-03-27 17:59:22 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-03-29 09:18:03 +0200 |
commit | ee8afd8034f47f2f17ae042a2efe16034556dcf4 (patch) | |
tree | df55a882beaeed19778070968d13d9e165ade901 | |
parent | 614a5473164418e6392e80e7f3d14777e39a6d0e (diff) | |
download | ModemManager-ee8afd8034f47f2f17ae042a2efe16034556dcf4.tar.gz |
libmm-common,location-gps-nmea: allow sequences of traces
Some traces, e.g. $GPGSV, are part of a sequence. For those traces, we'll try
to always keep the whole sequence around, not just the last received trace.
-rw-r--r-- | libmm-common/mm-location-gps-nmea.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/libmm-common/mm-location-gps-nmea.c b/libmm-common/mm-location-gps-nmea.c index c2fae249b..46c685c27 100644 --- a/libmm-common/mm-location-gps-nmea.c +++ b/libmm-common/mm-location-gps-nmea.c @@ -17,6 +17,7 @@ #include <ctype.h> #include <stdlib.h> +#include "mm-common-helpers.h" #include "mm-errors-types.h" #include "mm-location-gps-nmea.h" @@ -24,11 +25,38 @@ G_DEFINE_TYPE (MMLocationGpsNmea, mm_location_gps_nmea, G_TYPE_OBJECT); struct _MMLocationGpsNmeaPrivate { GHashTable *traces; + GRegex *sequence_regex; }; /*****************************************************************************/ static gboolean +check_append_or_replace (MMLocationGpsNmea *self, + const gchar *trace) +{ + /* By default, replace */ + gboolean append_or_replace = FALSE; + GMatchInfo *match_info = NULL; + + if (G_UNLIKELY (!self->priv->sequence_regex)) + self->priv->sequence_regex = g_regex_new ("\\$GPGSV,(\\d),(\\d).*", + G_REGEX_RAW | G_REGEX_OPTIMIZE, + 0, + NULL); + + if (g_regex_match (self->priv->sequence_regex, trace, 0, &match_info)) { + guint index; + + /* If we don't have the first element of a sequence, append */ + if (mm_get_uint_from_match_info (match_info, 2, &index) && index != 1) + append_or_replace = TRUE; + } + g_match_info_free (match_info); + + return append_or_replace; +} + +static gboolean location_gps_nmea_take_trace (MMLocationGpsNmea *self, gchar *trace) { @@ -43,6 +71,22 @@ location_gps_nmea_take_trace (MMLocationGpsNmea *self, memcpy (trace_type, trace, i - trace); trace_type[i - trace] = '\0'; + /* Some traces are part of a SEQUENCE; so we need to decide whether we + * completely replace the previous trace, or we append the new one to + * the already existing list */ + if (check_append_or_replace (self, trace)) { + /* Append */ + const gchar *previous; + gchar *sequence; + + previous = g_hash_table_lookup (self->priv->traces, trace_type); + sequence = g_strdup_printf ("%s%s", + previous ? previous : "", + trace); + g_free (trace); + trace = sequence; + } + g_hash_table_replace (self->priv->traces, trace_type, trace); @@ -176,6 +220,8 @@ finalize (GObject *object) MMLocationGpsNmea *self = MM_LOCATION_GPS_NMEA (object); g_hash_table_destroy (self->priv->traces); + if (self->priv->sequence_regex) + g_regex_unref (self->priv->sequence_regex); G_OBJECT_CLASS (mm_location_gps_nmea_parent_class)->finalize (object); } |