diff options
Diffstat (limited to 'src/wimax')
| -rw-r--r-- | src/wimax/Makefile.in | 8 | ||||
| -rw-r--r-- | src/wimax/iwmxsdk.c | 77 | ||||
| -rw-r--r-- | src/wimax/iwmxsdk.h | 2 | ||||
| -rw-r--r-- | src/wimax/nm-device-wimax.c | 115 |
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); } /*************************************************************************/ |