summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-03-27 17:59:22 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-03-29 09:18:03 +0200
commitee8afd8034f47f2f17ae042a2efe16034556dcf4 (patch)
treedf55a882beaeed19778070968d13d9e165ade901
parent614a5473164418e6392e80e7f3d14777e39a6d0e (diff)
downloadModemManager-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.c46
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);
}