Hi, Here's a reworked patch that makes use of the netlink/wireless event stuff from about a month ago. It's got a few features:
* Notices driver-provided scan completion events and pulls from them * Uses wpa_supplicant for scanning when a wireless connection is active * Works around older drivers that don't send scan completion events * Doesn't block waiting for scan results Please test it out (against HEAD) and see if it works for you. I've noticed one fairly large issue though... wpa_supplicant seems to get its link state confused and doesn't reconnect. I don't know if this is due to the driver not sending reconnect events or whether wpa_supplicant is just dumb. It doesn't appear that wpa_supplicant has much special logic to 'fake' a connection through a scan, which sucks for us. More investigation is certainly needed. Dan
Index: src/nm-device-802-11-wireless.c =================================================================== RCS file: /cvs/gnome/NetworkManager/src/nm-device-802-11-wireless.c,v retrieving revision 1.66 diff -u -r1.66 nm-device-802-11-wireless.c --- src/nm-device-802-11-wireless.c 8 Mar 2006 14:45:14 -0000 1.66 +++ src/nm-device-802-11-wireless.c 30 Mar 2006 04:12:11 -0000 @@ -73,10 +73,12 @@ gint8 num_freqs; double freqs[IW_MAX_FREQUENCIES]; - GMutex * scan_mutex; + gboolean scanning; NMAccessPointList * ap_list; guint8 scan_interval; /* seconds */ guint32 last_scan; + GSource * scan_timeout; + GSource * pending_scan; struct _Supplicant supplicant; @@ -97,25 +99,21 @@ guint32 results_len; } NMWirelessScanResults; -typedef struct -{ - NMDevice80211Wireless * dev; - gboolean force; -} NMWirelessScanCB; - static void nm_device_802_11_wireless_ap_list_clear (NMDevice80211Wireless *self); static gboolean nm_device_802_11_wireless_scan (gpointer user_data); +static void cancel_scan_results_timeout (NMDevice80211Wireless *self); + +static void cancel_pending_scan (NMDevice80211Wireless *self); + +static void request_and_convert_scan_results (NMDevice80211Wireless *self); + static gboolean process_scan_results (NMDevice80211Wireless *dev, const guint8 *res_buf, guint32 res_buf_len); - -static gboolean get_scan_results (NMDevice80211Wireless *dev, - NMSock *sk, - guint8 **out_res_buf, - guint32 *data_len); +static void schedule_scan (NMDevice80211Wireless *self); static int wireless_qual_to_percent (const struct iw_quality *qual, const struct iw_quality *max_qual, @@ -140,7 +138,7 @@ char *data, int data_len, NMDevice80211Wireless *self); - + static guint nm_wireless_scan_interval_to_seconds (NMWirelessScanInterval interval) { guint seconds; @@ -263,9 +261,7 @@ NMSock * sk; NmNetlinkMonitor * monitor; - self->priv->scan_mutex = g_mutex_new (); - nm_register_mutex_desc (self->priv->scan_mutex, "Scan Mutex"); - + self->priv->scanning = FALSE; self->priv->ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE); app_data = nm_device_get_app_data (NM_DEVICE (self)); @@ -395,7 +391,10 @@ } break; case SIOCGIWSCAN: - /* Got some scan results */ +nm_info ("(%s) got scan results wireless event.", nm_device_get_iface (NM_DEVICE (self))); + cancel_scan_results_timeout (self); + request_and_convert_scan_results (self); + schedule_scan (self); break; } pos += iwe->len; @@ -475,16 +474,11 @@ /* Start the scanning timeout for devices that can do scanning */ if (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_WIRELESS_SCAN) { - NMWirelessScanCB * scan_cb; - - scan_cb = g_malloc0 (sizeof (NMWirelessScanCB)); - scan_cb->dev = self; - scan_cb->force = TRUE; - - source = g_idle_source_new (); - g_source_set_callback (source, nm_device_802_11_wireless_scan, scan_cb, NULL); - source_id = g_source_attach (source, nm_device_get_main_context (dev)); - g_source_unref (source); + self->priv->pending_scan = g_idle_source_new (); + g_source_set_callback (self->priv->pending_scan, + nm_device_802_11_wireless_scan, self, NULL); + source_id = g_source_attach (self->priv->pending_scan, + nm_device_get_main_context (dev)); } /* Peridoically update link status and signal strength */ @@ -616,8 +610,11 @@ { gboolean have_link = FALSE; - /* Checking hardware's ESSID during a scan is doesn't work. */ - nm_lock_mutex (self->priv->scan_mutex, __func__); + /* Fake a link if we're scanning, we'll drop it later + * if it's really dead. + */ + if (self->priv->scanning) + return TRUE; if (is_associated (self)) { @@ -631,8 +628,6 @@ } } - nm_unlock_mutex (self->priv->scan_mutex, __func__); - if (!have_link) { self->priv->failed_link_count++; @@ -1261,20 +1256,20 @@ g_return_if_fail (self != NULL); + /* Signal strength is pretty meaningless during a scan */ + if (self->priv->scanning) + return; + app_data = nm_device_get_app_data (NM_DEVICE (self)); g_assert (app_data); - /* Grab the scan lock since our strength is meaningless during a scan. */ - if (!nm_try_acquire_mutex (self->priv->scan_mutex, __FUNCTION__)) - return; - /* If we aren't the active device, we don't really have a signal strength * that would mean anything. */ if (!nm_device_get_act_request (NM_DEVICE (self))) { self->priv->strength = -1; - goto out; + return; } if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) @@ -1310,9 +1305,6 @@ nm_dbus_signal_device_strength_change (app_data->dbus_connection, self, percent); self->priv->strength = percent; - -out: - nm_unlock_mutex (self->priv->scan_mutex, __func__); } @@ -1419,6 +1411,7 @@ } +#if 0 /* * nm_device_get_frequency * @@ -1458,7 +1451,6 @@ return freq; } - /* * nm_device_set_frequency * @@ -1534,7 +1526,7 @@ nm_dev_sock_close (sk); } } - +#endif /* * nm_device_get_bitrate @@ -1566,7 +1558,7 @@ return ((err >= 0) ? wrq.u.bitrate.value / 1000000 : 0); } - +#if 0 /* * nm_device_set_bitrate * @@ -1611,6 +1603,7 @@ nm_dev_sock_close (sk); } } +#endif /* @@ -1738,34 +1731,6 @@ } else nm_warning ("could not get wireless control socket for device %s", iface); } -/* - * nm_device_wireless_schedule_scan - * - * Schedule a wireless scan in the /device's/ thread. - * - */ -static void -schedule_scan (NMDevice80211Wireless *self) -{ - GSource * wscan_source; - guint wscan_source_id; - NMWirelessScanCB * scan_cb; - GMainContext * context; - - g_return_if_fail (self != NULL); - - scan_cb = g_malloc0 (sizeof (NMWirelessScanCB)); - scan_cb->dev = self; - scan_cb->force = FALSE; - - wscan_source = g_timeout_source_new (self->priv->scan_interval * 1000); - g_source_set_callback (wscan_source, nm_device_802_11_wireless_scan, scan_cb, NULL); - context = nm_device_get_main_context (NM_DEVICE (self)); - wscan_source_id = g_source_attach (wscan_source, context); - g_source_unref (wscan_source); -} - - static void free_process_scan_cb_data (NMWirelessScanResults *cb_data) { @@ -1780,14 +1745,14 @@ } /* - * nm_device_wireless_process_scan_results + * convert_scan_results * * Process results of an iwscan() into our own AP lists. We're an idle function, * but we never reschedule ourselves. * */ static gboolean -handle_scan_results (gpointer user_data) +convert_scan_results (gpointer user_data) { NMWirelessScanResults * cb_data = (NMWirelessScanResults *) user_data; NMDevice80211Wireless * self; @@ -1800,6 +1765,7 @@ g_return_val_if_fail (cb_data != NULL, FALSE); self = NM_DEVICE_802_11_WIRELESS (cb_data->dev); +nm_info ("(%s) converting scan results.", nm_device_get_iface (NM_DEVICE (self))); if (!self || !cb_data->results) { free_process_scan_cb_data (cb_data); @@ -1876,37 +1842,198 @@ } +#define SCAN_SLEEP_CENTISECONDS 10 /* sleep 1/10 of a second, waiting for data */ +static void +request_and_convert_scan_results (NMDevice80211Wireless *self) +{ + NMSock *sk; + NMWirelessScanResults *scan_results = NULL; + const char *iface; + struct iwreq iwr; + guint8 tries = 0; + gboolean success = FALSE; + guint8 *buf = NULL; + size_t buflen = IW_SCAN_MAX_DATA; + + g_return_if_fail (self != NULL); + + if (!(sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) + return; + +nm_info ("(%s) request_and_convert called.", nm_device_get_iface (NM_DEVICE (self))); + iface = nm_device_get_iface (NM_DEVICE (self)); + for (;;) + { + if (!(buf = g_malloc0 (buflen))) + break; + iwr.u.data.pointer = buf; + iwr.u.data.flags = 0; + iwr.u.data.length = buflen; + + if (iw_get_ext (nm_dev_sock_get_fd (sk), iface, SIOCGIWSCAN, &iwr) == 0) + { + /* success */ + buflen = iwr.u.data.length; + success = TRUE; + break; + } + + g_free (buf); + buf = NULL; + + if ((errno == E2BIG) && (buflen < 100000)) /* Buffer not big enough */ + { + buflen *= 2; + } + else if (errno == EAGAIN) /* Card doesn't have results yet */ + { + /* We've already waited for the scan data, so don't give + * drivers too much slack here. + */ + if (tries > 4 * SCAN_SLEEP_CENTISECONDS) + { + nm_warning ("card took too much time scanning. Get a better one."); + break; + } + g_usleep (G_USEC_PER_SEC / SCAN_SLEEP_CENTISECONDS); + tries++; + } + else if (errno == ENODATA) /* No scan results */ + { + buflen = 0; + success = TRUE; + break; + } + else /* Random errors */ + { + nm_warning ("unknown error, or the card returned too much scan info: %s", + strerror (errno)); + break; + } + } + nm_dev_sock_close (sk); + + if (success) + { + NMData * app_data = nm_device_get_app_data (NM_DEVICE (self)); + GSource * convert_source = g_idle_source_new (); + GTimeVal cur_time; + + /* We run the scan processing function from the main thread, since it must deliver + * messages over DBUS. Plus, that way the main thread is the only thread that has + * to modify the device's access point list. + */ +nm_info ("(%s) scheduling scan request conversion in main context.", nm_device_get_iface (NM_DEVICE (self))); + scan_results = g_malloc0 (sizeof (NMWirelessScanResults)); + g_object_ref (G_OBJECT (self)); + scan_results->dev = self; + scan_results->results = buf; + scan_results->results_len = buflen; + + g_source_set_callback (convert_source, convert_scan_results, scan_results, NULL); + g_source_attach (convert_source, app_data->main_context); + g_source_unref (convert_source); + g_get_current_time (&cur_time); + self->priv->last_scan = cur_time.tv_sec; + } +} + + +/* + * scan_results_timeout + * + * Request scan results from the card if it has taken more time than + * we allow. Also works around drivers that don't send notifications of + * completed scans to userspace. + */ +static gboolean +scan_results_timeout (NMDevice80211Wireless *self) +{ + g_return_val_if_fail (self != NULL, FALSE); + +nm_info ("(%s) scan_request_timeout called.", nm_device_get_iface (NM_DEVICE (self))); + request_and_convert_scan_results (self); + schedule_scan (self); + g_source_unref (self->priv->scan_timeout); /* Balance g_timeout_source_new() */ + self->priv->scan_timeout = NULL; + return FALSE; /* Balance g_source_attach(), destroyed on return */ +} + + +/* + * schedule_scan_results_timeout + * + * For cards that don't send a wireless event for scan results, + * we hit the card after the timeout and explicitly ask for them. + * + */ +static void +schedule_scan_results_timeout (NMDevice80211Wireless *self) +{ + GMainContext * context; + + g_return_if_fail (self != NULL); + + cancel_scan_results_timeout (self); + + /* Wait 10 seconds for scan results */ +nm_info ("(%s) scheduling scan request timeout.", nm_device_get_iface (NM_DEVICE (self))); + self->priv->scan_timeout = g_timeout_source_new (10000); + g_source_set_callback (self->priv->scan_timeout, + (GSourceFunc) scan_results_timeout, self, NULL); + context = nm_device_get_main_context (NM_DEVICE (self)); + g_source_attach (self->priv->scan_timeout, context); +} + + +/* + * cancel_scan_results_timeout + * + * Cancel an existing scan results timeout + * + */ +static void +cancel_scan_results_timeout (NMDevice80211Wireless *self) +{ + g_return_if_fail (self != NULL); + +nm_info ("(%s) cancel_scan_results_timeout called.", nm_device_get_iface (NM_DEVICE (self))); + if (self->priv->scan_timeout) + { + g_source_destroy (self->priv->scan_timeout); /* Balance g_source_attach() */ + g_source_unref (self->priv->scan_timeout); /* Balance g_timeout_source_new() */ + self->priv->scan_timeout = NULL; +nm_info ("(%s) cancelled scan request timeout.", nm_device_get_iface (NM_DEVICE (self))); + } +} + + /* * nm_device_802_11_wireless_scan * - * Get a list of access points this device can see. + * Trigger a scan request * */ static gboolean nm_device_802_11_wireless_scan (gpointer user_data) { - NMWirelessScanCB * scan_cb = (NMWirelessScanCB *)(user_data); - NMDevice80211Wireless * self = NULL; - NMWirelessScanResults * scan_results = NULL; + NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (user_data); guint32 caps; NMData * app_data; + gboolean success = FALSE; + const char * iface; - g_return_val_if_fail (scan_cb != NULL, FALSE); + g_return_val_if_fail (self != NULL, FALSE); - self = scan_cb->dev; - if (!self || !nm_device_get_app_data (NM_DEVICE (self))) - { - g_free (scan_cb); - return FALSE; - } - app_data = nm_device_get_app_data (NM_DEVICE (self)); + if (!(app_data = nm_device_get_app_data (NM_DEVICE (self)))) + goto out; caps = nm_device_get_capabilities (NM_DEVICE (self)); if (!(caps & NM_DEVICE_CAP_NM_SUPPORTED) || !(caps & NM_DEVICE_CAP_WIRELESS_SCAN)) - { - g_free (scan_cb); - return FALSE; - } + goto out; + + g_source_unref (self->priv->pending_scan); /* Balance g_timeout_source_new() */ + self->priv->pending_scan = NULL; /* Reschedule ourselves if all wireless is disabled, we're asleep, * or we are currently activating. @@ -1916,7 +2043,8 @@ || (nm_device_is_activating (NM_DEVICE (self)) == TRUE)) { nm_device_802_11_wireless_set_scan_interval (app_data, self, NM_WIRELESS_SCAN_INTERVAL_INIT); - goto reschedule; + schedule_scan (self); + goto out; } /* @@ -1927,115 +2055,102 @@ if ((self->priv->num_freqs > 14) && nm_device_is_activated (NM_DEVICE (self)) == TRUE) { nm_device_802_11_wireless_set_scan_interval (app_data, self, NM_WIRELESS_SCAN_INTERVAL_ACTIVE); - goto reschedule; + schedule_scan (self); + goto out; } - /* Grab the scan mutex */ - if (nm_try_acquire_mutex (self->priv->scan_mutex, __func__)) +nm_info ("(%s) Requesting a scan.", nm_device_get_iface (NM_DEVICE (self))); + self->priv->scanning = TRUE; + + /* Device must be up before we can scan */ + if (nm_device_bring_up_wait (NM_DEVICE (self), 1)) { - NMSock * sk; - gboolean devup_err; - const char * iface; + schedule_scan (self); + goto out; + } - /* Device must be up before we can scan */ - devup_err = nm_device_bring_up_wait (NM_DEVICE (self), 1); - if (devup_err) - { - nm_unlock_mutex (self->priv->scan_mutex, __func__); - goto reschedule; - } + /* If we're currently connected to an AP, let wpa_supplicant initiate + * the scan request rather than doing it ourselves. + */ + iface = nm_device_get_iface (NM_DEVICE (self)); + if (self->priv->supplicant.ctrl) + { + if (nm_utils_supplicant_request_with_check (self->priv->supplicant.ctrl, + "OK", __func__, NULL, "SCAN")) +{ +nm_info ("(%s) triggered supplicant scan.", nm_device_get_iface (NM_DEVICE (self))); + success = TRUE; +} + } + else + { + NMSock * sk; - iface = nm_device_get_iface (NM_DEVICE (self)); if ((sk = nm_dev_sock_open (NM_DEVICE (self), DEV_WIRELESS, __FUNCTION__, NULL))) { - int orig_mode; - double orig_freq = 0; - int orig_rate = 0; - struct iwreq wrq; - - orig_mode = nm_device_802_11_wireless_get_mode (self); - if (orig_mode == IW_MODE_ADHOC) - { - orig_freq = nm_device_802_11_wireless_get_frequency (self); - orig_rate = nm_device_802_11_wireless_get_bitrate (self); - } - - /* Must be in infrastructure mode during scan, otherwise we don't get a full - * list of scan results. Scanning doesn't work well in Ad-Hoc mode :( - */ - nm_device_802_11_wireless_set_mode (self, IW_MODE_INFRA); - - /* We only unlock the frequency if the card is in adhoc mode, in case it is - * a costly operation for the driver. - */ - if (orig_mode == IW_MODE_ADHOC) - nm_device_802_11_wireless_set_frequency (self, 0); + struct iwreq wrq; wrq.u.data.pointer = NULL; wrq.u.data.flags = 0; wrq.u.data.length = 0; - if (iw_set_ext (nm_dev_sock_get_fd (sk), iface, SIOCSIWSCAN, &wrq) < 0) - { - nm_warning ("could not trigger wireless scan on device %s: %s", - iface, strerror (errno)); - } - else - { - guint8 * results = NULL; - guint32 results_len = 0; - - /* Initial pause for card to return data */ - g_usleep (G_USEC_PER_SEC / 4); - - if (get_scan_results (self, sk, &results, &results_len)) - { - scan_results = g_malloc0 (sizeof (NMWirelessScanResults)); - g_object_ref (G_OBJECT (self)); - scan_results->dev = self; - scan_results->results = results; - scan_results->results_len = results_len; - } - else - nm_warning ("device %s returned an error.", iface); - } - - nm_device_802_11_wireless_set_mode (self, orig_mode); - /* Only set frequency if ad-hoc mode */ - if (orig_mode == IW_MODE_ADHOC) - { - nm_device_802_11_wireless_set_frequency (self, orig_freq); - nm_device_802_11_wireless_set_bitrate (self, orig_rate); - } - + if (iw_set_ext (nm_dev_sock_get_fd (sk), iface, SIOCSIWSCAN, &wrq) == 0) +{ +nm_info ("(%s) triggered manual scan.", nm_device_get_iface (NM_DEVICE (self))); + success = TRUE; +} nm_dev_sock_close (sk); } - nm_unlock_mutex (self->priv->scan_mutex, __func__); } - /* We run the scan processing function from the main thread, since it must deliver - * messages over DBUS. Plus, that way the main thread is the only thread that has - * to modify the device's access point list. - */ - if (scan_results != NULL) + if (success) { - guint scan_process_source_id = 0; - GSource * scan_process_source = g_idle_source_new (); - GTimeVal cur_time; + schedule_scan_results_timeout (self); + } + else + { + nm_warning ("could not trigger wireless scan on device %s: %s", + iface, strerror (errno)); + schedule_scan (self); + } - g_source_set_callback (scan_process_source, handle_scan_results, scan_results, NULL); - scan_process_source_id = g_source_attach (scan_process_source, app_data->main_context); - g_source_unref (scan_process_source); +out: + return FALSE; /* Balance g_source_attach(), destroyed on return */ +} - g_get_current_time (&cur_time); - self->priv->last_scan = cur_time.tv_sec; - } -reschedule: - /* Make sure we reschedule ourselves so we keep scanning */ - schedule_scan (self); +/* + * nm_device_wireless_schedule_scan + * + * Schedule a wireless scan in the /device's/ thread. + * + */ +static void +schedule_scan (NMDevice80211Wireless *self) +{ + g_return_if_fail (self != NULL); - g_free (scan_cb); - return FALSE; + cancel_pending_scan (self); + +nm_info ("(%s) Scheduling wireless scan.", nm_device_get_iface (NM_DEVICE (self))); + self->priv->pending_scan = g_timeout_source_new (self->priv->scan_interval * 1000); + g_source_set_callback (self->priv->pending_scan, nm_device_802_11_wireless_scan, self, NULL); + g_source_attach (self->priv->pending_scan, nm_device_get_main_context (NM_DEVICE (self))); +} + + +static void +cancel_pending_scan (NMDevice80211Wireless *self) +{ + g_return_if_fail (self != NULL); + + self->priv->scanning = FALSE; + if (self->priv->pending_scan) + { + g_source_destroy (self->priv->pending_scan); /* Balance g_source_attach() */ + g_source_unref (self->priv->pending_scan); /* Balance g_timeout_source_new() */ + self->priv->pending_scan = NULL; +nm_info ("(%s) cancelled pending scan.", nm_device_get_iface (NM_DEVICE (self))); + } } @@ -2289,7 +2404,7 @@ static gboolean link_timeout_cb (gpointer user_data) { - NMDevice * dev = NM_DEVICE (user_data); + NMDevice * dev = NM_DEVICE (user_data); g_assert (dev); @@ -2332,6 +2447,8 @@ wpa_ctrl_recv (ctrl, message, &len); message[len] = '\0'; +nm_info ("(%s): supplicant said '%s'\n", nm_device_get_iface (NM_DEVICE (self)), message); + if (strstr (message, WPA_EVENT_CONNECTED) != NULL) { remove_link_timeout (self); @@ -2357,7 +2474,7 @@ if (nm_device_is_activated (dev) || nm_device_is_activating (dev)) { /* Start the link timeout so we allow some time for reauthentication */ - if (self->priv->link_timeout == NULL) + if ((self->priv->link_timeout == NULL) && !self->priv->scanning) { GMainContext * context = nm_device_get_main_context (dev); self->priv->link_timeout = g_timeout_source_new (8000); @@ -3032,7 +3149,9 @@ nm_device_802_11_wireless_ap_list_clear (self); if (self->priv->ap_list) nm_ap_list_unref (self->priv->ap_list); - g_mutex_free (self->priv->scan_mutex); + + cancel_scan_results_timeout (self); + cancel_pending_scan (self); g_signal_handler_disconnect (G_OBJECT (data->netlink_monitor), self->priv->wireless_event_id); @@ -3162,81 +3281,6 @@ } return 0; } - -#define SCAN_SLEEP_CENTISECONDS 10 /* sleep 1/10 of a second, waiting for data */ -static gboolean -get_scan_results (NMDevice80211Wireless *dev, - NMSock *sk, - guint8 **out_res_buf, - guint32 *data_len) -{ - struct iwreq iwr; - guint8 *res_buf; - size_t res_buf_len = IW_SCAN_MAX_DATA; - guint8 tries = 0; - gboolean success = FALSE; - - g_return_val_if_fail (dev != NULL, FALSE); - g_return_val_if_fail (sk != NULL, FALSE); - g_return_val_if_fail (out_res_buf != NULL, FALSE); - g_return_val_if_fail (*out_res_buf == NULL, FALSE); - g_return_val_if_fail (data_len != NULL, FALSE); - - *data_len = 0; - - for (;;) - { - res_buf = g_malloc (res_buf_len); - if (!res_buf) - break; - memset (&iwr, 0, sizeof (struct iwreq)); - iwr.u.data.pointer = res_buf; - iwr.u.data.flags = 0; - iwr.u.data.length = res_buf_len; - - if (iw_get_ext (nm_dev_sock_get_fd (sk), nm_device_get_iface (NM_DEVICE (dev)), SIOCGIWSCAN, &iwr) == 0) - { - /* success */ - *data_len = iwr.u.data.length; - *out_res_buf = res_buf; - success = TRUE; - break; - } - - g_free (res_buf); - res_buf = NULL; - - if ((errno == E2BIG) && (res_buf_len < 100000)) /* Buffer not big enough */ - { - res_buf_len *= 2; - } - else if (errno == EAGAIN) /* Card doesn't have results yet */ - { - if (tries > 20 * SCAN_SLEEP_CENTISECONDS) - { - nm_warning ("card took too much time scanning. Get a better one."); - break; - } - - g_usleep (G_USEC_PER_SEC / SCAN_SLEEP_CENTISECONDS); - tries++; - } - else if (errno == ENODATA) /* No scan results */ - { - success = TRUE; - break; - } - else /* Random errors */ - { - nm_warning ("unknown error, or the card returned too much scan info: %s", - strerror (errno)); - break; - } - } - - return success; -} - static void add_new_ap_to_device_list (NMDevice80211Wireless *dev,
_______________________________________________ NetworkManager-list mailing list NetworkManager-list@gnome.org http://mail.gnome.org/mailman/listinfo/networkmanager-list