From 35e5656e655007c9e9b80e6caa46b7a67134ad80 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 23 Mar 2010 22:51:19 -0700 Subject: [PATCH] bluetooth: fix race condition causing NAP connections to fail (rh #572340) The race would start DHCP before we had the BNEP interface from bluez, causing the wrong interface name to be used. --- src/nm-device-bt.c | 97 ++++++++++++++++++++++++++++------------------ 1 file changed, 60 insertions(+), 37 deletions(-) diff --git a/src/nm-device-bt.c b/src/nm-device-bt.c index 7e0f459dd6..0eec484ad4 100644 --- a/src/nm-device-bt.c +++ b/src/nm-device-bt.c @@ -51,6 +51,9 @@ typedef struct { char *name; guint32 capabilities; + gboolean connected; + gboolean have_iface; + DBusGProxy *type_proxy; DBusGProxy *dev_proxy; @@ -535,6 +538,53 @@ nm_device_bt_modem_removed (NMDeviceBt *self, NMModem *modem) return TRUE; } +static gboolean +modem_find_timeout (gpointer user_data) +{ + NMDeviceBt *self = NM_DEVICE_BT (user_data); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + + priv->timeout_id = 0; + + nm_device_state_changed (NM_DEVICE (user_data), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND); + return FALSE; +} + +static void +check_connect_continue (NMDeviceBt *self) +{ + NMDevice *device = NM_DEVICE (self); + NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); + gboolean pan = (priv->bt_type == NM_BT_CAPABILITY_NAP); + gboolean dun = (priv->bt_type == NM_BT_CAPABILITY_DUN); + + if (!priv->connected || !priv->have_iface) + return; + + nm_info ("Activation (%s %s/bluetooth) Stage 2 of 5 (Device Configure) " + "successful. Will connect via %s.", + nm_device_get_iface (device), + nm_device_get_ip_iface (device), + dun ? "DUN" : (pan ? "PAN" : "unknown")); + + if (pan) { + /* Bluez says we're connected now. Start IP config. */ + nm_device_activate_schedule_stage3_ip_config_start (device); + } else if (dun) { + /* Wait for ModemManager to find the modem */ + if (priv->timeout_id) + g_source_remove (priv->timeout_id); + priv->timeout_id = g_timeout_add_seconds (20, modem_find_timeout, self); + + nm_info ("Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) " + "waiting for modem to appear.", + nm_device_get_iface (device)); + } else + g_assert_not_reached (); +} + static void bluez_connect_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, @@ -573,20 +623,8 @@ bluez_connect_cb (DBusGProxy *proxy, } /* Stage 3 gets scheduled when Bluez says we're connected */ -} - -static gboolean -modem_find_timeout (gpointer user_data) -{ - NMDeviceBt *self = NM_DEVICE_BT (user_data); - NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); - - priv->timeout_id = 0; - - nm_device_state_changed (NM_DEVICE (user_data), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND); - return FALSE; + priv->have_iface = TRUE; + check_connect_continue (self); } static void @@ -608,28 +646,8 @@ bluez_property_changed (DBusGProxy *proxy, connected = g_value_get_boolean (value); if (connected) { if (state == NM_DEVICE_STATE_CONFIG) { - gboolean pan = (priv->bt_type == NM_BT_CAPABILITY_NAP); - gboolean dun = (priv->bt_type == NM_BT_CAPABILITY_DUN); - - nm_info ("Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) " - "successful. Will connect via %s.", - nm_device_get_iface (device), - dun ? "DUN" : (pan ? "PAN" : "unknown")); - - if (pan) { - /* Bluez says we're connected now. Start IP config. */ - nm_device_activate_schedule_stage3_ip_config_start (device); - } else if (dun) { - /* Wait for ModemManager to find the modem */ - if (priv->timeout_id) - g_source_remove (priv->timeout_id); - priv->timeout_id = g_timeout_add_seconds (20, modem_find_timeout, self); - - nm_info ("Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) " - "waiting for modem to appear.", - nm_device_get_iface (device)); - } else - g_assert_not_reached (); + priv->connected = TRUE; + check_connect_continue (self); } } else { gboolean fail = FALSE; @@ -645,8 +663,10 @@ bluez_property_changed (DBusGProxy *proxy, fail = TRUE; } - if (fail) + if (fail) { nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CARRIER); + priv->connected = FALSE; + } } } @@ -761,6 +781,9 @@ real_deactivate_quickly (NMDevice *device) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); + priv->have_iface = FALSE; + priv->connected = FALSE; + if (priv->bt_type == NM_BT_CAPABILITY_DUN) { if (priv->modem) {