From 74ae50185ef5b76f06cdd257c79a42090fabbe5d Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 23 Jun 2009 14:33:41 +0100 Subject: [PATCH] Use NetworkManager to export the AP MAC address Add ability for the connectivity objects to get the MAC address of the wireless APs around. --- configure.ac | 2 +- src/connectivity-networkmanager.c | 68 +++++++++++++++++++++++++++++++++++++ src/connectivity-networkmanager.h | 4 ++ src/connectivity.c | 8 ++++ src/connectivity.h | 3 ++ 5 files changed, 84 insertions(+), 1 deletions(-) diff --git a/configure.ac b/configure.ac index 3109048..71a158e 100644 --- a/configure.ac +++ b/configure.ac @@ -77,7 +77,7 @@ if test "x$HAVE_CONIC" = "xyes"; then fi PKG_CHECK_MODULES(NETWORK_MANAGER, [ - NetworkManager + NetworkManager libnm_glib ], HAVE_NETWORK_MANAGER=yes, HAVE_NETWORK_MANAGER=no) if test "x$HAVE_NETWORK_MANAGER" = "xyes"; then CONNECTIVITY="Network Manager" diff --git a/src/connectivity-networkmanager.c b/src/connectivity-networkmanager.c index 78750dd..eb5e980 100644 --- a/src/connectivity-networkmanager.c +++ b/src/connectivity-networkmanager.c @@ -12,6 +12,12 @@ #include #include /*for DBus strings */ + +#ifdef HAVE_NETWORK_MANAGER +#include +#include +#endif + #include "connectivity-networkmanager.h" static void geoclue_networkmanager_connectivity_init (GeoclueConnectivityInterface *iface); @@ -30,6 +36,59 @@ get_status (GeoclueConnectivity *iface) return nm->status; } +static char * +get_ap_mac (GeoclueConnectivity *iface) +{ + GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (iface); + + return self->cache_ap_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); + if (devices == NULL) { + g_free (self->cache_ap_mac); + self->cache_ap_mac = NULL; + } + + g_free (self->cache_ap_mac); + self->cache_ap_mac = NULL; + self->ap_strength = 0; + + for (i = 0; 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 finalize (GObject *object) @@ -45,6 +104,10 @@ dispose (GObject *object) GeoclueNetworkManager *self = GEOCLUE_NETWORKMANAGER (object); dbus_g_connection_unref (self->connection); + 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); } @@ -87,6 +150,7 @@ geoclue_networkmanager_state_changed (DBusGProxy *proxy, gc_status = nmstate_to_geocluenetworkstatus (status); if (gc_status != self->status) { + cache_ap_mac (self); self->status = gc_status; geoclue_connectivity_emit_status_changed (GEOCLUE_CONNECTIVITY (self), self->status); @@ -131,6 +195,9 @@ geoclue_networkmanager_init (GeoclueNetworkManager *self) g_warning ("Could not get connectivity state from NetworkManager: %s", error->message); g_error_free (error); } + + self->client = nm_client_new (); + cache_ap_mac (self); } @@ -138,6 +205,7 @@ static void geoclue_networkmanager_connectivity_init (GeoclueConnectivityInterface *iface) { iface->get_status = get_status; + iface->get_ap_mac = get_ap_mac; } #endif /* HAVE_NETWORK_MANAGER */ diff --git a/src/connectivity-networkmanager.h b/src/connectivity-networkmanager.h index 3513054..ba5b325 100644 --- a/src/connectivity-networkmanager.h +++ b/src/connectivity-networkmanager.h @@ -10,6 +10,7 @@ #define _CONNECTIVITY_NETWORKMANAGER_H #include +#include #include "connectivity.h" @@ -24,6 +25,9 @@ typedef struct { /* private */ GeoclueNetworkStatus status; DBusGConnection *connection; + NMClient *client; + char *cache_ap_mac; + int ap_strength; } GeoclueNetworkManager; typedef struct { diff --git a/src/connectivity.c b/src/connectivity.c index 107495a..a7e16fb 100644 --- a/src/connectivity.c +++ b/src/connectivity.c @@ -61,6 +61,14 @@ geoclue_connectivity_get_status (GeoclueConnectivity *self) return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_status (self); } +char * +geoclue_connectivity_get_ap_mac (GeoclueConnectivity *self) +{ + if (GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_ap_mac != NULL) + return GEOCLUE_CONNECTIVITY_GET_INTERFACE (self)->get_ap_mac (self); + return NULL; +} + void geoclue_connectivity_emit_status_changed (GeoclueConnectivity *self, GeoclueNetworkStatus status) diff --git a/src/connectivity.h b/src/connectivity.h index b877521..f4eae5e 100644 --- a/src/connectivity.h +++ b/src/connectivity.h @@ -32,6 +32,7 @@ struct _GeoclueConnectivityInterface { /* vtable */ int (*get_status) (GeoclueConnectivity *self); + char * (*get_ap_mac) (GeoclueConnectivity *self); }; GType geoclue_connectivity_get_type (void); @@ -39,6 +40,8 @@ GType geoclue_connectivity_get_type (void); GeoclueNetworkStatus geoclue_connectivity_get_status (GeoclueConnectivity *self); +char *geoclue_connectivity_get_ap_mac (GeoclueConnectivity *self); + void geoclue_connectivity_emit_status_changed (GeoclueConnectivity *self, GeoclueNetworkStatus status); -- 1.6.2.2