Exemplo n.º 1
0
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 *) &range;
	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;
}