summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059>2014-05-28 17:23:49 +0800
committergusi <gusi@df743ca5-7f9a-e211-a948-0013205c9059>2014-05-28 17:23:49 +0800
commited9eda94eefbd05c94b0be722e4d4fcc42bf8f5c (patch)
tree1d1358f0525cd31b6f743fbaed435c6068cca77d
parentc8c049c26fef8de5192d024460204ac03f9f484c (diff)
downloadmarcuscom-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/Makefile10
-rw-r--r--net/geoclue/files/patch-configure.ac30
-rw-r--r--net/geoclue/files/patch-data_org.freedesktop.GeoClue2.conf.in43
-rw-r--r--net/geoclue/files/patch-src_Makefile.am68
-rw-r--r--net/geoclue/files/patch-src_fi.w1.wpa_supplicant1.xml41
-rw-r--r--net/geoclue/files/patch-src_gclue-web-source.c12
-rw-r--r--net/geoclue/files/patch-src_gclue-wifi.c835
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