summaryrefslogtreecommitdiff
path: root/.pc/tizen.patch/providers
diff options
context:
space:
mode:
authorKibum Kim <kb0929.kim@samsung.com>2012-01-07 00:46:29 +0900
committerKibum Kim <kb0929.kim@samsung.com>2012-01-07 00:46:29 +0900
commit0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d (patch)
tree327fd58b5a721a2ecf835f2eccffde08cdbc4070 /.pc/tizen.patch/providers
parent9f11ee482a4a28d6e85613ac5c765c588fdf20aa (diff)
downloadgeoclue-0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d.tar.gz
geoclue-0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d.tar.bz2
geoclue-0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d.zip
Git init
Diffstat (limited to '.pc/tizen.patch/providers')
-rwxr-xr-x.pc/tizen.patch/providers/example/Makefile.am30
-rwxr-xr-x.pc/tizen.patch/providers/example/geoclue-example.c168
-rwxr-xr-x.pc/tizen.patch/providers/geonames/Makefile.am35
-rwxr-xr-x.pc/tizen.patch/providers/gpsd/Makefile.am32
-rwxr-xr-x.pc/tizen.patch/providers/gpsd/geoclue-gpsd.c519
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/Makefile.am77
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.c779
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.h56
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc.c459
-rwxr-xr-x.pc/tizen.patch/providers/gsmloc/mm-marshal.list2
-rwxr-xr-x.pc/tizen.patch/providers/gypsy/Makefile.am32
-rwxr-xr-x.pc/tizen.patch/providers/gypsy/geoclue-gypsy.c623
-rwxr-xr-x.pc/tizen.patch/providers/hostip/Makefile.am35
-rwxr-xr-x.pc/tizen.patch/providers/localnet/Makefile.am56
-rwxr-xr-x.pc/tizen.patch/providers/localnet/geoclue-localnet.c512
-rwxr-xr-x.pc/tizen.patch/providers/manual/Makefile.am54
-rwxr-xr-x.pc/tizen.patch/providers/manual/geoclue-manual.c365
-rwxr-xr-x.pc/tizen.patch/providers/nominatim/Makefile.am35
-rwxr-xr-x.pc/tizen.patch/providers/plazes/Makefile.am33
-rwxr-xr-x.pc/tizen.patch/providers/plazes/geoclue-plazes.c377
-rwxr-xr-x.pc/tizen.patch/providers/skyhook/Makefile.am35
-rwxr-xr-x.pc/tizen.patch/providers/skyhook/geoclue-skyhook.c303
-rwxr-xr-x.pc/tizen.patch/providers/skyhook/geoclue-skyhook.provider8
-rwxr-xr-x.pc/tizen.patch/providers/yahoo/Makefile.am31
24 files changed, 4656 insertions, 0 deletions
diff --git a/.pc/tizen.patch/providers/example/Makefile.am b/.pc/tizen.patch/providers/example/Makefile.am
new file mode 100755
index 0000000..bb052fc
--- /dev/null
+++ b/.pc/tizen.patch/providers/example/Makefile.am
@@ -0,0 +1,30 @@
+libexec_PROGRAMS = geoclue-example
+
+geoclue_example_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_example_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_example_SOURCES = \
+ geoclue-example.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-example.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Example.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/example/geoclue-example.c b/.pc/tizen.patch/providers/example/geoclue-example.c
new file mode 100755
index 0000000..a7ef6f7
--- /dev/null
+++ b/.pc/tizen.patch/providers/example/geoclue-example.c
@@ -0,0 +1,168 @@
+/*
+ * Geoclue
+ * geoclue-example.c - Example provider which doesn't do anything.
+ *
+ * Author: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+
+typedef struct {
+ GcProvider parent;
+
+ GMainLoop *loop;
+} GeoclueExample;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueExampleClass;
+
+#define GEOCLUE_TYPE_EXAMPLE (geoclue_example_get_type ())
+#define GEOCLUE_EXAMPLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_EXAMPLE, GeoclueExample))
+
+static void geoclue_example_position_init (GcIfacePositionClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueExample, geoclue_example, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_example_position_init))
+
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ *status = GEOCLUE_STATUS_AVAILABLE;
+
+ return TRUE;
+}
+
+static void
+print_option (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ if (G_VALUE_TYPE (value) == G_TYPE_STRING)
+ g_print (" %s - %s\n", key, g_value_get_string (value));
+ else
+ g_print (" %s - %d\n", key, g_value_get_int (value));
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ g_print ("Options received---\n");
+ g_hash_table_foreach (options, print_option, NULL);
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueExample *example = GEOCLUE_EXAMPLE (provider);
+
+ g_main_loop_quit (example->loop);
+}
+
+static void
+geoclue_example_class_init (GeoclueExampleClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+static void
+geoclue_example_init (GeoclueExample *example)
+{
+ gc_provider_set_details (GC_PROVIDER (example),
+ "org.freedesktop.Geoclue.Providers.Example",
+ "/org/freedesktop/Geoclue/Providers/Example",
+ "Example", "Example provider");
+}
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ *timestamp = time (NULL);
+
+ /* We're not emitting location details here because we don't want
+ geoclue to accidently use this as a source */
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ return TRUE;
+}
+
+static void
+geoclue_example_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+emit_position_signal (gpointer data)
+{
+ GeoclueExample *example = data;
+ GeoclueAccuracy *accuracy;
+
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0.0, 0.0);
+
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (example),
+ GEOCLUE_POSITION_FIELDS_NONE,
+ time (NULL), 0.0, 0.0, 0.0, accuracy);
+
+ geoclue_accuracy_free (accuracy);
+
+ return TRUE;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueExample *example;
+
+ g_type_init ();
+
+ example = g_object_new (GEOCLUE_TYPE_EXAMPLE, NULL);
+
+ g_timeout_add (5000, emit_position_signal, example);
+
+ example->loop = g_main_loop_new (NULL, TRUE);
+ g_main_loop_run (example->loop);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/geonames/Makefile.am b/.pc/tizen.patch/providers/geonames/Makefile.am
new file mode 100755
index 0000000..55f31e3
--- /dev/null
+++ b/.pc/tizen.patch/providers/geonames/Makefile.am
@@ -0,0 +1,35 @@
+libexec_PROGRAMS = \
+ geoclue-geonames
+
+NOINST_H_FILES = \
+ geoclue-geonames.h
+
+geoclue_geonames_SOURCES = \
+ $(NOINST_H_FILES) \
+ geoclue-geonames.c
+
+geoclue_geonames_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_geonames_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-geonames.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Geonames.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/gpsd/Makefile.am b/.pc/tizen.patch/providers/gpsd/Makefile.am
new file mode 100755
index 0000000..cc2764e
--- /dev/null
+++ b/.pc/tizen.patch/providers/gpsd/Makefile.am
@@ -0,0 +1,32 @@
+libexec_PROGRAMS = geoclue-gpsd
+
+geoclue_gpsd_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS) \
+ $(GPSD_CFLAGS)
+
+geoclue_gpsd_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(GPSD_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_gpsd_SOURCES = \
+ geoclue-gpsd.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gpsd.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gpsd.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/gpsd/geoclue-gpsd.c b/.pc/tizen.patch/providers/gpsd/geoclue-gpsd.c
new file mode 100755
index 0000000..dba91be
--- /dev/null
+++ b/.pc/tizen.patch/providers/gpsd/geoclue-gpsd.c
@@ -0,0 +1,519 @@
+/*
+ * Geoclue
+ * geoclue-gpsd.c - Geoclue Position backend for gpsd
+ *
+ * Authors: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/* TODO:
+ *
+ * call to gps_set_callback blocks for a long time if
+ * BT device is not present.
+ *
+ **/
+
+#include <config.h>
+
+#include <math.h>
+#include <gps.h>
+#include <string.h>
+
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-velocity.h>
+
+typedef struct gps_data_t gps_data;
+typedef struct gps_fix_t gps_fix;
+
+/* only listing used tags */
+typedef enum {
+ NMEA_NONE,
+ NMEA_GSA,
+ NMEA_GGA,
+ NMEA_GSV,
+ NMEA_RMC
+} NmeaTag;
+
+
+typedef struct {
+ GcProvider parent;
+
+ char *host;
+ char *port;
+
+ gps_data *gpsdata;
+
+ gps_fix *last_fix;
+
+ GeoclueStatus last_status;
+ GeocluePositionFields last_pos_fields;
+ GeoclueAccuracy *last_accuracy;
+ GeoclueVelocityFields last_velo_fields;
+
+ GMainLoop *loop;
+
+} GeoclueGpsd;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueGpsdClass;
+
+static void geoclue_gpsd_position_init (GcIfacePositionClass *iface);
+static void geoclue_gpsd_velocity_init (GcIfaceVelocityClass *iface);
+
+#define GEOCLUE_TYPE_GPSD (geoclue_gpsd_get_type ())
+#define GEOCLUE_GPSD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GPSD, GeoclueGpsd))
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGpsd, geoclue_gpsd, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_gpsd_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_VELOCITY,
+ geoclue_gpsd_velocity_init))
+
+static void geoclue_gpsd_stop_gpsd (GeoclueGpsd *self);
+static gboolean geoclue_gpsd_start_gpsd (GeoclueGpsd *self);
+
+
+/* defining global GeoclueGpsd because gpsd does not support "user_data"
+ * pointers in callbacks */
+GeoclueGpsd *gpsd;
+
+
+
+/* Geoclue interface */
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+
+ *status = gpsd->last_status;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (provider);
+
+ g_main_loop_quit (gpsd->loop);
+}
+
+static void
+geoclue_gpsd_set_status (GeoclueGpsd *self, GeoclueStatus status)
+{
+ if (status != self->last_status) {
+ self->last_status = status;
+
+ /* make position and velocity invalid if no fix */
+ if (status != GEOCLUE_STATUS_AVAILABLE) {
+ self->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ self->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ }
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (self),
+ status);
+ }
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+ GValue *port_value, *host_value;
+ const char *port, *host;
+ gboolean changed = FALSE;
+
+ host_value = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSHost");
+ host = host_value ? g_value_get_string (host_value) : NULL;
+ port_value = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSPort");
+ port = port_value ? g_value_get_string (port_value) : NULL;
+
+ if (port == NULL) {
+ port = DEFAULT_GPSD_PORT;
+ }
+
+ /* new values? */
+ if (g_strcmp0 (host, gpsd->host) != 0 ||
+ g_strcmp0 (port, gpsd->port) != 0) {
+ changed = TRUE;
+ }
+
+ if (!changed) {
+ return TRUE;
+ }
+
+ /* update private values with new ones, restart gpsd */
+ g_free (gpsd->port);
+ gpsd->port = NULL;
+ g_free (gpsd->host);
+ gpsd->host = NULL;
+
+ geoclue_gpsd_stop_gpsd (gpsd);
+
+ if (host == NULL) {
+ return TRUE;
+ }
+
+ gpsd->port = g_strdup (port);
+ gpsd->host = g_strdup (host);
+ if (!geoclue_gpsd_start_gpsd (gpsd)) {
+ geoclue_gpsd_set_status (gpsd, GEOCLUE_STATUS_ERROR);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED, "Gpsd not found");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (object);
+
+ geoclue_gpsd_stop_gpsd (gpsd);
+ g_free (gpsd->last_fix);
+ geoclue_accuracy_free (gpsd->last_accuracy);
+
+ g_free (gpsd->port);
+ if (gpsd->host) {
+ g_free (gpsd->host);
+ }
+
+ ((GObjectClass *) geoclue_gpsd_parent_class)->finalize (object);
+}
+
+static void
+geoclue_gpsd_class_init (GeoclueGpsdClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+
+static gboolean
+equal_or_nan (double a, double b)
+{
+ if (isnan (a) && isnan (b)) {
+ return TRUE;
+ }
+ return a == b;
+}
+
+static void
+geoclue_gpsd_update_position (GeoclueGpsd *gpsd, NmeaTag nmea_tag)
+{
+ gps_fix *fix = &gpsd->gpsdata->fix;
+ gps_fix *last_fix = gpsd->last_fix;
+
+ last_fix->time = fix->time;
+
+ /* If a flag is not set, bail out.*/
+ if (!((gpsd->gpsdata->set & LATLON_SET) || (gpsd->gpsdata->set & ALTITUDE_SET))) {
+ return;
+ }
+ gpsd->gpsdata->set &= ~(LATLON_SET | ALTITUDE_SET);
+
+ if (equal_or_nan (fix->latitude, last_fix->latitude) &&
+ equal_or_nan (fix->longitude, last_fix->longitude) &&
+ equal_or_nan (fix->altitude, last_fix->altitude)) {
+ /* position has not changed */
+ return;
+ }
+
+ /* save values */
+ last_fix->latitude = fix->latitude;
+ last_fix->longitude = fix->longitude;
+ last_fix->altitude = fix->altitude;
+
+ /* Could use fix.eph for accuracy, but eph is
+ * often NaN... what then?
+ * Could also use fix mode (2d/3d) to decide vertical accuracy,
+ * but gpsd updates that so erratically that I couldn't
+ * be arsed so far */
+ geoclue_accuracy_set_details (gpsd->last_accuracy,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ 24, 60);
+
+ gpsd->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ gpsd->last_pos_fields |= (isnan (fix->latitude)) ?
+ 0 : GEOCLUE_POSITION_FIELDS_LATITUDE;
+ gpsd->last_pos_fields |= (isnan (fix->longitude)) ?
+ 0 : GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ gpsd->last_pos_fields |= (isnan (fix->altitude)) ?
+ 0 : GEOCLUE_POSITION_FIELDS_ALTITUDE;
+
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (gpsd), gpsd->last_pos_fields,
+ (int)(last_fix->time+0.5),
+ last_fix->latitude, last_fix->longitude, last_fix->altitude,
+ gpsd->last_accuracy);
+
+}
+
+static void
+geoclue_gpsd_update_velocity (GeoclueGpsd *gpsd, NmeaTag nmea_tag)
+{
+ gps_fix *fix = &gpsd->gpsdata->fix;
+ gps_fix *last_fix = gpsd->last_fix;
+ gboolean changed = FALSE;
+
+ /* at least with my devices, gpsd updates
+ * - climb on GGA, GSA and GSV messages (speed and track are set to NaN).
+ * - speed and track on RMC message (climb is set to NaN).
+ *
+ * couldn't think of an smart way to handle this, I don't think there is one
+ */
+
+ if (((gpsd->gpsdata->set & TRACK_SET) || (gpsd->gpsdata->set & SPEED_SET)) &&
+ nmea_tag == NMEA_RMC) {
+
+ gpsd->gpsdata->set &= ~(TRACK_SET | SPEED_SET);
+
+ last_fix->time = fix->time;
+
+ if (!equal_or_nan (fix->track, last_fix->track) ||
+ !equal_or_nan (fix->speed, last_fix->speed)){
+
+ /* velocity has changed */
+ changed = TRUE;
+ last_fix->track = fix->track;
+ last_fix->speed = fix->speed;
+ }
+ } else if ((gpsd->gpsdata->set & CLIMB_SET) &&
+ (nmea_tag == NMEA_GGA ||
+ nmea_tag == NMEA_GSA ||
+ nmea_tag == NMEA_GSV)) {
+
+ gpsd->gpsdata->set &= ~(CLIMB_SET);
+
+ last_fix->time = fix->time;
+
+ if (!equal_or_nan (fix->climb, last_fix->climb)){
+
+ /* velocity has changed */
+ changed = TRUE;
+ last_fix->climb = fix->climb;
+ }
+ }
+
+ if (changed) {
+ gpsd->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ gpsd->last_velo_fields |= (isnan (last_fix->track)) ?
+ 0 : GEOCLUE_VELOCITY_FIELDS_DIRECTION;
+ gpsd->last_velo_fields |= (isnan (last_fix->speed)) ?
+ 0 : GEOCLUE_VELOCITY_FIELDS_SPEED;
+ gpsd->last_velo_fields |= (isnan (last_fix->climb)) ?
+ 0 : GEOCLUE_VELOCITY_FIELDS_CLIMB;
+
+ gc_iface_velocity_emit_velocity_changed
+ (GC_IFACE_VELOCITY (gpsd), gpsd->last_velo_fields,
+ (int)(last_fix->time+0.5),
+ last_fix->speed, last_fix->track, last_fix->climb);
+ }
+}
+
+static void
+geoclue_gpsd_update_status (GeoclueGpsd *gpsd, NmeaTag nmea_tag)
+{
+ GeoclueStatus status;
+
+ /* gpsdata->online is supposedly always up-to-date */
+ if (gpsd->gpsdata->online <= 0) {
+ status = GEOCLUE_STATUS_UNAVAILABLE;
+ } else if (gpsd->gpsdata->set & STATUS_SET) {
+ gpsd->gpsdata->set &= ~(STATUS_SET);
+
+ if (gpsd->gpsdata->status > 0) {
+ status = GEOCLUE_STATUS_AVAILABLE;
+ } else {
+ status = GEOCLUE_STATUS_ACQUIRING;
+ }
+ } else {
+ return;
+ }
+
+ geoclue_gpsd_set_status (gpsd, status);
+}
+
+static void
+gpsd_raw_hook (struct gps_data_t *gpsdata, char *message, size_t len)
+{
+ char *tag_str = gpsd->gpsdata->tag;
+ NmeaTag nmea_tag = NMEA_NONE;
+
+ if (tag_str[0] == 'G' && tag_str[1] == 'S' && tag_str[2] == 'A') {
+ nmea_tag = NMEA_GSA;
+ } else if (tag_str[0] == 'G' && tag_str[1] == 'G' && tag_str[2] == 'A') {
+ nmea_tag = NMEA_GGA;
+ } else if (tag_str[0] == 'G' && tag_str[1] == 'S' && tag_str[2] == 'V') {
+ nmea_tag = NMEA_GSV;
+ } else if (tag_str[0] == 'R' && tag_str[1] == 'M' && tag_str[2] == 'C') {
+ nmea_tag = NMEA_RMC;
+ }
+
+ geoclue_gpsd_update_status (gpsd, nmea_tag);
+ geoclue_gpsd_update_position (gpsd, nmea_tag);
+ geoclue_gpsd_update_velocity (gpsd, nmea_tag);
+}
+
+static void
+geoclue_gpsd_stop_gpsd (GeoclueGpsd *self)
+{
+ if (self->gpsdata) {
+ gps_close (self->gpsdata);
+ self->gpsdata = NULL;
+ }
+}
+
+static gboolean
+geoclue_gpsd_start_gpsd (GeoclueGpsd *self)
+{
+ self->gpsdata = gps_open (self->host, self->port);
+ if (self->gpsdata) {
+ gps_stream(self->gpsdata, WATCH_ENABLE | WATCH_NMEA | POLL_NONBLOCK, NULL);
+ gps_set_raw_hook (self->gpsdata, gpsd_raw_hook);
+ return TRUE;
+ } else {
+ g_warning ("gps_open() failed, is gpsd running (host=%s,port=%s)?", self->host, self->port);
+ return FALSE;
+ }
+}
+
+gboolean
+gpsd_poll(gpointer data)
+{
+ GeoclueGpsd *self = (GeoclueGpsd*)data;
+ if (self->gpsdata) {
+ if (gps_poll(self->gpsdata) < 0) {
+ geoclue_gpsd_set_status (self, GEOCLUE_STATUS_ERROR);
+ geoclue_gpsd_stop_gpsd(self);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+geoclue_gpsd_init (GeoclueGpsd *self)
+{
+ self->gpsdata = NULL;
+ self->last_fix = g_new0 (gps_fix, 1);
+
+ self->last_pos_fields = GEOCLUE_POSITION_FIELDS_NONE;
+ self->last_velo_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+ self->last_accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+
+ gc_provider_set_details (GC_PROVIDER (self),
+ "org.freedesktop.Geoclue.Providers.Gpsd",
+ "/org/freedesktop/Geoclue/Providers/Gpsd",
+ "Gpsd", "Gpsd provider");
+
+ self->port = g_strdup (DEFAULT_GPSD_PORT);
+ self->host = NULL;
+ geoclue_gpsd_set_status (self, GEOCLUE_STATUS_ACQUIRING);
+ if (!geoclue_gpsd_start_gpsd (self)) {
+ geoclue_gpsd_set_status (self, GEOCLUE_STATUS_ERROR);
+ }
+}
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+
+ *timestamp = (int)(gpsd->last_fix->time+0.5);
+ *latitude = gpsd->last_fix->latitude;
+ *longitude = gpsd->last_fix->longitude;
+ *altitude = gpsd->last_fix->altitude;
+ *fields = gpsd->last_pos_fields;
+ *accuracy = geoclue_accuracy_copy (gpsd->last_accuracy);
+
+ return TRUE;
+}
+
+static void
+geoclue_gpsd_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+get_velocity (GcIfaceVelocity *gc,
+ GeoclueVelocityFields *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ GeoclueGpsd *gpsd = GEOCLUE_GPSD (gc);
+
+ *timestamp = (int)(gpsd->last_fix->time+0.5);
+ *speed = gpsd->last_fix->speed;
+ *direction = gpsd->last_fix->track;
+ *climb = gpsd->last_fix->climb;
+ *fields = gpsd->last_velo_fields;
+
+ return TRUE;
+}
+
+static void
+geoclue_gpsd_velocity_init (GcIfaceVelocityClass *iface)
+{
+ iface->get_velocity = get_velocity;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ g_type_init ();
+
+ gpsd = g_object_new (GEOCLUE_TYPE_GPSD, NULL);
+
+ gpsd->loop = g_main_loop_new (NULL, TRUE);
+ g_timeout_add(500, gpsd_poll, (gpointer)gpsd);
+
+ g_main_loop_run (gpsd->loop);
+
+ g_main_loop_unref (gpsd->loop);
+ g_object_unref (gpsd);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/gsmloc/Makefile.am b/.pc/tizen.patch/providers/gsmloc/Makefile.am
new file mode 100755
index 0000000..1820f8c
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/Makefile.am
@@ -0,0 +1,77 @@
+libexec_PROGRAMS = \
+ geoclue-gsmloc
+
+nodist_geoclue_gsmloc_SOURCES = \
+ ofono-marshal.c \
+ ofono-marshal.h \
+ ofono-manager-bindings.h \
+ ofono-modem-bindings.h \
+ ofono-network-registration-bindings.h \
+ ofono-network-operator-bindings.h \
+ mm-marshal.c \
+ mm-marshal.h
+
+BUILT_SOURCES = \
+ $(nodist_geoclue_gsmloc_SOURCES)
+
+geoclue_gsmloc_SOURCES = \
+ mcc.h \
+ geoclue-gsmloc.c \
+ geoclue-gsmloc-ofono.c \
+ geoclue-gsmloc-ofono.h \
+ geoclue-gsmloc-mm.c \
+ geoclue-gsmloc-mm.h
+
+
+geoclue_gsmloc_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_gsmloc_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gsmloc.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gsmloc.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ ofono-marshal.list \
+ ofono-manager.xml \
+ ofono-modem.xml \
+ ofono-network-operator.xml \
+ ofono-network-registration.xml \
+ mm-marshal.list \
+ $(service_in_files) \
+ $(providers_DATA)
+
+CLEANFILES = \
+ $(BUILT_SOURCES)
+
+DISTCLEANFILES = \
+ $(service_DATA)
+
+%-bindings.h: stamp-%-bindings.h
+ @true
+stamp-%-bindings.h: %.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --mode=glib-client $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+ofono-marshal.h: ofono-marshal.list $(GLIB_GENMARSHAL)
+ $(GLIB_GENMARSHAL) $< --header --prefix=ofono_marshal > $@
+ofono-marshal.c: ofono-marshal.list ofono-marshal.h $(GLIB_GENMARSHAL)
+ $(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=ofono_marshal $(srcdir)/ofono-marshal.list --header --body >> $@
+
+mm-marshal.h: mm-marshal.list $(GLIB_GENMARSHAL)
+ $(AM_V_GEN) $(GLIB_GENMARSHAL) $< --header --prefix=mm_marshal > $@
+mm-marshal.c: mm-marshal.list mm-marshal.h $(GLIB_GENMARSHAL)
+ $(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=mm_marshal $(srcdir)/mm-marshal.list --header --body >> $@
diff --git a/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.c b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.c
new file mode 100755
index 0000000..bd882d1
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.c
@@ -0,0 +1,779 @@
+/*
+ * Geoclue
+ * geoclue-gsmloc-mm.c - An Address/Position provider for ModemManager
+ *
+ * Author: Dan Williams <dcbw@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <config.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <glib-object.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include "geoclue-gsmloc-mm.h"
+
+#include "mm-marshal.h"
+
+#define MM_DBUS_SERVICE "org.freedesktop.ModemManager"
+#define MM_DBUS_PATH "/org/freedesktop/ModemManager"
+#define MM_DBUS_INTERFACE "org.freedesktop.ModemManager"
+#define MM_DBUS_LOC_INTERFACE "org.freedesktop.ModemManager.Modem.Location"
+#define DBUS_PROPS_INTERFACE "org.freedesktop.DBus.Properties"
+#define MM_DBUS_MODEM_INTERFACE "org.freedesktop.ModemManager.Modem"
+
+G_DEFINE_TYPE (GeoclueGsmlocMm, geoclue_gsmloc_mm, G_TYPE_OBJECT)
+
+#define GEOCLUE_GSMLOC_MM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_GSMLOC_MM, GeoclueGsmlocMmPrivate))
+
+typedef struct {
+ char *path;
+
+ DBusGProxy *loc_proxy;
+ DBusGProxy *props_proxy;
+ DBusGProxy *modem_proxy;
+
+ gboolean got_enabled;
+ gboolean enabled;
+ gboolean enabling;
+
+ gboolean got_loc_enabled;
+ gboolean loc_enabled;
+ gboolean loc_enabling;
+ gboolean got_initial_loc;
+
+ /* Whether the modem signals its location or whether we
+ * have to poll for it.
+ */
+ gboolean signals;
+ guint loc_idle;
+
+ gboolean has_location;
+
+ gpointer owner;
+} Modem;
+
+typedef struct {
+ DBusGConnection *bus;
+ DBusGProxy *dbus_proxy;
+
+ /* Listens for device add/remove events */
+ DBusGProxy *mm_proxy;
+ DBusGProxy *props_proxy;
+
+ /* List of Modem objects */
+ GSList *modems;
+} GeoclueGsmlocMmPrivate;
+
+enum {
+ PROP_0,
+ PROP_AVAILABLE,
+};
+
+enum {
+ NETWORK_DATA_CHANGED,
+ LAST_SIGNAL
+};
+static guint signals[LAST_SIGNAL] = {0};
+
+#define LOC_CAP_GSM_LACCI 0x02
+
+gboolean mm_debug = FALSE;
+
+#define debugmsg(fmt, args...) \
+ { if (mm_debug) { g_debug (fmt, ##args); } }
+
+
+static gboolean
+is_available (GeoclueGsmlocMm *self)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ GSList *iter;
+
+ for (iter = priv->modems; iter; iter = g_slist_next (iter)) {
+ Modem *modem = iter->data;
+
+ if (modem->enabled && modem->loc_enabled && modem->has_location)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static Modem *
+find_modem (GeoclueGsmlocMm *self, const char *path)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ GSList *iter;
+
+ g_return_val_if_fail (path != NULL, NULL);
+
+ for (iter = priv->modems; iter; iter = g_slist_next (iter)) {
+ Modem *modem = iter->data;
+
+ if (strcmp (path, modem->path) == 0)
+ return modem;
+ }
+
+ return NULL;
+}
+
+static void
+recheck_available (GeoclueGsmlocMm *self)
+{
+ g_object_notify (G_OBJECT (self), "available");
+}
+
+static void
+location_update (GeoclueGsmlocMm *self, const char *loc)
+{
+ char **components = NULL;
+ char *dec_lac = NULL, *dec_cid = NULL;
+ unsigned long int num;
+
+ components = g_strsplit (loc, ",", 0);
+ if (!components || g_strv_length (components) < 4) {
+ g_warning ("%s: invalid GSM LAC/CI location: '%s'", __func__, loc);
+ goto out;
+ }
+
+ /* convert lac to decimal */
+ errno = 0;
+ num = strtoul (components[2], NULL, 16);
+ if (errno != 0) {
+ g_warning ("%s: cannot convert LAC '%s' to decimal!",
+ __func__, components[2]);
+ goto out;
+ }
+ dec_lac = g_strdup_printf ("%u", num);
+
+ /* convert cell id to decimal */
+ errno = 0;
+ num = strtoul (components[3], NULL, 16);
+ if (errno != 0) {
+ g_warning ("%s: cannot convert Cell ID '%s' to decimal!",
+ __func__, components[3]);
+ goto out;
+ }
+ dec_cid = g_strdup_printf ("%u", num);
+
+ debugmsg ("%s: emitting location: %s/%s/%s/%s",
+ __func__, components[0], components[1], dec_lac, dec_cid);
+ g_signal_emit (G_OBJECT (self), signals[NETWORK_DATA_CHANGED], 0,
+ components[0], /* MCC */
+ components[1], /* MNC */
+ dec_lac, /* LAC */
+ dec_cid); /* CID */
+
+out:
+ if (components)
+ g_strfreev (components);
+ g_free (dec_lac);
+ g_free (dec_cid);
+}
+
+static void
+modem_location_update (Modem *modem, GHashTable *locations)
+{
+ GValue *lacci;
+
+ /* GSMLOC only handles GSM LAC/CI location info */
+ lacci = g_hash_table_lookup (locations, GUINT_TO_POINTER (LOC_CAP_GSM_LACCI));
+ if (!lacci)
+ return;
+ if (!G_VALUE_HOLDS_STRING (lacci)) {
+ g_warning ("%s: GSM LAC/CI location member not a string!", __func__);
+ return;
+ }
+
+ debugmsg ("%s: GSM LAC/CI: %s", __func__, g_value_get_string (lacci));
+ location_update (modem->owner, g_value_get_string (lacci));
+}
+
+#define DBUS_TYPE_LOCATIONS (dbus_g_type_get_map ("GHashTable", G_TYPE_UINT, G_TYPE_VALUE))
+#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
+
+static void
+loc_poll_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ GError *error = NULL;
+ GHashTable *locations = NULL;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ DBUS_TYPE_LOCATIONS, &locations,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: failed to get location: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ modem_location_update ((Modem *) user_data, locations);
+ g_hash_table_destroy (locations);
+}
+
+static gboolean
+modem_loc_poll (gpointer user_data)
+{
+ Modem *modem = user_data;
+
+ dbus_g_proxy_begin_call (modem->loc_proxy, "GetLocation",
+ loc_poll_cb, modem, NULL,
+ G_TYPE_INVALID);
+
+ return TRUE;
+}
+
+static void
+modem_loc_enable_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ Modem *modem = user_data;
+ GError *error = NULL;
+
+ modem->loc_enabling = FALSE;
+ if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
+ g_warning ("%s: failed to enable modem location services: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+}
+
+static void
+modem_try_loc_enable (Modem *modem)
+{
+ /* Don't enable location services if we don't have all the modem's
+ * status yet or if location services are already enabled.
+ */
+
+ if (!modem->got_loc_enabled ||
+ !modem->enabled ||
+ !modem->has_location ||
+ !modem->got_loc_enabled ||
+ modem->loc_enabled ||
+ modem->loc_enabling)
+ return;
+
+ modem->loc_enabling = TRUE;
+ debugmsg ("%s: (%s) enabling location services...", __func__, modem->path);
+ dbus_g_proxy_begin_call (modem->loc_proxy, "Enable",
+ modem_loc_enable_cb, modem, NULL,
+ G_TYPE_BOOLEAN, TRUE, /* enable */
+ G_TYPE_BOOLEAN, TRUE, /* signal location changes */
+ G_TYPE_INVALID);
+}
+
+static void
+modem_enable_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ Modem *modem = user_data;
+ GError *error = NULL;
+
+ modem->enabling = FALSE;
+ if (!dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_INVALID)) {
+ g_warning ("%s: failed to enable modem: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ /* enable location services */
+ modem_try_loc_enable (modem);
+}
+
+static void
+modem_properties_changed (DBusGProxy *proxy,
+ const char *interface,
+ GHashTable *props,
+ gpointer user_data)
+{
+ Modem *modem = user_data;
+ GValue *value;
+ gboolean old_avail = modem->enabled && modem->loc_enabled && modem->has_location;
+ gboolean new_avail;
+
+ if (strcmp (interface, MM_DBUS_MODEM_INTERFACE) == 0) {
+ value = g_hash_table_lookup (props, "Enabled");
+ if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+ modem->enabled = g_value_get_boolean (value);
+ modem->got_enabled = TRUE;
+ debugmsg ("%s: (%s) modem %s", __func__, modem->path,
+ modem->enabled ? "enabled" : "disabled");
+ }
+ } else if (strcmp (interface, MM_DBUS_LOC_INTERFACE) == 0) {
+ value = g_hash_table_lookup (props, "Enabled");
+ if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+ modem->loc_enabled = g_value_get_boolean (value);
+ modem->got_loc_enabled = TRUE;
+ debugmsg ("%s: (%s) modem location services %s",
+ __func__, modem->path,
+ modem->loc_enabled ? "enabled" : "disabled");
+ }
+
+ value = g_hash_table_lookup (props, "SignalsLocation");
+ if (value && G_VALUE_HOLDS_BOOLEAN (value)) {
+ modem->signals = g_value_get_boolean (value);
+ debugmsg ("%s: (%s) modem %s signal location updates",
+ __func__, modem->path,
+ modem->signals ? "will" : "does not");
+ }
+
+ value = g_hash_table_lookup (props, "Capabilities");
+ if (value && G_VALUE_HOLDS_UINT (value)) {
+ debugmsg ("%s: (%s) modem location capabilities: 0x%X",
+ __func__, modem->path,
+ g_value_get_uint (value));
+
+ if (g_value_get_uint (value) & LOC_CAP_GSM_LACCI)
+ modem->has_location = TRUE;
+ }
+
+ value = g_hash_table_lookup (props, "Location");
+ if (value && G_VALUE_HOLDS_BOXED (value))
+ modem_location_update (modem, (GHashTable *) g_value_get_boxed (value));
+ }
+
+ new_avail = modem->enabled && modem->loc_enabled && modem->has_location;
+
+ /* If the modem doesn't signal its location, start polling for the
+ * location now.
+ */
+ if (new_avail && !modem->signals && !modem->loc_idle) {
+ modem->loc_idle = g_timeout_add_seconds (20, modem_loc_poll, modem);
+ /* Kick off a quick location request */
+ modem_loc_poll (modem);
+ }
+
+ /* If the modem is no longer enabled, or it now signals its location
+ * then we no longer need to poll.
+ */
+ if ((!new_avail || modem->signals) && modem->loc_idle)
+ g_source_remove (modem->loc_idle);
+
+ /* Tell the manager to recheck availability of location info */
+ if (old_avail != new_avail)
+ recheck_available (modem->owner);
+
+ /* If we've successfully retrieved modem properties and the modem
+ * isn't enabled, do that now.
+ */
+ if (modem->got_enabled && !modem->enabled && !modem->enabling) {
+ debugmsg ("%s: (%s) enabling...", __func__, modem->path);
+ modem->enabling = TRUE;
+ dbus_g_proxy_begin_call (modem->modem_proxy, "Enable",
+ modem_enable_cb, modem, NULL,
+ G_TYPE_BOOLEAN, TRUE, G_TYPE_INVALID);
+ }
+
+ /* If the modem was already enabled but location services weren't,
+ * enable them now.
+ */
+ modem_try_loc_enable (modem);
+
+ /* After location is enabled, try to get the location ASAP */
+ if (modem->has_location && modem->loc_enabled && !modem->got_initial_loc) {
+ modem->got_initial_loc = TRUE;
+ modem_loc_poll (modem);
+ }
+}
+
+static void
+modem_props_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ GError *error = NULL;
+ GHashTable *props = NULL;
+ Modem *modem = user_data;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ DBUS_TYPE_G_MAP_OF_VARIANT, &props,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: failed to get modem interface properties: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ modem_properties_changed (modem->loc_proxy, MM_DBUS_MODEM_INTERFACE, props, modem);
+ g_hash_table_destroy (props);
+}
+
+static void
+loc_props_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ GError *error = NULL;
+ GHashTable *props = NULL;
+ Modem *modem = user_data;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ DBUS_TYPE_G_MAP_OF_VARIANT, &props,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: failed to get location interface properties: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ modem_properties_changed (modem->loc_proxy, MM_DBUS_LOC_INTERFACE, props, modem);
+ g_hash_table_destroy (props);
+
+ /* Now that we know the device supports location services, get basic
+ * modem properties and start grabbing location info.
+ */
+ dbus_g_proxy_begin_call (modem->props_proxy, "GetAll",
+ modem_props_cb, modem, NULL,
+ G_TYPE_STRING, MM_DBUS_MODEM_INTERFACE, G_TYPE_INVALID);
+}
+
+static Modem *
+modem_new (DBusGConnection *bus, const char *path, gpointer owner)
+{
+ Modem *modem;
+
+ modem = g_slice_new0 (Modem);
+ modem->owner = owner;
+ modem->path = g_strdup (path);
+
+ modem->loc_proxy = dbus_g_proxy_new_for_name (bus,
+ MM_DBUS_SERVICE,
+ path,
+ MM_DBUS_LOC_INTERFACE);
+
+ modem->modem_proxy = dbus_g_proxy_new_for_name (bus,
+ MM_DBUS_SERVICE,
+ path,
+ MM_DBUS_MODEM_INTERFACE);
+
+ /* Listen for property changes */
+ modem->props_proxy = dbus_g_proxy_new_for_name (bus,
+ MM_DBUS_SERVICE,
+ path,
+ "org.freedesktop.DBus.Properties");
+ dbus_g_object_register_marshaller (mm_marshal_VOID__STRING_BOXED,
+ G_TYPE_NONE,
+ G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (modem->props_proxy, "MmPropertiesChanged",
+ G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (modem->props_proxy, "MmPropertiesChanged",
+ G_CALLBACK (modem_properties_changed),
+ modem,
+ NULL);
+
+ debugmsg ("%s: (%s) modem created", __func__, path);
+
+ /* Check if the Location interface is actually supported before doing
+ * anything with the modem, because if it's not, we don't care about
+ * the modem at all.
+ */
+ dbus_g_proxy_begin_call (modem->props_proxy, "GetAll",
+ loc_props_cb, modem, NULL,
+ G_TYPE_STRING, MM_DBUS_LOC_INTERFACE, G_TYPE_INVALID);
+
+ return modem;
+}
+
+static void
+modem_free (Modem *modem)
+{
+
+ debugmsg ("%s: (%s) modem removed", __func__, modem->path);
+
+ g_free (modem->path);
+ g_object_unref (modem->loc_proxy);
+ g_object_unref (modem->modem_proxy);
+ g_object_unref (modem->props_proxy);
+
+ if (modem->loc_idle)
+ g_source_remove (modem->loc_idle);
+
+ memset (modem, 0, sizeof (Modem));
+ g_slice_free (Modem, modem);
+}
+
+static void
+modem_added (DBusGProxy *proxy, const char *path, gpointer user_data)
+{
+ GeoclueGsmlocMm *self = GEOCLUE_GSMLOC_MM (user_data);
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ Modem *modem;
+
+ if (!find_modem (self, path)) {
+ modem = modem_new (priv->bus, path, self);
+ priv->modems = g_slist_prepend (priv->modems, modem);
+ }
+}
+
+static void
+enumerate_modems_cb (DBusGProxy *proxy, DBusGProxyCall *call, gpointer user_data)
+{
+ GPtrArray *modems;
+ GError *error = NULL;
+ int i;
+
+ if (!dbus_g_proxy_end_call (proxy, call, &error,
+ dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &modems,
+ G_TYPE_INVALID)) {
+ g_warning ("%s: failed to enumerate modems: (%d) %s",
+ __func__,
+ error ? error->code : -1,
+ error && error->message ? error->message : "(unknown)");
+ g_clear_error (&error);
+ return;
+ }
+
+ for (i = 0; i < modems->len; i++) {
+ char *path = g_ptr_array_index (modems, i);
+
+ modem_added (NULL, path, GEOCLUE_GSMLOC_MM (user_data));
+ g_free (path);
+ }
+ g_ptr_array_free (modems, TRUE);
+}
+
+static void
+enumerate_modems (GeoclueGsmlocMm *self)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+
+ dbus_g_proxy_begin_call (priv->mm_proxy, "EnumerateDevices",
+ enumerate_modems_cb, self, NULL,
+ G_TYPE_INVALID);
+}
+
+static void
+modem_removed (DBusGProxy *proxy, const char *path, gpointer user_data)
+{
+ GeoclueGsmlocMm *self = GEOCLUE_GSMLOC_MM (user_data);
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ Modem *modem;
+
+ modem = find_modem (self, path);
+ if (modem) {
+ gboolean old_available = is_available (self);
+
+ priv->modems = g_slist_remove (priv->modems, modem);
+ modem_free (modem);
+ if (is_available (self) != old_available)
+ g_object_notify (G_OBJECT (self), "available");
+ }
+}
+
+static void
+kill_modems (GeoclueGsmlocMm *self)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+ gboolean old_available = is_available (self);
+ GSList *iter;
+
+ /* Kill all modems */
+ for (iter = priv->modems; iter; iter = g_slist_next (iter))
+ modem_free ((Modem *) iter->data);
+ g_slist_free (priv->modems);
+ priv->modems = NULL;
+
+ /* No more modems; clearly location is no longer available */
+ if (old_available)
+ g_object_notify (G_OBJECT (self), "available");
+}
+
+static void
+name_owner_changed (DBusGProxy *proxy,
+ const char *name,
+ const char *old_owner,
+ const char *new_owner,
+ gpointer user_data)
+{
+ gboolean old_owner_good;
+ gboolean new_owner_good;
+
+ if (strcmp (MM_DBUS_SERVICE, name) != 0)
+ return;
+
+ old_owner_good = (old_owner && strlen (old_owner));
+ new_owner_good = (new_owner && strlen (new_owner));
+
+ if (!old_owner_good && new_owner_good) {
+ debugmsg ("ModemManager appeared");
+ enumerate_modems (GEOCLUE_GSMLOC_MM (user_data));
+ } else if (old_owner_good && !new_owner_good) {
+ debugmsg ("ModemManager disappeared");
+ kill_modems (GEOCLUE_GSMLOC_MM (user_data));
+ }
+}
+
+GeoclueGsmlocMm *
+geoclue_gsmloc_mm_new (void)
+{
+ return (GeoclueGsmlocMm *) g_object_new (GEOCLUE_TYPE_GSMLOC_MM, NULL);
+}
+
+static gboolean
+mm_alive (DBusGProxy *proxy)
+{
+ char *owner = NULL;
+ gboolean owned = FALSE;
+ GError *error = NULL;
+
+ if (dbus_g_proxy_call_with_timeout (proxy,
+ "GetNameOwner", 2000, &error,
+ G_TYPE_STRING, MM_DBUS_SERVICE,
+ G_TYPE_INVALID,
+ G_TYPE_STRING, &owner,
+ G_TYPE_INVALID)) {
+ owned = !!owner;
+ g_free (owner);
+ }
+ return owned;
+}
+
+static void
+geoclue_gsmloc_mm_init (GeoclueGsmlocMm *self)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (self);
+
+ if (getenv ("GEOCLUE_GSMLOC_MM_DEBUG"))
+ mm_debug = TRUE;
+
+ priv->bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL);
+ if (!priv->bus) {
+ g_warning ("Failed to acquire a connection to the D-Bus system bus.");
+ return;
+ }
+
+ priv->dbus_proxy = dbus_g_proxy_new_for_name (priv->bus,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ /* Handle ModemManager restarts */
+ dbus_g_proxy_add_signal (priv->dbus_proxy, "NameOwnerChanged",
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->dbus_proxy, "NameOwnerChanged",
+ G_CALLBACK (name_owner_changed),
+ self, NULL);
+
+ priv->mm_proxy = dbus_g_proxy_new_for_name (priv->bus,
+ MM_DBUS_SERVICE,
+ MM_DBUS_PATH,
+ MM_DBUS_INTERFACE);
+ g_assert (priv->mm_proxy);
+
+ dbus_g_proxy_add_signal (priv->mm_proxy, "DeviceAdded",
+ DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->mm_proxy, "DeviceAdded",
+ G_CALLBACK (modem_added), self, NULL);
+ dbus_g_proxy_add_signal (priv->mm_proxy, "DeviceRemoved",
+ DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->mm_proxy, "DeviceRemoved",
+ G_CALLBACK (modem_removed), self, NULL);
+
+ if (mm_alive (priv->dbus_proxy)) {
+ debugmsg ("ModemManager is alive");
+ enumerate_modems (self);
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueGsmlocMmPrivate *priv = GEOCLUE_GSMLOC_MM_GET_PRIVATE (object);
+
+ kill_modems (GEOCLUE_GSMLOC_MM (object));
+
+ /* Stop listening to ModemManager */
+ if (priv->mm_proxy) {
+ g_object_unref (priv->mm_proxy);
+ priv->mm_proxy = NULL;
+ }
+
+ if (priv->props_proxy) {
+ g_object_unref (priv->props_proxy);
+ priv->props_proxy = NULL;
+ }
+
+ if (priv->dbus_proxy) {
+ g_object_unref (priv->dbus_proxy);
+ priv->dbus_proxy = NULL;
+ }
+
+ G_OBJECT_CLASS (geoclue_gsmloc_mm_parent_class)->dispose (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_AVAILABLE:
+ g_value_set_boolean (value, is_available (GEOCLUE_GSMLOC_MM (object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+geoclue_gsmloc_mm_class_init (GeoclueGsmlocMmClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (GeoclueGsmlocMmPrivate));
+
+ /* virtual methods */
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ /* properties */
+ g_object_class_install_property
+ (object_class, PROP_AVAILABLE,
+ g_param_spec_boolean ("available",
+ "Available",
+ "Whether any mobile broadband device is "
+ "providing location information at this "
+ "time.",
+ FALSE,
+ G_PARAM_READABLE));
+
+ /* signals */
+ signals[NETWORK_DATA_CHANGED] =
+ g_signal_new ("network-data-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ mm_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+}
+
diff --git a/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.h b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.h
new file mode 100755
index 0000000..8daf1eb
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc-mm.h
@@ -0,0 +1,56 @@
+/*
+ * Geoclue
+ * geoclue-gsmloc-mm.h - An Address/Position provider for ModemManager
+ *
+ * Author: Dan Williams <dcbw@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef _GEOCLUE_GSMLOC_MM
+#define _GEOCLUE_GSMLOC_MM
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_GSMLOC_MM (geoclue_gsmloc_mm_get_type ())
+
+#define GEOCLUE_GSMLOC_MM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GSMLOC_MM, GeoclueGsmlocMm))
+#define GEOCLUE_GSMLOC_MM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GEOCLUE_TYPE_GSMLOC_MM, GeoclueGsmlocMmClass))
+#define GEOCLUE_IS_GSMLOC_MM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_GSMLOC_MM))
+#define GEOCLUE_IS_GSMLOC_MM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEOCLUE_TYPE_GSMLOC_MM))
+
+typedef struct _GeoclueGsmlocMm {
+ GObject parent;
+} GeoclueGsmlocMm;
+
+typedef struct _GeoclueGsmlocMmClass {
+ GObjectClass parent_class;
+
+ void (*network_data_changed) (GeoclueGsmlocMm *mm,
+ char *mcc, char *mnc,
+ char *lac, char *cid);
+} GeoclueGsmlocMmClass;
+
+GType geoclue_gsmloc_mm_get_type (void);
+
+GeoclueGsmlocMm *geoclue_gsmloc_mm_new (void);
+
+G_END_DECLS
+
+#endif /* _GEOCLUE_GSMLOC_MM */
+
diff --git a/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc.c b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc.c
new file mode 100755
index 0000000..6d8b5ba
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/geoclue-gsmloc.c
@@ -0,0 +1,459 @@
+/*
+ * Geoclue
+ * geoclue-gsmloc.c - A GSM cell based Position provider
+ *
+ * Author: Jussi Kukkonen <jku@linux.intel.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ * 2010 Intel Corporation
+ * 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+ /**
+ * Gsmloc provider is a position and address provider that uses GSM cell
+ * location and the webservice http://www.opencellid.org/ (a similar service
+ * used to live at gsmloc.org, hence the name). The web service does not
+ * provide any address data: that is done with a
+ * "mobile country code -> ISO country code" lookup table: as a result address
+ * will only ever have country code and country fields.
+ *
+ * Gsmloc requires the oFono or ModemManager telephony stacks to work -- more
+ * IMSI data sources could be added fairly easily.
+ **/
+
+#include <config.h>
+
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+/* ofono implementation */
+#include "geoclue-gsmloc-ofono.h"
+
+/* ModemManager implementation */
+#include "geoclue-gsmloc-mm.h"
+
+/* country code list */
+#include "mcc.h"
+
+#define GEOCLUE_DBUS_SERVICE_GSMLOC "org.freedesktop.Geoclue.Providers.Gsmloc"
+#define GEOCLUE_DBUS_PATH_GSMLOC "/org/freedesktop/Geoclue/Providers/Gsmloc"
+
+#define OPENCELLID_URL "http://www.opencellid.org/cell/get"
+#define OPENCELLID_LAT "/rsp/cell/@lat"
+#define OPENCELLID_LON "/rsp/cell/@lon"
+#define OPENCELLID_CID "/rsp/cell/@cellId"
+
+#define GEOCLUE_TYPE_GSMLOC (geoclue_gsmloc_get_type ())
+#define GEOCLUE_GSMLOC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GSMLOC, GeoclueGsmloc))
+
+typedef struct _GeoclueGsmloc GeoclueGsmloc;
+
+struct _GeoclueGsmloc {
+ GcProvider parent;
+ GMainLoop *loop;
+ GcWebService *web_service;
+
+ GeoclueGsmlocOfono *ofono;
+ GeoclueGsmlocMm *mm;
+
+ /* current data */
+ char *mcc;
+ char *mnc;
+ char *lac;
+ char *cid;
+ GeocluePositionFields last_position_fields;
+ GeoclueAccuracyLevel last_accuracy_level;
+ double last_lat;
+ double last_lon;
+
+ GHashTable *address;
+};
+
+typedef struct _GeoclueGsmlocClass {
+ GcProviderClass parent_class;
+} GeoclueGsmlocClass;
+
+
+static void geoclue_gsmloc_init (GeoclueGsmloc *gsmloc);
+static void geoclue_gsmloc_position_init (GcIfacePositionClass *iface);
+static void geoclue_gsmloc_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGsmloc, geoclue_gsmloc, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_gsmloc_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_gsmloc_address_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_gsmloc_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueGsmloc *gsmloc = GEOCLUE_GSMLOC (iface);
+ gboolean ofono_available;
+ gboolean mm_available;
+
+ g_object_get (gsmloc->ofono, "available", &ofono_available, NULL);
+ g_object_get (gsmloc->mm, "available", &mm_available, NULL);
+
+ if (!ofono_available && !mm_available) {
+ *status = GEOCLUE_STATUS_ERROR;
+ } else if (!gsmloc->mcc || !gsmloc->mnc ||
+ !gsmloc->lac || !gsmloc->cid) {
+ *status = GEOCLUE_STATUS_UNAVAILABLE;
+ } else {
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ }
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGsmloc *gsmloc = GEOCLUE_GSMLOC (provider);
+ g_main_loop_quit (gsmloc->loop);
+}
+
+static gboolean
+geoclue_gsmloc_query_opencellid (GeoclueGsmloc *gsmloc)
+{
+ double lat, lon;
+ GeocluePositionFields fields = GEOCLUE_POSITION_FIELDS_NONE;
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+
+ if (gsmloc->mcc && gsmloc->mnc &&
+ gsmloc->lac && gsmloc->cid) {
+
+ if (gc_web_service_query (gsmloc->web_service, NULL,
+ "mcc", gsmloc->mcc,
+ "mnc", gsmloc->mnc,
+ "lac", gsmloc->lac,
+ "cellid", gsmloc->cid,
+ (char *)0)) {
+
+ if (gc_web_service_get_double (gsmloc->web_service,
+ &lat, OPENCELLID_LAT)) {
+ fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+ if (gc_web_service_get_double (gsmloc->web_service,
+ &lon, OPENCELLID_LON)) {
+ fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+
+ if (fields != GEOCLUE_POSITION_FIELDS_NONE) {
+ char *retval_cid;
+ /* if cellid is not present, location is for the local area code.
+ * the accuracy might be an overstatement -- I have no idea how
+ * big LACs typically are */
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ if (gc_web_service_get_string (gsmloc->web_service,
+ &retval_cid, OPENCELLID_CID)) {
+ if (retval_cid && strlen (retval_cid) != 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ }
+ g_free (retval_cid);
+ }
+ }
+ }
+ }
+
+ if (fields != gsmloc->last_position_fields ||
+ (fields != GEOCLUE_POSITION_FIELDS_NONE &&
+ (lat != gsmloc->last_lat ||
+ lon != gsmloc->last_lon ||
+ level != gsmloc->last_accuracy_level))) {
+ GeoclueAccuracy *acc;
+
+ /* position changed */
+
+ gsmloc->last_position_fields = fields;
+ gsmloc->last_accuracy_level = level;
+ gsmloc->last_lat = lat;
+ gsmloc->last_lon = lon;
+
+ acc = geoclue_accuracy_new (gsmloc->last_accuracy_level, 0.0, 0.0);
+ gc_iface_position_emit_position_changed (GC_IFACE_POSITION (gsmloc),
+ fields,
+ time (NULL),
+ lat, lon, 0.0,
+ acc);
+ geoclue_accuracy_free (acc);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+geoclue_gsmloc_update_address (GeoclueGsmloc *gsmloc)
+{
+ char *countrycode = NULL;
+ const char *old_countrycode;
+ gboolean changed = FALSE;
+ GeoclueAccuracy *acc;
+
+ if (gsmloc->mcc) {
+ gint64 i;
+ i = g_ascii_strtoll (gsmloc->mcc, NULL, 10);
+ if (i > 0 && i < 800 && mcc_country_codes[i]) {
+ countrycode = mcc_country_codes[i];
+ }
+ }
+
+ old_countrycode = g_hash_table_lookup (gsmloc->address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE);
+ if (g_strcmp0 (old_countrycode, countrycode) != 0) {
+ changed = TRUE;
+ }
+
+ if (countrycode) {
+ g_hash_table_insert (gsmloc->address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE, g_strdup (countrycode));
+ acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_COUNTRY, 0.0, 0.0);
+ } else {
+ g_hash_table_remove (gsmloc->address, GEOCLUE_ADDRESS_KEY_COUNTRYCODE);
+ g_hash_table_remove (gsmloc->address, GEOCLUE_ADDRESS_KEY_COUNTRY);
+ acc = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ }
+ geoclue_address_details_set_country_from_code (gsmloc->address);
+
+ if (changed) {
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (gsmloc),
+ time (NULL),
+ gsmloc->address,
+ acc);
+
+ }
+ geoclue_accuracy_free (acc);
+}
+static void
+geoclue_gsmloc_set_cell (GeoclueGsmloc *gsmloc,
+ const char *mcc, const char *mnc,
+ const char *lac, const char *cid)
+{
+ g_free (gsmloc->mcc);
+ g_free (gsmloc->mnc);
+ g_free (gsmloc->lac);
+ g_free (gsmloc->cid);
+
+ gsmloc->mcc = g_strdup (mcc);
+ gsmloc->mnc = g_strdup (mnc);
+ gsmloc->lac = g_strdup (lac);
+ gsmloc->cid = g_strdup (cid);
+
+ geoclue_gsmloc_update_address (gsmloc);
+ geoclue_gsmloc_query_opencellid (gsmloc);
+}
+
+static void
+network_data_changed_cb (gpointer connection_manager,
+ const char *mcc, const char *mnc,
+ const char *lac, const char *cid,
+ GeoclueGsmloc *gsmloc)
+{
+ if (g_strcmp0 (mcc, gsmloc->mcc) != 0 ||
+ g_strcmp0 (mnc, gsmloc->mnc) != 0 ||
+ g_strcmp0 (lac, gsmloc->lac) != 0 ||
+ g_strcmp0 (cid, gsmloc->cid) != 0) {
+
+ /* new cell data, do a opencellid lookup */
+ geoclue_gsmloc_set_cell (gsmloc, mcc, mnc, lac, cid);
+ }
+}
+
+/* Position interface implementation */
+
+static gboolean
+geoclue_gsmloc_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGsmloc *gsmloc;
+
+ gsmloc = (GEOCLUE_GSMLOC (iface));
+
+ if (gsmloc->last_position_fields == GEOCLUE_POSITION_FIELDS_NONE) {
+ /* re-query in case there was a network problem */
+ geoclue_gsmloc_query_opencellid (gsmloc);
+ }
+
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ if (fields) {
+ *fields = gsmloc->last_position_fields;
+ }
+ if (latitude) {
+ *latitude = gsmloc->last_lat;
+ }
+ if (longitude) {
+ *longitude = gsmloc->last_lon;
+ }
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_new (gsmloc->last_accuracy_level, 0, 0);
+ }
+
+ return TRUE;
+}
+
+/* Address interface implementation */
+static gboolean
+geoclue_gsmloc_get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGsmloc *obj = GEOCLUE_GSMLOC (iface);
+
+ if (address) {
+ *address = geoclue_address_details_copy (obj->address);
+ }
+ if (accuracy) {
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ if (g_hash_table_lookup (obj->address, GEOCLUE_ADDRESS_KEY_COUNTRY)) {
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ *accuracy = geoclue_accuracy_new (level, 0.0, 0.0);
+ }
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ return TRUE;
+}
+
+
+static void
+geoclue_gsmloc_dispose (GObject *obj)
+{
+ GeoclueGsmloc *gsmloc = GEOCLUE_GSMLOC (obj);
+
+ if (gsmloc->ofono) {
+ g_signal_handlers_disconnect_by_func (gsmloc->ofono,
+ network_data_changed_cb,
+ gsmloc);
+ g_object_unref (gsmloc->ofono);
+ gsmloc->ofono = NULL;
+ }
+
+ if (gsmloc->mm) {
+ g_signal_handlers_disconnect_by_func (gsmloc->mm,
+ network_data_changed_cb,
+ gsmloc);
+ g_object_unref (gsmloc->mm);
+ gsmloc->mm = NULL;
+ }
+
+ if (gsmloc->address) {
+ g_hash_table_destroy (gsmloc->address);
+ gsmloc->address = NULL;
+ }
+
+ ((GObjectClass *) geoclue_gsmloc_parent_class)->dispose (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_gsmloc_class_init (GeoclueGsmlocClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_gsmloc_get_status;
+
+ o_class->dispose = geoclue_gsmloc_dispose;
+}
+
+static void
+geoclue_gsmloc_init (GeoclueGsmloc *gsmloc)
+{
+ gsmloc->address = geoclue_address_details_new ();
+
+ gc_provider_set_details (GC_PROVIDER (gsmloc),
+ GEOCLUE_DBUS_SERVICE_GSMLOC,
+ GEOCLUE_DBUS_PATH_GSMLOC,
+ "Gsmloc", "GSM cell based position provider");
+
+ gsmloc->web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (gsmloc->web_service, OPENCELLID_URL);
+
+ geoclue_gsmloc_set_cell (gsmloc, NULL, NULL, NULL, NULL);
+
+ gsmloc->address = geoclue_address_details_new ();
+
+ /* init ofono*/
+ gsmloc->ofono = geoclue_gsmloc_ofono_new ();
+ g_signal_connect (gsmloc->ofono, "network-data-changed",
+ G_CALLBACK (network_data_changed_cb), gsmloc);
+
+ /* init mm */
+ gsmloc->mm = geoclue_gsmloc_mm_new ();
+ g_signal_connect (gsmloc->mm, "network-data-changed",
+ G_CALLBACK (network_data_changed_cb), gsmloc);
+}
+
+static void
+geoclue_gsmloc_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_gsmloc_get_position;
+}
+
+static void
+geoclue_gsmloc_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = geoclue_gsmloc_get_address;
+}
+
+int
+main()
+{
+ g_type_init();
+
+ GeoclueGsmloc *o = g_object_new (GEOCLUE_TYPE_GSMLOC, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/gsmloc/mm-marshal.list b/.pc/tizen.patch/providers/gsmloc/mm-marshal.list
new file mode 100755
index 0000000..d2ce65a
--- /dev/null
+++ b/.pc/tizen.patch/providers/gsmloc/mm-marshal.list
@@ -0,0 +1,2 @@
+VOID:STRING,STRING,STRING,STRING
+VOID:STRING,BOXED
diff --git a/.pc/tizen.patch/providers/gypsy/Makefile.am b/.pc/tizen.patch/providers/gypsy/Makefile.am
new file mode 100755
index 0000000..937bf06
--- /dev/null
+++ b/.pc/tizen.patch/providers/gypsy/Makefile.am
@@ -0,0 +1,32 @@
+libexec_PROGRAMS = geoclue-gypsy
+
+geoclue_gypsy_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS) \
+ $(GYPSY_CFLAGS)
+
+geoclue_gypsy_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(GYPSY_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+geoclue_gypsy_SOURCES = \
+ geoclue-gypsy.c
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-gypsy.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Gypsy.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/gypsy/geoclue-gypsy.c b/.pc/tizen.patch/providers/gypsy/geoclue-gypsy.c
new file mode 100755
index 0000000..bc390ce
--- /dev/null
+++ b/.pc/tizen.patch/providers/gypsy/geoclue-gypsy.c
@@ -0,0 +1,623 @@
+/*
+ * Geoclue
+ * geoclue-gypsy.c - Geoclue backend for Gypsy which provides the Position.
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Copyright 2007 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <gypsy/gypsy-control.h>
+#include <gypsy/gypsy-device.h>
+#include <gypsy/gypsy-position.h>
+#include <gypsy/gypsy-course.h>
+#include <gypsy/gypsy-accuracy.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-velocity.h>
+
+typedef struct {
+ GcProvider parent;
+
+ char *device_name;
+ guint baud_rate;
+
+ GypsyControl *control;
+ GypsyDevice *device;
+ GypsyPosition *position;
+ GypsyCourse *course;
+ GypsyAccuracy *acc;
+
+ GMainLoop *loop;
+
+ int timestamp;
+
+ GeoclueStatus status;
+
+ /* Cached so we don't have to make D-Bus method calls all the time */
+ GypsyPositionFields position_fields;
+ double latitude;
+ double longitude;
+ double altitude;
+
+ GypsyCourseFields course_fields;
+ double speed;
+ double direction;
+ double climb;
+
+ GeoclueAccuracy *accuracy;
+} GeoclueGypsy;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueGypsyClass;
+
+static void geoclue_gypsy_position_init (GcIfacePositionClass *iface);
+static void geoclue_gypsy_velocity_init (GcIfaceVelocityClass *iface);
+
+#define GEOCLUE_TYPE_GYPSY (geoclue_gypsy_get_type ())
+#define GEOCLUE_GYPSY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_GYPSY, GeoclueGypsy))
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueGypsy, geoclue_gypsy, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_gypsy_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_VELOCITY,
+ geoclue_gypsy_velocity_init))
+
+
+/* GcIfaceGeoclue methods */
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc);
+
+ *status = gypsy->status;
+
+ return TRUE;
+}
+
+
+/* Compare the two fields and return TRUE if they have changed */
+static gboolean
+compare_field (GypsyPositionFields fields_a,
+ double value_a,
+ GypsyPositionFields fields_b,
+ double value_b,
+ GypsyPositionFields field)
+{
+ /* If both fields are valid, compare the values */
+ if ((fields_a & field) && (fields_b & field)) {
+ if (value_a == value_b) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ }
+
+ /* Otherwise return if both the fields set are the same */
+ return ((fields_a & field) != (fields_b & field));
+}
+
+static GeocluePositionFields
+gypsy_position_to_geoclue (GypsyPositionFields fields)
+{
+ GeocluePositionFields gc_fields = GEOCLUE_POSITION_FIELDS_NONE;
+
+ gc_fields |= (fields & GYPSY_POSITION_FIELDS_LATITUDE) ? GEOCLUE_POSITION_FIELDS_LATITUDE : 0;
+ gc_fields |= (fields & GYPSY_POSITION_FIELDS_LONGITUDE) ? GEOCLUE_POSITION_FIELDS_LONGITUDE : 0;
+ gc_fields |= (fields & GYPSY_POSITION_FIELDS_ALTITUDE) ? GEOCLUE_POSITION_FIELDS_ALTITUDE : 0;
+
+ return gc_fields;
+}
+
+static GeoclueVelocityFields
+gypsy_course_to_geoclue (GypsyCourseFields fields)
+{
+ GeoclueVelocityFields gc_fields = GEOCLUE_VELOCITY_FIELDS_NONE;
+
+ gc_fields |= (fields & GYPSY_COURSE_FIELDS_SPEED) ? GEOCLUE_VELOCITY_FIELDS_SPEED : 0;
+ gc_fields |= (fields & GYPSY_COURSE_FIELDS_DIRECTION) ? GEOCLUE_VELOCITY_FIELDS_DIRECTION : 0;
+ gc_fields |= (fields & GYPSY_COURSE_FIELDS_CLIMB) ? GEOCLUE_VELOCITY_FIELDS_CLIMB : 0;
+
+ return gc_fields;
+}
+
+static void
+position_changed (GypsyPosition *position,
+ GypsyPositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+
+ g_print ("Gypsy position changed\n");
+ gypsy->timestamp = timestamp;
+ if (compare_field (gypsy->position_fields, gypsy->latitude,
+ fields, latitude, GYPSY_POSITION_FIELDS_LATITUDE)) {
+ if (fields | GYPSY_POSITION_FIELDS_LATITUDE) {
+ gypsy->position_fields |= GYPSY_POSITION_FIELDS_LATITUDE;
+ gypsy->latitude = latitude;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->position_fields, gypsy->longitude,
+ fields, longitude, GYPSY_POSITION_FIELDS_LONGITUDE)) {
+ if (fields | GYPSY_POSITION_FIELDS_LONGITUDE) {
+ gypsy->position_fields |= GYPSY_POSITION_FIELDS_LONGITUDE;
+ gypsy->longitude = longitude;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->position_fields, gypsy->altitude,
+ fields, altitude, GYPSY_POSITION_FIELDS_ALTITUDE)) {
+ if (fields | GYPSY_POSITION_FIELDS_ALTITUDE) {
+ gypsy->position_fields |= GYPSY_POSITION_FIELDS_ALTITUDE;
+ gypsy->altitude = altitude;
+ changed = TRUE;
+ }
+ }
+
+ if (changed) {
+ GeocluePositionFields fields;
+
+ g_print ("Emitting signal\n");
+ fields = gypsy_position_to_geoclue (gypsy->position_fields);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (gypsy), fields,
+ timestamp, gypsy->latitude, gypsy->longitude,
+ gypsy->altitude, gypsy->accuracy);
+ }
+}
+
+static void
+course_changed (GypsyCourse *course,
+ GypsyCourseFields fields,
+ int timestamp,
+ double speed,
+ double direction,
+ double climb,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+
+ gypsy->timestamp = timestamp;
+ if (compare_field (gypsy->course_fields, gypsy->speed,
+ fields, speed, GYPSY_COURSE_FIELDS_SPEED)) {
+ if (fields & GYPSY_COURSE_FIELDS_SPEED) {
+ gypsy->course_fields |= GYPSY_COURSE_FIELDS_SPEED;
+ gypsy->speed = speed;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->course_fields, gypsy->direction,
+ fields, direction, GYPSY_COURSE_FIELDS_DIRECTION)) {
+ if (fields & GYPSY_COURSE_FIELDS_DIRECTION) {
+ gypsy->course_fields |= GYPSY_COURSE_FIELDS_DIRECTION;
+ gypsy->direction = direction;
+ changed = TRUE;
+ }
+ }
+
+ if (compare_field (gypsy->course_fields, gypsy->climb,
+ fields, climb, GYPSY_COURSE_FIELDS_CLIMB)) {
+ if (fields & GYPSY_COURSE_FIELDS_CLIMB) {
+ gypsy->course_fields |= GYPSY_COURSE_FIELDS_CLIMB;
+ gypsy->climb = climb;
+ changed = TRUE;
+ }
+ }
+
+ if (changed) {
+ GeoclueVelocityFields fields;
+
+ fields = gypsy_course_to_geoclue (gypsy->course_fields);
+ gc_iface_velocity_emit_velocity_changed
+ (GC_IFACE_VELOCITY (gypsy), fields,
+ timestamp, gypsy->speed, gypsy->direction, gypsy->climb);
+ }
+}
+
+static void
+accuracy_changed (GypsyAccuracy *accuracy,
+ GypsyAccuracyFields fields,
+ double pdop,
+ double hdop,
+ double vdop,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+ GeoclueAccuracyLevel level;
+ double horiz, vert;
+
+ geoclue_accuracy_get_details (gypsy->accuracy, &level, &horiz, &vert);
+ if (fields & (GYPSY_ACCURACY_FIELDS_HORIZONTAL |
+ GYPSY_ACCURACY_FIELDS_VERTICAL)){
+ if (level != GEOCLUE_ACCURACY_LEVEL_DETAILED ||
+ horiz != hdop || vert != vdop) {
+ changed = TRUE;
+ }
+
+ geoclue_accuracy_set_details (gypsy->accuracy,
+ GEOCLUE_ACCURACY_LEVEL_DETAILED,
+ hdop, vdop);
+ } else {
+
+ if (level != GEOCLUE_ACCURACY_LEVEL_NONE ||
+ horiz != 0.0 || vert != 0.0) {
+ changed = TRUE;
+ }
+
+ geoclue_accuracy_set_details (gypsy->accuracy,
+ GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0.0, 0.0);
+ }
+
+ if (changed) {
+ GeocluePositionFields fields;
+
+ fields = gypsy_position_to_geoclue (gypsy->position_fields);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (gypsy), fields,
+ gypsy->timestamp, gypsy->latitude, gypsy->longitude,
+ gypsy->altitude, gypsy->accuracy);
+ }
+}
+
+static void
+connection_changed (GypsyDevice *device,
+ gboolean connected,
+ GeoclueGypsy *gypsy)
+{
+ if (connected == FALSE &&
+ gypsy->status != GEOCLUE_STATUS_UNAVAILABLE) {
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (gypsy),
+ gypsy->status);
+ }
+}
+
+static void
+fix_status_changed (GypsyDevice *device,
+ GypsyDeviceFixStatus status,
+ GeoclueGypsy *gypsy)
+{
+ gboolean changed = FALSE;
+
+ switch (status) {
+ case GYPSY_DEVICE_FIX_STATUS_INVALID:
+ if (gypsy->status != GEOCLUE_STATUS_UNAVAILABLE) {
+ changed = TRUE;
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ }
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_NONE:
+ if (gypsy->status != GEOCLUE_STATUS_ACQUIRING) {
+ changed = TRUE;
+ gypsy->status = GEOCLUE_STATUS_ACQUIRING;
+ }
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_2D:
+ case GYPSY_DEVICE_FIX_STATUS_3D:
+ if (gypsy->status != GEOCLUE_STATUS_AVAILABLE) {
+ changed = TRUE;
+ gypsy->status = GEOCLUE_STATUS_AVAILABLE;
+ }
+ break;
+ }
+
+ if (changed) {
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (gypsy),
+ gypsy->status);
+ }
+}
+
+static void
+get_initial_status (GeoclueGypsy *gypsy)
+{
+ gboolean connected;
+ GypsyDeviceFixStatus status;
+ GError *error = NULL;
+
+ connected = gypsy_device_get_connection_status (gypsy->device, &error);
+ if (connected == FALSE) {
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ g_print ("Initial status - %d (disconnected)\n", gypsy->status);
+ return;
+ }
+
+ status = gypsy_device_get_fix_status (gypsy->device, &error);
+ switch (status) {
+ case GYPSY_DEVICE_FIX_STATUS_INVALID:
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_NONE:
+ gypsy->status = GEOCLUE_STATUS_ACQUIRING;
+ break;
+
+ case GYPSY_DEVICE_FIX_STATUS_2D:
+ case GYPSY_DEVICE_FIX_STATUS_3D:
+ gypsy->status = GEOCLUE_STATUS_AVAILABLE;
+ break;
+ }
+
+ g_print ("Initial status - %d (connected)\n", gypsy->status);
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *gc,
+ GHashTable *options,
+ GError **error)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc);
+ GValue *device_value, *baud_rate_value;
+ const char *device_name;
+ char *path;
+ int baud_rate;
+
+ device_value = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSDevice");
+ device_name = device_value ? g_value_get_string (device_value) : NULL;
+ baud_rate_value = g_hash_table_lookup (options,
+ "org.freedesktop.Geoclue.GPSBaudRate");
+ baud_rate = baud_rate_value ? g_value_get_int (baud_rate_value) : 0;
+
+ if (g_strcmp0 (gypsy->device_name, device_name) == 0 &&
+ gypsy->baud_rate == baud_rate)
+ return TRUE;
+
+ /* Disconnect from the old device, if any */
+ if (gypsy->device != NULL) {
+ g_object_unref (gypsy->device);
+ gypsy->device = NULL;
+ }
+
+ g_free (gypsy->device_name);
+ gypsy->device_name = NULL;
+
+ if (device_name == NULL || *device_name == '\0') {
+ return TRUE;
+ }
+
+ gypsy->device_name = g_strdup (device_name);
+ gypsy->baud_rate = baud_rate;
+ g_print ("Gypsy provider using '%s' at %d bps\n", gypsy->device_name, gypsy->baud_rate);
+ path = gypsy_control_create (gypsy->control, gypsy->device_name,
+ error);
+ if (*error != NULL) {
+ g_print ("Error - %s?\n", (*error)->message);
+ gypsy->status = GEOCLUE_STATUS_ERROR;
+ return FALSE;
+ }
+
+ /* If we've got here, then we are out of the ERROR condition */
+ gypsy->status = GEOCLUE_STATUS_UNAVAILABLE;
+
+ gypsy->device = gypsy_device_new (path);
+ g_signal_connect (gypsy->device, "connection-changed",
+ G_CALLBACK (connection_changed), gypsy);
+ g_signal_connect (gypsy->device, "fix-status-changed",
+ G_CALLBACK (fix_status_changed), gypsy);
+
+ gypsy->position = gypsy_position_new (path);
+ g_signal_connect (gypsy->position, "position-changed",
+ G_CALLBACK (position_changed), gypsy);
+ gypsy->course = gypsy_course_new (path);
+ g_signal_connect (gypsy->course, "course-changed",
+ G_CALLBACK (course_changed), gypsy);
+ gypsy->acc = gypsy_accuracy_new (path);
+ g_signal_connect (gypsy->acc, "accuracy-changed",
+ G_CALLBACK (accuracy_changed), gypsy);
+
+ g_debug ("starting device");
+ if (gypsy->baud_rate != 0) {
+ GHashTable *goptions;
+ GValue speed_val = { 0, };
+ GError *err = NULL;
+
+ g_value_init (&speed_val, G_TYPE_UINT);
+ g_value_set_uint (&speed_val, gypsy->baud_rate);
+ goptions = g_hash_table_new (g_str_hash,
+ g_str_equal);
+ g_hash_table_insert (goptions, "BaudRate", &speed_val);
+ if (!gypsy_device_set_start_options (gypsy->device,
+ goptions,
+ &err)) {
+ g_warning ("Error: %s", err->message);
+ g_error_free (err);
+ }
+ g_hash_table_destroy (goptions);
+ }
+ gypsy_device_start (gypsy->device, error);
+ if (*error != NULL) {
+ g_print ("Error - %s?\n", (*error)->message);
+ gypsy->status = GEOCLUE_STATUS_ERROR;
+ g_free (path);
+ return FALSE;
+ }
+ get_initial_status (gypsy);
+ g_free (path);
+
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (provider);
+
+ g_main_loop_quit (gypsy->loop);
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (object);
+
+ geoclue_accuracy_free (gypsy->accuracy);
+ g_free (gypsy->device_name);
+
+ ((GObjectClass *) geoclue_gypsy_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (object);
+
+ if (gypsy->control) {
+ g_object_unref (gypsy->control);
+ gypsy->control = NULL;
+ }
+
+ if (gypsy->device) {
+ g_object_unref (gypsy->device);
+ gypsy->device = NULL;
+ }
+
+ if (gypsy->position) {
+ g_object_unref (gypsy->position);
+ gypsy->position = NULL;
+ }
+
+ ((GObjectClass *) geoclue_gypsy_parent_class)->dispose (object);
+}
+
+static void
+geoclue_gypsy_class_init (GeoclueGypsyClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ p_class->get_status = get_status;
+ p_class->set_options = set_options;
+ p_class->shutdown = shutdown;
+}
+
+static void
+geoclue_gypsy_init (GeoclueGypsy *gypsy)
+{
+ gypsy->status = GEOCLUE_STATUS_ERROR;
+ gypsy->control = gypsy_control_get_default ();
+
+ gc_provider_set_details (GC_PROVIDER (gypsy),
+ "org.freedesktop.Geoclue.Providers.Gypsy",
+ "/org/freedesktop/Geoclue/Providers/Gypsy",
+ "Gypsy", "Gypsy provider");
+
+ gypsy->position_fields = GYPSY_POSITION_FIELDS_NONE;
+
+ gypsy->accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0.0, 0.0);
+}
+
+static gboolean
+get_position (GcIfacePosition *gc,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc);
+ GeoclueAccuracyLevel level;
+ double horizontal, vertical;
+
+ *timestamp = gypsy->timestamp;
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (gypsy->position_fields & GYPSY_POSITION_FIELDS_LATITUDE) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ *latitude = gypsy->latitude;
+ }
+ if (gypsy->position_fields & GYPSY_POSITION_FIELDS_LONGITUDE) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ *longitude = gypsy->longitude;
+ }
+ if (gypsy->position_fields & GYPSY_POSITION_FIELDS_ALTITUDE) {
+ *fields |= GEOCLUE_POSITION_FIELDS_ALTITUDE;
+ *altitude = gypsy->altitude;
+ }
+
+ geoclue_accuracy_get_details (gypsy->accuracy, &level,
+ &horizontal, &vertical);
+ *accuracy = geoclue_accuracy_new (level, horizontal, vertical);
+
+ return TRUE;
+}
+
+static void
+geoclue_gypsy_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static gboolean
+get_velocity (GcIfaceVelocity *gc,
+ GeoclueVelocityFields *fields,
+ int *timestamp,
+ double *speed,
+ double *direction,
+ double *climb,
+ GError **error)
+{
+ return TRUE;
+}
+
+static void
+geoclue_gypsy_velocity_init (GcIfaceVelocityClass *iface)
+{
+ iface->get_velocity = get_velocity;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueGypsy *gypsy;
+
+ g_type_init ();
+
+ gypsy = g_object_new (GEOCLUE_TYPE_GYPSY, NULL);
+
+ gypsy->loop = g_main_loop_new (NULL, TRUE);
+ g_main_loop_run (gypsy->loop);
+
+ /* Unref the object so that gypsy-daemon knows we've shutdown */
+ g_object_unref (gypsy);
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/hostip/Makefile.am b/.pc/tizen.patch/providers/hostip/Makefile.am
new file mode 100755
index 0000000..1131187
--- /dev/null
+++ b/.pc/tizen.patch/providers/hostip/Makefile.am
@@ -0,0 +1,35 @@
+libexec_PROGRAMS = \
+ geoclue-hostip
+
+NOINST_H_FILES = \
+ geoclue-hostip.h
+
+geoclue_hostip_SOURCES = \
+ $(NOINST_H_FILES) \
+ geoclue-hostip.c
+
+geoclue_hostip_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_hostip_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-hostip.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Hostip.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/localnet/Makefile.am b/.pc/tizen.patch/providers/localnet/Makefile.am
new file mode 100755
index 0000000..382f1b2
--- /dev/null
+++ b/.pc/tizen.patch/providers/localnet/Makefile.am
@@ -0,0 +1,56 @@
+libexec_PROGRAMS = geoclue-localnet
+
+noinst_DATA = \
+ geoclue-localnet.xml
+
+nodist_geoclue_localnet_SOURCES = \
+ geoclue-localnet-glue.h
+
+BUILT_SOURCES = \
+ $(nodist_geoclue_localnet_SOURCES)
+
+geoclue_localnet_SOURCES = \
+ geoclue-localnet.c
+
+geoclue_localnet_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/src \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_localnet_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/src/libconnectivity.la \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-localnet.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Localnet.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+CLEANFILES = \
+ stamp-geoclue-localnet-glue.h
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA) \
+ $(noinst_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA) \
+ $(nodist_geoclue_localnet_SOURCES)
+
+%-glue.h: stamp-%-glue.h
+ @true
+
+stamp-geoclue-localnet-glue.h: geoclue-localnet.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=geoclue_localnet --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
diff --git a/.pc/tizen.patch/providers/localnet/geoclue-localnet.c b/.pc/tizen.patch/providers/localnet/geoclue-localnet.c
new file mode 100755
index 0000000..b834b75
--- /dev/null
+++ b/.pc/tizen.patch/providers/localnet/geoclue-localnet.c
@@ -0,0 +1,512 @@
+/**
+ *
+ * Expects to find a keyfile in user config dir
+ * (~/.config/geoclue-localnet-gateways).
+ *
+ * The keyfile should contain entries like this:
+ *
+ * [00:1D:7E:55:8D:80]
+ * country=Finland
+ * street=Solnantie 24
+ * locality=Helsinki
+ *
+ * Only address interface is supported so far.
+ *
+ * Any application that can obtain a reliable address can submit it
+ * to localnet provider through the D-Bus API -- it will then be provided
+ * whenever connected to the same router:
+ * org.freedesktop.Geoclue.Localnet.SetAddress
+ * org.freedesktop.Geoclue.Localnet.SetAddressFields
+ *
+ * SetAddress allows setting the current address as a GeoclueAddress,
+ * while SetAddressFields is a convenience version with separate
+ * address fields. Shell example using SetAddressFields:
+ *
+ dbus-send --print-reply --type=method_call \
+ --dest=org.freedesktop.Geoclue.Providers.Localnet \
+ /org/freedesktop/Geoclue/Providers/Localnet \
+ org.freedesktop.Geoclue.Localnet.SetAddressFields \
+ string: \
+ string:"Finland" \
+ string: \
+ string:"Helsinki" \
+ string: \
+ string: \
+ string:"Solnantie 24"
+
+ * This would make the provider save the specified address with current
+ * router mac address. It will provide the address to clients whenever
+ * the computer is connected to the same router again.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-address.h>
+
+#include "connectivity.h"
+
+#define KEYFILE_NAME "geoclue-localnet-gateways"
+
+typedef struct {
+ char *mac;
+ GHashTable *address;
+ GeoclueAccuracy *accuracy;
+} Gateway;
+
+
+typedef struct {
+ GcProvider parent;
+
+ GMainLoop *loop;
+ GeoclueConnectivity *conn;
+
+ char *keyfile_name;
+ GSList *gateways;
+} GeoclueLocalnet;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueLocalnetClass;
+
+#define GEOCLUE_TYPE_LOCALNET (geoclue_localnet_get_type ())
+#define GEOCLUE_LOCALNET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_LOCALNET, GeoclueLocalnet))
+
+static void geoclue_localnet_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueLocalnet, geoclue_localnet, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_localnet_address_init))
+
+static gboolean geoclue_localnet_set_address (GeoclueLocalnet *localnet, GHashTable *address, GError **error);
+static gboolean geoclue_localnet_set_address_fields (GeoclueLocalnet *localnet, char *country_code, char *country, char *region, char *locality, char *area, char *postalcode, char *street, GError **error);
+#include "geoclue-localnet-glue.h"
+
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueLocalnet *localnet;
+
+ localnet = GEOCLUE_LOCALNET (provider);
+ g_main_loop_quit (localnet->loop);
+}
+
+static void
+free_gateway_list (GSList *gateways)
+{
+ GSList *l;
+
+ l = gateways;
+ while (l) {
+ Gateway *gw;
+
+ gw = l->data;
+ g_free (gw->mac);
+ g_hash_table_destroy (gw->address);
+ geoclue_accuracy_free (gw->accuracy);
+ g_free (gw);
+
+ l = l->next;
+ }
+ g_slist_free (gateways);
+}
+
+static void
+finalize (GObject *object)
+{
+ GeoclueLocalnet *localnet;
+
+ localnet = GEOCLUE_LOCALNET (object);
+
+ if (localnet->conn != NULL) {
+ g_object_unref (localnet->conn);
+ localnet->conn = NULL;
+ }
+ g_free (localnet->keyfile_name);
+ free_gateway_list (localnet->gateways);
+
+ G_OBJECT_CLASS (geoclue_localnet_parent_class)->finalize (object);
+}
+
+static void
+geoclue_localnet_class_init (GeoclueLocalnetClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->shutdown = shutdown;
+
+ dbus_g_object_type_install_info (geoclue_localnet_get_type (),
+ &dbus_glib_geoclue_localnet_object_info);
+
+}
+
+static void
+geoclue_localnet_load_gateways_from_keyfile (GeoclueLocalnet *localnet,
+ GKeyFile *keyfile)
+{
+ char **groups;
+ char **g;
+ GError *error = NULL;
+
+ groups = g_key_file_get_groups (keyfile, NULL);
+ g = groups;
+ while (*g) {
+ GeoclueAccuracyLevel level;
+ char **keys;
+ char **k;
+ Gateway *gateway = g_new0 (Gateway, 1);
+
+ gateway->mac = g_ascii_strdown (*g, -1);
+ gateway->address = geoclue_address_details_new ();
+
+ /* read all keys in the group as address fields */
+ keys = g_key_file_get_keys (keyfile, *g,
+ NULL, &error);
+ if (error) {
+ g_warning ("Could not load keys for group [%s] from %s: %s",
+ *g, localnet->keyfile_name, error->message);
+ g_error_free (error);
+ error = NULL;
+ }
+
+ k = keys;
+ while (*k) {
+ char *value;
+
+ value = g_key_file_get_string (keyfile, *g, *k, NULL);
+ g_hash_table_insert (gateway->address,
+ *k, value);
+ k++;
+ }
+ g_free (keys);
+
+ level = geoclue_address_details_get_accuracy_level (gateway->address);
+ gateway->accuracy = geoclue_accuracy_new (level, 0, 0);
+
+ localnet->gateways = g_slist_prepend (localnet->gateways, gateway);
+
+ g++;
+ }
+ g_strfreev (groups);
+}
+
+static Gateway *
+geoclue_localnet_find_gateway (GeoclueLocalnet *localnet, char *mac)
+{
+ GSList *l;
+
+ l = localnet->gateways;
+ /* eww, should be using a hashtable or something here */
+ while (l) {
+ Gateway *gw = l->data;
+
+ if (g_ascii_strcasecmp (gw->mac, mac) == 0) {
+ return gw;
+ }
+
+ l = l->next;
+ }
+
+ return NULL;
+}
+
+static void
+geoclue_localnet_init (GeoclueLocalnet *localnet)
+{
+ const char *dir;
+ GKeyFile *keyfile;
+ GError *error = NULL;
+
+ gc_provider_set_details (GC_PROVIDER (localnet),
+ "org.freedesktop.Geoclue.Providers.Localnet",
+ "/org/freedesktop/Geoclue/Providers/Localnet",
+ "Localnet", "provides Address based on current gateway mac address and a local address file (which can be updated through D-Bus)");
+
+
+ localnet->gateways = NULL;
+
+ /* load known addresses from keyfile */
+ dir = g_get_user_config_dir ();
+ g_mkdir_with_parents (dir, 0755);
+ localnet->keyfile_name = g_build_filename (dir, KEYFILE_NAME, NULL);
+
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_file (keyfile, localnet->keyfile_name,
+ G_KEY_FILE_NONE, &error)) {
+ g_warning ("Could not load keyfile %s: %s",
+ localnet->keyfile_name, error->message);
+ g_error_free (error);
+ }
+ geoclue_localnet_load_gateways_from_keyfile (localnet, keyfile);
+ g_key_file_free (keyfile);
+
+ localnet->conn = geoclue_connectivity_new ();
+}
+
+typedef struct {
+ GKeyFile *keyfile;
+ char *group_name;
+} localnet_keyfile_group;
+
+static void
+add_address_detail_to_keyfile (char *key, char *value,
+ localnet_keyfile_group *group)
+{
+ g_key_file_set_string (group->keyfile, group->group_name,
+ key, value);
+}
+
+static gboolean
+geoclue_localnet_set_address (GeoclueLocalnet *localnet,
+ GHashTable *details,
+ GError **error)
+{
+ char *str, *mac;
+ GKeyFile *keyfile;
+ GError *int_err = NULL;
+ localnet_keyfile_group *keyfile_group;
+ Gateway *gw;
+
+ if (!details) {
+ /* TODO set error */
+ return FALSE;
+ }
+
+ mac = geoclue_connectivity_get_router_mac (localnet->conn);
+ if (!mac) {
+ g_warning ("Couldn't get current gateway mac address");
+ /* TODO set error */
+ return FALSE;
+ }
+ /* reload keyfile just in case it's changed */
+ keyfile = g_key_file_new ();
+ if (!g_key_file_load_from_file (keyfile, localnet->keyfile_name,
+ G_KEY_FILE_NONE, &int_err)) {
+ g_warning ("Could not load keyfile %s: %s",
+ localnet->keyfile_name, int_err->message);
+ g_error_free (int_err);
+ int_err = NULL;
+ }
+
+ /* remove old group (if exists) and add new to GKeyFile */
+ g_key_file_remove_group (keyfile, mac, NULL);
+
+ keyfile_group = g_new0 (localnet_keyfile_group, 1);
+ keyfile_group->keyfile = keyfile;
+ keyfile_group->group_name = mac;
+ g_hash_table_foreach (details, (GHFunc) add_address_detail_to_keyfile, keyfile_group);
+ g_free (keyfile_group);
+
+ /* save keyfile*/
+ str = g_key_file_to_data (keyfile, NULL, &int_err);
+ if (int_err) {
+ g_warning ("Failed to get keyfile data as string: %s", int_err->message);
+ g_error_free (int_err);
+ g_key_file_free (keyfile);
+ g_free (mac);
+ /* TODO set error */
+ return FALSE;
+ }
+
+ g_file_set_contents (localnet->keyfile_name, str, -1, &int_err);
+ g_free (str);
+ if (int_err) {
+ g_warning ("Failed to save keyfile: %s", int_err->message);
+ g_error_free (int_err);
+ g_key_file_free (keyfile);
+ g_free (mac);
+ /* TODO set error */
+ return FALSE;
+ }
+
+ /* re-parse keyfile */
+ free_gateway_list (localnet->gateways);
+ localnet->gateways = NULL;
+ geoclue_localnet_load_gateways_from_keyfile (localnet, keyfile);
+ g_key_file_free (keyfile);
+
+ gw = geoclue_localnet_find_gateway (localnet, mac);
+ g_free (mac);
+
+ if (gw) {
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (localnet),
+ time (NULL), gw->address, gw->accuracy);
+ } else {
+ /* empty address -- should emit anyway? */
+ }
+ return TRUE;
+}
+
+static gboolean
+geoclue_localnet_set_address_fields (GeoclueLocalnet *localnet,
+ char *country_code,
+ char *country,
+ char *region,
+ char *locality,
+ char *area,
+ char *postalcode,
+ char *street,
+ GError **error)
+{
+ GHashTable *address;
+ gboolean ret;
+
+ address = geoclue_address_details_new ();
+ if (country_code && (strlen (country_code) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRYCODE),
+ g_strdup (country_code));
+ if (!country) {
+ geoclue_address_details_set_country_from_code (address);
+ }
+ }
+ if (country && (strlen (country) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRY),
+ g_strdup (country));
+ }
+ if (region && (strlen (region) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_REGION),
+ g_strdup (region));
+ }
+ if (locality && (strlen (locality) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_LOCALITY),
+ g_strdup (locality));
+ }
+ if (area && (strlen (area) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_AREA),
+ g_strdup (area));
+ }
+ if (postalcode && (strlen (postalcode) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_POSTALCODE),
+ g_strdup (postalcode));
+ }
+ if (street && (strlen (street) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_STREET),
+ g_strdup (street));
+ }
+
+ ret = geoclue_localnet_set_address (localnet,
+ address,
+ error);
+ g_hash_table_destroy (address);
+ return ret;
+}
+
+static gboolean
+get_address (GcIfaceAddress *gc,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueLocalnet *localnet;
+ char *mac;
+ Gateway *gw;
+
+ localnet = GEOCLUE_LOCALNET (gc);
+
+ /* we may be trying to read /proc/net/arp right after network connection.
+ * It's sometimes not up yet, try a couple of times */
+ mac = geoclue_connectivity_get_router_mac (localnet->conn);
+
+ if (!mac) {
+ g_warning ("Couldn't get current gateway mac address");
+ if (error) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE, "Could not get current gateway mac address");
+ }
+ return FALSE;
+ }
+
+ gw = geoclue_localnet_find_gateway (localnet, mac);
+ g_free (mac);
+
+ if (timestamp) {
+ *timestamp = time(NULL);
+ }
+ if (address) {
+ if (gw) {
+ *address = geoclue_address_details_copy (gw->address);
+ } else {
+ *address = geoclue_address_details_new ();
+ }
+ }
+ if (accuracy) {
+ if (gw) {
+ *accuracy = geoclue_accuracy_copy (gw->accuracy);
+ } else {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+ }
+ }
+ return TRUE;
+}
+
+static void
+geoclue_localnet_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = get_address;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueLocalnet *localnet;
+
+ g_type_init ();
+
+ localnet = g_object_new (GEOCLUE_TYPE_LOCALNET, NULL);
+ localnet->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (localnet->loop);
+
+ g_main_loop_unref (localnet->loop);
+ g_object_unref (localnet);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/manual/Makefile.am b/.pc/tizen.patch/providers/manual/Makefile.am
new file mode 100755
index 0000000..231e042
--- /dev/null
+++ b/.pc/tizen.patch/providers/manual/Makefile.am
@@ -0,0 +1,54 @@
+libexec_PROGRAMS = geoclue-manual
+
+noinst_DATA = \
+ geoclue-manual.xml
+
+nodist_geoclue_manual_SOURCES = \
+ geoclue-manual-glue.h
+
+BUILT_SOURCES = \
+ $(nodist_geoclue_manual_SOURCES)
+
+geoclue_manual_SOURCES = \
+ geoclue-manual.c
+
+geoclue_manual_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_manual_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-manual.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Manual.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+CLEANFILES = \
+ stamp-geoclue-manual-glue.h
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA) \
+ $(noinst_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA) \
+ $(nodist_geoclue_manual_SOURCES)
+
+%-glue.h: stamp-%-glue.h
+ @true
+
+stamp-geoclue-manual-glue.h: geoclue-manual.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=geoclue_manual --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
diff --git a/.pc/tizen.patch/providers/manual/geoclue-manual.c b/.pc/tizen.patch/providers/manual/geoclue-manual.c
new file mode 100755
index 0000000..2b6620a
--- /dev/null
+++ b/.pc/tizen.patch/providers/manual/geoclue-manual.c
@@ -0,0 +1,365 @@
+/*
+ * Geoclue
+ * geoclue-manual.c - Manual address provider
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+/** Geoclue manual provider
+ *
+ * This is an address provider which gets its address data from user
+ * input. No UI is included, any application may query the address from
+ * the user and submit it to manual provider through the D-Bus API:
+ * org.freedesktop.Geoclue.Manual.SetAddress
+ * org.freedesktop.Geoclue.Manual.SetAddressFields
+ *
+ * SetAddress allows setting the current address as a GeoclueAddress,
+ * while SetAddressFields is a convenience version with separate
+ * address fields. Shell example using SetAddressFields:
+ *
+ * dbus-send --print-reply --type=method_call \
+ * --dest=org.freedesktop.Geoclue.Providers.Manual \
+ * /org/freedesktop/Geoclue/Providers/Manual \
+ * org.freedesktop.Geoclue.Manual.SetAddressFields \
+ * int32:7200 \
+ * string: \
+ * string:"Finland" \
+ * string: \
+ * string:"Helsinki" \
+ * string: \
+ * string: \
+ * string:"Solnantie 24"
+ *
+ * This would make the provider emit a AddressChanged signal with
+ * accuracy level GEOCLUE_ACCURACY_STREET. Unless new SetAddress* calls
+ * are made, provider will emit another signal in two hours (7200 sec),
+ * with empty address and GEOCLUE_ACCURACY_NONE.
+ **/
+
+#include <config.h>
+#include <string.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <dbus/dbus.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-address.h>
+
+typedef struct {
+ GcProvider parent;
+
+ GMainLoop *loop;
+
+ guint event_id;
+
+ int timestamp;
+ GHashTable *address;
+ GeoclueAccuracy *accuracy;
+} GeoclueManual;
+
+typedef struct {
+ GcProviderClass parent_class;
+} GeoclueManualClass;
+
+#define GEOCLUE_TYPE_MANUAL (geoclue_manual_get_type ())
+#define GEOCLUE_MANUAL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_MANUAL, GeoclueManual))
+
+static void geoclue_manual_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueManual, geoclue_manual, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_manual_address_init))
+
+static gboolean
+geoclue_manual_set_address (GeoclueManual *manual,
+ int valid_until,
+ GHashTable *address,
+ GError **error);
+
+static gboolean
+geoclue_manual_set_address_fields (GeoclueManual *manual,
+ int valid_until,
+ char *country_code,
+ char *country,
+ char *region,
+ char *locality,
+ char *area,
+ char *postalcode,
+ char *street,
+ GError **error);
+
+#include "geoclue-manual-glue.h"
+
+
+static GeoclueAccuracyLevel
+get_accuracy_for_address (GHashTable *address)
+{
+ if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_STREET)) {
+ return GEOCLUE_ACCURACY_LEVEL_STREET;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_POSTALCODE)) {
+ return GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_LOCALITY)) {
+ return GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_REGION)) {
+ return GEOCLUE_ACCURACY_LEVEL_REGION;
+ } else if (g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRY) ||
+ g_hash_table_lookup (address, GEOCLUE_ADDRESS_KEY_COUNTRYCODE)) {
+ return GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ return GEOCLUE_ACCURACY_LEVEL_NONE;
+}
+
+static gboolean
+get_status (GcIfaceGeoclue *gc,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (GEOCLUE_MANUAL (gc)->accuracy,
+ &level, NULL, NULL);
+ if (level == GEOCLUE_ACCURACY_LEVEL_NONE) {
+ *status = GEOCLUE_STATUS_UNAVAILABLE;
+ } else {
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ }
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeoclueManual *manual;
+
+ manual = GEOCLUE_MANUAL (provider);
+ g_main_loop_quit (manual->loop);
+}
+
+gboolean
+validity_ended (GeoclueManual *manual)
+{
+ manual->event_id = 0;
+ g_hash_table_remove_all (manual->address);
+ geoclue_accuracy_set_details (manual->accuracy,
+ GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (manual),
+ manual->timestamp,
+ manual->address,
+ manual->accuracy);
+ return FALSE;
+}
+
+
+static void
+geoclue_manual_set_address_common (GeoclueManual *manual,
+ int valid_for,
+ GHashTable *address)
+{
+ if (manual->event_id > 0) {
+ g_source_remove (manual->event_id);
+ }
+
+ manual->timestamp = time (NULL);
+
+ g_hash_table_destroy (manual->address);
+ manual->address = address;
+
+ geoclue_accuracy_set_details (manual->accuracy,
+ get_accuracy_for_address (address),
+ 0, 0);
+
+ gc_iface_address_emit_address_changed (GC_IFACE_ADDRESS (manual),
+ manual->timestamp,
+ manual->address,
+ manual->accuracy);
+
+ if (valid_for > 0) {
+ manual->event_id = g_timeout_add (valid_for * 1000,
+ (GSourceFunc)validity_ended,
+ manual);
+ }
+}
+
+static gboolean
+geoclue_manual_set_address (GeoclueManual *manual,
+ int valid_for,
+ GHashTable *address,
+ GError **error)
+{
+ geoclue_manual_set_address_common (manual,
+ valid_for,
+ geoclue_address_details_copy (address));
+ return TRUE;
+}
+
+static gboolean
+geoclue_manual_set_address_fields (GeoclueManual *manual,
+ int valid_for,
+ char *country_code,
+ char *country,
+ char *region,
+ char *locality,
+ char *area,
+ char *postalcode,
+ char *street,
+ GError **error)
+{
+ GHashTable *address;
+
+ address = geoclue_address_details_new ();
+ if (country_code && (strlen (country_code) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRYCODE),
+ g_strdup (country_code));
+ }
+ if (country && (strlen (country) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_COUNTRY),
+ g_strdup (country));
+ }
+ if (region && (strlen (region) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_REGION),
+ g_strdup (region));
+ }
+ if (locality && (strlen (locality) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_LOCALITY),
+ g_strdup (locality));
+ }
+ if (area && (strlen (area) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_AREA),
+ g_strdup (area));
+ }
+ if (postalcode && (strlen (postalcode) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_POSTALCODE),
+ g_strdup (postalcode));
+ }
+ if (street && (strlen (street) > 0)) {
+ g_hash_table_insert (address,
+ g_strdup (GEOCLUE_ADDRESS_KEY_STREET),
+ g_strdup (street));
+ }
+
+ geoclue_manual_set_address_common (manual,
+ valid_for,
+ address);
+ return TRUE;
+}
+
+
+static void
+finalize (GObject *object)
+{
+ GeoclueManual *manual;
+
+ manual = GEOCLUE_MANUAL (object);
+
+ g_hash_table_destroy (manual->address);
+ geoclue_accuracy_free (manual->accuracy);
+
+ ((GObjectClass *) geoclue_manual_parent_class)->finalize (object);
+}
+
+static void
+geoclue_manual_class_init (GeoclueManualClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+ GcProviderClass *p_class = (GcProviderClass *) klass;
+
+ o_class->finalize = finalize;
+
+ p_class->get_status = get_status;
+ p_class->shutdown = shutdown;
+
+ dbus_g_object_type_install_info (geoclue_manual_get_type (),
+ &dbus_glib_geoclue_manual_object_info);
+}
+
+static void
+geoclue_manual_init (GeoclueManual *manual)
+{
+ gc_provider_set_details (GC_PROVIDER (manual),
+ "org.freedesktop.Geoclue.Providers.Manual",
+ "/org/freedesktop/Geoclue/Providers/Manual",
+ "Manual", "Manual provider");
+
+ manual->address = geoclue_address_details_new ();
+ manual->accuracy =
+ geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0, 0);
+}
+
+static gboolean
+get_address (GcIfaceAddress *gc,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueManual *manual = GEOCLUE_MANUAL (gc);
+ GeoclueAccuracyLevel level;
+
+ geoclue_accuracy_get_details (manual->accuracy, &level, NULL, NULL);
+ if (level == GEOCLUE_ACCURACY_LEVEL_NONE) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "No manual address set");
+ return FALSE;
+ }
+
+ if (timestamp) {
+ *timestamp = manual->timestamp;
+ }
+ if (address) {
+ *address = geoclue_address_details_copy (manual->address);
+ }
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_copy (manual->accuracy);
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_manual_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = get_address;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ GeoclueManual *manual;
+
+ g_type_init ();
+
+ manual = g_object_new (GEOCLUE_TYPE_MANUAL, NULL);
+ manual->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (manual->loop);
+
+ g_main_loop_unref (manual->loop);
+ g_object_unref (manual);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/nominatim/Makefile.am b/.pc/tizen.patch/providers/nominatim/Makefile.am
new file mode 100755
index 0000000..f723ac9
--- /dev/null
+++ b/.pc/tizen.patch/providers/nominatim/Makefile.am
@@ -0,0 +1,35 @@
+libexec_PROGRAMS = \
+ geoclue-nominatim
+
+NOINST_H_FILES = \
+ geoclue-nominatim.h
+
+geoclue_nominatim_SOURCES = \
+ $(NOINST_H_FILES) \
+ geoclue-nominatim.c
+
+geoclue_nominatim_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_nominatim_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-nominatim.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Nominatim.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/plazes/Makefile.am b/.pc/tizen.patch/providers/plazes/Makefile.am
new file mode 100755
index 0000000..dc9fb47
--- /dev/null
+++ b/.pc/tizen.patch/providers/plazes/Makefile.am
@@ -0,0 +1,33 @@
+libexec_PROGRAMS = \
+ geoclue-plazes
+
+geoclue_plazes_SOURCES = \
+ geoclue-plazes.c
+
+geoclue_plazes_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/src \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_plazes_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/src/libconnectivity.la \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-plazes.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Plazes.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/plazes/geoclue-plazes.c b/.pc/tizen.patch/providers/plazes/geoclue-plazes.c
new file mode 100755
index 0000000..be44d90
--- /dev/null
+++ b/.pc/tizen.patch/providers/plazes/geoclue-plazes.c
@@ -0,0 +1,377 @@
+/*
+ * Geoclue
+ * geoclue-plazes.c - A plazes.com-based Address/Position provider
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2008 by Garmin Ltd. or its subsidiaries
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <config.h>
+
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+#include "connectivity.h"
+
+#define GEOCLUE_DBUS_SERVICE_PLAZES "org.freedesktop.Geoclue.Providers.Plazes"
+#define GEOCLUE_DBUS_PATH_PLAZES "/org/freedesktop/Geoclue/Providers/Plazes"
+#define PLAZES_URL "http://plazes.com/suggestions.xml"
+#define PLAZES_KEY_MAC "mac_address"
+#define PLAZES_LAT_XPATH "//plaze/latitude"
+#define PLAZES_LON_XPATH "//plaze/longitude"
+
+#define GEOCLUE_TYPE_PLAZES (geoclue_plazes_get_type ())
+#define GEOCLUE_PLAZES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_PLAZES, GeocluePlazes))
+
+typedef struct _GeocluePlazes {
+ GcProvider parent;
+ GMainLoop *loop;
+ GeoclueConnectivity *conn;
+ GcWebService *web_service;
+ GeoclueStatus last_status;
+} GeocluePlazes;
+
+typedef struct _GeocluePlazesClass {
+ GcProviderClass parent_class;
+} GeocluePlazesClass;
+
+
+static void geoclue_plazes_init (GeocluePlazes *plazes);
+static void geoclue_plazes_position_init (GcIfacePositionClass *iface);
+static void geoclue_plazes_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeocluePlazes, geoclue_plazes, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_plazes_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ geoclue_plazes_address_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_plazes_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (iface);
+
+ *status = plazes->last_status;
+ return TRUE;
+}
+
+static void
+shutdown (GcProvider *provider)
+{
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (provider);
+ g_main_loop_quit (plazes->loop);
+}
+
+static void
+geoclue_plazes_set_status (GeocluePlazes *self, GeoclueStatus status)
+{
+ if (status != self->last_status) {
+ self->last_status = status;
+ gc_iface_geoclue_emit_status_changed (GC_IFACE_GEOCLUE (self), status);
+ }
+}
+
+static char *
+mac_strdown (char *mac)
+{
+ guint i;
+ for (i = 0; mac[i] != '\0' ; i++) {
+ if (g_ascii_isalpha (mac[i]))
+ mac[i] = g_ascii_tolower (mac[i]);
+ }
+ return mac;
+}
+/* Position interface implementation */
+
+static gboolean
+geoclue_plazes_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeocluePlazes *plazes;
+ char *mac, *mac_lc;
+
+ plazes = (GEOCLUE_PLAZES (iface));
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ mac = geoclue_connectivity_get_router_mac (plazes->conn);
+ if (mac == NULL) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Router mac address query failed");
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ return FALSE;
+ }
+
+ mac = mac_strdown (mac);
+
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ACQUIRING);
+
+ mac_lc = g_ascii_strdown (mac, -1);
+ g_free (mac);
+ if (!gc_web_service_query (plazes->web_service, error,
+ PLAZES_KEY_MAC, mac,
+ (char *)0)) {
+ g_free (mac_lc);
+ // did not get a reply; we can try again later
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Did not get reply from server");
+ return FALSE;
+ }
+
+ g_free (mac);
+
+ if (latitude && gc_web_service_get_double (plazes->web_service,
+ latitude, PLAZES_LAT_XPATH)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ }
+ if (longitude && gc_web_service_get_double (plazes->web_service,
+ longitude, PLAZES_LON_XPATH)) {
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+ }
+
+ if (accuracy) {
+ /* Educated guess. Plazes are typically hand pointed on
+ * a map, or geocoded from address, so should be fairly
+ * accurate */
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_STREET, 0, 0);
+ }
+
+ if (!(*fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
+ *fields & GEOCLUE_POSITION_FIELDS_LONGITUDE)) {
+
+ // we got a reply, but could not exploit it. It would probably be the
+ // same next time.
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Could not understand reply from server");
+ return FALSE;
+ }
+
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+
+ return TRUE;
+}
+
+/* Address interface implementation */
+
+static gboolean
+geoclue_plazes_get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (iface);
+ char *mac, *mac_lc;
+
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+
+ if (timestamp) {
+ *timestamp = time (NULL);
+ }
+
+ mac = geoclue_connectivity_get_router_mac (plazes->conn);
+
+ if (mac == NULL) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Router mac address query failed");
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ return FALSE;
+ }
+
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ACQUIRING);
+
+ mac_lc = g_ascii_strdown (mac, -1);
+ g_free (mac);
+ if (!gc_web_service_query (plazes->web_service, error,
+ PLAZES_KEY_MAC, mac_lc,
+ (char *)0)) {
+ g_free (mac_lc);
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Did not get reply from server");
+ return FALSE;
+ }
+ g_free (mac_lc);
+
+ if (address) {
+ char *str;
+
+ *address = geoclue_address_details_new ();
+
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/country")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRY,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/country_code")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_COUNTRYCODE,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/city")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_LOCALITY,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/zip_code")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_POSTALCODE,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ }
+ if (gc_web_service_get_string (plazes->web_service,
+ &str, "//plaze/address")) {
+ geoclue_address_details_insert (*address,
+ GEOCLUE_ADDRESS_KEY_STREET,
+ str);
+ g_free (str);
+ level = GEOCLUE_ACCURACY_LEVEL_STREET;
+ }
+ }
+
+ if (level == GEOCLUE_ACCURACY_LEVEL_NONE) {
+ // we got a reply, but could not exploit it. It would probably be the
+ // same next time.
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_ERROR);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Could not understand reply from server");
+ return FALSE;
+ }
+
+ if (accuracy) {
+ *accuracy = geoclue_accuracy_new (level, 0, 0);
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_plazes_finalize (GObject *obj)
+{
+ GeocluePlazes *plazes = GEOCLUE_PLAZES (obj);
+
+ if (plazes->conn != NULL) {
+ g_object_unref (plazes->conn);
+ plazes->conn = NULL;
+ }
+ g_object_unref (plazes->web_service);
+
+ ((GObjectClass *) geoclue_plazes_parent_class)->finalize (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_plazes_class_init (GeocluePlazesClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = shutdown;
+ p_class->get_status = geoclue_plazes_get_status;
+
+ o_class->finalize = geoclue_plazes_finalize;
+}
+
+static void
+geoclue_plazes_init (GeocluePlazes *plazes)
+{
+ gc_provider_set_details (GC_PROVIDER (plazes),
+ GEOCLUE_DBUS_SERVICE_PLAZES,
+ GEOCLUE_DBUS_PATH_PLAZES,
+ "Plazes", "Plazes.com based provider, uses gateway mac address to locate");
+
+ plazes->conn = geoclue_connectivity_new ();
+ plazes->web_service = g_object_new (GC_TYPE_WEB_SERVICE, NULL);
+ gc_web_service_set_base_url (plazes->web_service, PLAZES_URL);
+ geoclue_plazes_set_status (plazes, GEOCLUE_STATUS_AVAILABLE);
+}
+
+static void
+geoclue_plazes_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_plazes_get_position;
+}
+
+static void
+geoclue_plazes_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = geoclue_plazes_get_address;
+}
+
+int
+main()
+{
+ g_type_init();
+
+ GeocluePlazes *o = g_object_new (GEOCLUE_TYPE_PLAZES, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/skyhook/Makefile.am b/.pc/tizen.patch/providers/skyhook/Makefile.am
new file mode 100755
index 0000000..a6e2107
--- /dev/null
+++ b/.pc/tizen.patch/providers/skyhook/Makefile.am
@@ -0,0 +1,35 @@
+libexec_PROGRAMS = \
+ geoclue-skyhook
+
+geoclue_skyhook_SOURCES = \
+ geoclue-skyhook.c
+
+geoclue_skyhook_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/src \
+ $(GEOCLUE_CFLAGS) \
+ $(SKYHOOK_CFLAGS)
+
+geoclue_skyhook_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(SKYHOOK_LIBS) \
+ $(top_builddir)/src/libconnectivity.la \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-skyhook.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Skyhook.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.c b/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.c
new file mode 100755
index 0000000..5af7b45
--- /dev/null
+++ b/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.c
@@ -0,0 +1,303 @@
+/*
+ * Geoclue
+ * geoclue-skyhook.c - A skyhook.com-based Address/Position provider
+ *
+ * Author: Bastien Nocera <hadess@hadess.net>
+ * Copyright 2009 Bastien Nocera
+ */
+
+#include <config.h>
+
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib-object.h>
+#include <dbus/dbus-glib-bindings.h>
+#include <libsoup/soup.h>
+#include <libxml/xpathInternals.h>
+
+#include <geoclue/gc-web-service.h>
+#include <geoclue/gc-provider.h>
+#include <geoclue/geoclue-error.h>
+#include <geoclue/gc-iface-position.h>
+
+#include "connectivity.h"
+
+#define GEOCLUE_DBUS_SERVICE_SKYHOOK "org.freedesktop.Geoclue.Providers.Skyhook"
+#define GEOCLUE_DBUS_PATH_SKYHOOK "/org/freedesktop/Geoclue/Providers/Skyhook"
+#define SKYHOOK_URL "https://api.skyhookwireless.com/wps2/location"
+#define SKYHOOK_LAT_XPATH "//prefix:latitude"
+#define SKYHOOK_LON_XPATH "//prefix:longitude"
+#define USER_AGENT "Geoclue "VERSION
+
+#define GEOCLUE_TYPE_SKYHOOK (geoclue_skyhook_get_type ())
+#define GEOCLUE_SKYHOOK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_SKYHOOK, GeoclueSkyhook))
+
+#define QUERY_START "<?xml version=\'1.0\'?><LocationRQ xmlns=\'http://skyhookwireless.com/wps/2005\' version=\'2.6\' street-address-lookup=\'full\'><authentication version=\'2.0\'><simple><username>beta</username><realm>js.loki.com</realm></simple></authentication>"
+#define QUERY_AP "<access-point><mac>%s</mac><signal-strength>%d</signal-strength></access-point>"
+#define QUERY_END "</LocationRQ>"
+
+typedef struct _GeoclueSkyhook {
+ GcProvider parent;
+ GMainLoop *loop;
+ SoupSession *session;
+ GeoclueConnectivity *conn;
+} GeoclueSkyhook;
+
+typedef struct _GeoclueSkyhookClass {
+ GcProviderClass parent_class;
+} GeoclueSkyhookClass;
+
+
+static void geoclue_skyhook_init (GeoclueSkyhook *skyhook);
+static void geoclue_skyhook_position_init (GcIfacePositionClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueSkyhook, geoclue_skyhook, GC_TYPE_PROVIDER,
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ geoclue_skyhook_position_init))
+
+
+/* Geoclue interface implementation */
+static gboolean
+geoclue_skyhook_get_status (GcIfaceGeoclue *iface,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* Assume available so long as all the requirements are satisfied
+ ie: Network is available */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static void
+_shutdown (GcProvider *provider)
+{
+ GeoclueSkyhook *skyhook = GEOCLUE_SKYHOOK (provider);
+ g_main_loop_quit (skyhook->loop);
+}
+
+static void
+add_ap (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ char *mac;
+ char **split;
+
+ /* Remove the ":" */
+ split = g_strsplit (key, ":", -1);
+ mac = g_strjoinv ("", split);
+ g_strfreev (split);
+
+ g_string_append_printf (data, QUERY_AP, mac, GPOINTER_TO_INT (value));
+ g_free (mac);
+}
+
+static char *
+create_post_query (GeoclueConnectivity *conn)
+{
+ GHashTable *ht;
+ GString *str;
+
+ ht = geoclue_connectivity_get_aps (conn);
+ if (ht == NULL)
+ return NULL;
+ str = g_string_new (QUERY_START);
+ g_hash_table_foreach (ht, add_ap, str);
+ g_string_append (str, QUERY_END);
+ g_hash_table_destroy (ht);
+
+ return g_string_free (str, FALSE);
+}
+
+static gboolean
+get_double (xmlXPathContext *xpath_ctx, char *xpath, gdouble *value)
+{
+ xmlXPathObject *obj = NULL;
+
+ obj = xmlXPathEvalExpression (BAD_CAST (xpath), xpath_ctx);
+ if (obj &&
+ (!obj->nodesetval || xmlXPathNodeSetIsEmpty (obj->nodesetval))) {
+ xmlXPathFreeObject (obj);
+ return FALSE;
+ }
+ *value = xmlXPathCastNodeSetToNumber (obj->nodesetval);
+ xmlXPathFreeObject (obj);
+ return TRUE;
+}
+
+static gboolean
+parse_response (const char *body, gdouble *latitude, gdouble *longitude)
+{
+ xmlDocPtr doc;
+ xmlXPathContext *xpath_ctx;
+ gboolean ret = TRUE;
+
+ doc = xmlParseDoc (BAD_CAST (body));
+ if (!doc)
+ return FALSE;
+
+ xpath_ctx = xmlXPathNewContext(doc);
+ if (!xpath_ctx) {
+ xmlFreeDoc (doc);
+ return FALSE;
+ }
+ xmlXPathRegisterNs (xpath_ctx, BAD_CAST ("prefix"), BAD_CAST("http://skyhookwireless.com/wps/2005"));
+ if (get_double (xpath_ctx, SKYHOOK_LAT_XPATH, latitude) == FALSE) {
+ ret = FALSE;
+ } else if (get_double (xpath_ctx, SKYHOOK_LON_XPATH, longitude) == FALSE) {
+ ret = FALSE;
+ }
+ xmlXPathFreeContext (xpath_ctx);
+ xmlFreeDoc (doc);
+
+ return ret;
+}
+
+/* Position interface implementation */
+
+static gboolean
+geoclue_skyhook_get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GeoclueSkyhook *skyhook;
+ char *query;
+ SoupMessage *msg;
+
+ skyhook = (GEOCLUE_SKYHOOK (iface));
+
+ *fields = GEOCLUE_POSITION_FIELDS_NONE;
+ if (timestamp)
+ *timestamp = time (NULL);
+
+ query = create_post_query (skyhook->conn);
+ if (query == NULL) {
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Router mac address query failed");
+ /* TODO: set status == error ? */
+ return FALSE;
+ }
+
+ msg = soup_message_new ("POST", SKYHOOK_URL);
+ soup_message_headers_append (msg->request_headers, "User-Agent", USER_AGENT);
+ soup_message_set_request (msg,
+ "text/xml",
+ SOUP_MEMORY_TAKE,
+ query,
+ strlen (query));
+ soup_session_send_message (skyhook->session, msg);
+ if (msg->response_body == NULL || msg->response_body->data == NULL) {
+ g_object_unref (msg);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Failed to query web service");
+ return FALSE;
+ }
+
+ if (strstr (msg->response_body->data, "<error>") != NULL) {
+ g_object_unref (msg);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Web service returned an error");
+ return FALSE;
+ }
+
+ if (parse_response (msg->response_body->data, latitude, longitude) == FALSE) {
+ g_object_unref (msg);
+ g_set_error (error, GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Couldn't parse response from web service");
+ return FALSE;
+ }
+
+ if (latitude)
+ *fields |= GEOCLUE_POSITION_FIELDS_LATITUDE;
+ if (longitude)
+ *fields |= GEOCLUE_POSITION_FIELDS_LONGITUDE;
+
+ if (accuracy) {
+ if (*fields == GEOCLUE_POSITION_FIELDS_NONE) {
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE,
+ 0, 0);
+ } else {
+ /* Educated guess. Skyhook are typically hand pointed on
+ * a map, or geocoded from address, so should be fairly
+ * accurate */
+ *accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_STREET,
+ 0, 0);
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+geoclue_skyhook_finalize (GObject *obj)
+{
+ GeoclueSkyhook *skyhook = GEOCLUE_SKYHOOK (obj);
+
+ if (skyhook->conn != NULL) {
+ g_object_unref (skyhook->conn);
+ skyhook->conn = NULL;
+ }
+ g_object_unref (skyhook->session);
+
+ ((GObjectClass *) geoclue_skyhook_parent_class)->finalize (obj);
+}
+
+
+/* Initialization */
+
+static void
+geoclue_skyhook_class_init (GeoclueSkyhookClass *klass)
+{
+ GcProviderClass *p_class = (GcProviderClass *)klass;
+ GObjectClass *o_class = (GObjectClass *)klass;
+
+ p_class->shutdown = _shutdown;
+ p_class->get_status = geoclue_skyhook_get_status;
+
+ o_class->finalize = geoclue_skyhook_finalize;
+}
+
+static void
+geoclue_skyhook_init (GeoclueSkyhook *skyhook)
+{
+ gc_provider_set_details (GC_PROVIDER (skyhook),
+ GEOCLUE_DBUS_SERVICE_SKYHOOK,
+ GEOCLUE_DBUS_PATH_SKYHOOK,
+ "Skyhook", "Skyhook.com based provider, uses gateway mac address to locate");
+ skyhook->session = soup_session_sync_new ();
+ skyhook->conn = geoclue_connectivity_new ();
+}
+
+static void
+geoclue_skyhook_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = geoclue_skyhook_get_position;
+}
+
+int
+main()
+{
+ g_type_init();
+ g_thread_init (NULL);
+
+ GeoclueSkyhook *o = g_object_new (GEOCLUE_TYPE_SKYHOOK, NULL);
+ o->loop = g_main_loop_new (NULL, TRUE);
+
+ g_main_loop_run (o->loop);
+
+ g_main_loop_unref (o->loop);
+ g_object_unref (o);
+
+ return 0;
+}
diff --git a/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.provider b/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.provider
new file mode 100755
index 0000000..1e0fcde
--- /dev/null
+++ b/.pc/tizen.patch/providers/skyhook/geoclue-skyhook.provider
@@ -0,0 +1,8 @@
+[Geoclue Provider]
+Name=Skyhook
+Service=org.freedesktop.Geoclue.Providers.Skyhook
+Path=/org/freedesktop/Geoclue/Providers/Skyhook
+Accuracy=Street
+Requires=RequiresNetwork
+Provides=ProvidesCacheableOnConnection
+Interfaces=org.freedesktop.Geoclue.Position
diff --git a/.pc/tizen.patch/providers/yahoo/Makefile.am b/.pc/tizen.patch/providers/yahoo/Makefile.am
new file mode 100755
index 0000000..fee408b
--- /dev/null
+++ b/.pc/tizen.patch/providers/yahoo/Makefile.am
@@ -0,0 +1,31 @@
+libexec_PROGRAMS = \
+ geoclue-yahoo
+
+geoclue_yahoo_SOURCES = \
+ geoclue-yahoo.c
+
+geoclue_yahoo_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ $(GEOCLUE_CFLAGS)
+
+geoclue_yahoo_LDADD = \
+ $(GEOCLUE_LIBS) \
+ $(top_builddir)/geoclue/libgeoclue.la
+
+providersdir = $(datadir)/geoclue-providers
+providers_DATA = geoclue-yahoo.provider
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Providers.Yahoo.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(providers_DATA)
+
+DISTCLEANFILES = \
+ $(service_DATA)