summaryrefslogtreecommitdiff
path: root/.pc/tizen.patch/src
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/src
parent9f11ee482a4a28d6e85613ac5c765c588fdf20aa (diff)
downloadgeoclue-0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d.tar.gz
geoclue-0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d.tar.bz2
geoclue-0c44dc6cd8d3ede16172f22fa2b7c6af4459e55d.zip
Git init
Diffstat (limited to '.pc/tizen.patch/src')
-rwxr-xr-x.pc/tizen.patch/src/Makefile.am90
-rwxr-xr-x.pc/tizen.patch/src/client.c994
-rwxr-xr-x.pc/tizen.patch/src/connectivity-connman.c739
-rwxr-xr-x.pc/tizen.patch/src/connectivity-connman.h56
-rwxr-xr-x.pc/tizen.patch/src/connectivity-networkmanager.c369
-rwxr-xr-x.pc/tizen.patch/src/connectivity-networkmanager.h56
-rwxr-xr-x.pc/tizen.patch/src/connectivity.c276
-rwxr-xr-x.pc/tizen.patch/src/connectivity.h73
-rwxr-xr-x.pc/tizen.patch/src/geoclue3
-rwxr-xr-x.pc/tizen.patch/src/main.c231
-rwxr-xr-x.pc/tizen.patch/src/master-provider.c1309
-rwxr-xr-x.pc/tizen.patch/src/master.c211
-rwxr-xr-x.pc/tizen.patch/src/org.freedesktop.Geoclue.gschema.xml15
-rwxr-xr-x.pc/tizen.patch/src/test-connectivity.c97
14 files changed, 4519 insertions, 0 deletions
diff --git a/.pc/tizen.patch/src/Makefile.am b/.pc/tizen.patch/src/Makefile.am
new file mode 100755
index 0000000..ebb5f22
--- /dev/null
+++ b/.pc/tizen.patch/src/Makefile.am
@@ -0,0 +1,90 @@
+libexec_PROGRAMS = geoclue-master
+noinst_LTLIBRARIES = libconnectivity.la
+noinst_PROGRAMS = test-connectivity
+
+AM_CFLAGS = \
+ -I$(top_srcdir) \
+ -I$(srcdir) \
+ -I$(top_builddir) \
+ -DGEOCLUE_PROVIDERS_DIR=\""$(datadir)/geoclue-providers"\" \
+ $(GEOCLUE_CFLAGS) \
+ $(MASTER_CFLAGS) \
+ $(CONNECTIVITY_CFLAGS)
+
+geoclue_master_LDADD = \
+ $(top_builddir)/geoclue/libgeoclue.la \
+ libconnectivity.la \
+ $(GEOCLUE_LIBS) \
+ $(MASTER_LIBS)
+
+NOINST_H_FILES = \
+ main.h \
+ master.h \
+ master-provider.h \
+ client.h
+
+libconnectivity_la_SOURCES = \
+ connectivity.h \
+ connectivity-networkmanager.h \
+ connectivity-conic.h \
+ connectivity-connman.h \
+ connectivity.c \
+ connectivity-networkmanager.c \
+ connectivity-conic.c \
+ connectivity-connman.c
+
+libconnectivity_la_LIBADD = $(CONNECTIVITY_LIBS)
+
+test_connectivity_SOURCES = test-connectivity.c
+test_connectivity_LDADD = libconnectivity.la $(GEOCLUE_LIBS)
+
+geoclue_master_SOURCES = \
+ $(NOINST_H_FILES) \
+ client.c \
+ main.c \
+ master.c \
+ master-provider.c
+
+BUILT_SOURCES = \
+ gc-iface-master-glue.h \
+ gc-iface-master-client-glue.h
+
+%-glue.h: stamp-%-glue.h
+ @true
+stamp-gc-iface-master-glue.h: ../interfaces/gc-iface-master.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_master --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+stamp-gc-iface-master-client-glue.h: ../interfaces/gc-iface-master-client.xml
+ $(AM_V_GEN) $(DBUS_BINDING_TOOL) --prefix=gc_iface_master_client --mode=glib-server $< > xgen-$(@F) \
+ && (cmp -s xgen-$(@F) $(@F:stamp-%=%) || cp xgen-$(@F) $(@F:stamp-%=%)) \
+ && rm -f xgen-$(@F) \
+ && echo timestamp > $(@F)
+
+servicedir = $(DBUS_SERVICES_DIR)
+service_in_files = org.freedesktop.Geoclue.Master.service.in
+service_DATA = $(service_in_files:.service.in=.service)
+
+$(service_DATA): $(service_in_files) Makefile
+ $(AM_V_GEN) sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@
+
+convertdir = $(datadir)/GConf/gsettings
+convert_DATA = geoclue
+
+gsettings_SCHEMAS = org.freedesktop.Geoclue.gschema.xml
+@GSETTINGS_RULES@
+
+EXTRA_DIST = \
+ $(service_in_files) \
+ $(gsettings_SCHEMAS) \
+ $(convert_DATA)
+
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ stamp-gc-iface-master-glue.h \
+ stamp-gc-iface-master-client-glue.h
+
+DISTCLEANFILES = \
+ $(service_DATA)
diff --git a/.pc/tizen.patch/src/client.c b/.pc/tizen.patch/src/client.c
new file mode 100755
index 0000000..dbe5361
--- /dev/null
+++ b/.pc/tizen.patch/src/client.c
@@ -0,0 +1,994 @@
+/*
+ * Geoclue
+ * client.c - Geoclue Master Client
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * 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
+ *
+ * might want to write a testing-provider with a gui for
+ * choosing what to emit...
+ *
+ **/
+
+
+#include <config.h>
+
+#include <geoclue/geoclue-error.h>
+#include <geoclue/geoclue-marshal.h>
+
+#include <geoclue/gc-provider.h>
+#include <geoclue/gc-iface-position.h>
+#include <geoclue/gc-iface-address.h>
+
+#include "client.h"
+
+#define GEOCLUE_POSITION_INTERFACE_NAME "org.freedesktop.Geoclue.Position"
+#define GEOCLUE_ADDRESS_INTERFACE_NAME "org.freedesktop.Geoclue.Address"
+
+enum {
+ ADDRESS_PROVIDER_CHANGED,
+ POSITION_PROVIDER_CHANGED,
+ LAST_SIGNAL
+};
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+
+enum {
+ POSITION_CHANGED, /* signal id of current provider */
+ ADDRESS_CHANGED, /* signal id of current provider */
+ LAST_PRIVATE_SIGNAL
+};
+
+typedef struct _GcMasterClientPrivate {
+ guint32 signals[LAST_PRIVATE_SIGNAL];
+
+ GeoclueAccuracyLevel min_accuracy;
+ int min_time;
+ gboolean require_updates;
+ GeoclueResourceFlags allowed_resources;
+
+ gboolean position_started;
+ GcMasterProvider *position_provider;
+ GList *position_providers;
+ gboolean position_provider_choice_in_progress;
+ time_t last_position_changed;
+
+ gboolean address_started;
+ GcMasterProvider *address_provider;
+ GList *address_providers;
+ gboolean address_provider_choice_in_progress;
+ time_t last_address_changed;
+
+} GcMasterClientPrivate;
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GC_TYPE_MASTER_CLIENT, GcMasterClientPrivate))
+
+
+
+static gboolean gc_iface_master_client_set_requirements (GcMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GError **error);
+static gboolean gc_iface_master_client_position_start (GcMasterClient *client, GError **error);
+static gboolean gc_iface_master_client_address_start (GcMasterClient *client, GError **error);
+static gboolean gc_iface_master_client_get_address_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error);
+static gboolean gc_iface_master_client_get_position_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error);
+
+static void gc_master_client_geoclue_init (GcIfaceGeoclueClass *iface);
+static void gc_master_client_position_init (GcIfacePositionClass *iface);
+static void gc_master_client_address_init (GcIfaceAddressClass *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GcMasterClient, gc_master_client, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE(GC_TYPE_IFACE_GEOCLUE,
+ gc_master_client_geoclue_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_POSITION,
+ gc_master_client_position_init)
+ G_IMPLEMENT_INTERFACE (GC_TYPE_IFACE_ADDRESS,
+ gc_master_client_address_init))
+
+#include "gc-iface-master-client-glue.h"
+
+
+static gboolean status_change_requires_provider_change (GList *provider_list,
+ GcMasterProvider *current_provider,
+ GcMasterProvider *changed_provider,
+ GeoclueStatus status);
+static void gc_master_client_emit_position_changed (GcMasterClient *client);
+static void gc_master_client_emit_address_changed (GcMasterClient *client);
+static gboolean gc_master_client_choose_position_provider (GcMasterClient *client,
+ GList *providers);
+static gboolean gc_master_client_choose_address_provider (GcMasterClient *client,
+ GList *providers);
+
+
+static void
+status_changed (GcMasterProvider *provider,
+ GeoclueStatus status,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ g_debug ("client: provider %s status changed: %d", gc_master_provider_get_name (provider), status);
+
+ /* change providers if needed (and if we're not choosing provider already) */
+
+ if (!priv->position_provider_choice_in_progress &&
+ status_change_requires_provider_change (priv->position_providers,
+ priv->position_provider,
+ provider, status) &&
+ gc_master_client_choose_position_provider (client,
+ priv->position_providers)) {
+
+ /* we have a new position provider, force-emit position_changed */
+ gc_master_client_emit_position_changed (client);
+ }
+
+ if (!priv->address_provider_choice_in_progress &&
+ status_change_requires_provider_change (priv->address_providers,
+ priv->address_provider,
+ provider, status) &&
+ gc_master_client_choose_address_provider (client,
+ priv->address_providers)) {
+
+ /* we have a new address provider, force-emit address_changed */
+ gc_master_client_emit_address_changed (client);
+ }
+}
+
+static void
+accuracy_changed (GcMasterProvider *provider,
+ GcInterfaceFlags interface,
+ GeoclueAccuracyLevel level,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcInterfaceAccuracy *accuracy_data;
+
+ accuracy_data = g_new0 (GcInterfaceAccuracy, 1);
+ g_debug ("client: %s accuracy changed (%d)",
+ gc_master_provider_get_name (provider), level);
+
+ accuracy_data->interface = interface;
+ accuracy_data->accuracy_level = priv->min_accuracy;
+ switch (interface) {
+ case GC_IFACE_POSITION:
+ priv->position_providers =
+ g_list_sort_with_data (priv->position_providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+ if (priv->position_provider_choice_in_progress) {
+ g_debug (" ...but provider choice in progress");
+ } else if (gc_master_client_choose_position_provider (client,
+ priv->position_providers)) {
+ gc_master_client_emit_position_changed (client);
+ }
+ break;
+
+ case GC_IFACE_ADDRESS:
+ priv->address_providers =
+ g_list_sort_with_data (priv->address_providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+ if (priv->address_provider_choice_in_progress) {
+ g_debug (" ...but provider choice in progress");
+ } else if (gc_master_client_choose_address_provider (client,
+ priv->address_providers)) {
+ gc_master_client_emit_address_changed (client);
+ }
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+ g_free (accuracy_data);
+}
+
+static void
+position_changed (GcMasterProvider *provider,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ time_t now;
+
+ now = time (NULL);
+ if (priv->min_time > (now - priv->last_position_changed)) {
+ /* NOTE: currently no-one makes sure there is an emit
+ * after min_time */
+ return;
+ }
+ priv->last_position_changed = now;
+
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (client),
+ fields,
+ timestamp,
+ latitude, longitude, altitude,
+ accuracy);
+}
+
+static void
+address_changed (GcMasterProvider *provider,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ time_t now;
+
+ now = time (NULL);
+ if (priv->min_time > (now - priv->last_address_changed)) {
+ /* NOTE: currently no-one makes sure there is an emit
+ * after min_time */
+ return;
+ }
+ priv->last_address_changed = now;
+
+ gc_iface_address_emit_address_changed
+ (GC_IFACE_ADDRESS (client),
+ timestamp,
+ details,
+ accuracy);
+}
+
+/*if changed_provider status changes, do we need to choose a new provider? */
+static gboolean
+status_change_requires_provider_change (GList *provider_list,
+ GcMasterProvider *current_provider,
+ GcMasterProvider *changed_provider,
+ GeoclueStatus status)
+{
+ if (!provider_list) {
+ return FALSE;
+
+ } else if (current_provider == NULL) {
+ return (status == GEOCLUE_STATUS_AVAILABLE);
+
+ } else if (current_provider == changed_provider) {
+ return (status != GEOCLUE_STATUS_AVAILABLE);
+
+ }else if (status != GEOCLUE_STATUS_AVAILABLE) {
+ return FALSE;
+
+ }
+
+ while (provider_list) {
+ GcMasterProvider *p = provider_list->data;
+ if (p == current_provider) {
+ /* not interested in worse-than-current providers */
+ return FALSE;
+ }
+ if (p == changed_provider) {
+ /* changed_provider is better than current */
+ return (status == GEOCLUE_STATUS_AVAILABLE);
+ }
+ provider_list = provider_list->next;
+ }
+ return FALSE;
+}
+
+static void
+gc_master_client_connect_common_signals (GcMasterClient *client, GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GList *l;
+
+ /* connect to common signals if the provider is not already connected */
+ l = providers;
+ while (l) {
+ GcMasterProvider *p = l->data;
+ if (!g_list_find (priv->address_providers, p) &&
+ !g_list_find (priv->position_providers, p)) {
+ g_debug ("client: connecting to '%s' accuracy-changed and status-changed", gc_master_provider_get_name (p));
+ g_signal_connect (G_OBJECT (p),
+ "status-changed",
+ G_CALLBACK (status_changed),
+ client);
+ g_signal_connect (G_OBJECT (p),
+ "accuracy-changed",
+ G_CALLBACK (accuracy_changed),
+ client);
+ }
+ l = l->next;
+ }
+}
+
+static void
+gc_master_client_unsubscribe_providers (GcMasterClient *client, GList *provider_list, GcInterfaceFlags iface)
+{
+ while (provider_list) {
+ GcMasterProvider *provider = provider_list->data;
+
+ gc_master_provider_unsubscribe (provider, client, iface);
+ provider_list = provider_list->next;
+ }
+
+}
+
+/* get_best_provider will return the best provider with status == GEOCLUE_STATUS_AVAILABLE.
+ * It will also "subscribe" to that provider and all better ones, and unsubscribe from worse.*/
+static GcMasterProvider *
+gc_master_client_get_best_provider (GcMasterClient *client,
+ GList **provider_list,
+ GcInterfaceFlags iface)
+{
+ GList *l = *provider_list;
+ /* TODO: should maybe choose a acquiring provider if better ones are are not available */
+
+ g_debug ("client: choosing best provider");
+
+ while (l) {
+ GcMasterProvider *provider = l->data;
+
+ g_debug (" ...trying provider %s", gc_master_provider_get_name (provider));
+ if (gc_master_provider_subscribe (provider, client, iface)) {
+ /* provider was started, so accuracy may have changed
+ (which re-sorts provider lists), restart provider selection */
+ /* TODO re-think this: restarting provider selection leads to potentially
+ never-ending looping */
+ g_debug (" ...started %s (status %d), re-starting provider selection",
+ gc_master_provider_get_name (provider),
+ gc_master_provider_get_status (provider));
+ l = *provider_list;
+ continue;
+ }
+ /* provider did not need to be started */
+
+ /* TODO: currently returning even providers that are worse than priv->min_accuracy,
+ * if nothing else is available */
+ if (gc_master_provider_get_status (provider) == GEOCLUE_STATUS_AVAILABLE) {
+ /* unsubscribe from all providers worse than this */
+ gc_master_client_unsubscribe_providers (client, l->next, iface);
+ return provider;
+ }
+ l = l->next;
+ }
+
+ /* no provider found */
+ gc_master_client_unsubscribe_providers (client, *provider_list, iface);
+ return NULL;
+}
+
+static void
+gc_master_client_emit_position_changed (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GeocluePositionFields fields;
+ int timestamp;
+ double latitude, longitude, altitude;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+
+ if (priv->position_provider == NULL) {
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (client),
+ GEOCLUE_POSITION_FIELDS_NONE,
+ time (NULL),
+ 0.0, 0.0, 0.0,
+ accuracy);
+ geoclue_accuracy_free (accuracy);
+ return;
+ }
+
+ fields = gc_master_provider_get_position
+ (priv->position_provider,
+ &timestamp,
+ &latitude, &longitude, &altitude,
+ &accuracy,
+ &error);
+ if (error) {
+ /*TODO what now?*/
+ g_warning ("client: failed to get position from %s: %s",
+ gc_master_provider_get_name (priv->position_provider),
+ error->message);
+ g_error_free (error);
+ return;
+ }
+ gc_iface_position_emit_position_changed
+ (GC_IFACE_POSITION (client),
+ fields,
+ timestamp,
+ latitude, longitude, altitude,
+ accuracy);
+}
+
+static void
+gc_master_client_emit_address_changed (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ int timestamp;
+ GHashTable *details = NULL;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ if (priv->address_provider == NULL) {
+ accuracy = geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0.0, 0.0);
+ details = g_hash_table_new (g_str_hash, g_str_equal);
+ gc_iface_address_emit_address_changed
+ (GC_IFACE_ADDRESS (client),
+ time (NULL),
+ details,
+ accuracy);
+ g_hash_table_destroy (details);
+ geoclue_accuracy_free (accuracy);
+ return;
+ }
+ if (!gc_master_provider_get_address
+ (priv->address_provider,
+ &timestamp,
+ &details,
+ &accuracy,
+ &error)) {
+ /*TODO what now?*/
+ g_warning ("client: failed to get address from %s: %s",
+ gc_master_provider_get_name (priv->address_provider),
+ error->message);
+ g_error_free (error);
+ return;
+ }
+ gc_iface_address_emit_address_changed
+ (GC_IFACE_ADDRESS (client),
+ timestamp,
+ details,
+ accuracy);
+}
+
+/* return true if a _new_ provider was chosen */
+static gboolean
+gc_master_client_choose_position_provider (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcMasterProvider *new_p;
+
+ /* choose and start provider */
+ priv->position_provider_choice_in_progress = TRUE;
+ new_p = gc_master_client_get_best_provider (client,
+ &priv->position_providers,
+ GC_IFACE_POSITION);
+ priv->position_provider_choice_in_progress = FALSE;
+
+ if (priv->position_provider && new_p == priv->position_provider) {
+ return FALSE;
+ }
+
+ if (priv->signals[POSITION_CHANGED] > 0) {
+ g_signal_handler_disconnect (priv->position_provider,
+ priv->signals[POSITION_CHANGED]);
+ priv->signals[POSITION_CHANGED] = 0;
+ }
+
+ priv->position_provider = new_p;
+
+ if (priv->position_provider == NULL) {
+ g_debug ("client: position provider changed (to NULL)");
+ g_signal_emit (client, signals[POSITION_PROVIDER_CHANGED], 0,
+ NULL, NULL, NULL, NULL);
+ return TRUE;
+ }
+
+ g_debug ("client: position provider changed (to %s)", gc_master_provider_get_name (priv->position_provider));
+ g_signal_emit (client, signals[POSITION_PROVIDER_CHANGED], 0,
+ gc_master_provider_get_name (priv->position_provider),
+ gc_master_provider_get_description (priv->position_provider),
+ gc_master_provider_get_service (priv->position_provider),
+ gc_master_provider_get_path (priv->position_provider));
+ priv->signals[POSITION_CHANGED] =
+ g_signal_connect (G_OBJECT (priv->position_provider),
+ "position-changed",
+ G_CALLBACK (position_changed),
+ client);
+ return TRUE;
+}
+
+/* return true if a _new_ provider was chosen */
+static gboolean
+gc_master_client_choose_address_provider (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcMasterProvider *new_p;
+
+
+ /* choose and start provider */
+ priv->address_provider_choice_in_progress = TRUE;
+ new_p = gc_master_client_get_best_provider (client,
+ &priv->address_providers,
+ GC_IFACE_ADDRESS);
+ priv->address_provider_choice_in_progress = FALSE;
+
+ if (priv->address_provider != NULL && new_p == priv->address_provider) {
+ /* keep using the same provider */
+ return FALSE;
+ }
+
+ if (priv->address_provider && priv->signals[ADDRESS_CHANGED] > 0) {
+ g_signal_handler_disconnect (priv->address_provider,
+ priv->signals[ADDRESS_CHANGED]);
+ priv->signals[ADDRESS_CHANGED] = 0;
+ }
+
+ priv->address_provider = new_p;
+
+ if (priv->address_provider == NULL) {
+ g_debug ("client: address provider changed (to NULL)");
+ g_signal_emit (client, signals[ADDRESS_PROVIDER_CHANGED], 0,
+ NULL, NULL, NULL, NULL);
+ return TRUE;
+ }
+
+ g_debug ("client: address provider changed (to %s)", gc_master_provider_get_name (priv->address_provider));
+ g_signal_emit (client, signals[ADDRESS_PROVIDER_CHANGED], 0,
+ gc_master_provider_get_name (priv->address_provider),
+ gc_master_provider_get_description (priv->address_provider),
+ gc_master_provider_get_service (priv->address_provider),
+ gc_master_provider_get_path (priv->address_provider));
+ priv->signals[ADDRESS_CHANGED] =
+ g_signal_connect (G_OBJECT (priv->address_provider),
+ "address-changed",
+ G_CALLBACK (address_changed),
+ client);
+ return TRUE;
+}
+
+static void
+gc_master_provider_set_position_providers (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcInterfaceAccuracy *accuracy_data;
+
+ accuracy_data = g_new0(GcInterfaceAccuracy, 1);
+ accuracy_data->interface = GC_IFACE_POSITION;
+ accuracy_data->accuracy_level = priv->min_accuracy;
+
+ gc_master_client_connect_common_signals (client, providers);
+ priv->position_providers =
+ g_list_sort_with_data (providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+
+ g_free (accuracy_data);
+}
+
+static void
+gc_master_provider_set_address_providers (GcMasterClient *client,
+ GList *providers)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GcInterfaceAccuracy *accuracy_data;
+
+ accuracy_data = g_new0(GcInterfaceAccuracy, 1);
+ accuracy_data->interface = GC_IFACE_ADDRESS;
+ accuracy_data->accuracy_level = priv->min_accuracy;
+
+ gc_master_client_connect_common_signals (client, providers);
+ priv->address_providers =
+ g_list_sort_with_data (providers,
+ (GCompareDataFunc)gc_master_provider_compare,
+ accuracy_data);
+
+ g_free (accuracy_data);
+}
+
+static void
+gc_master_client_init_position_providers (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+ GList *providers;
+
+ if (!priv->position_started) {
+ return;
+ }
+
+ /* TODO: free priv->position_providers */
+
+ providers = gc_master_get_providers (GC_IFACE_POSITION,
+ priv->min_accuracy,
+ priv->require_updates,
+ priv->allowed_resources,
+ NULL);
+ g_debug ("client: %d position providers matching requirements found, now choosing current provider",
+ g_list_length (providers));
+
+ gc_master_provider_set_position_providers (client, providers);
+ gc_master_client_choose_position_provider (client, priv->position_providers);
+}
+static void
+gc_master_client_init_address_providers (GcMasterClient *client)
+{
+ GList *providers;
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (!priv->address_started) {
+ return;
+ }
+
+ /* TODO: free priv->address_providers */
+
+ providers = gc_master_get_providers (GC_IFACE_ADDRESS,
+ priv->min_accuracy,
+ priv->require_updates,
+ priv->allowed_resources,
+ NULL);
+ g_debug ("client: %d address providers matching requirements found, now choosing current provider",
+ g_list_length (providers));
+
+ gc_master_provider_set_address_providers (client, providers);
+ gc_master_client_choose_address_provider (client, priv->address_providers);
+}
+
+static gboolean
+gc_iface_master_client_set_requirements (GcMasterClient *client,
+ GeoclueAccuracyLevel min_accuracy,
+ int min_time,
+ gboolean require_updates,
+ GeoclueResourceFlags allowed_resources,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ priv->min_accuracy = min_accuracy;
+ priv->min_time = min_time;
+ priv->require_updates = require_updates;
+ priv->allowed_resources = allowed_resources;
+
+ gc_master_client_init_position_providers (client);
+ gc_master_client_init_address_providers (client);
+
+ return TRUE;
+}
+
+
+static gboolean
+gc_iface_master_client_position_start (GcMasterClient *client,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->position_providers) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED,
+ "Position interface already started");
+ }
+ return FALSE;
+ }
+
+ priv->position_started = TRUE;
+
+ gc_master_client_init_position_providers (client);
+
+ return TRUE;
+}
+
+static gboolean
+gc_iface_master_client_address_start (GcMasterClient *client,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->address_providers) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_FAILED,
+ "Address interface already started");
+ }
+ return FALSE;
+ }
+
+ priv->address_started = TRUE;
+ gc_master_client_init_address_providers (client);
+ return TRUE;
+}
+
+static void
+get_master_provider_details (GcMasterProvider *provider,
+ char **name,
+ char **description,
+ char **service,
+ char **path)
+{
+ if (name) {
+ if (!provider) {
+ *name = NULL;
+ } else {
+ *name = g_strdup (gc_master_provider_get_name (provider));
+ }
+ }
+ if (description) {
+ if (!provider) {
+ *description = NULL;
+ } else {
+ *description = g_strdup (gc_master_provider_get_description (provider));
+ }
+ }
+ if (service) {
+ if (!provider) {
+ *service = NULL;
+ } else {
+ *service = g_strdup (gc_master_provider_get_service (provider));
+ }
+ }
+ if (path) {
+ if (!provider) {
+ *path = NULL;
+ } else {
+ *path = g_strdup (gc_master_provider_get_path (provider));
+ }
+ }
+}
+
+
+static gboolean
+gc_iface_master_client_get_address_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ get_master_provider_details (priv->address_provider,
+ name, description, service, path);
+ return TRUE;
+}
+
+static gboolean
+gc_iface_master_client_get_position_provider (GcMasterClient *client,
+ char **name,
+ char **description,
+ char **service,
+ char **path,
+ GError **error)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ get_master_provider_details (priv->position_provider,
+ name, description, service, path);
+ return TRUE;
+}
+
+static void
+finalize (GObject *object)
+{
+ GcMasterClient *client = GC_MASTER_CLIENT (object);
+ GcMasterClientPrivate *priv = GET_PRIVATE (object);
+
+ /* do not free contents of the lists, Master takes care of them */
+ if (priv->position_providers) {
+ gc_master_client_unsubscribe_providers (client, priv->position_providers, GC_IFACE_ALL);
+ g_list_free (priv->position_providers);
+ priv->position_providers = NULL;
+ }
+ if (priv->address_providers) {
+ gc_master_client_unsubscribe_providers (client, priv->address_providers, GC_IFACE_ALL);
+ g_list_free (priv->address_providers);
+ priv->address_providers = NULL;
+ }
+
+ ((GObjectClass *) gc_master_client_parent_class)->finalize (object);
+}
+
+static void
+gc_master_client_class_init (GcMasterClientClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+
+ g_type_class_add_private (klass, sizeof (GcMasterClientPrivate));
+
+ signals[ADDRESS_PROVIDER_CHANGED] =
+ g_signal_new ("address-provider-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ signals[POSITION_PROVIDER_CHANGED] =
+ g_signal_new ("position-provider-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST, 0,
+ NULL, NULL,
+ geoclue_marshal_VOID__STRING_STRING_STRING_STRING,
+ G_TYPE_NONE, 4,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ dbus_g_object_type_install_info (gc_master_client_get_type (),
+ &dbus_glib_gc_iface_master_client_object_info);
+
+
+}
+
+static void
+gc_master_client_init (GcMasterClient *client)
+{
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ priv->position_provider_choice_in_progress = FALSE;
+ priv->address_provider_choice_in_progress = FALSE;
+
+ priv->position_started = FALSE;
+ priv->position_provider = NULL;
+ priv->position_providers = NULL;
+
+ priv->address_started = FALSE;
+ priv->address_provider = NULL;
+ priv->address_providers = NULL;
+}
+
+static gboolean
+get_position (GcIfacePosition *iface,
+ GeocluePositionFields *fields,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterClient *client = GC_MASTER_CLIENT (iface);
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->position_provider == NULL) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Geoclue master client has no usable Position providers");
+ }
+ return FALSE;
+ }
+
+ *fields = gc_master_provider_get_position
+ (priv->position_provider,
+ timestamp,
+ latitude, longitude, altitude,
+ accuracy,
+ error);
+ return (!*error);
+}
+
+static gboolean
+get_address (GcIfaceAddress *iface,
+ int *timestamp,
+ GHashTable **address,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterClient *client = GC_MASTER_CLIENT (iface);
+ GcMasterClientPrivate *priv = GET_PRIVATE (client);
+
+ if (priv->address_provider == NULL) {
+ if (error) {
+ *error = g_error_new (GEOCLUE_ERROR,
+ GEOCLUE_ERROR_NOT_AVAILABLE,
+ "Geoclue master client has no usable Address providers");
+ }
+ return FALSE;
+ }
+
+ return gc_master_provider_get_address
+ (priv->address_provider,
+ timestamp,
+ address,
+ accuracy,
+ error);
+}
+
+static gboolean
+get_status (GcIfaceGeoclue *geoclue,
+ GeoclueStatus *status,
+ GError **error)
+{
+ /* not really meaningful */
+ *status = GEOCLUE_STATUS_AVAILABLE;
+ return TRUE;
+}
+
+static gboolean
+set_options (GcIfaceGeoclue *geoclue,
+ GHashTable *options,
+ GError **error)
+{
+ /* not meaningful, options come from master */
+
+ /* It is not an error to not have a SetOptions implementation */
+ return TRUE;
+}
+
+static gboolean
+get_provider_info (GcIfaceGeoclue *geoclue,
+ gchar **name,
+ gchar **description,
+ GError **error)
+{
+ if (name) {
+ *name = g_strdup ("Geoclue Master");
+ }
+ if (description) {
+ *description = g_strdup ("Meta-provider that internally uses what ever provider is the best ");
+ }
+ return TRUE;
+}
+
+static void
+add_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ /* TODO implement if needed */
+ dbus_g_method_return (context);
+}
+
+static void
+remove_reference (GcIfaceGeoclue *geoclue,
+ DBusGMethodInvocation *context)
+{
+ /* TODO implement if needed */
+ dbus_g_method_return (context);
+}
+
+static void
+gc_master_client_geoclue_init (GcIfaceGeoclueClass *iface)
+{
+ iface->get_provider_info = get_provider_info;
+ iface->get_status = get_status;
+ iface->set_options = set_options;
+ iface->add_reference = add_reference;
+ iface->remove_reference = remove_reference;
+}
+
+static void
+gc_master_client_position_init (GcIfacePositionClass *iface)
+{
+ iface->get_position = get_position;
+}
+
+static void
+gc_master_client_address_init (GcIfaceAddressClass *iface)
+{
+ iface->get_address = get_address;
+}
diff --git a/.pc/tizen.patch/src/connectivity-connman.c b/.pc/tizen.patch/src/connectivity-connman.c
new file mode 100755
index 0000000..42ccce0
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity-connman.c
@@ -0,0 +1,739 @@
+/*
+ * Geoclue
+ * connectivity-connman.c
+ *
+ * Author: Javier Fernandez <jfernandez@igalia.com>
+ * Copyright (C) 2010 Igalia S.L
+ *
+ * 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>
+
+#ifdef HAVE_CONNMAN
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+#include "connectivity-connman.h"
+
+#define CONNMAN_SERVICE "org.moblin.connman"
+#define CONNMAN_MANAGER_PATH "/"
+#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
+#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
+#define CONNMAN_DEVICE_INTERFACE CONNMAN_SERVICE ".Device"
+#define CONNMAN_NETWORK_INTERFACE CONNMAN_SERVICE ".Network"
+#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
+
+typedef void (*ConnmanFunc) (GeoclueConnman *self,
+ const gchar *path,
+ gpointer out);
+
+static void geoclue_connman_connectivity_init (GeoclueConnectivityInterface *iface);
+
+static int _strength_to_dbm (int strength);
+static char *_get_mac_for_gateway (const char *gateway);
+static char *_mac_strup (char *mac);
+static gchar *_get_gateway (GeoclueConnman *self, const gchar *service);
+static void _get_best_ap (GeoclueConnman *self, const gchar *network);
+static void _get_aps_info (GeoclueConnman *self, const gchar *network, GHashTable **out);
+static const GPtrArray *_get_technologies (GeoclueConnman *self, GHashTable **props);
+static const GPtrArray *_get_services (GeoclueConnman *self, GHashTable **props);
+static const GPtrArray *_get_devices (GeoclueConnman *self, GHashTable **props, const gchar *technology);
+static const GPtrArray *_get_networks (GeoclueConnman *self, GHashTable **props, const gchar *device, const gchar *type_filter);
+static void _explore_available_aps (GeoclueConnman *self, ConnmanFunc func, gpointer out);
+
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueConnman, geoclue_connman, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GEOCLUE_TYPE_CONNECTIVITY,
+ geoclue_connman_connectivity_init))
+
+
+/* GeoclueConnectivity iface methods */
+static int
+_get_status (GeoclueConnectivity *iface)
+{
+ GeoclueConnman *connman = GEOCLUE_CONNMAN (iface);
+
+ return connman->status;
+}
+
+static char *
+_get_ap_mac (GeoclueConnectivity *iface)
+{
+ GeoclueConnman *connman = GEOCLUE_CONNMAN (iface);
+
+ return g_strdup (connman->cache_ap_mac);
+}
+
+static GHashTable *
+_get_aps (GeoclueConnectivity *iface)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (iface);
+ GHashTable *ht = NULL;
+
+ /* Explore the active networks to collect the APs. */
+ _explore_available_aps (self, (ConnmanFunc) _get_aps_info, &ht);
+
+ return ht;
+}
+
+static char *
+_get_router_mac (GeoclueConnectivity *iface)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (iface);
+ GHashTable *props = NULL;
+ const GPtrArray *servs = NULL;
+ const gchar *serv = NULL;
+ gchar *gateway = NULL;
+ char *mac = NULL;
+ guint i;
+
+ /* Get available services and iterate over them */
+ /* to get the MAC of the connected router. */
+ servs = _get_services (self, &props);
+ if (servs != NULL) {
+ for (i = 0; gateway == NULL && servs->len; i++) {
+ serv = g_ptr_array_index (servs, i);
+ gateway = _get_gateway (self, serv);
+ }
+ }
+
+ /* Check the result. */
+ if (gateway != NULL) {
+ mac = _get_mac_for_gateway (gateway);
+ g_free (gateway);
+ }
+
+ /* Free */
+ g_hash_table_destroy (props);
+
+ return mac;
+}
+
+/* internal private GObject methods */
+static void
+dispose (GObject *object)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (object);
+
+ g_object_unref (self->client);
+ self->client = NULL;
+
+ dbus_g_connection_unref (self->conn);
+ self->conn = NULL;
+
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+
+ ((GObjectClass *) geoclue_connman_parent_class)->dispose (object);
+}
+
+static void
+geoclue_connman_class_init (GeoclueConnmanClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->dispose = dispose;
+}
+
+static int
+_strength_to_dbm (int strength)
+{
+ /* Hackish linear strength to dBm conversion.
+ * 0% is -90 dBm
+ * 100% is -20 dBm */
+ return (strength * 0.7) - 90;
+}
+
+static char *
+_get_mac_for_gateway (const char *gateway)
+{
+ char *cmd, *out, *mac, **split;
+
+ cmd = g_strdup_printf ("ip neigh show %s", gateway);
+
+ if (g_spawn_command_line_sync (cmd, &out, NULL, NULL, NULL) == FALSE) {
+ g_free (out);
+ g_free (cmd);
+ return NULL;
+ }
+ g_free (cmd);
+
+ /* 192.168.1.1 dev eth0 lladdr 00:00:00:00:00:00 STALE */
+ split = g_strsplit (out, " ", -1);
+ g_free (out);
+
+ if (split == NULL)
+ return NULL;
+ if (g_strv_length (split) != 6) {
+ g_strfreev (split);
+ return NULL;
+ }
+ mac = g_strdup (split[4]);
+ g_strfreev (split);
+
+ return _mac_strup (mac);
+}
+
+static char *
+_mac_strup (char *mac)
+{
+ guint i;
+
+ g_assert (mac != NULL);
+
+ for (i = 0; mac[i] != '\0' ; i++) {
+ if (g_ascii_isalpha (mac[i]))
+ mac[i] = g_ascii_toupper (mac[i]);
+ }
+ return mac;
+}
+
+static GeoclueNetworkStatus
+connmanstatus_to_geocluenetworkstatus (const gchar *status)
+{
+ if (g_strcmp0 (status, "online")) {
+ return GEOCLUE_CONNECTIVITY_OFFLINE;
+ } else {
+ return GEOCLUE_CONNECTIVITY_ONLINE;
+ }
+}
+
+static gchar *
+_get_gateway (GeoclueConnman *self,
+ const gchar *service)
+{
+ DBusGProxy *proxy = NULL;
+ GHashTable *props = NULL;
+ gchar *gateway = NULL;
+ const GHashTable *ht = NULL;
+ const GValue *value = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ service,
+ CONNMAN_SERVICE_INTERFACE);
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Service iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return NULL;
+ }
+
+ /* Get Service properties to get the gateway address. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ &props,
+ G_TYPE_INVALID)) {
+
+ /* Get the mac of the connected router. */
+ value = g_hash_table_lookup (props, "IPv4");
+ if (value != NULL) {
+ ht = g_value_get_boxed (value);
+ value = g_hash_table_lookup ((GHashTable *) ht, "Gateway");
+ if (value != NULL) {
+ gateway = g_value_dup_string (value);
+ }
+ }
+ } else {
+ msg = "Error getting Service properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_hash_table_destroy (props);
+ g_object_unref (proxy);
+
+ return gateway;
+}
+
+static void
+_get_aps_info (GeoclueConnman *self,
+ const gchar *network,
+ GHashTable **out)
+{
+ DBusGProxy *proxy = NULL;
+ GHashTable *props = NULL;
+ gchar *ap_mac = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+ int strength;
+
+ g_assert (out != NULL);
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ network,
+ CONNMAN_NETWORK_INTERFACE);
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Network iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return;
+ }
+
+ /* Collect available APs into a HasTable. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ &props,
+ G_TYPE_INVALID)) {
+
+ /* Store the AP information. */
+ ap_mac = g_value_dup_string (g_hash_table_lookup (props, "Address"));
+ strength = g_value_get_uchar (g_hash_table_lookup (props, "Strength"));
+ if (ap_mac != NULL) {
+ /* Create storage for the first case. */
+ if (*out == NULL) {
+ *out = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, NULL);
+ }
+ g_hash_table_insert (*out, ap_mac,
+ GINT_TO_POINTER (_strength_to_dbm (strength)));
+ }
+ } else {
+ msg = "Error getting Network properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_hash_table_destroy (props);
+ g_object_unref (proxy);
+}
+
+static void
+_get_best_ap (GeoclueConnman *self,
+ const gchar *network)
+{
+ DBusGProxy *proxy = NULL;
+ GHashTable *props = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+ int strength;
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ network,
+ CONNMAN_NETWORK_INTERFACE);
+
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Network iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return;
+ }
+
+ /* Evaluate Network properties and update best AP. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ &props,
+ G_TYPE_INVALID)) {
+
+ strength = g_value_get_uchar (g_hash_table_lookup (props, "Strength"));
+ if (strength > self->ap_strength) {
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = g_value_dup_string (g_hash_table_lookup (props, "Address"));
+ self->ap_strength = strength;
+ }
+ } else {
+ msg = "Error getting Network properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_hash_table_destroy (props);
+ g_object_unref (proxy);
+}
+
+static const GPtrArray *
+_get_networks (GeoclueConnman *self,
+ GHashTable **props,
+ const gchar *device,
+ const gchar *type_filter)
+{
+ DBusGProxy *proxy = NULL;
+ const GPtrArray *nets = NULL;
+ const GValue *value = NULL;
+ const gchar *type = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ device,
+ CONNMAN_DEVICE_INTERFACE);
+
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Device iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return NULL;
+ }
+
+ /* Get available Networks for a specific Device. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ props,
+ G_TYPE_INVALID)) {
+
+ /* Check only specific networks. */
+ if (type_filter != NULL) {
+ type = g_value_get_string (g_hash_table_lookup (*props, "Type"));
+ if (g_strcmp0 (type, type_filter)) {
+ goto frees;
+ }
+ }
+ value = g_hash_table_lookup (*props, "Networks");
+ nets = g_value_get_boxed (value);
+ } else {
+ msg = "Error getting Device properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ frees:
+ g_object_unref (proxy);
+
+ return nets;
+}
+
+static const GPtrArray *
+_get_devices (GeoclueConnman *self,
+ GHashTable **props,
+ const gchar *technology)
+{
+ DBusGProxy *proxy = NULL;
+ const GPtrArray *devs = NULL;
+ const GValue *value = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Create proxy. */
+ proxy = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ technology,
+ CONNMAN_TECHNOLOGY_INTERFACE);
+
+ if (proxy == NULL) {
+ g_warning ("%s was unable to create connection to Technology iface.",
+ G_OBJECT_TYPE_NAME (self));
+ return NULL;
+ }
+
+ /* Get available Devices for a specific Technology. */
+ if (dbus_g_proxy_call (proxy, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ props,
+ G_TYPE_INVALID)) {
+
+ value = g_hash_table_lookup (*props, "Devices");
+ devs = g_value_get_boxed (value);
+ } else {
+ msg = "Error getting Technologies properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_object_unref (proxy);
+
+ return devs;
+}
+
+static const GPtrArray *
+_get_technologies (GeoclueConnman *self,
+ GHashTable **props)
+{
+ const GPtrArray *techs = NULL;
+ const GValue *value = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Get available technologies (Wifi, Eth, ...). */
+ if (dbus_g_proxy_call (self->client, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ props,
+ G_TYPE_INVALID)) {
+
+ value = g_hash_table_lookup (*props, "Technologies");
+ techs = g_value_get_boxed (value);
+ } else {
+ msg = "Error getting Manager properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ return techs;
+}
+
+static const GPtrArray *
+_get_services (GeoclueConnman *self,
+ GHashTable **props)
+{
+ const GPtrArray *servs = NULL;
+ const GValue *value = NULL;
+ const gchar *msg = NULL;
+ GError *error = NULL;
+
+ /* Get available services. */
+ if (dbus_g_proxy_call (self->client, "GetProperties",
+ &error,
+ G_TYPE_INVALID,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ props,
+ G_TYPE_INVALID)) {
+
+ value = g_hash_table_lookup (*props, "Services");
+ servs = g_value_get_boxed (value);
+ } else {
+ msg = "Error getting Manager properties: %s";
+ if (error != NULL) {
+ g_warning (msg, error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, "Unknown error");
+ }
+ }
+
+ return servs;
+}
+
+static void
+_explore_available_aps (GeoclueConnman *self,
+ ConnmanFunc func,
+ gpointer out)
+{
+ GHashTable *mgr_props = NULL;
+ GHashTable *tech_props = NULL;
+ GHashTable *dev_props = NULL;
+ const GPtrArray *techs = NULL;
+ const GPtrArray *devs = NULL;
+ const GPtrArray *nets = NULL;
+ const gchar *tech = NULL;
+ const gchar *dev = NULL;
+ const gchar *net = NULL;
+ guint i, j, k;
+
+ techs = _get_technologies (self, &mgr_props);
+ if (techs == NULL) {
+ goto frees;
+ }
+ for (i = 0; i < techs->len; i++) {
+ tech = g_ptr_array_index (techs, i);
+ devs = _get_devices (self, &tech_props, tech);
+ if (devs == NULL) {
+ continue;
+ }
+ for (j = 0; j < devs->len; j++) {
+ dev = g_ptr_array_index (devs, j);
+ nets = _get_networks (self, &dev_props, dev, "wifi");
+ if (nets == NULL) {
+ continue;
+ }
+ for (k = 0; k < nets->len; k++) {
+ net = g_ptr_array_index (nets, k);
+
+ /* Perform specific actions. */
+ func (self, net, out);
+ }
+ }
+ }
+
+ /* Free */
+ frees:
+ if (mgr_props != NULL) {
+ g_hash_table_destroy (mgr_props);
+ }
+ if (tech_props != NULL) {
+ g_hash_table_destroy (tech_props);
+ }
+ if (dev_props != NULL) {
+ g_hash_table_destroy (dev_props);
+ }
+}
+
+static void
+_cache_ap_mac (GeoclueConnman *self)
+{
+ /* Cleanup the cache. */
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+ self->ap_strength = 0;
+
+ /* Explore the active networks to get the best AP. */
+ _explore_available_aps (self, (ConnmanFunc) _get_best_ap, NULL);
+}
+
+
+
+static void
+_geoclue_connman_state_changed (DBusGProxy *proxy,
+ const gchar *status,
+ gpointer userdata)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (userdata);
+ GeoclueNetworkStatus gc_status;
+
+ gc_status = connmanstatus_to_geocluenetworkstatus (status);
+
+ if (gc_status != self->status) {
+ /* Update status. */
+ self->status = gc_status;
+
+ /* Update AP cache. */
+ _cache_ap_mac (self);
+
+ /* Notification. */
+ geoclue_connectivity_emit_status_changed (GEOCLUE_CONNECTIVITY (self),
+ self->status);
+ }
+}
+
+
+static void
+_method_call_notify_cb (DBusGProxy *proxy,
+ DBusGProxyCall *call,
+ gpointer user_data)
+{
+ GeoclueConnman *self = GEOCLUE_CONNMAN (user_data);
+ const gchar *msg = NULL;
+ GError *error = NULL;
+ gchar *state = NULL;
+
+ /* Collect output data. */
+ if (dbus_g_proxy_end_call (proxy,
+ call,
+ &error,
+ G_TYPE_STRING,
+ &state,
+ G_TYPE_INVALID)) {
+
+ /* Set current status. */
+ _geoclue_connman_state_changed (proxy,
+ (const gchar *) state,
+ self);
+ } else {
+ msg = "%s was unable to get the current network status: %s.";
+ if (error != NULL) {
+ g_warning (msg, G_OBJECT_TYPE_NAME (self),
+ error->message);
+ g_error_free (error);
+ } else {
+ g_warning (msg, G_OBJECT_TYPE_NAME (self),
+ "Unknown error");
+ }
+ }
+
+ /* Free */
+ g_free (state);
+}
+
+static void
+geoclue_connman_init (GeoclueConnman *self)
+{
+ GError *error = NULL;
+
+ /* Get DBus connection to the System bus. */
+ self->conn = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+ if (self->conn == NULL) {
+ g_warning ("%s was unable to create a connection to D-Bus: %s",
+ G_OBJECT_TYPE_NAME (self), error->message);
+ g_error_free (error);
+ return;
+ }
+
+ /* Create proxy. */
+ self->client = dbus_g_proxy_new_for_name (self->conn,
+ CONNMAN_SERVICE,
+ CONNMAN_MANAGER_PATH,
+ CONNMAN_MANAGER_INTERFACE);
+
+ if (self->client == NULL) {
+ g_warning ("%s was unable to create connection to Connman Manager.",
+ G_OBJECT_TYPE_NAME (self));
+ return;
+ }
+
+ /* Get current state (async). */
+ dbus_g_proxy_begin_call (self->client, "GetState",
+ _method_call_notify_cb,
+ self,
+ NULL,
+ G_TYPE_INVALID,
+ G_TYPE_STRING);
+
+ /* Be aware of State changes. */
+ dbus_g_proxy_add_signal (self->client, "StateChanged",
+ G_TYPE_STRING, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (self->client,
+ "StateChanged",
+ G_CALLBACK (_geoclue_connman_state_changed),
+ self,
+ NULL);
+}
+
+
+static void
+geoclue_connman_connectivity_init (GeoclueConnectivityInterface *iface)
+{
+ iface->get_status = _get_status;
+ iface->get_ap_mac = _get_ap_mac;
+ iface->get_router_mac = _get_router_mac;
+ iface->get_aps = _get_aps;
+}
+
+#endif /* HAVE_CONNMAN*/
diff --git a/.pc/tizen.patch/src/connectivity-connman.h b/.pc/tizen.patch/src/connectivity-connman.h
new file mode 100755
index 0000000..24c5907
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity-connman.h
@@ -0,0 +1,56 @@
+/*
+ * Geoclue
+ * connectivity-connman.h
+ *
+ * Author: Javier Fernandez <jfernandez@igalia.com>
+ * Copyright (C) 2010 Igalia S.L
+ *
+ * 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.
+ *
+ */
+
+#ifndef _CONNECTIVITY_CONNMAN_H
+#define _CONNECTIVITY_CONNMAN_H
+
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include "connectivity.h"
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_CONNMAN (geoclue_connman_get_type ())
+#define GEOCLUE_CONNMAN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_CONNMAN, GeoclueConnman))
+
+typedef struct {
+ GObject parent;
+
+ /* private */
+ GeoclueNetworkStatus status;
+ DBusGConnection *conn;
+ DBusGProxy *client;
+ gchar *cache_ap_mac;
+ int ap_strength;
+} GeoclueConnman;
+
+typedef struct {
+ GObjectClass parent_class;
+} GeoclueConnmanClass;
+
+GType geoclue_connman_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/.pc/tizen.patch/src/connectivity-networkmanager.c b/.pc/tizen.patch/src/connectivity-networkmanager.c
new file mode 100755
index 0000000..09630a0
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity-networkmanager.c
@@ -0,0 +1,369 @@
+/*
+ * Geoclue
+ * geoclue-networkmanager.c
+ *
+ * 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.
+ *
+ */
+#include <config.h>
+
+#ifdef HAVE_NETWORK_MANAGER
+
+
+#include <dbus/dbus-glib.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <NetworkManager.h> /*for DBus strings */
+
+#include <nm-client.h>
+#include <nm-device-wifi.h>
+#include <nm-setting-ip4-config.h>
+
+#if !defined(NM_CHECK_VERSION)
+#define NM_CHECK_VERSION(x,y,z) 0
+#endif
+
+#include "connectivity-networkmanager.h"
+
+static void geoclue_networkmanager_connectivity_init (GeoclueConnectivityInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GeoclueNetworkManager, geoclue_networkmanager, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GEOCLUE_TYPE_CONNECTIVITY,
+ geoclue_networkmanager_connectivity_init))
+
+
+/* GeoclueConnectivity iface method */
+static int
+get_status (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *nm = GEOCLUE_NETWORKMANAGER (iface);
+
+ return nm->status;
+}
+
+static char *
+get_ap_mac (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (iface);
+
+ return g_strdup (self->cache_ap_mac);
+}
+
+static int
+strength_to_dbm (int strength)
+{
+ /* Hackish linear strength to dBm conversion.
+ * 0% is -90 dBm
+ * 100% is -20 dBm */
+ return (strength * 0.7) - 90;
+}
+
+static GHashTable *
+get_aps (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (iface);
+ const GPtrArray *devices;
+ GHashTable *ht;
+ guint i;
+
+ devices = nm_client_get_devices (self->client);
+ if (devices == NULL)
+ return NULL;
+
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, NULL);
+
+ for (i = 0; i < devices->len; i++) {
+ NMDevice *device = g_ptr_array_index (devices, i);
+ if (NM_IS_DEVICE_WIFI (device)) {
+ const GPtrArray *aps;
+ guint j;
+
+ aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
+ if (aps == NULL || aps->len == 0)
+ continue;
+ for (j = 0; j < aps->len; j++) {
+ NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, j));
+ char *ap_mac;
+ int strength;
+
+ ap_mac = g_strdup (nm_access_point_get_hw_address (ap));
+ strength = nm_access_point_get_strength (ap);
+ g_hash_table_insert (ht, ap_mac, GINT_TO_POINTER (strength_to_dbm (strength)));
+ }
+ }
+ }
+ if (g_hash_table_size (ht) == 0) {
+ g_hash_table_destroy (ht);
+ return NULL;
+ }
+
+ return ht;
+}
+
+static char *
+mac_strup (char *mac)
+{
+ guint i;
+ for (i = 0; mac[i] != '\0' ; i++) {
+ if (g_ascii_isalpha (mac[i]))
+ mac[i] = g_ascii_toupper (mac[i]);
+ }
+ return mac;
+}
+
+static char *
+get_mac_for_gateway (const char *gateway)
+{
+ char *cmd, *out, *mac, **split;
+
+ cmd = g_strdup_printf ("ip neigh show %s", gateway);
+
+ if (g_spawn_command_line_sync (cmd, &out, NULL, NULL, NULL) == FALSE) {
+ g_free (out);
+ g_free (cmd);
+ return NULL;
+ }
+ g_free (cmd);
+
+ /* 192.168.1.1 dev eth0 lladdr 00:00:00:00:00:00 STALE */
+ split = g_strsplit (out, " ", -1);
+ g_free (out);
+
+ if (split == NULL)
+ return NULL;
+ if (g_strv_length (split) != 6) {
+ g_strfreev (split);
+ return NULL;
+ }
+ mac = g_strdup (split[4]);
+ g_strfreev (split);
+
+ return mac_strup (mac);
+}
+
+static gchar *
+ip4_address_as_string (guint32 ip)
+{
+ struct in_addr tmp_addr;
+ char buf[INET_ADDRSTRLEN+1];
+
+ memset (&buf, '\0', sizeof (buf));
+ tmp_addr.s_addr = ip;
+
+ if (inet_ntop (AF_INET, &tmp_addr, buf, INET_ADDRSTRLEN))
+ return g_strdup (buf);
+
+ return NULL;
+}
+
+static char *
+get_router_mac (GeoclueConnectivity *iface)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (iface);
+ const GPtrArray *devices;
+ char *gateway, *mac;
+ guint i;
+
+ devices = nm_client_get_devices (self->client);
+ if (devices == NULL)
+ return NULL;
+
+ gateway = NULL;
+
+ for (i = 0; i < devices->len; i++) {
+ NMDevice *device = g_ptr_array_index (devices, i);
+ NMIP4Config *cfg4;
+ GSList *iter;
+
+ if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED)
+ continue;
+
+ cfg4 = nm_device_get_ip4_config (device);
+ if (cfg4 == NULL)
+ continue;
+
+ for (iter = (GSList *) nm_ip4_config_get_addresses (cfg4); iter; iter = g_slist_next (iter)) {
+ NMIP4Address *addr = (NMIP4Address *) iter->data;
+
+ gateway = ip4_address_as_string (nm_ip4_address_get_gateway (addr));
+ if (gateway != NULL)
+ break;
+ }
+ }
+ if (gateway == NULL)
+ return NULL;
+
+ mac = get_mac_for_gateway (gateway);
+ g_free (gateway);
+
+ return mac;
+}
+
+static void
+get_best_ap (GeoclueNetworkManager *self, NMDevice *device)
+{
+ const GPtrArray *aps;
+ guint i;
+
+ aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device));
+ if (aps == NULL || aps->len == 0)
+ return;
+ for (i = 0; i < aps->len; i++) {
+ NMAccessPoint *ap = NM_ACCESS_POINT (g_ptr_array_index (aps, i));
+ int strength;
+
+ strength = nm_access_point_get_strength (ap);
+ if (strength > self->ap_strength) {
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = g_strdup (nm_access_point_get_hw_address (ap));
+ self->ap_strength = strength;
+ }
+ }
+}
+
+static void
+cache_ap_mac (GeoclueNetworkManager *self)
+{
+ const GPtrArray *devices;
+ guint i;
+
+ devices = nm_client_get_devices (self->client);
+
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+ self->ap_strength = 0;
+
+ for (i = 0; devices != NULL && i < devices->len; i++) {
+ NMDevice *device = g_ptr_array_index (devices, i);
+ if (NM_IS_DEVICE_WIFI (device)) {
+ get_best_ap (self, device);
+ }
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (object);
+
+ g_free (self->cache_ap_mac);
+ self->cache_ap_mac = NULL;
+ g_object_unref (self->client);
+ self->client = NULL;
+ ((GObjectClass *) geoclue_networkmanager_parent_class)->dispose (object);
+}
+
+static void
+geoclue_networkmanager_class_init (GeoclueNetworkManagerClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->dispose = dispose;
+}
+
+static GeoclueNetworkStatus
+nmstate_to_geocluenetworkstatus (NMState status)
+{
+ switch (status) {
+ case NM_STATE_UNKNOWN:
+ return GEOCLUE_CONNECTIVITY_UNKNOWN;
+ case NM_STATE_ASLEEP:
+ case NM_STATE_DISCONNECTED:
+#if NM_CHECK_VERSION(0,8,992)
+ case NM_STATE_DISCONNECTING:
+#endif
+ return GEOCLUE_CONNECTIVITY_OFFLINE;
+ case NM_STATE_CONNECTING:
+ return GEOCLUE_CONNECTIVITY_ACQUIRING;
+#if NM_CHECK_VERSION(0,8,992)
+ case NM_STATE_CONNECTED_LOCAL:
+ case NM_STATE_CONNECTED_SITE:
+ case NM_STATE_CONNECTED_GLOBAL:
+#else
+ case NM_STATE_CONNECTED:
+#endif
+ return GEOCLUE_CONNECTIVITY_ONLINE;
+ default:
+ g_warning ("Unknown NMStatus: %d", status);
+ return GEOCLUE_CONNECTIVITY_UNKNOWN;
+ }
+}
+
+static void
+update_status (GeoclueNetworkManager *self, gboolean do_signal)
+{
+ GeoclueNetworkStatus old_status;
+ NMState state;
+
+ old_status = self->status;
+
+ if (nm_client_get_manager_running (self->client)) {
+ state = nm_client_get_state (self->client);
+ self->status = nmstate_to_geocluenetworkstatus (state);
+ cache_ap_mac (self);
+ } else {
+ self->status = GEOCLUE_CONNECTIVITY_OFFLINE;
+ }
+
+ if ((self->status != old_status) && do_signal) {
+ geoclue_connectivity_emit_status_changed (GEOCLUE_CONNECTIVITY (self),
+ self->status);
+ }
+}
+
+static void
+nm_update_status_cb (GObject *obj, GParamSpec *spec, gpointer userdata)
+{
+ update_status (GEOCLUE_NETWORKMANAGER (userdata), TRUE);
+}
+
+static void
+geoclue_networkmanager_init (GeoclueNetworkManager *self)
+{
+ self->status = GEOCLUE_CONNECTIVITY_UNKNOWN;
+ self->client = nm_client_new ();
+ if (self->client == NULL) {
+ g_warning ("%s was unable to create a connection to NetworkManager",
+ G_OBJECT_TYPE_NAME (self));
+ return;
+ }
+
+ g_signal_connect (G_OBJECT (self->client), "notify::running",
+ G_CALLBACK (nm_update_status_cb), self);
+ g_signal_connect (G_OBJECT (self->client), "notify::state",
+ G_CALLBACK (nm_update_status_cb), self);
+
+ /* get initial status */
+ update_status (self, FALSE);
+}
+
+static void
+geoclue_networkmanager_connectivity_init (GeoclueConnectivityInterface *iface)
+{
+ iface->get_status = get_status;
+ iface->get_ap_mac = get_ap_mac;
+ iface->get_router_mac = get_router_mac;
+ iface->get_aps = get_aps;
+}
+
+#endif /* HAVE_NETWORK_MANAGER */
diff --git a/.pc/tizen.patch/src/connectivity-networkmanager.h b/.pc/tizen.patch/src/connectivity-networkmanager.h
new file mode 100755
index 0000000..d2e5cae
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity-networkmanager.h
@@ -0,0 +1,56 @@
+/*
+ * Geoclue
+ * connectivity-networkmanager.h
+ *
+ * Author: 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.
+ *
+ */
+
+#ifndef _CONNECTIVITY_NETWORKMANAGER_H
+#define _CONNECTIVITY_NETWORKMANAGER_H
+
+#include <glib-object.h>
+#include <nm-client.h>
+#include "connectivity.h"
+
+
+G_BEGIN_DECLS
+
+#define GEOCLUE_TYPE_NETWORKMANAGER (geoclue_networkmanager_get_type ())
+#define GEOCLUE_NETWORKMANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_NETWORKMANAGER, GeoclueNetworkManager))
+
+typedef struct {
+ GObject parent;
+
+ /* private */
+ GeoclueNetworkStatus status;
+ NMClient *client;
+ char *cache_ap_mac;
+ int ap_strength;
+} GeoclueNetworkManager;
+
+typedef struct {
+ GObjectClass parent_class;
+} GeoclueNetworkManagerClass;
+
+GType geoclue_networkmanager_get_type (void);
+
+G_END_DECLS
+
+#endif
diff --git a/.pc/tizen.patch/src/connectivity.c b/.pc/tizen.patch/src/connectivity.c
new file mode 100755
index 0000000..96d83ab
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity.c
@@ -0,0 +1,276 @@
+/*
+ * Geoclue
+ * geoclue-connectivity.c
+ *
+ * Author: 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.
+ *
+ */
+#include <config.h>
+
+#include <glib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "connectivity.h"
+
+#ifdef HAVE_NETWORK_MANAGER
+#include "connectivity-networkmanager.h"
+#else
+#ifdef HAVE_CONIC
+#include "connectivity-conic.h"
+#else
+#ifdef HAVE_CONNMAN
+#include "connectivity-connman.h"
+#endif
+#endif
+#endif
+
+#define DEFAULT_DBM -50
+
+enum {
+ STATUS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0};
+
+static void
+geoclue_connectivity_base_init (gpointer klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized) {
+ return;
+ }
+
+ initialized = TRUE;
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_OBJECT_CLASS_TYPE (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GeoclueConnectivityInterface,
+ status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
+}
+
+GType
+geoclue_connectivity_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ const GTypeInfo info = {
+ sizeof (GeoclueConnectivityInterface),
+ geoclue_connectivity_base_init,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GeoclueConnectivity",
+ &info, 0);
+ }
+
+ return type;
+}
+
+GeoclueConnectivity *
+geoclue_connectivity_new (void)
+{
+ GeoclueConnectivity *connectivity = NULL;
+
+#ifdef HAVE_NETWORK_MANAGER
+ connectivity = GEOCLUE_CONNECTIVITY (g_object_new (GEOCLUE_TYPE_NETWORKMANAGER, NULL));
+#else
+#ifdef HAVE_CONIC
+ connectivity = GEOCLUE_CONNECTIVITY (g_object_new (GEOCLUE_TYPE_CONIC, NULL));
+#else
+#ifdef HAVE_CONNMAN
+ connectivity = GEOCLUE_CONNECTIVITY (g_object_new (GEOCLUE_TYPE_CONNMAN, NULL));
+#endif
+#endif
+#endif
+ return connectivity;
+}
+
+GeoclueNetworkStatus
+geoclue_connectivity_get_status (GeoclueConnectivity *self)
+{
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_status (self);
+}
+
+/* Parse /proc/net/route to get default gateway address and then parse
+ * /proc/net/arp to find matching mac address.
+ *
+ * There are some problems with this. First, it's IPv4 only.
+ * Second, there must be a way to do this with ioctl, but that seemed really
+ * complicated... even /usr/sbin/arp parses /proc/net/arp
+ *
+ * returns:
+ * 1 : on success
+ * 0 : no success, no errors
+ * <0 : error
+ */
+static int
+get_router_mac_fallback (char **mac)
+{
+ char *content;
+ char **lines, **entry;
+ GError *error = NULL;
+ char *route_gateway = NULL;
+
+ g_assert (*mac == NULL);
+
+ if (!g_file_get_contents ("/proc/net/route", &content, NULL, &error)) {
+ g_warning ("Failed to read /proc/net/route: %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ lines = g_strsplit (content, "\n", 0);
+ g_free (content);
+ entry = lines + 1;
+
+ while (*entry && strlen (*entry) > 0) {
+ char dest[9];
+ char gateway[9];
+ if (sscanf (*entry,
+ "%*s %8[0-9A-Fa-f] %8[0-9A-Fa-f] %*s",
+ dest, gateway) != 2) {
+ g_warning ("Failed to parse /proc/net/route entry '%s'", *entry);
+ } else if (strcmp (dest, "00000000") == 0) {
+ route_gateway = g_strdup (gateway);
+ break;
+ }
+ entry++;
+ }
+ g_strfreev (lines);
+
+ if (!route_gateway) {
+ g_warning ("Failed to find default route in /proc/net/route");
+ return -1;
+ }
+
+ if (!g_file_get_contents ("/proc/net/arp", &content, NULL, &error)) {
+ g_warning ("Failed to read /proc/net/arp: %s", error->message);
+ g_error_free (error);
+ return -1;
+ }
+
+ lines = g_strsplit (content, "\n", 0);
+ g_free (content);
+ entry = lines+1;
+ while (*entry && strlen (*entry) > 0) {
+ char hwa[100];
+ char *arp_gateway;
+ int ip[4];
+
+ if (sscanf(*entry,
+ "%d.%d.%d.%d 0x%*x 0x%*x %100s %*s %*s\n",
+ &ip[0], &ip[1], &ip[2], &ip[3], hwa) != 5) {
+ g_warning ("Failed to parse /proc/net/arp entry '%s'", *entry);
+ } else {
+ arp_gateway = g_strdup_printf ("%02X%02X%02X%02X", ip[3], ip[2], ip[1], ip[0]);
+ if (strcmp (arp_gateway, route_gateway) == 0) {
+ g_free (arp_gateway);
+ *mac = g_strdup (hwa);
+ break;
+ }
+ g_free (arp_gateway);
+
+ }
+ entry++;
+ }
+ g_free (route_gateway);
+ g_strfreev (lines);
+
+ return *mac ? 1 : 0;
+}
+
+static char *
+mac_strup (char *mac)
+{
+ guint i;
+ for (i = 0; mac[i] != '\0' ; i++) {
+ if (g_ascii_isalpha (mac[i]))
+ mac[i] = g_ascii_toupper (mac[i]);
+ }
+ return mac;
+}
+
+char *
+geoclue_connectivity_get_router_mac (GeoclueConnectivity *self)
+{
+ if (self == NULL ||
+ GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_router_mac == NULL) {
+ char *mac = NULL;
+ guint i;
+ int ret_val;
+
+ for (i = 0; i < 5; i++) {
+ ret_val = get_router_mac_fallback (&mac);
+ if (ret_val < 0)
+ return NULL;
+ else if (ret_val == 1)
+ break;
+ g_usleep (G_USEC_PER_SEC / 10);
+ }
+ return mac_strup (mac);
+ }
+
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_router_mac (self);
+}
+
+char *
+geoclue_connectivity_get_ap_mac (GeoclueConnectivity *self)
+{
+ if (self != NULL &&
+ GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_ap_mac != NULL)
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_ap_mac (self);
+
+ /* Hack when not using NetworkManager */
+ return geoclue_connectivity_get_router_mac (self);
+}
+
+GHashTable *
+geoclue_connectivity_get_aps (GeoclueConnectivity *self)
+{
+ char *ap;
+ GHashTable *ht;
+
+ if (self != NULL &&
+ GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_aps != NULL)
+ return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_aps (self);
+
+ /* Fallback if the backend does not support get_aps */
+ ap = geoclue_connectivity_get_ap_mac (self);
+ if (ap == NULL)
+ return NULL;
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, NULL);
+ g_hash_table_insert (ht, ap, GINT_TO_POINTER (DEFAULT_DBM));
+ return NULL;
+}
+
+void
+geoclue_connectivity_emit_status_changed (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status)
+{
+ g_signal_emit (self, signals[STATUS_CHANGED], 0, status);
+}
diff --git a/.pc/tizen.patch/src/connectivity.h b/.pc/tizen.patch/src/connectivity.h
new file mode 100755
index 0000000..76afbd9
--- /dev/null
+++ b/.pc/tizen.patch/src/connectivity.h
@@ -0,0 +1,73 @@
+/*
+ * Geoclue
+ * geoclue-connectivity.h
+ *
+ * Author: 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.
+ *
+ */
+
+#ifndef _GEOCLUE_CONNECTIVITY_H
+#define _GEOCLUE_CONNECTIVITY_H
+
+#include <glib-object.h>
+#include <geoclue/geoclue-types.h>
+
+G_BEGIN_DECLS
+
+
+#define GEOCLUE_TYPE_CONNECTIVITY (geoclue_connectivity_get_type ())
+#define GEOCLUE_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_CONNECTIVITY, GeoclueConnectivity))
+#define GEOCLUE_IS_CONNECTIVITY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GEOCLUE_TYPE_CONNECTIVITY))
+#define GEOCLUE_CONNECTIVITY_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GEOCLUE_TYPE_CONNECTIVITY, GeoclueConnectivityInterface))
+
+typedef struct _GeoclueConnectivity GeoclueConnectivity;
+typedef struct _GeoclueConnectivityInterface GeoclueConnectivityInterface;
+
+struct _GeoclueConnectivityInterface {
+ GTypeInterface parent;
+
+ /* signals */
+ void (* status_changed) (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status);
+
+ /* vtable */
+ int (*get_status) (GeoclueConnectivity *self);
+ GHashTable * (*get_aps) (GeoclueConnectivity *self);
+ char * (*get_ap_mac) (GeoclueConnectivity *self);
+ char * (*get_router_mac) (GeoclueConnectivity *self);
+};
+
+GType geoclue_connectivity_get_type (void);
+
+GeoclueConnectivity *geoclue_connectivity_new (void);
+
+GeoclueNetworkStatus geoclue_connectivity_get_status (GeoclueConnectivity *self);
+
+char *geoclue_connectivity_get_ap_mac (GeoclueConnectivity *self);
+char *geoclue_connectivity_get_router_mac (GeoclueConnectivity *self);
+
+GHashTable *geoclue_connectivity_get_aps (GeoclueConnectivity *self);
+
+void
+geoclue_connectivity_emit_status_changed (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status);
+
+G_END_DECLS
+
+#endif
diff --git a/.pc/tizen.patch/src/geoclue b/.pc/tizen.patch/src/geoclue
new file mode 100755
index 0000000..03bde7f
--- /dev/null
+++ b/.pc/tizen.patch/src/geoclue
@@ -0,0 +1,3 @@
+[org.freedesktop.Geoclue]
+gps-baudrate = /apps/geoclue/master/org.freedesktop.Geoclue.GPSBaudRate
+gps-device = /apps/geoclue/master/org.freedesktop.Geoclue.GPSDevice
diff --git a/.pc/tizen.patch/src/main.c b/.pc/tizen.patch/src/main.c
new file mode 100755
index 0000000..22668e6
--- /dev/null
+++ b/.pc/tizen.patch/src/main.c
@@ -0,0 +1,231 @@
+/*
+ * Geoclue
+ * main.c - Master process
+ *
+ * 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <dbus/dbus-protocol.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-bindings.h>
+
+#include "master.h"
+
+static GMainLoop *mainloop;
+static GHashTable *options;
+static GSettings *settings;
+static GcMaster *master;
+
+
+#define GEOCLUE_SCHEMA_NAME "org.freedesktop.Geoclue"
+#define GEOCLUE_MASTER_NAME "org.freedesktop.Geoclue.Master"
+
+static GValue *
+gvariant_value_to_value (GVariant *value)
+{
+ GValue *gvalue;
+ const GVariantType *type;
+
+ g_return_val_if_fail (value != NULL, NULL);
+ type = g_variant_get_type (value);
+
+ if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_STRING)) {
+ const char *str;
+
+ gvalue = g_new0 (GValue, 1);
+ str = g_variant_get_string (value, NULL);
+
+ /* Don't add empty strings in the hashtable */
+ if (str != NULL && str[0] == '\0')
+ str = NULL;
+
+ g_value_init (gvalue, G_TYPE_STRING);
+ g_value_set_string (gvalue, str);
+ } else if (g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_UINT32)) {
+ int i;
+
+ gvalue = g_new0 (GValue, 1);
+ i = g_variant_get_uint32 (value);
+ g_value_init (gvalue, G_TYPE_INT);
+ g_value_set_int (gvalue, i);
+ } else {
+ gvalue = NULL;
+ g_warning ("Value is of unknown type");
+ }
+
+ return gvalue;
+}
+
+static void
+debug_print_key (gboolean init,
+ const char *key,
+ GValue *gvalue)
+{
+ const char *message;
+ char *string;
+
+ if (init)
+ message = "GSettings key '%s' initialised to '%s'";
+ else
+ message = "GSettings key '%s' changed to '%s'";
+
+ if (G_VALUE_TYPE (gvalue) == G_TYPE_STRING) {
+ string = g_value_dup_string (gvalue);
+ } else if (G_VALUE_TYPE (gvalue) == G_TYPE_INT) {
+ string = g_strdup_printf ("%d", g_value_get_int (gvalue));
+ } else {
+ return;
+ }
+
+ g_message (message, key, string);
+ g_free (string);
+}
+
+static void
+gsettings_key_changed (GSettings *settings,
+ char *key,
+ gpointer user_data)
+{
+ GVariant *v;
+ GValue *gvalue;
+
+ v = g_settings_get_value (settings, key);
+ gvalue = gvariant_value_to_value (v);
+ if (gvalue == NULL) {
+ g_variant_unref (v);
+ return;
+ }
+
+ debug_print_key (FALSE, key, gvalue);
+
+ g_hash_table_insert (options, g_strdup (key), gvalue);
+
+ g_signal_emit_by_name (G_OBJECT (master), "options-changed", options);
+}
+
+static void
+free_gvalue (GValue *value)
+{
+ if (value == NULL)
+ return;
+ g_value_unset (value);
+ g_free (value);
+}
+
+static GHashTable *
+load_options (void)
+{
+ GHashTable *ht = NULL;
+ guint i;
+ const char const * keys[] = {
+ "gps-baudrate",
+ "gps-device"
+ };
+
+ /* Setup keys monitoring */
+ g_signal_connect (G_OBJECT (settings), "changed",
+ G_CALLBACK (gsettings_key_changed), NULL);
+
+ ht = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) free_gvalue);
+
+ g_print ("Master options:\n");
+ for (i = 0; i < G_N_ELEMENTS (keys); i++) {
+ GVariant *v;
+ GValue *gvalue;
+ const char *key = keys[i];
+
+ v = g_settings_get_value (settings, key);
+ gvalue = gvariant_value_to_value (v);
+
+ if (gvalue == NULL) {
+ g_variant_unref (v);
+ continue;
+ }
+
+ debug_print_key (TRUE, key, gvalue);
+
+ g_hash_table_insert (ht, g_strdup (key), gvalue);
+ g_variant_unref (v);
+ }
+
+ return ht;
+ }
+
+GHashTable *
+geoclue_get_main_options (void)
+{
+ return options;
+}
+
+int
+main (int argc,
+ char **argv)
+{
+ DBusGConnection *conn;
+ DBusGProxy *proxy;
+ GError *error = NULL;
+ guint32 request_name_ret;
+
+ g_type_init ();
+
+ mainloop = g_main_loop_new (NULL, FALSE);
+
+ conn = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (!conn) {
+ g_error ("Error getting bus: %s", error->message);
+ return 1;
+ }
+
+ proxy = dbus_g_proxy_new_for_name (conn,
+ DBUS_SERVICE_DBUS,
+ DBUS_PATH_DBUS,
+ DBUS_INTERFACE_DBUS);
+ if (!org_freedesktop_DBus_request_name (proxy, GEOCLUE_MASTER_NAME,
+ 0, &request_name_ret, &error)) {
+ g_error ("Error registering D-Bus service %s: %s",
+ GEOCLUE_MASTER_NAME, error->message);
+ return 1;
+ }
+
+ /* Just quit if master is already running */
+ if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ return 1;
+ }
+
+ /* Load options */
+ settings = g_settings_new (GEOCLUE_SCHEMA_NAME);
+ options = load_options ();
+
+ master = g_object_new (GC_TYPE_MASTER, NULL);
+ dbus_g_connection_register_g_object (conn,
+ "/org/freedesktop/Geoclue/Master",
+ G_OBJECT (master));
+
+ g_main_loop_run (mainloop);
+ return 0;
+}
diff --git a/.pc/tizen.patch/src/master-provider.c b/.pc/tizen.patch/src/master-provider.c
new file mode 100755
index 0000000..e4ea053
--- /dev/null
+++ b/.pc/tizen.patch/src/master-provider.c
@@ -0,0 +1,1309 @@
+/*
+ * Geoclue
+ * master-provider.c - Provider object for master and master client
+ *
+ * Author: Jussi Kukkonen <jku@o-hand.com>
+ *
+ * Copyright 2007-2008 by Garmin Ltd. or its subsidiaries
+ * 2008 OpenedHand Ltd
+ *
+ * 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.
+ *
+ */
+
+/**
+ * Provider object for GcMaster. Takes care of cacheing
+ * queried data.
+ *
+ * Should probably start/stop the actual providers as needed
+ * in the future
+ *
+ * Cache could also be used to save "stale" data for situations when
+ * current data is not available (MasterClient api would have to
+ * have a "allowOldData" setting)
+ *
+ * TODO:
+ * figure out what to do if get_* returns GEOCLUE_ERROR_NOT_AVAILABLE.
+ * Should try again, but when?
+ *
+ * implement velocity
+ *
+ * implement other (non-updating) ifaces
+ **/
+
+#include <string.h>
+
+#include "main.h"
+#include "master-provider.h"
+#include <geoclue/geoclue-position.h>
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-marshal.h>
+
+typedef enum _GeoclueProvideFlags {
+ GEOCLUE_PROVIDE_NONE = 0,
+ GEOCLUE_PROVIDE_UPDATES = 1 << 0, /* will send *-changed signals */
+ GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION = 1 << 1, /* data can be queried on new connection, and cached until connection ends */
+} GeoclueProvideFlags;
+
+typedef struct _GcPositionCache {
+ int timestamp;
+ GeocluePositionFields fields;
+ double latitude;
+ double longitude;
+ double altitude;
+ GeoclueAccuracy *accuracy;
+ GError *error;
+} GcPositionCache;
+
+typedef struct _GcAddressCache {
+ int timestamp;
+ GHashTable *details;
+ GeoclueAccuracy *accuracy;
+ GError *error;
+} GcAddressCache;
+
+typedef struct _GcMasterProviderPrivate {
+ char *name;
+ char *description;
+
+ char *service;
+ char *path;
+ GcInterfaceFlags interfaces;
+
+ GList *position_clients; /* list of clients currently using this provider */
+ GList *address_clients;
+
+ GeoclueAccuracyLevel expected_accuracy;
+
+ GeoclueResourceFlags required_resources;
+ GeoclueProvideFlags provides;
+
+ GeoclueStatus master_status; /* net_status and status affect this */
+ GeoclueNetworkStatus net_status;
+
+ GeoclueStatus status; /* cached status from actual provider */
+
+ GeocluePosition *position;
+ GcPositionCache position_cache;
+
+ GeoclueAddress *address;
+ GcAddressCache address_cache;
+
+} GcMasterProviderPrivate;
+
+enum {
+ STATUS_CHANGED,
+ ACCURACY_CHANGED,
+ POSITION_CHANGED,
+ ADDRESS_CHANGED,
+ LAST_SIGNAL
+};
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GC_TYPE_MASTER_PROVIDER, GcMasterProviderPrivate))
+
+G_DEFINE_TYPE (GcMasterProvider, gc_master_provider, G_TYPE_OBJECT)
+
+static void
+copy_error (GError **target, GError *source)
+{
+ if (*target) {
+ g_error_free (*target);
+ *target = NULL;
+ }
+ if (source) {
+ *target = g_error_copy (source);
+
+ /* If the error type is a D-Bus remote exception,
+ * don't lose the "magic" sauce after the message string.
+ * See the code in gerror_to_dbus_error_message() in dbus-glib */
+ if (source->domain == DBUS_GERROR &&
+ source->code == DBUS_GERROR_REMOTE_EXCEPTION) {
+ int len;
+ g_free ((*target)->message);
+ len = strlen (source->message);
+ len += strlen (source->message + len + 1);
+ len += 2;
+ (*target)->message = g_memdup (source->message, len);
+ }
+ }
+}
+
+static GeoclueProvider*
+gc_master_provider_get_provider (GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (master_provider);
+
+ if (priv->address) {
+ return GEOCLUE_PROVIDER (priv->address);
+ }
+ if (priv->position) {
+ return GEOCLUE_PROVIDER (priv->position);
+ }
+ return NULL;
+}
+
+static gboolean
+gc_master_provider_is_running (GcMasterProvider *master_provider)
+{
+ return (gc_master_provider_get_provider (master_provider) != NULL);
+}
+
+static void
+gc_master_provider_handle_new_position_accuracy (GcMasterProvider *provider,
+ GeoclueAccuracy *accuracy)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueAccuracyLevel old_level;
+ GeoclueAccuracyLevel new_level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ double new_hor_acc, new_vert_acc;
+
+ geoclue_accuracy_get_details (priv->position_cache.accuracy,
+ &old_level, NULL, NULL);
+ if (accuracy) {
+ geoclue_accuracy_get_details (accuracy,
+ &new_level, &new_hor_acc, &new_vert_acc);
+ }
+ geoclue_accuracy_set_details (priv->position_cache.accuracy,
+ new_level, new_hor_acc, new_vert_acc);
+
+ if (old_level != new_level) {
+ g_signal_emit (provider, signals[ACCURACY_CHANGED], 0,
+ GC_IFACE_POSITION, new_level);
+ }
+}
+
+static void
+gc_master_provider_handle_new_address_accuracy (GcMasterProvider *provider,
+ GeoclueAccuracy *accuracy)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueAccuracyLevel old_level;
+ GeoclueAccuracyLevel new_level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ double new_hor_acc, new_vert_acc;
+
+ geoclue_accuracy_get_details (priv->address_cache.accuracy,
+ &old_level, NULL, NULL);
+ if (accuracy) {
+ geoclue_accuracy_get_details (accuracy,
+ &new_level, &new_hor_acc, &new_vert_acc);
+ }
+ geoclue_accuracy_set_details (priv->address_cache.accuracy,
+ new_level, new_hor_acc, new_vert_acc);
+
+ if (old_level != new_level) {
+ g_signal_emit (provider, signals[ACCURACY_CHANGED], 0,
+ GC_IFACE_ADDRESS, new_level);
+ }
+}
+
+static void
+gc_master_provider_set_position (GcMasterProvider *provider,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GError *error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ priv->position_cache.timestamp = timestamp;
+ priv->position_cache.fields = fields;
+ priv->position_cache.latitude = latitude;
+ priv->position_cache.longitude = longitude;
+ priv->position_cache.altitude = altitude;
+
+ copy_error (&priv->position_cache.error, error);
+
+ /* emit accuracy-changed if needed, so masterclient can re-choose providers
+ * before we emit position-changed */
+ gc_master_provider_handle_new_position_accuracy (provider, accuracy);
+
+ if (!error) {
+ g_signal_emit (provider, signals[POSITION_CHANGED], 0,
+ fields, timestamp,
+ latitude, longitude, altitude,
+ priv->position_cache.accuracy);
+ }
+}
+
+static void
+gc_master_provider_set_address (GcMasterProvider *provider,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GError *error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ priv->address_cache.timestamp = timestamp;
+
+ g_hash_table_destroy (priv->address_cache.details);
+ if (details) {
+ priv->address_cache.details = geoclue_address_details_copy (details);
+ }else {
+ priv->address_cache.details = geoclue_address_details_new ();
+ }
+ copy_error (&priv->address_cache.error, error);
+
+ /* emit accuracy-changed if needed, so masterclient can re-choose providers
+ * before we emit position-changed */
+ gc_master_provider_handle_new_address_accuracy (provider, accuracy);
+
+ if (!error) {
+ g_signal_emit (provider, signals[ADDRESS_CHANGED], 0,
+ priv->address_cache.timestamp,
+ priv->address_cache.details,
+ priv->address_cache.accuracy);
+ }
+}
+
+
+
+static GeoclueResourceFlags
+parse_resource_strings (char **flags)
+{
+ GeoclueResourceFlags resources = GEOCLUE_RESOURCE_NONE;
+ int i;
+
+ for (i = 0; flags[i]; i++) {
+ if (strcmp (flags[i], "RequiresNetwork") == 0) {
+ resources |= GEOCLUE_RESOURCE_NETWORK;
+ } else if (strcmp (flags[i], "RequiresCell") == 0) {
+ resources |= GEOCLUE_RESOURCE_CELL;
+ } else if (strcmp (flags[i], "RequiresGPS") == 0) {
+ resources |= GEOCLUE_RESOURCE_GPS;
+ }
+ }
+
+ return resources;
+}
+
+static GeoclueProvideFlags
+parse_provide_strings (char **flags)
+{
+ GeoclueProvideFlags provides = GEOCLUE_PROVIDE_NONE;
+ int i;
+
+ for (i = 0; flags[i]; i++) {
+ if (strcmp (flags[i], "ProvidesUpdates") == 0) {
+ provides |= GEOCLUE_PROVIDE_UPDATES;
+ } else if (strcmp (flags[i], "ProvidesCacheableOnConnection") == 0) {
+ provides |= GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION;
+ }
+ }
+
+ return provides;
+}
+
+static GcInterfaceFlags
+parse_interface_strings (char **strs)
+{
+ GcInterfaceFlags ifaces = GC_IFACE_GEOCLUE;
+ int i;
+
+ for (i = 0; strs[i]; i++) {
+ if (strcmp (strs[i], GEOCLUE_POSITION_INTERFACE_NAME) == 0) {
+ ifaces |= GC_IFACE_POSITION;
+ } else if (strcmp (strs[i], GEOCLUE_ADDRESS_INTERFACE_NAME) == 0) {
+ ifaces |= GC_IFACE_ADDRESS;
+ }
+ }
+ return ifaces;
+}
+
+static GeoclueAccuracyLevel
+parse_accuracy_string (char *str)
+{
+ GeoclueAccuracyLevel level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ if (!str || strcmp (str, "None") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_NONE;
+ } else if (strcmp (str, "Country") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_COUNTRY;
+ } else if (strcmp (str, "Region") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_REGION;
+ } else if (strcmp (str, "Locality") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_LOCALITY;
+ } else if (strcmp (str, "Postalcode") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_POSTALCODE;
+ } else if (strcmp (str, "Street") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_STREET;
+ } else if (strcmp (str, "Detailed") == 0) {
+ level = GEOCLUE_ACCURACY_LEVEL_DETAILED;
+ } else {
+ g_warning ("'%s' is not a recognised accuracy level value", str);
+ }
+ return level;
+}
+
+static void
+gc_master_provider_handle_error (GcMasterProvider *provider, GError *error)
+{
+ GcMasterProviderPrivate *priv;
+
+ g_assert (error);
+
+ priv = GET_PRIVATE (provider);
+ g_debug ("%s handling error %d", priv->name, error->code);
+
+ /* web service providers that are unavailable */
+ if (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION &&
+ error->code == GEOCLUE_ERROR_NOT_AVAILABLE) {
+ priv->master_status = GEOCLUE_STATUS_UNAVAILABLE;
+ /* TODO set timer to re-check availability */
+ }
+}
+
+/* Sets master_status based on provider status and net_status
+ * Should be called whenever priv->status or priv->net_status change */
+static void
+gc_master_provider_handle_status_change (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ GeoclueStatus new_master_status;
+
+ /* calculate new master status */
+ if (priv->required_resources & GEOCLUE_RESOURCE_NETWORK ||
+ priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION) {
+ switch (priv->net_status) {
+ case GEOCLUE_CONNECTIVITY_UNKNOWN:
+ /* falling through */
+ case GEOCLUE_CONNECTIVITY_OFFLINE:
+ new_master_status = GEOCLUE_STATUS_UNAVAILABLE;
+ break;
+ case GEOCLUE_CONNECTIVITY_ACQUIRING:
+ if (priv->status == GEOCLUE_STATUS_AVAILABLE){
+ new_master_status = GEOCLUE_STATUS_ACQUIRING;
+ } else {
+ new_master_status = priv->status;
+ }
+ break;
+ case GEOCLUE_CONNECTIVITY_ONLINE:
+ new_master_status = priv->status;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ } else {
+ new_master_status = priv->status;
+ }
+
+ if (new_master_status != priv->master_status) {
+ priv->master_status = new_master_status;
+
+ g_signal_emit (provider, signals[STATUS_CHANGED], 0, new_master_status);
+ }
+}
+
+
+static void
+gc_master_provider_update_cache (GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (master_provider);
+
+ if ((!(priv->provides & GEOCLUE_PROVIDE_UPDATES)) ||
+ (!gc_master_provider_get_provider (master_provider))) {
+ /* non-cacheable provider or provider not running */
+ return;
+ }
+
+ g_debug ("%s: Updating cache ", priv->name);
+ priv->master_status = GEOCLUE_STATUS_ACQUIRING;
+ g_signal_emit (master_provider, signals[STATUS_CHANGED], 0, priv->master_status);
+
+ if (priv->position) {
+ int timestamp;
+ double lat, lon, alt;
+ GeocluePositionFields fields;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ fields = geoclue_position_get_position (priv->position,
+ &timestamp,
+ &lat, &lon, &alt,
+ &accuracy,
+ &error);
+ if (error){
+ g_warning ("Error updating position cache: %s", error->message);
+ gc_master_provider_handle_error (master_provider, error);
+ }
+ gc_master_provider_set_position (master_provider,
+ fields, timestamp,
+ lat, lon, alt,
+ accuracy, error);
+ }
+
+ if (priv->address) {
+ int timestamp;
+ GHashTable *details = NULL;
+ GeoclueAccuracy *accuracy = NULL;
+ GError *error = NULL;
+
+ if (!geoclue_address_get_address (priv->address,
+ &timestamp,
+ &details,
+ &accuracy,
+ &error)) {
+ g_warning ("Error updating address cache: %s", error->message);
+ gc_master_provider_handle_error (master_provider, error);
+ }
+ gc_master_provider_set_address (master_provider,
+ timestamp,
+ details,
+ accuracy,
+ error);
+ }
+
+ gc_master_provider_handle_status_change (master_provider);
+}
+
+/* signal handlers for the actual providers signals */
+
+static void
+provider_status_changed (GeoclueProvider *provider,
+ GeoclueStatus status,
+ GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (master_provider);
+
+ priv->status = status;
+ gc_master_provider_handle_status_change (master_provider);
+}
+
+static void
+position_changed (GeocluePosition *position,
+ GeocluePositionFields fields,
+ int timestamp,
+ double latitude,
+ double longitude,
+ double altitude,
+ GeoclueAccuracy *accuracy,
+ GcMasterProvider *provider)
+{
+ /* is there a situation when we'd need to check against cache
+ * if data has really changed? probably not */
+ gc_master_provider_set_position (provider,
+ fields, timestamp,
+ latitude, longitude, altitude,
+ accuracy, NULL);
+}
+
+static void
+address_changed (GeoclueAddress *address,
+ int timestamp,
+ GHashTable *details,
+ GeoclueAccuracy *accuracy,
+ GcMasterProvider *provider)
+{
+ /* is there a situation when we'd need to check against cache
+ * if data has really changed? probably not */
+ gc_master_provider_set_address (provider,
+ timestamp,
+ details,
+ accuracy,
+ NULL);
+}
+
+
+static void
+finalize (GObject *object)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (object);
+
+ geoclue_accuracy_free (priv->position_cache.accuracy);
+ geoclue_accuracy_free (priv->address_cache.accuracy);
+ if (priv->position_cache.error) {
+ g_error_free (priv->position_cache.error);
+ }
+ if (priv->address_cache.error) {
+ g_error_free (priv->address_cache.error);
+ }
+
+ g_free (priv->name);
+ g_free (priv->description);
+ g_free (priv->service);
+ g_free (priv->path);
+
+ g_free (priv->position_clients);
+ g_free (priv->address_clients);
+
+ G_OBJECT_CLASS (gc_master_provider_parent_class)->finalize (object);
+}
+
+static void
+dispose (GObject *object)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (object);
+
+ if (priv->position) {
+ g_object_unref (priv->position);
+ priv->position = NULL;
+ }
+
+ if (priv->address) {
+ g_object_unref (priv->address);
+ priv->address = NULL;
+ }
+ if (priv->address_cache.details) {
+ g_hash_table_destroy (priv->address_cache.details);
+ priv->address_cache.details = NULL;
+ }
+
+ G_OBJECT_CLASS (gc_master_provider_parent_class)->dispose (object);
+}
+
+static void
+gc_master_provider_class_init (GcMasterProviderClass *klass)
+{
+ GObjectClass *o_class = (GObjectClass *) klass;
+
+ o_class->finalize = finalize;
+ o_class->dispose = dispose;
+
+ g_type_class_add_private (klass, sizeof (GcMasterProviderPrivate));
+
+ signals[STATUS_CHANGED] = g_signal_new ("status-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+ signals[ACCURACY_CHANGED] = g_signal_new ("accuracy-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, accuracy_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT, G_TYPE_INT);
+ signals[POSITION_CHANGED] = g_signal_new ("position-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, position_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_INT_DOUBLE_DOUBLE_DOUBLE_BOXED,
+ G_TYPE_NONE, 6,
+ G_TYPE_INT, G_TYPE_INT,
+ G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE,
+ G_TYPE_POINTER);
+ signals[ADDRESS_CHANGED] = g_signal_new ("address-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterProviderClass, address_changed),
+ NULL, NULL,
+ geoclue_marshal_VOID__INT_BOXED_BOXED,
+ G_TYPE_NONE, 3,
+ G_TYPE_INT,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+}
+
+static void
+gc_master_provider_init (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ priv->position_clients = NULL;
+ priv->address_clients = NULL;
+
+ priv->master_status = GEOCLUE_STATUS_UNAVAILABLE;
+
+ priv->position = NULL;
+ priv->position_cache.accuracy =
+ geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0 ,0);
+ priv->position_cache.error = NULL;
+
+ priv->address = NULL;
+ priv->address_cache.accuracy =
+ geoclue_accuracy_new (GEOCLUE_ACCURACY_LEVEL_NONE, 0 ,0);
+ priv->address_cache.details = geoclue_address_details_new ();
+ priv->address_cache.error = NULL;
+}
+
+#if DEBUG_INFO
+static void
+gc_master_provider_dump_position (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+ GeocluePositionFields fields;
+ int time;
+ double lat, lon, alt;
+ GError *error = NULL;
+
+ priv = GET_PRIVATE (provider);
+
+
+ g_print (" Position Information:\n");
+ g_print (" ---------------------\n");
+
+ fields = gc_master_provider_get_position (provider,
+ &time,
+ &lat, &lon, &alt,
+ NULL, &error);
+ if (error) {
+ g_print (" Error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ g_print (" Timestamp: %d\n", time);
+ g_print (" Latitude: %.2f %s\n", lat,
+ fields & GEOCLUE_POSITION_FIELDS_LATITUDE ? "" : "(not set)");
+ g_print (" Longitude: %.2f %s\n", lon,
+ fields & GEOCLUE_POSITION_FIELDS_LONGITUDE ? "" : "(not set)");
+ g_print (" Altitude: %.2f %s\n", alt,
+ fields & GEOCLUE_POSITION_FIELDS_ALTITUDE ? "" : "(not set)");
+
+}
+
+static void
+dump_address_key_and_value (char *key, char *value, GHashTable *target)
+{
+ g_print (" %s: %s\n", key, value);
+}
+
+static void
+gc_master_provider_dump_address (GcMasterProvider *provider)
+{
+ int time;
+ GHashTable *details;
+ GError *error = NULL;
+
+ g_print (" Address Information:\n");
+ g_print (" --------------------\n");
+ if (!gc_master_provider_get_address (provider,
+ &time,
+ &details,
+ NULL, &error)) {
+ g_print (" Error: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ g_print (" Timestamp: %d\n", time);
+ g_hash_table_foreach (details, (GHFunc)dump_address_key_and_value, NULL);
+
+}
+
+static void
+gc_master_provider_dump_required_resources (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+ g_print (" Requires\n");
+ if (priv->required_resources & GEOCLUE_RESOURCE_GPS) {
+ g_print (" - GPS\n");
+ }
+
+ if (priv->required_resources & GEOCLUE_RESOURCE_NETWORK) {
+ g_print (" - Network\n");
+ }
+}
+
+static void
+gc_master_provider_dump_provides (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+ g_print (" Provides\n");
+ if (priv->provides & GEOCLUE_PROVIDE_UPDATES) {
+ g_print (" - Updates\n");
+ }
+ if (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION) {
+ g_print (" - Cacheable on network connection\n");
+ }
+}
+
+static void
+gc_master_provider_dump_provider_details (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+ g_print ("\n Name - %s\n", priv->name);
+ g_print (" Description - %s\n", priv->description);
+ g_print (" Service - %s\n", priv->service);
+ g_print (" Path - %s\n", priv->path);
+ g_print (" Accuracy level - %d\n", priv->expected_accuracy);
+ g_print (" Provider is currently %srunning, status %d\n",
+ gc_master_provider_get_provider (master_provider) ? "" : "not ",
+ priv->master_status);
+ gc_master_provider_dump_required_resources (provider);
+ gc_master_provider_dump_provides (provider);
+
+
+ if (priv->interfaces & GC_IFACE_POSITION) {
+ g_print (" Interface - Position\n");
+ gc_master_provider_dump_position (provider);
+ }
+ if (priv->interfaces & GC_IFACE_ADDRESS) {
+ g_print (" Interface - Address\n");
+ gc_master_provider_dump_address (provider);
+ }
+}
+#endif
+
+static gboolean
+gc_master_provider_initialize_geoclue (GcMasterProvider *master_provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (master_provider);
+ GeoclueProvider *geoclue;
+ GError *error = NULL;
+
+ geoclue = gc_master_provider_get_provider (master_provider);
+
+ if (!geoclue_provider_set_options (geoclue,
+ geoclue_get_main_options (),
+ &error)) {
+ g_warning ("Error setting provider options: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ /* priv->name has been read from .provider-file earlier...
+ * could ask the provider anyway, just to be consistent */
+ if (!geoclue_provider_get_provider_info (geoclue, NULL,
+ &priv->description, &error)) {
+ g_warning ("Error getting provider info: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ g_signal_connect (G_OBJECT (geoclue), "status-changed",
+ G_CALLBACK (provider_status_changed), master_provider);
+
+
+ if (!geoclue_provider_get_status (geoclue, &priv->status, &error)) {
+ g_warning ("Error getting provider status: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+gc_master_provider_initialize_interfaces (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+
+ if (priv->interfaces <= GC_IFACE_GEOCLUE) {
+ g_warning ("No interfaces defined for %s", priv->name);
+ return FALSE;
+ }
+
+ if (priv->interfaces & GC_IFACE_POSITION) {
+ g_assert (priv->position == NULL);
+
+ priv->position = geoclue_position_new (priv->service,
+ priv->path);
+ g_signal_connect (G_OBJECT (priv->position), "position-changed",
+ G_CALLBACK (position_changed), provider);
+ }
+ if (priv->interfaces & GC_IFACE_ADDRESS) {
+ g_assert (priv->address == NULL);
+
+ priv->address = geoclue_address_new (priv->service,
+ priv->path);
+ g_signal_connect (G_OBJECT (priv->address), "address-changed",
+ G_CALLBACK (address_changed), provider);
+ }
+
+ if (!gc_master_provider_initialize_geoclue (provider)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+static gboolean
+gc_master_provider_initialize (GcMasterProvider *provider)
+{
+ if (!gc_master_provider_initialize_interfaces (provider)) {
+ return FALSE;
+ }
+
+ gc_master_provider_update_cache (provider);
+#if DEBUG_INFO
+ gc_master_provider_dump_provider_details (provider);
+#endif
+ return TRUE;
+}
+
+static void
+gc_master_provider_deinitialize (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (priv->position) {
+ g_object_unref (priv->position);
+ priv->position = NULL;
+ }
+ if (priv->address) {
+ g_object_unref (priv->address);
+ priv->address = NULL;
+ }
+ g_debug ("deinited %s", priv->name);
+}
+
+static void
+network_status_changed (gpointer *connectivity,
+ GeoclueNetworkStatus status,
+ GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv;
+
+ priv = GET_PRIVATE (provider);
+
+ priv->net_status = status;
+ /* update connection-cacheable providers */
+ if (status == GEOCLUE_CONNECTIVITY_ONLINE &&
+ priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION) {
+ /* intialize to fill cache (this will handle status change) */
+ if (gc_master_provider_initialize (provider)) {
+ gc_master_provider_deinitialize (provider);
+ }
+ } else {
+ gc_master_provider_handle_status_change (provider);
+ }
+}
+
+/* for updating cache on providers that are not running */
+static gboolean
+update_cache_and_deinit (GcMasterProvider *provider)
+{
+ /* fill cache */
+ if (gc_master_provider_initialize (provider)) {
+ gc_master_provider_deinitialize (provider);
+ }
+ return FALSE;
+}
+
+
+/* public methods (for GcMaster and GcMasterClient) */
+
+/* Loads provider details from 'filename' */
+GcMasterProvider *
+gc_master_provider_new (const char *filename,
+ GeoclueConnectivity *connectivity)
+{
+ GcMasterProvider *provider;
+ GcMasterProviderPrivate *priv;
+ GKeyFile *keyfile;
+ GError *error = NULL;
+ gboolean ret;
+ char *accuracy_str;
+ char **flags, **interfaces;
+
+ keyfile = g_key_file_new ();
+ ret = g_key_file_load_from_file (keyfile, filename,
+ G_KEY_FILE_NONE, &error);
+ if (ret == FALSE) {
+ g_warning ("Error loading %s: %s", filename, error->message);
+ g_error_free (error);
+ g_key_file_free (keyfile);
+ return NULL;
+ }
+
+ provider = g_object_new (GC_TYPE_MASTER_PROVIDER, NULL);
+ priv = GET_PRIVATE (provider);
+
+ priv->name = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Name", NULL);
+ priv->service = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Service", NULL);
+ priv->path = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Path", NULL);
+
+ accuracy_str = g_key_file_get_value (keyfile, "Geoclue Provider",
+ "Accuracy", NULL);
+ priv->expected_accuracy = parse_accuracy_string (accuracy_str);
+ if (accuracy_str){
+ g_free (accuracy_str);
+ }
+
+ /* set cached accuracies to a default value */
+ geoclue_accuracy_set_details (priv->position_cache.accuracy,
+ priv->expected_accuracy, 0.0, 0.0);
+ geoclue_accuracy_set_details (priv->address_cache.accuracy,
+ priv->expected_accuracy, 0.0, 0.0);
+
+
+ flags = g_key_file_get_string_list (keyfile, "Geoclue Provider",
+ "Requires", NULL, NULL);
+ if (flags != NULL) {
+ priv->required_resources = parse_resource_strings (flags);
+ g_strfreev (flags);
+ } else {
+ priv->required_resources = GEOCLUE_RESOURCE_NONE;
+ }
+
+ flags = g_key_file_get_string_list (keyfile, "Geoclue Provider",
+ "Provides", NULL, NULL);
+ if (flags != NULL) {
+ priv->provides = parse_provide_strings (flags);
+ g_strfreev (flags);
+ } else {
+ priv->provides = GEOCLUE_PROVIDE_NONE;
+ }
+
+ if (!connectivity &&
+ (priv->required_resources & GEOCLUE_RESOURCE_NETWORK)) {
+ priv->provides &= ~GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION;
+ priv->net_status = GEOCLUE_CONNECTIVITY_ONLINE;
+ priv->status = GEOCLUE_STATUS_AVAILABLE;
+ gc_master_provider_handle_status_change (provider);
+ }
+
+ if (connectivity &&
+ (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION)) {
+
+ /* we have network status events: mark network provider
+ * with update flag, set the callback and set use_cache */
+ priv->provides |= GEOCLUE_PROVIDE_UPDATES;
+
+ g_signal_connect (connectivity,
+ "status-changed",
+ G_CALLBACK (network_status_changed),
+ provider);
+ priv->net_status = geoclue_connectivity_get_status (connectivity);
+ }
+
+ priv->interfaces = GC_IFACE_GEOCLUE;
+ interfaces = g_key_file_get_string_list (keyfile,
+ "Geoclue Provider",
+ "Interfaces",
+ NULL, NULL);
+ if (interfaces) {
+ priv->interfaces = parse_interface_strings (interfaces);
+ g_strfreev (interfaces);
+ }
+
+ if (priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION &&
+ priv->net_status == GEOCLUE_CONNECTIVITY_ONLINE) {
+ /* do this as idle so we can return without waiting for http queries */
+ g_idle_add ((GSourceFunc)update_cache_and_deinit, provider);
+ }
+ return provider;
+}
+
+/* client calls this when it wants to use the provider.
+ Returns true if provider was actually started, and
+ client should assume accuracy has changed.
+ Returns false if provider was not started (it was either already
+ running or starting the provider failed). */
+gboolean
+gc_master_provider_subscribe (GcMasterProvider *provider,
+ gpointer client,
+ GcInterfaceFlags interface)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ gboolean started = FALSE;
+
+ /* decide wether to run initialize or not */
+ if (!gc_master_provider_is_running (provider)) {
+ if (!(priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION)) {
+ started = gc_master_provider_initialize (provider);
+ }
+ }
+
+ /* add subscription */
+ if (interface & GC_IFACE_POSITION) {
+ if (!g_list_find (priv->position_clients, client)) {
+ priv->position_clients = g_list_prepend (priv->position_clients, client);
+ }
+ }
+ if (interface & GC_IFACE_ADDRESS) {
+ if (!g_list_find (priv->address_clients, client)) {
+ priv->address_clients = g_list_prepend (priv->address_clients, client);
+ }
+ }
+
+ return started;
+}
+
+/* client calls this when it does not intend to use the provider */
+void
+gc_master_provider_unsubscribe (GcMasterProvider *provider,
+ gpointer client,
+ GcInterfaceFlags interface)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ if (interface & GC_IFACE_POSITION) {
+ priv->position_clients = g_list_remove (priv->position_clients, client);
+ }
+ if (interface & GC_IFACE_ADDRESS) {
+ priv->address_clients = g_list_remove (priv->address_clients, client);
+ }
+
+ if (!priv->position_clients &&
+ !priv->address_clients) {
+ /* no one is using this provider, shutdown... */
+ /* not clearing cached accuracies on purpose */
+ g_debug ("%s without clients", priv->name);
+
+ /* gc_master_provider_deinitialize (provider); */
+ }
+}
+
+
+GeocluePositionFields
+gc_master_provider_get_position (GcMasterProvider *provider,
+ int *timestamp,
+ double *latitude,
+ double *longitude,
+ double *altitude,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ g_assert (priv->position ||
+ priv->provides & GEOCLUE_PROVIDE_CACHEABLE_ON_CONNECTION);
+
+ if (priv->provides & GEOCLUE_PROVIDE_UPDATES) {
+ if (timestamp != NULL) {
+ *timestamp = priv->position_cache.timestamp;
+ }
+ if (latitude != NULL) {
+ *latitude = priv->position_cache.latitude;
+ }
+ if (longitude != NULL) {
+ *longitude = priv->position_cache.longitude;
+ }
+ if (altitude != NULL) {
+ *altitude = priv->position_cache.altitude;
+ }
+ if (accuracy != NULL) {
+ *accuracy = geoclue_accuracy_copy (priv->position_cache.accuracy);
+ }
+ if (error != NULL) {
+ g_assert (!*error);
+ copy_error (error, priv->position_cache.error);
+ }
+ return priv->position_cache.fields;
+ } else {
+ return geoclue_position_get_position (priv->position,
+ timestamp,
+ latitude,
+ longitude,
+ altitude,
+ accuracy,
+ error);
+ }
+}
+
+gboolean
+gc_master_provider_get_address (GcMasterProvider *provider,
+ int *timestamp,
+ GHashTable **details,
+ GeoclueAccuracy **accuracy,
+ GError **error)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ if (priv->provides & GEOCLUE_PROVIDE_UPDATES) {
+
+ if (timestamp != NULL) {
+ *timestamp = priv->address_cache.timestamp;
+ }
+ if (details != NULL) {
+ *details = geoclue_address_details_copy (priv->address_cache.details);
+ }
+ if (accuracy != NULL) {
+ *accuracy = geoclue_accuracy_copy (priv->address_cache.accuracy);
+ }
+ if (error != NULL) {
+ g_assert (!*error);
+ copy_error (error, priv->address_cache.error);
+ }
+ return (!priv->address_cache.error);
+ } else {
+ g_assert (priv->address);
+ return geoclue_address_get_address (priv->address,
+ timestamp,
+ details,
+ accuracy,
+ error);
+ }
+}
+
+gboolean
+gc_master_provider_is_good (GcMasterProvider *provider,
+ GcInterfaceFlags iface_type,
+ GeoclueAccuracyLevel min_accuracy,
+ gboolean need_update,
+ GeoclueResourceFlags allowed_resources)
+{
+ GcMasterProviderPrivate *priv;
+ GcInterfaceFlags supported_ifaces;
+ GeoclueProvideFlags required_flags = GEOCLUE_PROVIDE_NONE;
+
+ priv = GET_PRIVATE (provider);
+
+ if (need_update) {
+ required_flags |= GEOCLUE_PROVIDE_UPDATES;
+ }
+
+ supported_ifaces = priv->interfaces;
+
+ /* provider must provide all that is required and
+ * cannot require a resource that is not allowed */
+ /* TODO: really, we need to change some of those terms... */
+
+ return (((supported_ifaces & iface_type) == iface_type) &&
+ ((priv->provides & required_flags) == required_flags) &&
+ (priv->expected_accuracy >= min_accuracy) &&
+ ((priv->required_resources & (~allowed_resources)) == 0));
+}
+
+void
+gc_master_provider_update_options (GcMasterProvider *provider)
+{
+ GeoclueProvider *geoclue;
+ GError *error = NULL;
+
+ geoclue = gc_master_provider_get_provider (provider);
+
+ if (!geoclue_provider_set_options (geoclue,
+ geoclue_get_main_options (),
+ &error)) {
+ g_warning ("Error setting provider options: %s\n", error->message);
+ g_error_free (error);
+ }
+}
+
+GeoclueStatus
+gc_master_provider_get_status (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->master_status;
+}
+
+GeoclueAccuracyLevel
+gc_master_provider_get_accuracy (GcMasterProvider *provider, GcInterfaceFlags iface)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+ GeoclueAccuracyLevel acc_level;
+
+ switch (iface) {
+ case GC_IFACE_POSITION:
+ geoclue_accuracy_get_details (priv->position_cache.accuracy,
+ &acc_level, NULL, NULL);
+ break;
+ case GC_IFACE_ADDRESS:
+ geoclue_accuracy_get_details (priv->address_cache.accuracy,
+ &acc_level, NULL, NULL);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ return acc_level;
+}
+
+/*returns a reference, but is not meant for editing...*/
+char *
+gc_master_provider_get_name (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->name;
+}
+char *
+gc_master_provider_get_description (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->description;
+}
+char *
+gc_master_provider_get_service (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->service;
+}
+char *
+gc_master_provider_get_path (GcMasterProvider *provider)
+{
+ GcMasterProviderPrivate *priv = GET_PRIVATE (provider);
+
+ return priv->path;
+}
+
+/* GCompareDataFunc for sorting providers by accuracy and required resources */
+int
+gc_master_provider_compare (GcMasterProvider *a,
+ GcMasterProvider *b,
+ GcInterfaceAccuracy *iface_min_accuracy)
+{
+ int diff;
+ GeoclueAccuracy *acc_a, *acc_b;
+ GeoclueAccuracyLevel level_a, level_b, min_level;
+
+
+ GcMasterProviderPrivate *priv_a = GET_PRIVATE (a);
+ GcMasterProviderPrivate *priv_b = GET_PRIVATE (b);
+
+ /* get the current accuracylevels */
+ switch (iface_min_accuracy->interface) {
+ case GC_IFACE_POSITION:
+ acc_a = priv_a->position_cache.accuracy;
+ acc_b = priv_b->position_cache.accuracy;
+ break;
+ case GC_IFACE_ADDRESS:
+ acc_a = priv_a->address_cache.accuracy;
+ acc_b = priv_b->address_cache.accuracy;
+ break;
+ default:
+ g_warning("iface: %d", iface_min_accuracy->interface);
+ g_assert_not_reached ();
+ }
+
+
+ geoclue_accuracy_get_details (acc_a, &level_a, NULL, NULL);
+ geoclue_accuracy_get_details (acc_b, &level_b, NULL, NULL);
+ min_level = iface_min_accuracy->accuracy_level;
+
+ /* sort by resource requirements and accuracy, but only if both
+ * providers meet the minimum accuracy requirement */
+ if ((level_b >= min_level) &&
+ (level_a >= min_level)) {
+ diff = priv_a->required_resources - priv_b->required_resources;
+ if (diff != 0 ) {
+ return diff;
+ }
+ return level_b - level_a;
+ }
+
+ /* one or both do not meet req's, sort by accuracy */
+ return level_b - level_a;
+}
diff --git a/.pc/tizen.patch/src/master.c b/.pc/tizen.patch/src/master.c
new file mode 100755
index 0000000..7877e61
--- /dev/null
+++ b/.pc/tizen.patch/src/master.c
@@ -0,0 +1,211 @@
+/*
+ * Geoclue
+ * master.c - Master process
+ *
+ * Authors: Iain Holmes <iain@openedhand.com>
+ * Jussi Kukkonen <jku@o-hand.com>
+ * Copyright 2007-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 <string.h>
+
+#include "main.h"
+#include "master.h"
+#include "client.h"
+#include "master-provider.h"
+
+#ifdef HAVE_NETWORK_MANAGER
+#include "connectivity-networkmanager.h"
+#else
+#ifdef HAVE_CONIC
+#include "connectivity-conic.h"
+#else
+#ifdef HAVE_CONNMAN
+#include "connectivity-connman.h"
+#endif
+#endif
+#endif
+
+enum {
+ OPTIONS_CHANGED,
+ LAST_SIGNAL
+};
+
+static guint32 signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE (GcMaster, gc_master, G_TYPE_OBJECT);
+
+static GList *providers = NULL;
+
+static gboolean gc_iface_master_create (GcMaster *master,
+ const char **object_path,
+ GError **error);
+
+#include "gc-iface-master-glue.h"
+
+#define GEOCLUE_MASTER_PATH "/org/freedesktop/Geoclue/Master/client"
+static gboolean
+gc_iface_master_create (GcMaster *master,
+ const char **object_path,
+ GError **error)
+{
+ static guint32 serial = 0;
+ GcMasterClient *client;
+ char *path;
+
+ path = g_strdup_printf ("%s%d", GEOCLUE_MASTER_PATH, serial++);
+ client = g_object_new (GC_TYPE_MASTER_CLIENT, NULL);
+ dbus_g_connection_register_g_object (master->connection, path,
+ G_OBJECT (client));
+
+ if (object_path) {
+ *object_path = path;
+ }
+ return TRUE;
+}
+
+static void
+gc_master_class_init (GcMasterClass *klass)
+{
+ dbus_g_object_type_install_info (gc_master_get_type (),
+ &dbus_glib_gc_iface_master_object_info);
+
+ signals[OPTIONS_CHANGED] = g_signal_new ("options-changed",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_NO_RECURSE,
+ G_STRUCT_OFFSET (GcMasterClass, options_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ G_TYPE_HASH_TABLE);
+}
+
+/* Load the provider details out of a keyfile */
+static void
+gc_master_add_new_provider (GcMaster *master,
+ const char *filename)
+{
+ GcMasterProvider *provider;
+
+ provider = gc_master_provider_new (filename,
+ master->connectivity);
+
+ if (!provider) {
+ g_warning ("Loading from %s failed", filename);
+ return;
+ }
+
+ providers = g_list_prepend (providers, provider);
+}
+
+/* Scan a directory for .provider files */
+#define PROVIDER_EXTENSION ".provider"
+
+static void
+gc_master_load_providers (GcMaster *master)
+{
+ GDir *dir;
+ GError *error = NULL;
+ const char *filename;
+
+ dir = g_dir_open (GEOCLUE_PROVIDERS_DIR, 0, &error);
+ if (dir == NULL) {
+ g_warning ("Error opening %s: %s\n", GEOCLUE_PROVIDERS_DIR,
+ error->message);
+ g_error_free (error);
+ return;
+ }
+
+ filename = g_dir_read_name (dir);
+ if (!filename) {
+ g_print ("No providers found in %s\n", dir);
+ } else {
+ g_print ("Found providers:\n");
+ }
+ while (filename) {
+ char *fullname, *ext;
+
+ g_print (" %s\n", filename);
+ ext = strrchr (filename, '.');
+ if (ext == NULL || strcmp (ext, PROVIDER_EXTENSION) != 0) {
+ g_print (" - Ignored\n");
+ filename = g_dir_read_name (dir);
+ continue;
+ }
+
+ fullname = g_build_filename (GEOCLUE_PROVIDERS_DIR,
+ filename, NULL);
+ gc_master_add_new_provider (master, fullname);
+ g_free (fullname);
+
+ filename = g_dir_read_name (dir);
+ }
+
+ g_dir_close (dir);
+}
+
+static void
+gc_master_init (GcMaster *master)
+{
+ GError *error = NULL;
+
+
+ master->connection = dbus_g_bus_get (GEOCLUE_DBUS_BUS, &error);
+ if (master->connection == NULL) {
+ g_warning ("Could not get %s: %s", GEOCLUE_DBUS_BUS,
+ error->message);
+ g_error_free (error);
+ }
+
+ master->connectivity = geoclue_connectivity_new ();
+
+ gc_master_load_providers (master);
+}
+
+
+GList *
+gc_master_get_providers (GcInterfaceFlags iface_type,
+ GeoclueAccuracyLevel min_accuracy,
+ gboolean can_update,
+ GeoclueResourceFlags allowed,
+ GError **error)
+{
+ GList *l, *p = NULL;
+
+ if (providers == NULL) {
+ return NULL;
+ }
+
+ for (l = providers; l; l = l->next) {
+ GcMasterProvider *provider = l->data;
+
+ if (gc_master_provider_is_good (provider,
+ iface_type,
+ min_accuracy,
+ can_update,
+ allowed)) {
+ p = g_list_prepend (p, provider);
+ }
+ }
+
+ return p;
+}
diff --git a/.pc/tizen.patch/src/org.freedesktop.Geoclue.gschema.xml b/.pc/tizen.patch/src/org.freedesktop.Geoclue.gschema.xml
new file mode 100755
index 0000000..94ff65d
--- /dev/null
+++ b/.pc/tizen.patch/src/org.freedesktop.Geoclue.gschema.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<schemalist>
+ <schema path="/apps/geoclue/" id="org.freedesktop.Geoclue">
+ <key type="u" name="gps-baudrate">
+ <default>0</default>
+ <summary>The baud rate for the attached GPS device</summary>
+ <description>The baud rate for the attached GPS device.</description>
+ </key>
+ <key type="s" name="gps-device">
+ <default>''</default>
+ <summary>The device node or Bluetooth address for the attached GPS device</summary>
+ <description>The device node or Bluetooth address for the attached GPS device.</description>
+ </key>
+ </schema>
+</schemalist>
diff --git a/.pc/tizen.patch/src/test-connectivity.c b/.pc/tizen.patch/src/test-connectivity.c
new file mode 100755
index 0000000..c8b7cf6
--- /dev/null
+++ b/.pc/tizen.patch/src/test-connectivity.c
@@ -0,0 +1,97 @@
+
+#include <connectivity.h>
+
+static void
+print_ap (gpointer key,
+ gpointer value,
+ gpointer data)
+{
+ g_message ("\t%s : %d dBm",
+ key,
+ GPOINTER_TO_INT (value));
+}
+
+static void
+print_aps (GeoclueConnectivity *conn)
+{
+ GHashTable *ht;
+
+ ht = geoclue_connectivity_get_aps (conn);
+ if (ht == NULL) {
+ g_message ("No Access Points available");
+ return;
+ }
+ g_message ("APs:");
+ g_hash_table_foreach (ht, print_ap, NULL);
+}
+
+static void
+print_if_avail (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status)
+{
+ char *router, *ap;
+ if (status != GEOCLUE_CONNECTIVITY_ONLINE)
+ return;
+ print_aps (self);
+ ap = geoclue_connectivity_get_ap_mac (self);
+ g_message ("AP is '%s'", ap ? ap : "Unavailable");
+ g_free (ap);
+
+ router = geoclue_connectivity_get_router_mac (self);
+ g_message ("Router is '%s'", router);
+ g_free (router);
+}
+
+static void
+status_changed_cb (GeoclueConnectivity *self,
+ GeoclueNetworkStatus status,
+ gpointer data)
+{
+ const char *str;
+
+ switch (status) {
+ case GEOCLUE_CONNECTIVITY_UNKNOWN:
+ str = "GEOCLUE_CONNECTIVITY_UNKNOWN";
+ break;
+ case GEOCLUE_CONNECTIVITY_OFFLINE:
+ str = "GEOCLUE_CONNECTIVITY_OFFLINE";
+ break;
+ case GEOCLUE_CONNECTIVITY_ACQUIRING:
+ str = "GEOCLUE_CONNECTIVITY_ACQUIRING";
+ break;
+ case GEOCLUE_CONNECTIVITY_ONLINE:
+ str = "GEOCLUE_CONNECTIVITY_ONLINE";
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ g_message ("Connectivity status switch to '%s'", str);
+
+ print_if_avail (self, status);
+}
+
+int main (int argc, char **argv)
+{
+ GMainLoop *mainloop;
+ GeoclueConnectivity *conn;
+ char *router;
+
+ g_type_init ();
+ mainloop = g_main_loop_new (NULL, FALSE);
+ conn = geoclue_connectivity_new ();
+
+ if (conn == NULL) {
+ router = geoclue_connectivity_get_router_mac (conn);
+ g_message ("Router MAC is detected as '%s'", router ? router : "empty");
+
+ return 1;
+ }
+ print_if_avail (conn, geoclue_connectivity_get_status (conn));
+ g_signal_connect (conn, "status-changed",
+ G_CALLBACK (status_changed_cb), NULL);
+
+ g_main_loop_run (mainloop);
+
+ return 0;
+}