summary refs log tree commit diff
path: root/src/wimax
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2011-10-28 23:04:16 +0200
committerMichael Biebl <biebl@debian.org>2011-10-28 23:04:16 +0200
commit485d149fe80915d94ed49ea6c2c0552cf7a3e79a (patch)
tree6a48492b46b8c1e3df1c58626c28f05a978c61f7 /src/wimax
parent263bf4c0c89bb88dc995acd9a6a2de9095fbd461 (diff)
Imported Upstream version 0.9.1.95 upstream/0.9.1.95
Diffstat (limited to 'src/wimax')
-rw-r--r--src/wimax/Makefile.in8
-rw-r--r--src/wimax/iwmxsdk.c77
-rw-r--r--src/wimax/iwmxsdk.h2
-rw-r--r--src/wimax/nm-device-wimax.c115
4 files changed, 135 insertions, 67 deletions
diff --git a/src/wimax/Makefile.in b/src/wimax/Makefile.in
index e6064bc6..1be78482 100644
--- a/src/wimax/Makefile.in
+++ b/src/wimax/Makefile.in
@@ -186,8 +186,16 @@ LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBM = @LIBM@
+LIBNL1_CFLAGS = @LIBNL1_CFLAGS@
+LIBNL1_LIBS = @LIBNL1_LIBS@
+LIBNL2_CFLAGS = @LIBNL2_CFLAGS@
+LIBNL2_LIBS = @LIBNL2_LIBS@
+LIBNL3_CFLAGS = @LIBNL3_CFLAGS@
+LIBNL3_LIBS = @LIBNL3_LIBS@
 LIBNL_CFLAGS = @LIBNL_CFLAGS@
 LIBNL_LIBS = @LIBNL_LIBS@
+LIBNL_ROUTE3_CFLAGS = @LIBNL_ROUTE3_CFLAGS@
+LIBNL_ROUTE3_LIBS = @LIBNL_ROUTE3_LIBS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c
index dd78d5a4..9c3a78bb 100644
--- a/src/wimax/iwmxsdk.c
+++ b/src/wimax/iwmxsdk.c
@@ -27,7 +27,8 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
-#include <net/if.h>
+#include <sys/socket.h>
+#include <linux/if.h>
 
 #include <glib.h>
 
@@ -190,6 +191,7 @@ typedef struct {
 	WIMAX_API_DEVICE_STATUS new_status;
 	WIMAX_API_DEVICE_STATUS old_status;
 	WIMAX_API_STATUS_REASON reason;
+	WIMAX_API_CONNECTION_PROGRESS_INFO progress;
 } StateChangeInfo;
 
 static gboolean
@@ -202,6 +204,7 @@ state_change_handler(gpointer user_data)
 		                              info->new_status,
 		                              info->old_status,
 		                              info->reason,
+		                              info->progress,
 		                              info->wmxsdk->callback_data);
 	}
 	wmxsdk_unref(info->wmxsdk);
@@ -214,7 +217,8 @@ static void
 _schedule_state_change(struct wmxsdk *wmxsdk,
                        WIMAX_API_DEVICE_STATUS new_status,
                        WIMAX_API_DEVICE_STATUS old_status,
-                       WIMAX_API_STATUS_REASON reason)
+                       WIMAX_API_STATUS_REASON reason,
+                       WIMAX_API_CONNECTION_PROGRESS_INFO progress)
 {
 	StateChangeInfo *info;
 
@@ -227,6 +231,7 @@ _schedule_state_change(struct wmxsdk *wmxsdk,
 	info->new_status = new_status;
 	info->old_status = old_status;
 	info->reason = reason;
+	info->progress = progress;
 
 	wmxsdk_ref(wmxsdk);
 	g_idle_add(state_change_handler, info);
@@ -476,6 +481,48 @@ const char *iwmx_sdk_media_status_to_str(WIMAX_API_MEDIA_STATUS status)
 	}
 }
 
