On Thu, 2015-12-17 at 10:05 +0000, John Ernberg wrote:
From: John Ernberg <john.ernberg(a)actia.se>
If Wi-Fi was disabled, either by removal of a Wi-Fi dongle, or through the
DBus API, the Wi-Fi technology would sometimes be cleaned up before
gsupplicant would be signalled by wpa_s that the Peers were removed.
This means that the discovered peers are not cleaned up properly as there is
no wifi instance that can handle the callback of the signal.
Thus the GetPeers() method call could return a list of Peers while Wi-Fi was
disabled or removed.
Rewrite the peer-handling to be done more like the networks handling so that
when the technology is disabled it's possible to loop over the peers and
free them.
Hrm,
GEN src/builtin.h
make --no-print-directory all-am
CC plugins/src_connmand-wifi.o
CC src/src_connmand-plugin.o
plugins/wifi.c: In function ‘peer_connect_timeout’:
plugins/wifi.c:260:37: error: ‘struct wifi_data’ has no member named ‘peer’
connman_peer_get_identifier(wifi->peer));
^
plugins/wifi.c: In function ‘peer_connect’:
plugins/wifi.c:319:6: error: ‘struct wifi_data’ has no member named ‘peer’
wifi->peer = NULL;
^
Makefile:3027: recipe for target 'plugins/src_connmand-wifi.o' failed
make[1]: *** [plugins/src_connmand-wifi.o] Error 1
make[1]: *** Waiting for unfinished jobs....
Makefile:1602: recipe for target 'all' failed
make: *** [all] Error 2
Patrik
---
plugins/wifi.c | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/plugins/wifi.c b/plugins/wifi.c
index 82834ce..da2914f 100644
--- a/plugins/wifi.c
+++ b/plugins/wifi.c
@@ -140,7 +140,7 @@ struct wifi_data {
unsigned int p2p_find_timeout;
unsigned int p2p_connection_timeout;
struct connman_peer *pending_peer;
- GSupplicantPeer *peer;
+ GSList *peers;
bool p2p_connecting;
bool p2p_device;
int servicing;
@@ -245,8 +245,6 @@ static void peer_cancel_timeout(struct wifi_data *wifi)
connman_peer_unref(wifi->pending_peer);
wifi->pending_peer = NULL;
}
-
- wifi->peer = NULL;
}
static gboolean peer_connect_timeout(gpointer data)
@@ -257,8 +255,11 @@ static gboolean peer_connect_timeout(gpointer data)
if (wifi->p2p_connecting) {
enum connman_peer_state state = CONNMAN_PEER_STATE_FAILURE;
+ GSupplicantPeer *gs_peer =
+ g_supplicant_interface_peer_lookup(wifi->interface,
+ connman_peer_get_identifier(wifi->peer));
- if (g_supplicant_peer_has_requested_connection(wifi->peer))
+ if (g_supplicant_peer_has_requested_connection(gs_peer))
state = CONNMAN_PEER_STATE_IDLE;
connman_peer_set_state(wifi->pending_peer, state);
@@ -355,7 +356,6 @@ static int peer_connect(struct connman_peer *peer,
peer_connect_callback, wifi);
if (ret == -EINPROGRESS) {
wifi->pending_peer = connman_peer_ref(peer);
- wifi->peer = gs_peer;
wifi->p2p_connecting = true;
} else if (ret < 0) {
g_free(peer_params->path);
@@ -794,6 +794,21 @@ static void remove_networks(struct connman_device *device,
wifi->networks = NULL;
}
+static void remove_peers(struct wifi_data *wifi)
+{
+ GSList *list;
+
+ for (list = wifi->peers; list; list = list->next) {
+ struct connman_peer *peer = list->data;
+
+ connman_peer_unregister(peer);
+ connman_peer_unref(peer);
+ }
+
+ g_slist_free(wifi->peers);
+ wifi->peers = NULL;
+}
+
static void reset_autoscan(struct connman_device *device)
{
struct wifi_data *wifi = connman_device_get_data(device);
@@ -877,6 +892,7 @@ static void wifi_remove(struct connman_device *device)
g_source_remove(wifi->p2p_connection_timeout);
remove_networks(device, wifi);
+ remove_peers(wifi);
connman_device_set_powered(device, false);
connman_device_set_data(device, NULL);
@@ -1524,6 +1540,7 @@ static int wifi_disable(struct connman_device *device)
}
remove_networks(device, wifi);
+ remove_peers(wifi);
ret = g_supplicant_interface_remove(wifi->interface, NULL, NULL);
if (ret < 0)
@@ -2783,6 +2800,8 @@ static void peer_found(GSupplicantPeer *peer)
ret = connman_peer_register(connman_peer);
if (ret < 0 && ret != -EALREADY)
connman_peer_unref(connman_peer);
+ else
+ wifi->peers = g_slist_prepend(wifi->peers, connman_peer);
}
static void peer_lost(GSupplicantPeer *peer)
@@ -2808,6 +2827,8 @@ static void peer_lost(GSupplicantPeer *peer)
connman_peer_unregister(connman_peer);
connman_peer_unref(connman_peer);
}
+
+ wifi->peers = g_slist_remove(wifi->peers, connman_peer);
}
static void peer_changed(GSupplicantPeer *peer, GSupplicantPeerState state)