diff options
-rw-r--r-- | libmm-common/Makefile.am | 4 | ||||
-rw-r--r-- | libmm-common/libmm-common.h | 1 | ||||
-rw-r--r-- | libmm-common/mm-location-gps-nmea.c | 189 | ||||
-rw-r--r-- | libmm-common/mm-location-gps-nmea.h | 61 |
4 files changed, 255 insertions, 0 deletions
diff --git a/libmm-common/Makefile.am b/libmm-common/Makefile.am index fc31fb5e..bc4be016 100644 --- a/libmm-common/Makefile.am +++ b/libmm-common/Makefile.am @@ -164,6 +164,7 @@ mm-bearer-properties.c: mm-errors-types.h mm-sms-properties.c: mm-errors-types.h mm-bearer-ip-config.c: mm-errors-types.h mm-location-3gpp.c: mm-errors-types.h +mm-location-gps-nmea.c: mm-errors-types.h mm-unlock-retries.c: mm-enums-types.h mm-network-timezone.c: mm-errors-types.h @@ -178,6 +179,7 @@ include_HEADERS = \ mm-sms-properties.h \ mm-bearer-ip-config.h \ mm-location-3gpp.h \ + mm-location-gps-nmea.h \ mm-unlock-retries.h \ mm-network-timezone.h \ mm-gdbus-manager.h \ @@ -205,6 +207,8 @@ libmm_common_la_SOURCES = \ mm-bearer-ip-config.c \ mm-location-3gpp.h \ mm-location-3gpp.c \ + mm-location-gps-nmea.h \ + mm-location-gps-nmea.c \ mm-unlock-retries.h \ mm-unlock-retries.c \ mm-network-timezone.h \ diff --git a/libmm-common/libmm-common.h b/libmm-common/libmm-common.h index 0dd3bab1..5b6eb84b 100644 --- a/libmm-common/libmm-common.h +++ b/libmm-common/libmm-common.h @@ -32,6 +32,7 @@ #include "mm-bearer-properties.h" #include "mm-bearer-ip-config.h" #include "mm-location-3gpp.h" +#include "mm-location-gps-nmea.h" #include "mm-unlock-retries.h" #include "mm-network-timezone.h" #include "mm-gdbus-manager.h" diff --git a/libmm-common/mm-location-gps-nmea.c b/libmm-common/mm-location-gps-nmea.c new file mode 100644 index 00000000..c2fae249 --- /dev/null +++ b/libmm-common/mm-location-gps-nmea.c @@ -0,0 +1,189 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2012 Lanedo GmbH <aleksander@lanedo.com> + */ + +#include <string.h> +#include <ctype.h> +#include <stdlib.h> + +#include "mm-errors-types.h" +#include "mm-location-gps-nmea.h" + +G_DEFINE_TYPE (MMLocationGpsNmea, mm_location_gps_nmea, G_TYPE_OBJECT); + +struct _MMLocationGpsNmeaPrivate { + GHashTable *traces; +}; + +/*****************************************************************************/ + +static gboolean +location_gps_nmea_take_trace (MMLocationGpsNmea *self, + gchar *trace) +{ + gchar *i; + gchar *trace_type; + + i = strchr (trace, ','); + if (!i || i == trace) + return FALSE; + + trace_type = g_malloc (i - trace + 1); + memcpy (trace_type, trace, i - trace); + trace_type[i - trace] = '\0'; + + g_hash_table_replace (self->priv->traces, + trace_type, + trace); + return TRUE; +} + +gboolean +mm_location_gps_nmea_add_trace (MMLocationGpsNmea *self, + const gchar *trace) +{ + return location_gps_nmea_take_trace (self, g_strdup (trace)); +} + +/*****************************************************************************/ + +const gchar * +mm_location_gps_nmea_get_trace (MMLocationGpsNmea *self, + const gchar *trace_type) +{ + return (const gchar *)g_hash_table_lookup (self->priv->traces, trace_type); +} + +/*****************************************************************************/ + +static void +build_full_foreach (const gchar *trace_type, + const gchar *trace, + GString **built) +{ + g_string_append (*built, trace); +} + +gchar * +mm_location_gps_nmea_build_full (MMLocationGpsNmea *self) +{ + GString *built; + + built = g_string_new (""); + g_hash_table_foreach (self->priv->traces, + (GHFunc)build_full_foreach, + &built); + return g_string_free (built, FALSE); +} + +/*****************************************************************************/ + +GVariant * +mm_location_gps_nmea_get_string_variant (MMLocationGpsNmea *self) +{ + GVariant *variant = NULL; + gchar *built; + + g_return_val_if_fail (MM_IS_LOCATION_GPS_NMEA (self), NULL); + + built = mm_location_gps_nmea_build_full (self); + variant = g_variant_new_string (built); + g_free (built); + + return variant; +} + +/*****************************************************************************/ + +MMLocationGpsNmea * +mm_location_gps_nmea_new_from_string_variant (GVariant *string, + GError **error) +{ + MMLocationGpsNmea *self = NULL; + gchar **split; + guint i; + + if (!g_variant_is_of_type (string, G_VARIANT_TYPE_STRING)) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Cannot create GPS NMEA location from string: " + "invalid variant type received"); + return NULL; + } + + split = g_strsplit (g_variant_get_string (string, NULL), "\r\n", -1); + if (!split) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_INVALID_ARGS, + "Invalid GPS NMEA location string: '%s'", + g_variant_get_string (string, NULL)); + return NULL; + } + + /* Create new location object */ + self = mm_location_gps_nmea_new (); + + for (i = 0; split[i]; i++) { + if (!location_gps_nmea_take_trace (self, split[i])) + g_free (split[i]); + } + + /* Note that the strings in the array of strings were already taken + * or freed */ + g_free (split); + + return self; +} + +/*****************************************************************************/ + +MMLocationGpsNmea * +mm_location_gps_nmea_new (void) +{ + return (MM_LOCATION_GPS_NMEA ( + g_object_new (MM_TYPE_LOCATION_GPS_NMEA, NULL))); +} + +static void +mm_location_gps_nmea_init (MMLocationGpsNmea *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), + MM_TYPE_LOCATION_GPS_NMEA, + MMLocationGpsNmeaPrivate); + + self->priv->traces = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + g_free); +} + +static void +finalize (GObject *object) +{ + MMLocationGpsNmea *self = MM_LOCATION_GPS_NMEA (object); + + g_hash_table_destroy (self->priv->traces); + + G_OBJECT_CLASS (mm_location_gps_nmea_parent_class)->finalize (object); +} + +static void +mm_location_gps_nmea_class_init (MMLocationGpsNmeaClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMLocationGpsNmeaPrivate)); +} diff --git a/libmm-common/mm-location-gps-nmea.h b/libmm-common/mm-location-gps-nmea.h new file mode 100644 index 00000000..c5ebe42c --- /dev/null +++ b/libmm-common/mm-location-gps-nmea.h @@ -0,0 +1,61 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2012 Lanedo GmbH <aleksander@lanedo.com> + */ + +#ifndef MM_LOCATION_GPS_NMEA_H +#define MM_LOCATION_GPS_NMEA_H + +#include <ModemManager.h> +#include <glib-object.h> + +G_BEGIN_DECLS + +#define MM_TYPE_LOCATION_GPS_NMEA (mm_location_gps_nmea_get_type ()) +#define MM_LOCATION_GPS_NMEA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_LOCATION_GPS_NMEA, MMLocationGpsNmea)) +#define MM_LOCATION_GPS_NMEA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_LOCATION_GPS_NMEA, MMLocationGpsNmeaClass)) +#define MM_IS_LOCATION_GPS_NMEA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_LOCATION_GPS_NMEA)) +#define MM_IS_LOCATION_GPS_NMEA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_LOCATION_GPS_NMEA)) +#define MM_LOCATION_GPS_NMEA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_LOCATION_GPS_NMEA, MMLocationGpsNmeaClass)) + +typedef struct _MMLocationGpsNmea MMLocationGpsNmea; +typedef struct _MMLocationGpsNmeaClass MMLocationGpsNmeaClass; +typedef struct _MMLocationGpsNmeaPrivate MMLocationGpsNmeaPrivate; + +struct _MMLocationGpsNmea { + GObject parent; + MMLocationGpsNmeaPrivate *priv; +}; + +struct _MMLocationGpsNmeaClass { + GObjectClass parent; +}; + +GType mm_location_gps_nmea_get_type (void); + +MMLocationGpsNmea *mm_location_gps_nmea_new (void); +MMLocationGpsNmea *mm_location_gps_nmea_new_from_string_variant (GVariant *string, + GError **error); + +gboolean mm_location_gps_nmea_add_trace (MMLocationGpsNmea *self, + const gchar *trace); + +const gchar *mm_location_gps_nmea_get_trace (MMLocationGpsNmea *self, + const gchar *trace_type); +gchar *mm_location_gps_nmea_build_full (MMLocationGpsNmea *self); + +GVariant *mm_location_gps_nmea_get_string_variant (MMLocationGpsNmea *self); + +G_END_DECLS + +#endif /* MM_LOCATION_GPS_NMEA_H */ |