+const char *
+iwmx_sdk_con_progress_to_str(WIMAX_API_CONNECTION_PROGRESS_INFO progress)
+{
+	switch (progress) {
+
+	/**< Device is in Ranging */
+	case WIMAX_API_DEVICE_CONNECTION_PROGRESS_Ranging:
+		return "ranging";
+
+	/**< Device is in SBC */
+	case WIMAX_API_DEVICE_CONNECTION_PROGRESS_SBC:
+		return "sbc";
+
+	/**< Device is in EAP authentication Device */
+	case WIMAX_API_DEVICE_CONNECTION_PROGRESS_EAP_authentication_Device:
+		return "eap-auth-device";
+
+	/**< Device is in EAP authentication User */
+	case WIMAX_API_DEVICE_CONNECTION_PROGRESS_EAP_authentication_User:
+		return "eap-auth-user";
+
+	/**< Device is in 3-way-handshake */
+	case WIMAX_API_DEVICE_CONNECTION_PROGRESS_3_way_handshake:
+		return "3way-handshake";
+
+	/**< Device is in Registration */
+	case WIMAX_API_DEVICE_CONNECTION_PROGRESS_Registration:
+		return "registration";
+
+	/**< Device is in De-registration */
+	case WIMAX_API_DEVICE_CONNECTION_PROGRESS_De_registration:
+		return "deregistration";
+
+	/**< Device is registered (operational) */
+	case WIMAX_API_DEVICE_CONNECTION_PROGRESS_Registered:
+		return "registered";
+
+	default:
+		return "unknown";
+	}
+}
+
 /*
  * Get the device's status from the device
  *
@@ -982,7 +1029,7 @@ static void __iwmx_sdk_state_change_cb(WIMAX_API_DEVICE_ID *device_id,
 	wmxsdk->status = status;
 	g_mutex_unlock(wmxsdk->status_mutex);
 
-	_schedule_state_change(wmxsdk, status, old_status, reason);
+	_schedule_state_change(wmxsdk, status, old_status, reason, pi);
 }
 
 /*
@@ -1170,7 +1217,8 @@ static int iwmx_sdk_setup(struct wmxsdk *wmxsdk)
 	_schedule_state_change(wmxsdk,
 	                       status,
 	                       WIMAX_API_DEVICE_STATUS_UnInitialized,
-	                       WIMAX_API_STATUS_REASON_Normal);
+	                       WIMAX_API_STATUS_REASON_Normal,
+	                       WIMAX_API_DEVICE_CONNECTION_PROGRESS_Ranging);
 
 	return 0;
 
@@ -1268,23 +1316,22 @@ void wmxsdk_unref(struct wmxsdk *wmxsdk)
 
 static void iwmx_sdk_dev_add(unsigned idx, unsigned api_idx, const char *name)
 {
-	int ifindex;
 	struct wmxsdk *wmxsdk;
 	const char *s;
 
 	if (idx >= IWMX_SDK_DEV_MAX) {
 		nm_log_err(LOGD_WIMAX, "BUG! idx (%u) >= IWMX_SDK_DEV_MAX (%u)", idx, IWMX_SDK_DEV_MAX);
-		goto error_bug;
+		return;
 	}
 	if (g_iwmx_sdk_devs[idx] != NULL) {
 		nm_log_err(LOGD_WIMAX, "BUG! device index %u already enumerated?", idx);
-		goto error_bug;
+		return;
 	}
 
 	wmxsdk = wmxsdk_new();
 	if (wmxsdk == NULL) {
 		nm_log_err(LOGD_WIMAX, "Can't allocate %zu bytes", sizeof(*wmxsdk));
-		goto error_bug;
+		return;
 	}
 
 	/*
@@ -1297,23 +1344,17 @@ static void iwmx_sdk_dev_add(unsigned idx, unsigned api_idx, const char *name)
 	    || sscanf(s, "if:%15[^ \f\n\r\t\v]", wmxsdk->ifname) != 1) {
 		nm_log_err(LOGD_WIMAX, "Cannot extract network interface name off '%s'",
 			      name);
-		goto error_noifname;
+		goto error;
 	}
 	nm_log_dbg(LOGD_WIMAX, "network interface name: '%s'", wmxsdk->ifname);
 
-	ifindex = if_nametoindex(wmxsdk->ifname);
-	if (ifindex <= 0) {
-		nm_log_err(LOGD_WIMAX, "wxmsdk: %s: cannot find interface index", wmxsdk->ifname);
-		goto error_noifname;
-	}
-
 	strncpy(wmxsdk->name, name, sizeof(wmxsdk->name));
 	wmxsdk->device_id.privilege = WIMAX_API_PRIVILEGE_READ_WRITE;
 	wmxsdk->device_id.deviceIndex = api_idx;
 
 	if (iwmx_sdk_setup(wmxsdk) != 0) {
 		nm_log_err(LOGD_WIMAX, "wxmsdk: %s: cannot set up interface", wmxsdk->ifname);
-		goto error_setup;
+		goto error;
 	}
 
 	g_iwmx_sdk_devs[idx] = wmxsdk;
@@ -1322,10 +1363,8 @@ static void iwmx_sdk_dev_add(unsigned idx, unsigned api_idx, const char *name)
 	iwmx_sdk_call_new_callbacks (wmxsdk);
 	return;
 
-error_setup:
-error_noifname:
+error:
 	wmxsdk_unref(wmxsdk);
-error_bug:
 	return;
 }
 
diff --git a/src/wimax/iwmxsdk.h b/src/wimax/iwmxsdk.h
index bd55679a..1888b709 100644
--- a/src/wimax/iwmxsdk.h
+++ b/src/wimax/iwmxsdk.h
@@ -34,6 +34,7 @@ typedef void (*WimaxStateChangeFunc) (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 info,
                                       void *user_data);
 
 typedef void (*WimaxMediaStatusFunc) (struct wmxsdk *wmxsdk,
@@ -101,6 +102,7 @@ WIMAX_API_LINK_STATUS_INFO_EX *iwmx_sdk_get_link_status_info(struct wmxsdk *wmxs
 const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status);
 const char *iwmx_sdk_reason_to_str(WIMAX_API_STATUS_REASON reason);
 const char *iwmx_sdk_media_status_to_str(WIMAX_API_MEDIA_STATUS status);
+const char *iwmx_sdk_con_progress_to_str(WIMAX_API_CONNECTION_PROGRESS_INFO progress);
 int iwmx_sdk_rf_state_set(struct wmxsdk *wmxsdk, WIMAX_API_RF_STATE rf_state);
 int iwmx_sdk_get_networks(struct wmxsdk *wmxsdk);
 int iwmx_sdk_api_init(void);
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);
 }
 
 /*************************************************************************/