diff options
author | gusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059> | 2014-05-28 17:23:49 +0800 |
---|---|---|
committer | gusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059> | 2014-05-28 17:23:49 +0800 |
commit | ed9eda94eefbd05c94b0be722e4d4fcc42bf8f5c (patch) | |
tree | 1d1358f0525cd31b6f743fbaed435c6068cca77d | |
parent | c8c049c26fef8de5192d024460204ac03f9f484c (diff) | |
download | marcuscom-ports-ed9eda94eefbd05c94b0be722e4d4fcc42bf8f5c.tar marcuscom-ports-ed9eda94eefbd05c94b0be722e4d4fcc42bf8f5c.tar.gz marcuscom-ports-ed9eda94eefbd05c94b0be722e4d4fcc42bf8f5c.tar.bz2 marcuscom-ports-ed9eda94eefbd05c94b0be722e4d4fcc42bf8f5c.tar.lz marcuscom-ports-ed9eda94eefbd05c94b0be722e4d4fcc42bf8f5c.tar.xz marcuscom-ports-ed9eda94eefbd05c94b0be722e4d4fcc42bf8f5c.tar.zst marcuscom-ports-ed9eda94eefbd05c94b0be722e4d4fcc42bf8f5c.zip |
Bring in the patches [1], [2] that make geoclue use wpa_supplicant instead
of NetworkManager (too linuxist for the linux people).
[1] http://cgit.freedesktop.org/geoclue
[2] Commits from e7760ff56a81 to c3f55aae540b
git-svn-id: svn://creme-brulee.marcuscom.com/ports/trunk@19706 df743ca5-7f9a-e211-a948-0013205c9059
-rw-r--r-- | net/geoclue/Makefile | 10 | ||||
-rw-r--r-- | net/geoclue/files/patch-configure.ac | 30 | ||||
-rw-r--r-- | net/geoclue/files/patch-data_org.freedesktop.GeoClue2.conf.in | 43 | ||||
-rw-r--r-- | net/geoclue/files/patch-src_Makefile.am | 68 | ||||
-rw-r--r-- | net/geoclue/files/patch-src_fi.w1.wpa_supplicant1.xml | 41 | ||||
-rw-r--r-- | net/geoclue/files/patch-src_gclue-web-source.c | 12 | ||||
-rw-r--r-- | net/geoclue/files/patch-src_gclue-wifi.c | 835 |
7 files changed, 1036 insertions, 3 deletions
diff --git a/net/geoclue/Makefile b/net/geoclue/Makefile index 04f26a81a..11012e6bd 100644 --- a/net/geoclue/Makefile +++ b/net/geoclue/Makefile @@ -4,6 +4,7 @@ PORTNAME= geoclue PORTVERSION= 2.1.8 +PORTREVISION= 2 CATEGORIES= net devel gnome MASTER_SITES= http://www.freedesktop.org/software/geoclue/releases/2.1/ @@ -15,13 +16,16 @@ LIB_DEPENDS= libjson-glib-1.0.so:${PORTSDIR}/devel/json-glib \ USES= gettext gmake pathfix pkgconfig tar:xz USE_GNOME= glib20 gnomehier intlhack +USE_AUTOTOOLS= autoconf automake GNU_CONFIGURE= yes USE_LDCONFIG= yes +PATHFIX_MAKEFILEIN= Makefile.am CONFIGURE_ARGS= --disable-3g-source \ - --disable-modem-gps-source \ - --disable-network-manager \ - --disable-wifi-source + --disable-modem-gps-source CPPFLAGS+= -I${LOCALBASE}/include LDFLAGS+= -L${LOCALBASE}/lib +pre-configure: + cd ${WRKSRC} && aclocal && autoconf + .include <bsd.port.mk> diff --git a/net/geoclue/files/patch-configure.ac b/net/geoclue/files/patch-configure.ac new file mode 100644 index 000000000..319cafca4 --- /dev/null +++ b/net/geoclue/files/patch-configure.ac @@ -0,0 +1,30 @@ +diff --git a/configure.ac b/configure.ac +index e1932ef..8a90057 100644 +--- configure.ac.orig ++++ configure.ac +@@ -40,7 +40,6 @@ AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[The name of the gettext d + GLIB_MIN_VERSION=2.34.0 + JSON_GLIB_MIN_VERSION=0.14 + GEOIP_MIN_VERSION=1.5.1 +-LIBNM_GLIB_MIN_VERSION=0.9.8.0 + LIBMM_GLIB_MIN_VERSION=1.0 + LIBXML_MIN_VERSION=2.7 + +@@ -84,17 +83,6 @@ else + fi + AM_CONDITIONAL([BUILD_MODEM_GPS_SOURCE], [test "$build_modem_gps_source" = "yes"]) + +-# NetworkManager +-AC_ARG_ENABLE(network-manager, +- AS_HELP_STRING([--disable-network-manager], [Disable use of NetworkManager)]), +- [use_nm=$enableval], [use_nm=yes]) +-if test "$use_nm" = "yes"; then +- PKG_CHECK_MODULES(NetworkManager, libnm-glib >= $LIBNM_GLIB_MIN_VERSION) +- AC_DEFINE([GCLUE_USE_NETWORK_MANAGER], [1], [Use NetowrkManager?]) +-else +- AC_DEFINE([GCLUE_USE_NETWORK_MANAGER], [0], [Use NetowrkManager?]) +-fi +- + # Modem source is used in common by GPS and 3G sources + if test "$build_modem_source" = "yes"; then + require_modemmanager=yes diff --git a/net/geoclue/files/patch-data_org.freedesktop.GeoClue2.conf.in b/net/geoclue/files/patch-data_org.freedesktop.GeoClue2.conf.in new file mode 100644 index 000000000..b0591de0e --- /dev/null +++ b/net/geoclue/files/patch-data_org.freedesktop.GeoClue2.conf.in @@ -0,0 +1,43 @@ +--- data/org.freedesktop.GeoClue2.conf.in.orig 2014-02-24 18:07:18.000000000 +0000 ++++ data/org.freedesktop.GeoClue2.conf.in 2014-05-26 11:06:39.353916380 +0000 +@@ -12,28 +12,19 @@ + <!-- Only allow @dbus_srv_user@ to own the name on the bus --> + <allow own="org.freedesktop.GeoClue2"/> + +- <!-- Also give @dbus_srv_user@ access to needed NetworkManager API --> +- <allow send_destination="org.freedesktop.NetworkManager"/> ++ <!-- Also give @dbus_srv_user@ access to wpa_supplicant API --> ++ <allow receive_sender="fi.w1.wpa_supplicant1" ++ receive_type="signal"/> ++ ++ <allow send_destination="fi.w1.wpa_supplicant1" ++ send_interface="org.freedesktop.DBus.Properties" ++ send_member="Get"/> ++ ++ <allow send_destination="fi.w1.wpa_supplicant1" ++ send_interface="org.freedesktop.DBus.Properties" ++ send_member="GetAll"/> + +- <allow send_destination="org.freedesktop.NetworkManager" ++ <allow send_destination="fi.w1.wpa_supplicant1" + send_interface="org.freedesktop.DBus.Introspectable"/> +- +- <allow send_destination="org.freedesktop.NetworkManager" +- send_interface="org.freedesktop.DBus.Properties"/> +- +- <allow send_destination="org.freedesktop.NetworkManager" +- send_interface="org.freedesktop.NetworkManager"/> +- +- <allow send_destination="org.freedesktop.NetworkManager" +- send_interface="org.freedesktop.NetworkManager.AccessPoint"/> +- +- <allow send_destination="org.freedesktop.NetworkManager" +- send_interface="org.freedesktop.NetworkManager.Connection.Active"/> +- +- <allow send_destination="org.freedesktop.NetworkManager" +- send_interface="org.freedesktop.NetworkManager.Device.Wireless"/> +- +- <allow send_destination="org.freedesktop.NetworkManager" +- send_interface="org.freedesktop.NetworkManager.Device"/> + </policy> + </busconfig> diff --git a/net/geoclue/files/patch-src_Makefile.am b/net/geoclue/files/patch-src_Makefile.am new file mode 100644 index 000000000..a777828b5 --- /dev/null +++ b/net/geoclue/files/patch-src_Makefile.am @@ -0,0 +1,68 @@ +--- src/Makefile.am.orig 2014-04-09 19:10:17.000000000 +0000 ++++ src/Makefile.am 2014-05-26 11:05:02.268923512 +0000 +@@ -7,7 +7,10 @@ + interfacedir = $(datadir)/dbus-1/interfaces + interface_DATA = org.freedesktop.GeoClue2.xml + +-dbus_built_sources = geoclue-interface.c geoclue-interface.h ++dbus_built_sources = geoclue-interface.c \ ++ geoclue-interface.h \ ++ wpa_supplicant-interface.c \ ++ wpa_supplicant-interface.h + geoclue-interface.c: geoclue-interface.h + geoclue-interface.h: Makefile.am $(interface_DATA) + $(AM_V_GEN)$(GDBUS_CODEGEN) \ +@@ -17,6 +20,27 @@ + --generate-docbook=docs \ + $(srcdir)/$(interface_DATA) + ++wpa_supplicant-interface.c: wpa_supplicant-interface.h ++wpa_supplicant-interface.h: Makefile.am fi.w1.wpa_supplicant1.xml ++ $(AM_V_GEN)$(GDBUS_CODEGEN) \ ++ --interface-prefix fi.w1 \ ++ --annotate "fi.w1.wpa_supplicant1" \ ++ org.gtk.GDBus.C.Name WPA_Supplicant \ ++ --annotate "fi.w1.wpa_supplicant1.Interface" \ ++ org.gtk.GDBus.C.Name WPA_Interface \ ++ --annotate "fi.w1.wpa_supplicant1.BSS" \ ++ org.gtk.GDBus.C.Name WPA_BSS \ ++ --annotate "fi.w1.wpa_supplicant1.BSS:SSID" \ ++ org.gtk.GDBus.C.ForceGVariant whatever \ ++ --annotate "fi.w1.wpa_supplicant1.BSS:BSSID" \ ++ org.gtk.GDBus.C.ForceGVariant whatever \ ++ --annotate "fi.w1.wpa_supplicant1.Interface::BSSAdded" \ ++ org.gtk.GDBus.C.Name BSS_Added \ ++ --annotate "fi.w1.wpa_supplicant1.Interface::BSSRemoved" \ ++ org.gtk.GDBus.C.Name BSS_Removed \ ++ --generate-c-code wpa_supplicant-interface \ ++ $(srcdir)/fi.w1.wpa_supplicant1.xml ++ + BUILT_SOURCES = \ + $(dbus_built_sources) \ + $(NULL) +@@ -25,7 +49,6 @@ + + AM_CPPFLAGS = $(GEOCLUE_CFLAGS) \ + $(ModemManager_CFLAGS) \ +- $(NetworkManager_CFLAGS) \ + $(WARN_CFLAGS) \ + -DLOCALEDIR="\"$(datadir)/locale\"" \ + -DG_LOG_DOMAIN=\""Geoclue"\" \ +@@ -74,7 +97,6 @@ + + libgeoclue_la_LIBADD = \ + $(GEOCLUE_LIBS) \ +- $(NetworkManager_LIBS) \ + $(ModemManager_LIBS) \ + $(LIBS) \ + $(NULL) +@@ -91,8 +113,7 @@ + + CLEANFILES = $(BUILT_SOURCES) + EXTRA_DIST = $(interface_DATA) \ +- test-data/fedora-geoip-results.json \ +- test-data/freegeoip-results.json ++ fi.w1.wpa_supplicant1.xml + + pkgconfigdir = $(libdir)/pkgconfig + pkgconfig_DATA = geoclue-$(GEOCLUE_API_VERSION).pc diff --git a/net/geoclue/files/patch-src_fi.w1.wpa_supplicant1.xml b/net/geoclue/files/patch-src_fi.w1.wpa_supplicant1.xml new file mode 100644 index 000000000..d0fb18a1d --- /dev/null +++ b/net/geoclue/files/patch-src_fi.w1.wpa_supplicant1.xml @@ -0,0 +1,41 @@ +--- /dev/null 2014-05-26 11:34:48.000000000 +0000 ++++ src/fi.w1.wpa_supplicant1.xml 2014-05-26 11:35:59.296015210 +0000 +@@ -0,0 +1,38 @@ ++<?xml version="1.0"?> ++<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" ++ "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> ++<node> ++ ++<interface name="fi.w1.wpa_supplicant1"> ++ ++<signal name="InterfaceAdded"> ++<arg name="path" type="o"/> ++<arg name="properties" type="a{sv}"/> ++</signal> ++<signal name="InterfaceRemoved"> ++<arg name="path" type="o"/> ++</signal> ++<property name="Interfaces" type="ao" access="read"/> ++</interface> ++ ++<interface name="fi.w1.wpa_supplicant1.Interface"> ++<signal name="BSSAdded"> ++<arg name="path" type="o"/> ++<arg name="properties" type="a{sv}"/> ++</signal> ++<signal name="BSSRemoved"> ++<arg name="path" type="o"/> ++</signal> ++<property name="State" type="s" access="read"/> ++<property name="Ifname" type="s" access="read"/> ++<property name="BSSs" type="ao" access="read"/> ++</interface> ++ ++<interface name="fi.w1.wpa_supplicant1.BSS"> ++<property name="SSID" type="ay" access="read"/> ++<property name="BSSID" type="ay" access="read"/> ++<property name="Signal" type="n" access="read"/> ++<property name="Frequency" type="q" access="read"/> ++</interface> ++ ++</node> diff --git a/net/geoclue/files/patch-src_gclue-web-source.c b/net/geoclue/files/patch-src_gclue-web-source.c new file mode 100644 index 000000000..b731f9870 --- /dev/null +++ b/net/geoclue/files/patch-src_gclue-web-source.c @@ -0,0 +1,12 @@ +diff --git a/src/gclue-web-source.c b/src/gclue-web-source.c +index cd0ee89..13c50ef 100644 +--- src/gclue-web-source.c.orig ++++ src/gclue-web-source.c +@@ -257,7 +257,6 @@ gclue_web_source_start (GClueLocationSource *source) + if (!base_class->start (source)) + return FALSE; + +- gclue_web_source_refresh (GCLUE_WEB_SOURCE (source)); + return TRUE; + } + diff --git a/net/geoclue/files/patch-src_gclue-wifi.c b/net/geoclue/files/patch-src_gclue-wifi.c new file mode 100644 index 000000000..b46069bfd --- /dev/null +++ b/net/geoclue/files/patch-src_gclue-wifi.c @@ -0,0 +1,835 @@ +--- src/gclue-wifi.c.orig 2014-04-11 17:20:33.000000000 +0000 ++++ src/gclue-wifi.c 2014-05-26 11:09:34.546901854 +0000 +@@ -25,11 +25,8 @@ + #include <json-glib/json-glib.h> + #include <string.h> + #include <config.h> +-#if GCLUE_USE_NETWORK_MANAGER +-#include <nm-client.h> +-#include <nm-device-wifi.h> +-#endif + #include "gclue-wifi.h" ++#include "wpa_supplicant-interface.h" + #include "gclue-config.h" + #include "gclue-error.h" + #include "geocode-glib/geocode-location.h" +@@ -45,19 +42,19 @@ + * configuration file so its easy to switch to Google's API. + **/ + +-#if GCLUE_USE_NETWORK_MANAGER + static gboolean + gclue_wifi_start (GClueLocationSource *source); + static gboolean + gclue_wifi_stop (GClueLocationSource *source); +-#endif + + struct _GClueWifiPrivate { +-#if GCLUE_USE_NETWORK_MANAGER +- NMClient *client; +- NMDeviceWifi *wifi_device; +-#endif +- gulong ap_added_id; ++ WPASupplicant *supplicant; ++ WPAInterface *interface; ++ GHashTable *bss_proxies; ++ GHashTable *ignored_bss_proxies; ++ ++ gulong bss_added_id; ++ gulong bss_removed_id; + + guint refresh_timeout; + +@@ -75,12 +72,10 @@ + static SoupMessage * + gclue_wifi_create_query (GClueWebSource *source, + GError **error); +-#if GCLUE_USE_NETWORK_MANAGER + static SoupMessage * + gclue_wifi_create_submit_query (GClueWebSource *source, + GeocodeLocation *location, + GError **error); +-#endif + static GeocodeLocation * + gclue_wifi_parse_response (GClueWebSource *source, + const char *json, +@@ -91,9 +86,8 @@ + + G_DEFINE_TYPE (GClueWifi, gclue_wifi, GCLUE_TYPE_WEB_SOURCE) + +-#if GCLUE_USE_NETWORK_MANAGER + static void +-disconnect_ap_signals (GClueWifi *wifi); ++disconnect_bss_signals (GClueWifi *wifi); + + static void + gclue_wifi_finalize (GObject *gwifi) +@@ -102,13 +96,12 @@ + + G_OBJECT_CLASS (gclue_wifi_parent_class)->finalize (gwifi); + +- if (wifi->priv->wifi_device != NULL) { +- disconnect_ap_signals (wifi); +- wifi->priv->wifi_device = NULL; +- } +- g_clear_object (&wifi->priv->client); ++ disconnect_bss_signals (wifi); ++ g_clear_object (&wifi->priv->supplicant); ++ g_clear_object (&wifi->priv->interface); ++ g_clear_pointer (&wifi->priv->bss_proxies, g_hash_table_unref); ++ g_clear_pointer (&wifi->priv->ignored_bss_proxies, g_hash_table_unref); + } +-#endif + + static void + gclue_wifi_constructed (GObject *object); +@@ -153,25 +146,19 @@ + gclue_wifi_class_init (GClueWifiClass *klass) + { + GClueWebSourceClass *web_class = GCLUE_WEB_SOURCE_CLASS (klass); +-#if GCLUE_USE_NETWORK_MANAGER + GClueLocationSourceClass *source_class = GCLUE_LOCATION_SOURCE_CLASS (klass); +-#endif + GObjectClass *gwifi_class = G_OBJECT_CLASS (klass); + +-#if GCLUE_USE_NETWORK_MANAGER + source_class->start = gclue_wifi_start; + source_class->stop = gclue_wifi_stop; + web_class->create_submit_query = gclue_wifi_create_submit_query; +-#endif + web_class->create_query = gclue_wifi_create_query; + web_class->parse_response = gclue_wifi_parse_response; + web_class->get_available_accuracy_level = + gclue_wifi_get_available_accuracy_level; + gwifi_class->get_property = gclue_wifi_get_property; + gwifi_class->set_property = gclue_wifi_set_property; +-#if GCLUE_USE_NETWORK_MANAGER + gwifi_class->finalize = gclue_wifi_finalize; +-#endif + gwifi_class->constructed = gclue_wifi_constructed; + + g_type_class_add_private (klass, sizeof (GClueWifiPrivate)); +@@ -188,7 +175,6 @@ + gParamSpecs[PROP_ACCURACY_LEVEL]); + } + +-#if GCLUE_USE_NETWORK_MANAGER + static gboolean + on_refresh_timeout (gpointer user_data) + { +@@ -200,118 +186,259 @@ + } + + static void +-on_ap_added (NMDeviceWifi *device, +- NMAccessPoint *ap, +- gpointer user_data); ++on_bss_added (WPAInterface *object, ++ const gchar *path, ++ GVariant *properties, ++ gpointer user_data); ++ ++static char * ++variant_to_string (GVariant *variant, guint *len) ++{ ++ guint n_bytes, i; ++ char *ret; ++ ++ n_bytes = g_variant_n_children (variant); ++ if (len != NULL) ++ *len = n_bytes; ++ if (n_bytes <= 0) ++ return NULL; ++ ret = g_malloc (n_bytes + 1); ++ ret[n_bytes] = '\0'; ++ ++ for (i = 0; i < n_bytes; i++) ++ g_variant_get_child (variant, ++ i, ++ "y", ++ &ret[i]); ++ ++ return ret; ++} ++ ++static char * ++get_ssid_from_bss (WPABSS *bss) ++{ ++ GVariant *variant = wpa_bss_get_ssid (bss); ++ ++ return variant_to_string (variant, NULL); ++} ++ ++static char * ++get_bssid_from_bss (WPABSS *bss) ++{ ++ GVariant *variant; ++ char *raw_bssid; ++ char *bssid; ++ guint raw_len, len, i, j; ++ ++ variant = wpa_bss_get_bssid (bss); ++ ++ raw_bssid = variant_to_string (variant, &raw_len); ++ len = raw_len * 2 + raw_len; ++ bssid = g_malloc (len); ++ for (i = 0, j = 0; i < len; i = i + 3, j++) ++ g_snprintf (bssid + i, ++ 4, ++ "%02x:", ++ (unsigned char) raw_bssid[j]); ++ bssid[len - 1] = '\0'; ++ ++ return bssid; ++} + + static void +-on_ap_strength_notify (GObject *gobject, +- GParamSpec *pspec, +- gpointer user_data) ++on_bss_signal_notify (GObject *gobject, ++ GParamSpec *pspec, ++ gpointer user_data) + { + GClueWifi *wifi = GCLUE_WIFI (user_data); +- NMAccessPoint *ap = NM_ACCESS_POINT (gobject); ++ WPABSS *bss = WPA_BSS (gobject); ++ const char *path; + +- if (nm_access_point_get_strength (ap) <= 20) { +- g_debug ("WiFi AP '%s' still has very low strength (%u)" ++ if (wpa_bss_get_signal (bss) <= -90) { ++ char *bssid = get_bssid_from_bss (bss); ++ g_debug ("WiFi AP '%s' still has very low strength (%u dBm)" + ", ignoring again..", +- nm_access_point_get_bssid (ap), +- nm_access_point_get_strength (ap)); ++ bssid, ++ wpa_bss_get_signal (bss)); ++ g_free (bssid); + return; + } ++ path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (bss)); + +- g_signal_handlers_disconnect_by_func (G_OBJECT (ap), +- on_ap_strength_notify, ++ g_signal_handlers_disconnect_by_func (G_OBJECT (bss), ++ on_bss_signal_notify, + user_data); +- on_ap_added (wifi->priv->wifi_device, ap, user_data); ++ on_bss_added (WPA_INTERFACE (wifi->priv->interface), ++ path, ++ NULL, ++ user_data); ++ ++ g_hash_table_replace (wifi->priv->bss_proxies, ++ g_strdup (path), ++ bss); ++ g_hash_table_remove (wifi->priv->ignored_bss_proxies, path); + } + + static gboolean +-should_ignore_ap (NMAccessPoint *ap) ++should_ignore_bss (WPABSS *bss) + { +- const GByteArray *ssid; ++ char *ssid, *bssid; + +- ssid = nm_access_point_get_ssid (ap); +- if (ssid == NULL || +- (ssid->len >= 6 && +- ssid->data[ssid->len - 1] == 'p' && +- ssid->data[ssid->len - 2] == 'a' && +- ssid->data[ssid->len - 3] == 'm' && +- ssid->data[ssid->len - 4] == 'o' && +- ssid->data[ssid->len - 5] == 'n' && +- ssid->data[ssid->len - 6] == '_')) { ++ ssid = get_ssid_from_bss (bss); ++ bssid = get_bssid_from_bss (bss); ++ if (ssid == NULL || g_str_has_suffix (ssid, "_nomap")) { + g_debug ("SSID for WiFi AP '%s' missing or has '_nomap' suffix." + ", Ignoring..", +- nm_access_point_get_bssid (ap)); ++ bssid); + return TRUE; + } ++ g_free (ssid); ++ g_free (bssid); + + return FALSE; + } + + static void +-on_ap_added (NMDeviceWifi *device, +- NMAccessPoint *ap, +- gpointer user_data) ++on_bss_proxy_ready (GObject *source_object, ++ GAsyncResult *res, ++ gpointer user_data) + { + GClueWifi *wifi = GCLUE_WIFI (user_data); ++ WPABSS *bss; ++ GError *error = NULL; ++ const char *path; ++ char *ssid; ++ ++ bss = wpa_bss_proxy_new_for_bus_finish (res, &error); ++ if (bss == NULL) { ++ g_debug ("%s", error->message); ++ g_error_free (error); + +- if (wifi->priv->refresh_timeout != 0) + return; +- g_debug ("WiFi AP '%s' added.", nm_access_point_get_bssid (ap)); ++ } ++ path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (bss)); ++ ++ if (should_ignore_bss (bss)) { ++ g_object_unref (bss); + +- if (should_ignore_ap (ap)) + return; ++ } + +- if (nm_access_point_get_strength (ap) <= 20) { +- g_debug ("WiFi AP '%s' has very low strength (%u)" ++ ssid = get_ssid_from_bss (bss); ++ g_debug ("WiFi AP '%s' added.", ssid); ++ g_free (ssid); ++ ++ path = g_dbus_proxy_get_object_path (G_DBUS_PROXY (bss)); ++ if (wpa_bss_get_signal (bss) <= -90) { ++ char *bssid = get_bssid_from_bss (bss); ++ g_debug ("WiFi AP '%s' has very low strength (%u dBm)" + ", ignoring for now..", +- nm_access_point_get_bssid (ap), +- nm_access_point_get_strength (ap)); +- g_signal_connect (G_OBJECT (ap), +- "notify::strength", +- G_CALLBACK (on_ap_strength_notify), ++ bssid, ++ wpa_bss_get_signal (bss)); ++ g_free (bssid); ++ g_signal_connect (G_OBJECT (bss), ++ "notify::signal", ++ G_CALLBACK (on_bss_signal_notify), + user_data); ++ g_hash_table_replace (wifi->priv->ignored_bss_proxies, ++ g_strdup (path), ++ bss); + return; + } + ++ + /* There could be multiple devices being added/removed at the same time + * so we don't immediately call refresh but rather wait 1 second. + */ ++ if (wifi->priv->refresh_timeout != 0) ++ g_source_remove (wifi->priv->refresh_timeout); + wifi->priv->refresh_timeout = g_timeout_add_seconds (1, + on_refresh_timeout, + wifi); ++ g_hash_table_replace (wifi->priv->bss_proxies, ++ g_strdup (path), ++ bss); ++} ++ ++static void ++on_bss_added (WPAInterface *object, ++ const gchar *path, ++ GVariant *properties, ++ gpointer user_data) ++{ ++ wpa_bss_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_NONE, ++ "fi.w1.wpa_supplicant1", ++ path, ++ NULL, ++ on_bss_proxy_ready, ++ user_data); + } + + static void +-connect_ap_signals (GClueWifi *wifi) ++on_bss_removed (WPAInterface *object, ++ const gchar *path, ++ gpointer user_data) ++{ ++ GClueWifiPrivate *priv = GCLUE_WIFI (user_data)->priv; ++ ++ g_hash_table_remove (priv->bss_proxies, path); ++ g_hash_table_remove (priv->ignored_bss_proxies, path); ++} ++ ++static void ++connect_bss_signals (GClueWifi *wifi) + { + GClueWifiPrivate *priv = wifi->priv; ++ const gchar *const *bss_list; ++ guint i; + +- if (priv->ap_added_id != 0 || priv->wifi_device == NULL) ++ if (priv->bss_added_id != 0) + return; ++ if (priv->interface == NULL) { ++ if (wifi->priv->accuracy_level == GCLUE_ACCURACY_LEVEL_CITY) ++ gclue_web_source_refresh (GCLUE_WEB_SOURCE (wifi)); + +- priv->ap_added_id = g_signal_connect (priv->wifi_device, +- "access-point-added", +- G_CALLBACK (on_ap_added), ++ return; ++ } ++ ++ priv->bss_added_id = g_signal_connect (priv->interface, ++ "bss-added", ++ G_CALLBACK (on_bss_added), + wifi); ++ priv->bss_removed_id = g_signal_connect (priv->interface, ++ "bss-removed", ++ G_CALLBACK (on_bss_removed), ++ wifi); ++ ++ bss_list = wpa_interface_get_bsss (WPA_INTERFACE (priv->interface)); ++ for (i = 0; bss_list[i] != NULL; i++) ++ on_bss_added (WPA_INTERFACE (priv->interface), ++ bss_list[i], ++ NULL, ++ wifi); + } + + static void +-disconnect_ap_signals (GClueWifi *wifi) ++disconnect_bss_signals (GClueWifi *wifi) + { + GClueWifiPrivate *priv = wifi->priv; + +- if (priv->ap_added_id == 0 || priv->wifi_device == NULL) ++ if (priv->bss_added_id == 0 || priv->interface == NULL) + return; + +- g_signal_handler_disconnect (priv->wifi_device, priv->ap_added_id); +- priv->ap_added_id = 0; ++ g_signal_handler_disconnect (priv->interface, priv->bss_added_id); ++ priv->bss_added_id = 0; ++ g_signal_handler_disconnect (priv->interface, priv->bss_removed_id); ++ priv->bss_removed_id = 0; + + if (priv->refresh_timeout != 0) { + g_source_remove (priv->refresh_timeout); + priv->refresh_timeout = 0; + } ++ ++ g_hash_table_remove_all (wifi->priv->bss_proxies); ++ g_hash_table_remove_all (wifi->priv->ignored_bss_proxies); + } + + static gboolean +@@ -325,7 +452,7 @@ + if (!base_class->start (source)) + return FALSE; + +- connect_ap_signals (GCLUE_WIFI (source)); ++ connect_bss_signals (GCLUE_WIFI (source)); + return TRUE; + } + +@@ -340,10 +467,9 @@ + if (!base_class->stop (source)) + return FALSE; + +- disconnect_ap_signals (GCLUE_WIFI (source)); ++ disconnect_bss_signals (GCLUE_WIFI (source)); + return TRUE; + } +-#endif + + static GClueAccuracyLevel + gclue_wifi_get_available_accuracy_level (GClueWebSource *source, +@@ -351,103 +477,150 @@ + { + if (!net_available) + return GCLUE_ACCURACY_LEVEL_NONE; +- +-#if GCLUE_USE_NETWORK_MANAGER +- return (GCLUE_WIFI (source)->priv->wifi_device != NULL)? +- GCLUE_ACCURACY_LEVEL_STREET : +- GCLUE_ACCURACY_LEVEL_CITY; +-#else +- return GCLUE_ACCURACY_LEVEL_CITY; +-#endif ++ else if (GCLUE_WIFI (source)->priv->interface != NULL) ++ return GCLUE_ACCURACY_LEVEL_STREET; ++ else ++ return GCLUE_ACCURACY_LEVEL_CITY; + } + +-#if GCLUE_USE_NETWORK_MANAGER +-static void +-on_device_added (NMClient *client, +- NMDevice *device, +- gpointer user_data) ++static void ++on_interface_proxy_ready (GObject *source_object, ++ GAsyncResult *res, ++ gpointer user_data) + { + GClueWifi *wifi = GCLUE_WIFI (user_data); ++ WPAInterface *interface; ++ GError *error = NULL; ++ ++ interface = wpa_interface_proxy_new_for_bus_finish (res, &error); ++ if (interface == NULL) { ++ g_debug ("%s", error->message); ++ g_error_free (error); + +- if (wifi->priv->wifi_device != NULL || !NM_IS_DEVICE_WIFI (device)) + return; ++ } + +- wifi->priv->wifi_device = NM_DEVICE_WIFI (device); ++ if (wifi->priv->interface != NULL) { ++ g_object_unref (interface); ++ return; ++ } ++ ++ wifi->priv->interface = interface; + g_debug ("WiFi device '%s' added.", +- nm_device_wifi_get_hw_address (wifi->priv->wifi_device)); ++ wpa_interface_get_ifname (interface)); + + if (gclue_location_source_get_active (GCLUE_LOCATION_SOURCE (wifi))) +- connect_ap_signals (wifi); ++ connect_bss_signals (wifi); ++ else ++ gclue_web_source_refresh (GCLUE_WEB_SOURCE (wifi)); ++} + +- gclue_web_source_refresh (GCLUE_WEB_SOURCE (wifi)); ++static void ++on_interface_added (WPASupplicant *supplicant, ++ const gchar *path, ++ GVariant *properties, ++ gpointer user_data) ++{ ++ GClueWifi *wifi = GCLUE_WIFI (user_data); ++ ++ if (wifi->priv->interface != NULL) ++ return; ++ ++ wpa_interface_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_NONE, ++ "fi.w1.wpa_supplicant1", ++ path, ++ NULL, ++ on_interface_proxy_ready, ++ wifi); + } + + static void +-on_device_removed (NMClient *client, +- NMDevice *device, +- gpointer user_data) ++on_interface_removed (WPASupplicant *supplicant, ++ const gchar *path, ++ gpointer user_data) + { + GClueWifi *wifi = GCLUE_WIFI (user_data); ++ GClueWifiPrivate *priv = wifi->priv; ++ const char *object_path; + +- if (wifi->priv->wifi_device == NULL || +- NM_DEVICE (wifi->priv->wifi_device) != device) ++ if (priv->interface == NULL) + return; ++ ++ object_path = g_dbus_proxy_get_object_path ++ (G_DBUS_PROXY (priv->interface)); ++ if (g_strcmp0 (object_path, path) != 0) ++ return; ++ + g_debug ("WiFi device '%s' removed.", +- nm_device_wifi_get_hw_address (wifi->priv->wifi_device)); ++ wpa_interface_get_ifname (priv->interface)); + +- disconnect_ap_signals (wifi); +- wifi->priv->wifi_device = NULL; ++ disconnect_bss_signals (wifi); ++ g_clear_object (&wifi->priv->interface); + + gclue_web_source_refresh (GCLUE_WEB_SOURCE (wifi)); + } +-#endif + + static void + gclue_wifi_init (GClueWifi *wifi) + { + wifi->priv = G_TYPE_INSTANCE_GET_PRIVATE ((wifi), GCLUE_TYPE_WIFI, GClueWifiPrivate); ++ ++ wifi->priv->bss_proxies = g_hash_table_new_full (g_str_hash, ++ g_str_equal, ++ g_free, ++ g_object_unref); ++ wifi->priv->ignored_bss_proxies = g_hash_table_new_full (g_str_hash, ++ g_str_equal, ++ g_free, ++ g_object_unref); + } + + static void + gclue_wifi_constructed (GObject *object) + { +-#if GCLUE_USE_NETWORK_MANAGER + GClueWifi *wifi = GCLUE_WIFI (object); +- const GPtrArray *devices; +- guint i; ++ GClueWifiPrivate *priv = wifi->priv; ++ const gchar *const *interfaces; ++ GError *error = NULL; + + G_OBJECT_CLASS (gclue_wifi_parent_class)->constructed (object); + + if (wifi->priv->accuracy_level == GCLUE_ACCURACY_LEVEL_CITY) + goto refresh_n_exit; + +- wifi->priv->client = nm_client_new (); /* FIXME: We should be using async variant */ +- g_signal_connect (wifi->priv->client, +- "device-added", +- G_CALLBACK (on_device_added), +- wifi); +- g_signal_connect (wifi->priv->client, +- "device-removed", +- G_CALLBACK (on_device_removed), +- wifi); +- +- devices = nm_client_get_devices (wifi->priv->client); +- if (devices == NULL) ++ /* FIXME: We should be using async variant */ ++ priv->supplicant = wpa_supplicant_proxy_new_for_bus_sync ++ (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_NONE, ++ "fi.w1.wpa_supplicant1", ++ "/fi/w1/wpa_supplicant1", ++ NULL, ++ &error); ++ if (priv->supplicant == NULL) { ++ g_warning ("Failed to connect to wpa_supplicant service: %s", ++ error->message); ++ g_error_free (error); + goto refresh_n_exit; ++ } + +- for (i = 0; i < devices->len; i++) { +- NMDevice *device = g_ptr_array_index (devices, i); +- if (NM_IS_DEVICE_WIFI (device)) { +- on_device_added (wifi->priv->client, device, wifi); ++ g_signal_connect (priv->supplicant, ++ "interface-added", ++ G_CALLBACK (on_interface_added), ++ wifi); ++ g_signal_connect (priv->supplicant, ++ "interface-removed", ++ G_CALLBACK (on_interface_removed), ++ wifi); + +- break; +- } +- } ++ interfaces = wpa_supplicant_get_interfaces (priv->supplicant); ++ if (interfaces != NULL && interfaces[0] != NULL) ++ on_interface_added (priv->supplicant, ++ interfaces[0], ++ NULL, ++ wifi); + + refresh_n_exit: +-#else +- G_OBJECT_CLASS (gclue_wifi_parent_class)->constructed (object); +-#endif + gclue_web_source_refresh (GCLUE_WEB_SOURCE (object)); + } + +@@ -509,14 +682,11 @@ + return gclue_config_get_wifi_url (config); + } + +-#if GCLUE_USE_NETWORK_MANAGER +-static const GPtrArray * +-get_ap_list (GClueWifi *wifi, +- GError **error) ++static GList * ++get_bss_list (GClueWifi *wifi, ++ GError **error) + { +- const GPtrArray *aps; +- +- if (wifi->priv->wifi_device == NULL) { ++ if (wifi->priv->interface == NULL) { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, +@@ -524,28 +694,15 @@ + return NULL; + } + +- aps = nm_device_wifi_get_access_points (wifi->priv->wifi_device); +- if (aps == NULL || aps->len == 0) { +- g_set_error_literal (error, +- G_IO_ERROR, +- G_IO_ERROR_FAILED, +- "No WiFi access points around"); +- return NULL; +- } +- +- return aps; ++ return g_hash_table_get_values (wifi->priv->bss_proxies); + } +-#endif + + static SoupMessage * + gclue_wifi_create_query (GClueWebSource *source, + GError **error) + { +-#if GCLUE_USE_NETWORK_MANAGER + GClueWifi *wifi = GCLUE_WIFI (source); +- const GPtrArray *aps; /* As in Access Points */ +- guint i; +-#endif ++ GList *bss_list; /* As in Access Points */ + SoupMessage *ret = NULL; + JsonBuilder *builder; + JsonGenerator *generator; +@@ -560,46 +717,35 @@ + json_builder_set_member_name (builder, "wifiAccessPoints"); + json_builder_begin_array (builder); + +-#if GCLUE_USE_NETWORK_MANAGER +- aps = get_ap_list (wifi, NULL); +- if (aps != NULL) { +- for (i = 0; i < aps->len; i++) { +- NMAccessPoint *ap = g_ptr_array_index (aps, i); +- const char *mac; +- gint8 strength_dbm; ++ bss_list = get_bss_list (wifi, NULL); ++ /* We send pure geoip query using empty object if bss_list is NULL. */ ++ if (bss_list != NULL) { ++ GList *iter; ++ ++ json_builder_set_member_name (builder, "wifiAccessPoints"); ++ json_builder_begin_array (builder); ++ ++ for (iter = bss_list; iter != NULL; iter = iter->next) { ++ WPABSS *bss = WPA_BSS (iter->data); ++ char *mac; ++ gint16 strength_dbm; + +- if (should_ignore_ap (ap)) ++ if (should_ignore_bss (bss)) + continue; + + json_builder_begin_object (builder); + json_builder_set_member_name (builder, "macAddress"); +- mac = nm_access_point_get_bssid (ap); ++ mac = get_bssid_from_bss (bss); + json_builder_add_string_value (builder, mac); ++ g_free (mac); + + json_builder_set_member_name (builder, "signalStrength"); +- strength_dbm = nm_access_point_get_strength (ap) / +- 2 - 100; ++ strength_dbm = wpa_bss_get_signal (bss); + json_builder_add_int_value (builder, strength_dbm); + json_builder_end_object (builder); + } +- } else { +-#endif +- /* Pure geoip query */ +- +- /* FIXME: Currently we need a dummy AP entry to work around: +- * https://github.com/mozilla/ichnaea/issues/165 +- */ +- json_builder_begin_object (builder); +- json_builder_set_member_name (builder, "macAddress"); +- json_builder_add_string_value (builder, "00:00:00:00:00:00"); +- +- json_builder_set_member_name (builder, "signalStrength"); +- json_builder_add_int_value (builder, -50); +- json_builder_end_object (builder); +-#if GCLUE_USE_NETWORK_MANAGER ++ json_builder_end_array (builder); + } +-#endif +- json_builder_end_array (builder); + json_builder_end_object (builder); + + generator = json_generator_new (); +@@ -679,7 +825,6 @@ + return location; + } + +-#if GCLUE_USE_NETWORK_MANAGER + static char * + get_submit_config (char **nick) + { +@@ -703,8 +848,7 @@ + JsonNode *root_node; + char *data, *timestamp, *url, *nick; + gsize data_len; +- const GPtrArray *aps; /* As in Access Points */ +- guint i, frequency; ++ GList *bss_list, *iter; /* As in Access Points */ + gdouble lat, lon, accuracy, altitude; + GTimeVal tv; + +@@ -712,8 +856,8 @@ + if (url == NULL) + goto out; + +- aps = get_ap_list (wifi, error); +- if (aps == NULL) ++ bss_list = get_bss_list (wifi, error); ++ if (bss_list == NULL) + goto out; + + builder = json_builder_new (); +@@ -754,25 +898,27 @@ + json_builder_set_member_name (builder, "wifi"); + json_builder_begin_array (builder); + +- for (i = 0; i < aps->len; i++) { +- NMAccessPoint *ap = g_ptr_array_index (aps, i); +- const char *mac; +- gint8 strength_dbm; ++ for (iter = bss_list; iter != NULL; iter = iter->next) { ++ WPABSS *bss = WPA_BSS (iter->data); ++ char *mac; ++ gint16 strength_dbm; ++ guint16 frequency; + +- if (should_ignore_ap (ap)) ++ if (should_ignore_bss (bss)) + continue; + + json_builder_begin_object (builder); + json_builder_set_member_name (builder, "key"); +- mac = nm_access_point_get_bssid (ap); ++ mac = get_bssid_from_bss (bss); + json_builder_add_string_value (builder, mac); ++ g_free (mac); + + json_builder_set_member_name (builder, "signal"); +- strength_dbm = nm_access_point_get_strength (ap) / 2 - 100; ++ strength_dbm = wpa_bss_get_signal (bss); + json_builder_add_int_value (builder, strength_dbm); + + json_builder_set_member_name (builder, "frequency"); +- frequency = nm_access_point_get_frequency (ap); ++ frequency = wpa_bss_get_frequency (bss); + json_builder_add_int_value (builder, frequency); + json_builder_end_object (builder); + } +@@ -807,4 +953,3 @@ + out: + return ret; + } +-#endif |