about summary refs log tree commit diff
path: root/src/wimax/nm-device-wimax.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-10-28 23:04:21 +0200
committerMichael Biebl <biebl@debian.org>2011-10-28 23:04:21 +0200
commitbc5840a47a748ffc2b6e7ec24c3dc5ba79664ca8 (patch)
treebace204fa423c7489da190c08c2e86242c6b4588 /src/wimax/nm-device-wimax.c
parent0ed641587611afffa0b2cd38d5c70bdb480fa241 (diff)
parent485d149fe80915d94ed49ea6c2c0552cf7a3e79a (diff)
Merge commit 'upstream/0.9.1.95'
Diffstat (limited to 'src/wimax/nm-device-wimax.c')
-rw-r--r--src/wimax/nm-device-wimax.c115
1 files changed, 67 insertions, 48 deletions
diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c
index 9dff503d..2d8553a0 100644
--- a/src/wimax/nm-device-wimax.c
+++ b/src/wimax/nm-device-wimax.c
@@ -23,7 +23,8 @@
 #include <unistd.h>
 #include <sys/ioctl.h>
 #include <net/ethernet.h>
-#include <net/if.h>
+#include <sys/socket.h>
+#include <linux/if.h>
 
 #include <WiMaxAPI.h>
 #include <WiMaxAPIEx.h>
@@ -91,6 +92,9 @@ typedef struct {
 	struct ether_addr hw_addr;
 	guint activation_timeout_id;
 
+	/* Track whether stage1 (Prepare) is completed yet or not */
+	gboolean prepare_done;
+
 	guint sdk_action_defer_id;
 
 	guint link_timeout_id;
@@ -231,27 +235,25 @@ set_current_nsp (NMDeviceWimax *self, NMWimaxNsp *new_nsp)
 {
 	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
 	NMWimaxNsp *old_nsp;
-	char *old_path = NULL;
+	gboolean path_changed = FALSE;
 
 	old_nsp = priv->current_nsp;
-	if (old_nsp) {
-		old_path = g_strdup (nm_wimax_nsp_get_dbus_path (old_nsp));
-		priv->current_nsp = NULL;
-	}
+	priv->current_nsp = NULL;
 
 	if (new_nsp)
 		priv->current_nsp = g_object_ref (new_nsp);
 
-	if (old_nsp)
-		g_object_unref (old_nsp);
+	if (old_nsp && new_nsp) {
+		path_changed = (g_strcmp0 (nm_wimax_nsp_get_dbus_path (old_nsp),
+		                           nm_wimax_nsp_get_dbus_path (new_nsp)) != 0);
+	}
 
 	/* Only notify if it's really changed */
-	if (   (!old_path && new_nsp)
-		|| (old_path && !new_nsp)
-	    || (old_path && new_nsp && strcmp (old_path, nm_wimax_nsp_get_dbus_path (new_nsp))))
+	if (old_nsp != new_nsp || path_changed)
 		g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP);
 
-	g_free (old_path);
+	if (old_nsp)
+		g_object_unref (old_nsp);
 }
 
 NMWimaxNsp *
@@ -390,7 +392,7 @@ real_take_down (NMDevice *device)
 static gboolean
 real_hw_is_up (NMDevice *device)
 {
-	return nm_system_device_is_up (device);
+	return nm_system_iface_is_up (nm_device_get_ip_ifindex (device));
 }
 
 static gboolean
@@ -401,13 +403,13 @@ real_hw_bring_up (NMDevice *dev, gboolean *no_firmware)
 	if (!priv->enabled || !priv->wimaxd_enabled)
 		return FALSE;
 
-	return nm_system_device_set_up_down (dev, TRUE, no_firmware);
+	return nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware);
 }
 
 static void
 real_hw_take_down (NMDevice *dev)
 {
-	nm_system_device_set_up_down (dev, FALSE, NULL);
+	nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL);
 }
 
 static void
@@ -749,6 +751,8 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
 
 	set_current_nsp (NM_DEVICE_WIMAX (device), nsp);
 
+	priv->prepare_done = TRUE;
+
 	/* If the device is scanning, it won't connect, so we have to wait until
 	 * it's not scanning to proceed to stage 2.
 	 */
