static void
dispose (GObject *object)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (object);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);

	if (priv->disposed)
		goto done;

	priv->disposed = TRUE;

	clear_activation_timeout (self);
	clear_link_timeout (self);
	clear_connected_poll (self);

	if (priv->sdk_action_defer_id)
		g_source_remove (priv->sdk_action_defer_id);

	if (priv->sdk) {
		iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL, NULL);
		wmxsdk_unref (priv->sdk);
	}

	g_free (priv->bsid);

	set_current_nsp (self, NULL);

	g_slist_free_full (priv->nsp_list, g_object_unref);

	iwmx_sdk_new_callback_unregister (wmx_new_sdk_cb, self);
	nm_wimax_util_sdk_unref ();

done:
	G_OBJECT_CLASS (nm_device_wimax_parent_class)->dispose (object);
}
static void
wmx_new_sdk_cb (struct wmxsdk *sdk, void *user_data)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);

	/* We only track one wmxsdk at a time because the WiMAX SDK is pretty stupid */
	if (priv->sdk) {
		nm_log_dbg (LOGD_WIMAX, "(%s): WiMAX interface already known", sdk->ifname);
		return;
	}

	nm_log_dbg (LOGD_WIMAX, "(%s): new WiMAX interface (%s)", sdk->ifname, sdk->name);

	/* Now that we have an SDK, schedule an idle handler to start the device up */
	priv->sdk = wmxsdk_ref (sdk);
	iwmx_sdk_set_callbacks(priv->sdk,
	                       wmx_state_change_cb,
	                       wmx_media_status_cb,
	                       wmx_connect_result_cb,
	                       wmx_scan_result_cb,
	                       wmx_removed_cb,
	                       self);
	iwmx_sdk_set_fast_reconnect_enabled (priv->sdk, 0);

	if (!priv->sdk_action_defer_id)
		priv->sdk_action_defer_id = g_idle_add (sdk_action_defer_cb, self);
}
static void
wmx_removed_cb (struct wmxsdk *wmxsdk, void *user_data)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);

	if (priv->sdk) {
		/* Clear callbacks just in case we don't hold the last reference */
		iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL, NULL);

		wmxsdk_unref (priv->sdk);
		priv->sdk = NULL;

		priv->status = WIMAX_API_DEVICE_STATUS_UnInitialized;
		nm_device_state_changed (NM_DEVICE (self),
								 NM_DEVICE_STATE_UNAVAILABLE,
								 NM_DEVICE_STATE_REASON_NONE);
	}
}
static void
wmx_new_sdk_cb (struct wmxsdk *sdk, void *user_data)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);

	/* If we now have the SDK, schedule an idle handler to start the device up */
	if (!priv->sdk) {
		priv->sdk = wmxsdk_ref (sdk);
		iwmx_sdk_set_callbacks(priv->sdk,
		                       wmx_state_change_cb,
		                       wmx_media_status_cb,
		                       wmx_connect_result_cb,
		                       wmx_scan_result_cb,
		                       wmx_removed_cb,
		                       self);
		iwmx_sdk_set_fast_reconnect_enabled (priv->sdk, 0);

		if (!priv->sdk_action_defer_id)
			priv->sdk_action_defer_id = g_idle_add (sdk_action_defer_cb, self);
	}
}
static void
wmx_removed_cb (struct wmxsdk *wmxsdk, void *user_data)
{
	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);

	if (!priv->sdk) {
		nm_log_dbg (LOGD_WIMAX, "(%s): removed unhandled WiMAX interface", wmxsdk->ifname);
		return;
	}

	nm_log_dbg (LOGD_WIMAX, "(%s): removed WiMAX interface", wmxsdk->ifname);

	/* Clear callbacks just in case we don't hold the last reference */
	iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL, NULL);
	wmxsdk_unref (priv->sdk);
	priv->sdk = NULL;

	priv->status = WIMAX_API_DEVICE_STATUS_UnInitialized;
	nm_device_state_changed (NM_DEVICE (self),
							 NM_DEVICE_STATE_UNAVAILABLE,
							 NM_DEVICE_STATE_REASON_NONE);
}