static void dispose (GObject *object) { NMDeviceOlpcMesh *self = NM_DEVICE_OLPC_MESH (object); NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self); NMManager *manager; if (priv->dispose_has_run) { G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); return; } priv->dispose_has_run = TRUE; if (priv->wifi_data) wifi_utils_deinit (priv->wifi_data); device_cleanup (self); manager = nm_manager_get (); if (priv->device_added_id) g_signal_handler_disconnect (manager, priv->device_added_id); g_object_unref (manager); G_OBJECT_CLASS (nm_device_olpc_mesh_parent_class)->dispose (object); }
WifiData * wifi_wext_init (const char *iface, int ifindex, gboolean check_scan) { WifiDataWext *wext; struct iw_range range; guint32 response_len = 0; struct iw_range_with_scan_capa *scan_capa_range; int i; gboolean freq_valid = FALSE, has_5ghz = FALSE, has_2ghz = FALSE; wext = wifi_data_new (iface, ifindex, sizeof (*wext)); wext->parent.get_mode = wifi_wext_get_mode; wext->parent.set_mode = wifi_wext_set_mode; wext->parent.set_powersave = wifi_wext_set_powersave; wext->parent.get_freq = wifi_wext_get_freq; wext->parent.find_freq = wifi_wext_find_freq; wext->parent.get_bssid = wifi_wext_get_bssid; wext->parent.get_rate = wifi_wext_get_rate; wext->parent.get_qual = wifi_wext_get_qual; wext->parent.deinit = wifi_wext_deinit; wext->parent.get_mesh_channel = wifi_wext_get_mesh_channel; wext->parent.set_mesh_channel = wifi_wext_set_mesh_channel; wext->parent.set_mesh_ssid = wifi_wext_set_mesh_ssid; wext->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (wext->fd < 0) goto error; memset (&range, 0, sizeof (struct iw_range)); if (wext_get_range (wext, &range, &response_len) == FALSE) { nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver WEXT range request failed", wext->parent.iface); goto error; } if ((response_len < 300) || (range.we_version_compiled < 21)) { nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver WEXT version too old (got %d, expected >= 21)", wext->parent.iface, range.we_version_compiled); goto error; } wext->max_qual.qual = range.max_qual.qual; wext->max_qual.level = range.max_qual.level; wext->max_qual.noise = range.max_qual.noise; wext->max_qual.updated = range.max_qual.updated; wext->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES); for (i = 0; i < wext->num_freqs; i++) { wext->freqs[i] = iw_freq_to_uint32 (&range.freq[i]); freq_valid = TRUE; if (wext->freqs[i] > 2400 && wext->freqs[i] < 2500) has_2ghz = TRUE; else if (wext->freqs[i] > 4900 && wext->freqs[i] < 6000) has_5ghz = TRUE; } /* Check for scanning capability; cards that can't scan are not supported */ if (check_scan && (wext_can_scan (wext) == FALSE)) { nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): drivers that cannot scan are unsupported", wext->parent.iface); goto error; } /* Check for the ability to scan specific SSIDs. Until the scan_capa * field gets added to wireless-tools, need to work around that by casting * to the custom structure. */ scan_capa_range = (struct iw_range_with_scan_capa *) ⦥ if (scan_capa_range->scan_capa & NM_IW_SCAN_CAPA_ESSID) { nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver supports SSID scans (scan_capa 0x%02X).", wext->parent.iface, scan_capa_range->scan_capa); } else { nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not support SSID scans (scan_capa 0x%02X).", wext->parent.iface, scan_capa_range->scan_capa); } wext->parent.caps = wext_get_caps (wext, &range); if (freq_valid) wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_VALID; if (has_2ghz) wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_2GHZ; if (has_5ghz) wext->parent.caps |= NM_WIFI_DEVICE_CAP_FREQ_5GHZ; nm_log_info (LOGD_PLATFORM | LOGD_WIFI, "(%s): using WEXT for WiFi device control", wext->parent.iface); return (WifiData *) wext; error: wifi_utils_deinit ((WifiData *) wext); return NULL; }