@@ -853,6 +857,7 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
                      WIMAX_API_DEVICE_STATUS new_status,
                      WIMAX_API_DEVICE_STATUS old_status,
                      WIMAX_API_STATUS_REASON reason,
+                     WIMAX_API_CONNECTION_PROGRESS_INFO progress,
                      void *user_data)
 {
 	NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
@@ -862,10 +867,17 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
 	gboolean old_available = FALSE;
 	const char *nsp_name = NULL;
 
+	iface = nm_device_get_iface (NM_DEVICE (self));
+	nm_log_info (LOGD_WIMAX, "(%s): wimax state change %s -> %s (%s (%d))",
+	             iface,
+	             iwmx_sdk_dev_status_to_str (old_status),
+	             iwmx_sdk_dev_status_to_str (new_status),
+	             iwmx_sdk_con_progress_to_str (progress),
+	             progress);
+
 	if (new_status == old_status)
 		return;
 
-	iface = nm_device_get_iface (NM_DEVICE (self));
 	state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
 	old_available = nm_device_is_available (NM_DEVICE (self));
 
@@ -873,12 +885,6 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
 	if (priv->current_nsp)
 		nsp_name = nm_wimax_nsp_get_name (priv->current_nsp);
 
-	nm_log_info (LOGD_WIMAX, "(%s): wimax state change %s -> %s (reason %d)",
-	             iface,
-	             iwmx_sdk_dev_status_to_str (old_status),
-	             iwmx_sdk_dev_status_to_str (new_status),
-	             reason);
-
 	switch (new_status) {
 	case WIMAX_API_DEVICE_STATUS_UnInitialized:
 	case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
@@ -936,7 +942,7 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk,
 		 * then check if we need to move to stage2 now that the device might be
 		 * ready.
 		 */
-		if (state == NM_DEVICE_STATE_PREPARE) {
+		if (state == NM_DEVICE_STATE_PREPARE && priv->prepare_done) {
 			if (   new_status == WIMAX_API_DEVICE_STATUS_Ready
 			    || new_status == WIMAX_API_DEVICE_STATUS_Connecting) {
 				nm_device_activate_schedule_stage2_device_config (NM_DEVICE (self));
@@ -1003,7 +1009,7 @@ wmx_media_status_cb (struct wmxsdk *wmxsdk,
 		break;
 	case WIMAX_API_MEDIA_STATUS_LINK_DOWN:
 		nm_log_dbg (LOGD_WIMAX, "(%s): starting link timeout", iface);
-		priv->link_timeout_id = g_timeout_add (15, link_timeout_cb, self);
+		priv->link_timeout_id = g_timeout_add_seconds (15, link_timeout_cb, self);
 		break;
 	case WIMAX_API_MEDIA_STATUS_LINK_RENEW:
 		nm_log_dbg (LOGD_WIMAX, "(%s): renewing DHCP lease", iface);
@@ -1130,18 +1136,22 @@ 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);
+	if (!priv->sdk) {
+		nm_log_dbg (LOGD_WIMAX, "(%s): removed unhandled WiMAX interface", wmxsdk->ifname);
+		return;
+	}
 
-		wmxsdk_unref (priv->sdk);
-		priv->sdk = NULL;
+	nm_log_dbg (LOGD_WIMAX, "(%s): removed WiMAX interface", wmxsdk->ifname);
 
-		priv->status = WIMAX_API_DEVICE_STATUS_UnInitialized;
-		nm_device_state_changed (NM_DEVICE (self),
-								 NM_DEVICE_STATE_UNAVAILABLE,
-								 NM_DEVICE_STATE_REASON_NONE);
-	}
+	/* 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);
 }
 
 /*************************************************************************/
@@ -1277,6 +1287,9 @@ device_state_changed (NMDevice *device,
 	NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
 	NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
 
+	/* Reset our stage1 (Prepare) done marker since it's only valid while in stage1 */
+	priv->prepare_done = FALSE;
+
 	if (new_state < NM_DEVICE_STATE_DISCONNECTED)
 		remove_all_nsps (self);
 
@@ -1323,21 +1336,27 @@ 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);
+	/* 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);
 }
 
 /*************************************************************************/