diff --git a/configure.ac b/configure.ac
index 2d59fa1b9c..cc79b67c5a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -229,6 +229,8 @@ PKG_CHECK_MODULES(POLKIT, polkit-gobject-1)
AC_SUBST(POLKIT_CFLAGS)
+PKG_CHECK_MODULES(WIMAX, libiWmxSdk-0)
+
AC_ARG_WITH(crypto, AS_HELP_STRING([--with-crypto=nss | gnutls], [Cryptography library to use for certificate and key operations]),ac_crypto=$withval, ac_crypto=nss)
with_nss=no
@@ -438,6 +440,7 @@ src/ppp-manager/Makefile
src/dnsmasq-manager/Makefile
src/modem-manager/Makefile
src/bluez-manager/Makefile
+src/wimax/Makefile
src/system-settings/Makefile
src/backends/Makefile
libnm-util/libnm-util.pc
diff --git a/include/NetworkManager.h b/include/NetworkManager.h
index c8d5074a1e..f269971123 100644
--- a/include/NetworkManager.h
+++ b/include/NetworkManager.h
@@ -38,6 +38,9 @@
#define NM_DBUS_INTERFACE_SERIAL_DEVICE NM_DBUS_INTERFACE_DEVICE ".Serial"
#define NM_DBUS_INTERFACE_GSM_DEVICE NM_DBUS_INTERFACE_DEVICE ".Gsm"
#define NM_DBUS_INTERFACE_CDMA_DEVICE NM_DBUS_INTERFACE_DEVICE ".Cdma"
+#define NM_DBUS_INTERFACE_WIMAX_DEVICE NM_DBUS_INTERFACE_DEVICE ".WiMax"
+#define NM_DBUS_INTERFACE_WIMAX_NSP NM_DBUS_INTERFACE ".WiMax.Nsp"
+#define NM_DBUS_PATH_WIMAX_NSP NM_DBUS_PATH "/Nsp"
#define NM_DBUS_INTERFACE_ACTIVE_CONNECTION NM_DBUS_INTERFACE ".Connection.Active"
#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config"
#define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config"
@@ -79,6 +82,7 @@ typedef enum NMDeviceType
NM_DEVICE_TYPE_GSM,
NM_DEVICE_TYPE_CDMA,
NM_DEVICE_TYPE_BT, /* Bluetooth */
+ NM_DEVICE_TYPE_WIMAX,
NM_DEVICE_TYPE_OLPC_MESH
} NMDeviceType;
diff --git a/introspection/Makefile.am b/introspection/Makefile.am
index 0dc286a9cd..091384f22d 100644
--- a/introspection/Makefile.am
+++ b/introspection/Makefile.am
@@ -23,5 +23,7 @@ EXTRA_DIST = \
nm-vpn-connection.xml \
nm-ppp-manager.xml \
nm-active-connection.xml \
- nm-dhcp4-config.xml
+ nm-dhcp4-config.xml \
+ nm-wimax-device.xml \
+ nm-wimax-nsp.xml
diff --git a/introspection/all.xml b/introspection/all.xml
index 67f1e54216..b84853c2c8 100644
--- a/introspection/all.xml
+++ b/introspection/all.xml
@@ -43,6 +43,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
diff --git a/introspection/nm-wimax-device.xml b/introspection/nm-wimax-device.xml
new file mode 100644
index 0000000000..69c1102b48
--- /dev/null
+++ b/introspection/nm-wimax-device.xml
@@ -0,0 +1,63 @@
+
+
+
+
+
+
+
+
+ List of NSP object paths
+
+
+
+ Get the list of NSPs visible to this device.
+
+
+
+
+
+ Hardware address of the device.
+
+
+
+
+
+ Object path of the NSP currently used by the WiMax device.
+
+
+
+
+
+
+ A dictionary mapping property names to variant boxed values.
+
+
+
+ Emitted when the WiMax device's properties changed.
+
+
+
+
+
+
+ The object path of the newly found NSP.
+
+
+
+ Emitted when a new NSP is found by the device.
+
+
+
+
+
+
+ The object path of the NSP that has disappeared.
+
+
+
+ Emitted when an NSP disappears from view of the device.
+
+
+
+
+
diff --git a/introspection/nm-wimax-nsp.xml b/introspection/nm-wimax-nsp.xml
new file mode 100644
index 0000000000..55ac4abcf2
--- /dev/null
+++ b/introspection/nm-wimax-nsp.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+ The name of the NSP.
+
+
+ The current signal quality of the NSP, in percent.
+
+
+ The network type of the NSP.
+
+
+
+
+
+ A dictionary mapping property names to variant boxed values.
+
+
+
+
+
+
+ Network type of the NSP.
+
+
+ Unknown network.
+
+
+ Home network.
+
+
+ Partner network.
+
+
+ Roaming partner network.
+
+
+
+
+
+
diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am
index f91623e1b9..9ad6c99cf1 100644
--- a/libnm-glib/Makefile.am
+++ b/libnm-glib/Makefile.am
@@ -20,7 +20,8 @@ BUILT_SOURCES = \
nm-active-connection-bindings.h \
nm-ip4-config-bindings.h \
nm-dhcp4-config-bindings.h \
- nm-ip6-config-bindings.h
+ nm-ip6-config-bindings.h \
+ nm-wimax-device-bindings.h
lib_LTLIBRARIES = libnm-glib.la libnm-glib-vpn.la
@@ -59,7 +60,9 @@ libnminclude_HEADERS = \
nm-remote-settings-system.h \
nm-settings-connection-interface.h \
nm-exported-connection.h \
- nm-settings-service.h
+ nm-settings-service.h \
+ nm-wimax-device.h \
+ nm-wimax-nsp.h
libnm_glib_la_SOURCES = \
libnm_glib.c \
@@ -94,7 +97,9 @@ libnm_glib_la_SOURCES = \
nm-remote-settings-system.c \
nm-settings-connection-interface.c \
nm-exported-connection.c \
- nm-settings-service.c
+ nm-settings-service.c \
+ nm-wimax-device.c \
+ nm-wimax-nsp.c
libnm_glib_la_LIBADD = \
$(top_builddir)/libnm-util/libnm-util.la \
@@ -172,6 +177,9 @@ nm-dhcp4-config-bindings.h: $(top_srcdir)/introspection/nm-dhcp4-config.xml
nm-ip6-config-bindings.h: $(top_srcdir)/introspection/nm-ip6-config.xml
dbus-binding-tool --prefix=nm_ip6_config --mode=glib-client --output=$@ $<
+nm-wimax-device-bindings.h: $(top_srcdir)/introspection/nm-wimax-device.xml
+ dbus-binding-tool --prefix=nm_wimax_device --mode=glib-client --output=$@ $<
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnm-glib.pc libnm-glib-vpn.pc
diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver
index 25556391dd..108a83726f 100644
--- a/libnm-glib/libnm-glib.ver
+++ b/libnm-glib/libnm-glib.ver
@@ -149,6 +149,17 @@ global:
nm_vpn_connection_get_type;
nm_vpn_connection_get_vpn_state;
nm_vpn_connection_new;
+ nm_wimax_device_get_hw_address;
+ nm_wimax_device_get_active_nsp;
+ nm_wimax_device_get_nsp_by_path;
+ nm_wimax_device_get_nsps;
+ nm_wimax_device_get_type;
+ nm_wimax_device_new;
+ nm_wimax_nsp_get_name;
+ nm_wimax_nsp_get_network_type;
+ nm_wimax_nsp_get_signal_quality;
+ nm_wimax_nsp_get_type;
+ nm_wimax_nsp_new;
local:
*;
};
diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c
index 17caa99d5d..aa6afeb0f6 100644
--- a/libnm-glib/nm-device.c
+++ b/libnm-glib/nm-device.c
@@ -32,6 +32,7 @@
#include "nm-gsm-device.h"
#include "nm-cdma-device.h"
#include "nm-device-bt.h"
+#include "nm-wimax-device.h"
#include "nm-device.h"
#include "nm-device-private.h"
#include "nm-object-private.h"
@@ -621,6 +622,9 @@ nm_device_new (DBusGConnection *connection, const char *path)
case NM_DEVICE_TYPE_BT:
dtype = NM_TYPE_DEVICE_BT;
break;
+ case NM_DEVICE_TYPE_WIMAX:
+ dtype = NM_TYPE_WIMAX_DEVICE;
+ break;
default:
g_warning ("Unknown device type %d", g_value_get_uint (&value));
break;
diff --git a/libnm-glib/nm-wimax-device.c b/libnm-glib/nm-wimax-device.c
new file mode 100644
index 0000000000..09a9bad64d
--- /dev/null
+++ b/libnm-glib/nm-wimax-device.c
@@ -0,0 +1,567 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#include
+
+#include "nm-wimax-device.h"
+#include "nm-object-private.h"
+#include "nm-object-cache.h"
+#include "nm-dbus-glib-types.h"
+#include "nm-types-private.h"
+
+#include "nm-wimax-device-bindings.h"
+
+G_DEFINE_TYPE (NMWimaxDevice, nm_wimax_device, NM_TYPE_DEVICE)
+
+#define NM_WIMAX_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_WIMAX_DEVICE, NMWimaxDevicePrivate))
+
+static gboolean demarshal_active_nsp (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field);
+
+void _nm_wimax_device_set_wireless_enabled (NMWimaxDevice *wimax, gboolean enabled);
+
+typedef struct {
+ gboolean disposed;
+ DBusGProxy *proxy;
+
+ char *hw_address;
+ NMWimaxNsp *active_nsp;
+ gboolean null_active_nsp;
+ GPtrArray *nsps;
+} NMWimaxDevicePrivate;
+
+enum {
+ PROP_0,
+ PROP_HW_ADDRESS,
+ PROP_ACTIVE_NSP,
+
+ LAST_PROP
+};
+
+#define DBUS_PROP_HW_ADDRESS "HwAddress"
+#define DBUS_PROP_ACTIVE_NSP "ActiveNsp"
+
+enum {
+ NSP_ADDED,
+ NSP_REMOVED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/**
+ * nm_wimax_device_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBus object path of the wimax
+ *
+ * Creates a new #NMWimaxDevice.
+ *
+ * Returns: a new wimax
+ **/
+GObject *
+nm_wimax_device_new (DBusGConnection *connection, const char *path)
+{
+ g_return_val_if_fail (connection != NULL, NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ return g_object_new (NM_TYPE_WIMAX_DEVICE,
+ NM_OBJECT_DBUS_CONNECTION, connection,
+ NM_OBJECT_DBUS_PATH, path,
+ NULL);
+}
+
+/**
+ * nm_wimax_device_get_hw_address:
+ * @device: a #NMWimaxDevice
+ *
+ * Gets the hardware (MAC) address of the #NMWimaxDevice
+ *
+ * Returns: the hardware address. This is the internal string used by the
+ * device, and must not be modified.
+ **/
+const char *
+nm_wimax_device_get_hw_address (NMWimaxDevice *wimax)
+{
+ NMWimaxDevicePrivate *priv;
+
+ g_return_val_if_fail (NM_IS_WIMAX_DEVICE (wimax), NULL);
+
+ priv = NM_WIMAX_DEVICE_GET_PRIVATE (wimax);
+ if (!priv->hw_address) {
+ priv->hw_address = _nm_object_get_string_property (NM_OBJECT (wimax),
+ NM_DBUS_INTERFACE_WIMAX_DEVICE,
+ DBUS_PROP_HW_ADDRESS);
+ }
+
+ return priv->hw_address;
+}
+
+/**
+ * nm_wimax_device_get_active_nsp:
+ * @wimax: a #NMWimaxDevice
+ *
+ * Gets the active #NMWimaxNsp.
+ *
+ * Returns: the access point or %NULL if none is active
+ **/
+NMWimaxNsp *
+nm_wimax_device_get_active_nsp (NMWimaxDevice *wimax)
+{
+ NMWimaxDevicePrivate *priv;
+ NMDeviceState state;
+ char *path;
+ GValue value = { 0, };
+
+ g_return_val_if_fail (NM_IS_WIMAX_DEVICE (wimax), NULL);
+
+ state = nm_device_get_state (NM_DEVICE (wimax));
+ switch (state) {
+ case NM_DEVICE_STATE_PREPARE:
+ case NM_DEVICE_STATE_CONFIG:
+ case NM_DEVICE_STATE_NEED_AUTH:
+ case NM_DEVICE_STATE_IP_CONFIG:
+ case NM_DEVICE_STATE_ACTIVATED:
+ break;
+ default:
+ return NULL;
+ break;
+ }
+
+ priv = NM_WIMAX_DEVICE_GET_PRIVATE (wimax);
+ if (priv->active_nsp)
+ return priv->active_nsp;
+ if (priv->null_active_nsp)
+ return NULL;
+
+ path = _nm_object_get_object_path_property (NM_OBJECT (wimax),
+ NM_DBUS_INTERFACE_WIMAX_DEVICE,
+ DBUS_PROP_ACTIVE_NSP);
+ if (path) {
+ g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH);
+ g_value_take_boxed (&value, path);
+ demarshal_active_nsp (NM_OBJECT (wimax), NULL, &value, &priv->active_nsp);
+ g_value_unset (&value);
+ }
+
+ return priv->active_nsp;
+}
+
+/**
+ * nm_wimax_device_get_nsps:
+ * @wimax: a #NMWimaxDevice
+ *
+ * Gets all the scanned NSPs of the #NMWimaxDevice.
+ *
+ * Returns: a #GPtrArray containing all the scanned #NMWimaxNsps.
+ * The returned array is owned by the client and should not be modified.
+ **/
+const GPtrArray *
+nm_wimax_device_get_nsps (NMWimaxDevice *wimax)
+{
+ NMWimaxDevicePrivate *priv;
+ DBusGConnection *connection;
+ GValue value = { 0, };
+ GError *error = NULL;
+ GPtrArray *temp;
+
+ g_return_val_if_fail (NM_IS_WIMAX_DEVICE (wimax), NULL);
+
+ priv = NM_WIMAX_DEVICE_GET_PRIVATE (wimax);
+ if (priv->nsps)
+ return handle_ptr_array_return (priv->nsps);
+
+ if (!org_freedesktop_NetworkManager_Device_WiMax_get_nsp_list (priv->proxy, &temp, &error)) {
+ g_warning ("%s: error getting NSPs: %s", __func__, error->message);
+ g_error_free (error);
+ return NULL;
+ }
+
+ g_value_init (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH);
+ g_value_take_boxed (&value, temp);
+ connection = nm_object_get_connection (NM_OBJECT (wimax));
+ _nm_object_array_demarshal (&value, &priv->nsps, connection, nm_wimax_nsp_new);
+ g_value_unset (&value);
+
+ return handle_ptr_array_return (priv->nsps);
+}
+
+/**
+ * nm_wimax_device_get_nsp_by_path:
+ * @wimax: a #NMWimaxDevice
+ * @path: the object path of the NSP
+ *
+ * Gets a #NMWimaxNsp by path.
+ *
+ * Returns: the access point or %NULL if none is found.
+ **/
+NMWimaxNsp *
+nm_wimax_device_get_nsp_by_path (NMWimaxDevice *wimax,
+ const char *path)
+{
+ const GPtrArray *nsps;
+ int i;
+ NMWimaxNsp *nsp = NULL;
+
+ g_return_val_if_fail (NM_IS_WIMAX_DEVICE (wimax), NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ nsps = nm_wimax_device_get_nsps (wimax);
+ if (!nsps)
+ return NULL;
+
+ for (i = 0; i < nsps->len; i++) {
+ NMWimaxNsp *candidate = g_ptr_array_index (nsps, i);
+ if (!strcmp (nm_object_get_path (NM_OBJECT (candidate)), path)) {
+ nsp = candidate;
+ break;
+ }
+ }
+
+ return nsp;
+}
+
+static void
+nsp_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
+{
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (user_data);
+ NMWimaxDevicePrivate *priv;
+ GObject *nsp;
+
+ g_return_if_fail (self != NULL);
+
+ nsp = G_OBJECT (nm_wimax_device_get_nsp_by_path (self, path));
+ if (!nsp) {
+ DBusGConnection *connection = nm_object_get_connection (NM_OBJECT (self));
+
+ priv = NM_WIMAX_DEVICE_GET_PRIVATE (self);
+ nsp = G_OBJECT (_nm_object_cache_get (path));
+ if (nsp) {
+ g_ptr_array_add (priv->nsps, g_object_ref (nsp));
+ } else {
+ nsp = G_OBJECT (nm_wimax_nsp_new (connection, path));
+ if (nsp)
+ g_ptr_array_add (priv->nsps, nsp);
+ }
+ }
+
+ if (nsp)
+ g_signal_emit (self, signals[NSP_ADDED], 0, nsp);
+}
+
+static void
+nsp_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data)
+{
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (user_data);
+ NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (self);
+ NMWimaxNsp *nsp;
+
+ g_return_if_fail (self != NULL);
+
+ nsp = nm_wimax_device_get_nsp_by_path (self, path);
+ if (nsp) {
+ if (nsp == priv->active_nsp) {
+ g_object_unref (priv->active_nsp);
+ priv->active_nsp = NULL;
+ priv->null_active_nsp = FALSE;
+
+ _nm_object_queue_notify (NM_OBJECT (self), NM_WIMAX_DEVICE_ACTIVE_NSP);
+ }
+
+ g_signal_emit (self, signals[NSP_REMOVED], 0, nsp);
+ g_ptr_array_remove (priv->nsps, nsp);
+ g_object_unref (G_OBJECT (nsp));
+ }
+}
+
+static void
+clean_up_nsps (NMWimaxDevice *self, gboolean notify)
+{
+ NMWimaxDevicePrivate *priv;
+
+ g_return_if_fail (NM_IS_WIMAX_DEVICE (self));
+
+ priv = NM_WIMAX_DEVICE_GET_PRIVATE (self);
+
+ if (priv->active_nsp) {
+ g_object_unref (priv->active_nsp);
+ priv->active_nsp = NULL;
+ }
+
+ if (priv->nsps) {
+ while (priv->nsps->len) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (g_ptr_array_index (priv->nsps, 0));
+
+ if (notify)
+ g_signal_emit (self, signals[NSP_REMOVED], 0, nsp);
+ g_ptr_array_remove (priv->nsps, nsp);
+ g_object_unref (nsp);
+ }
+ g_ptr_array_free (priv->nsps, TRUE);
+ priv->nsps = NULL;
+ }
+}
+
+/**************************************************************/
+
+static void
+nm_wimax_device_init (NMWimaxDevice *wimax)
+{
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (object);
+
+ switch (prop_id) {
+ case PROP_HW_ADDRESS:
+ g_value_set_string (value, nm_wimax_device_get_hw_address (self));
+ break;
+ case PROP_ACTIVE_NSP:
+ g_value_set_object (value, nm_wimax_device_get_active_nsp (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data)
+{
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (device);
+ NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (self);
+
+ switch (nm_device_get_state (device)) {
+ case NM_DEVICE_STATE_UNKNOWN:
+ case NM_DEVICE_STATE_UNMANAGED:
+ case NM_DEVICE_STATE_UNAVAILABLE:
+ case NM_DEVICE_STATE_DISCONNECTED:
+ case NM_DEVICE_STATE_FAILED:
+ if (priv->active_nsp) {
+ g_object_unref (priv->active_nsp);
+ priv->active_nsp = NULL;
+ priv->null_active_nsp = FALSE;
+ }
+ _nm_object_queue_notify (NM_OBJECT (device), NM_WIMAX_DEVICE_ACTIVE_NSP);
+ break;
+ default:
+ break;
+ }
+}
+
+static gboolean
+demarshal_active_nsp (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
+{
+ NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (object);
+ const char *path;
+ NMWimaxNsp *nsp = NULL;
+ DBusGConnection *connection;
+
+ if (!G_VALUE_HOLDS (value, DBUS_TYPE_G_OBJECT_PATH))
+ return FALSE;
+
+ priv->null_active_nsp = FALSE;
+
+ path = g_value_get_boxed (value);
+ if (path) {
+ if (!strcmp (path, "/"))
+ priv->null_active_nsp = TRUE;
+ else {
+ nsp = NM_WIMAX_NSP (_nm_object_cache_get (path));
+ if (nsp)
+ nsp = g_object_ref (nsp);
+ else {
+ connection = nm_object_get_connection (object);
+ nsp = NM_WIMAX_NSP (nm_wimax_nsp_new (connection, path));
+ }
+ }
+ }
+
+ if (priv->active_nsp) {
+ g_object_unref (priv->active_nsp);
+ priv->active_nsp = NULL;
+ }
+
+ if (nsp)
+ priv->active_nsp = nsp;
+
+ _nm_object_queue_notify (object, NM_WIMAX_DEVICE_ACTIVE_NSP);
+ return TRUE;
+}
+
+static void
+register_for_property_changed (NMWimaxDevice *wimax)
+{
+ NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (wimax);
+ const NMPropertiesChangedInfo property_changed_info[] = {
+ { NM_WIMAX_DEVICE_HW_ADDRESS, _nm_object_demarshal_generic, &priv->hw_address },
+ { NM_WIMAX_DEVICE_ACTIVE_NSP, demarshal_active_nsp, &priv->active_nsp },
+ { NULL },
+ };
+
+ _nm_object_handle_properties_changed (NM_OBJECT (wimax),
+ priv->proxy,
+ property_changed_info);
+}
+
+static GObject*
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ NMWimaxDevicePrivate *priv;
+
+ object = G_OBJECT_CLASS (nm_wimax_device_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+ if (!object)
+ return NULL;
+
+ priv = NM_WIMAX_DEVICE_GET_PRIVATE (object);
+
+ priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)),
+ NM_DBUS_SERVICE,
+ nm_object_get_path (NM_OBJECT (object)),
+ NM_DBUS_INTERFACE_WIMAX_DEVICE);
+
+ dbus_g_proxy_add_signal (priv->proxy, "NspAdded",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "NspAdded",
+ G_CALLBACK (nsp_added_proxy),
+ object, NULL);
+
+ dbus_g_proxy_add_signal (priv->proxy, "NspRemoved",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "NspRemoved",
+ G_CALLBACK (nsp_removed_proxy),
+ object, NULL);
+
+ register_for_property_changed (NM_WIMAX_DEVICE (object));
+
+ g_signal_connect (object,
+ "notify::" NM_DEVICE_STATE,
+ G_CALLBACK (state_changed_cb),
+ NULL);
+
+ return object;
+}
+
+static void
+dispose (GObject *object)
+{
+ NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (object);
+
+ if (priv->disposed) {
+ G_OBJECT_CLASS (nm_wimax_device_parent_class)->dispose (object);
+ return;
+ }
+
+ priv->disposed = TRUE;
+
+ clean_up_nsps (NM_WIMAX_DEVICE (object), FALSE);
+ g_object_unref (priv->proxy);
+
+ G_OBJECT_CLASS (nm_wimax_device_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+ NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (object);
+
+ if (priv->hw_address)
+ g_free (priv->hw_address);
+
+ G_OBJECT_CLASS (nm_wimax_device_parent_class)->finalize (object);
+}
+
+static void
+nm_wimax_device_class_init (NMWimaxDeviceClass *wimax_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (wimax_class);
+
+ g_type_class_add_private (wimax_class, sizeof (NMWimaxDevicePrivate));
+
+ /* virtual methods */
+ object_class->constructor = constructor;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+ object_class->finalize = finalize;
+
+ /* properties */
+
+ /**
+ * NMWimaxDevice:active-nsp:
+ *
+ * The active #NMWimaxNsp of the device.
+ **/
+ g_object_class_install_property
+ (object_class, PROP_ACTIVE_NSP,
+ g_param_spec_object (NM_WIMAX_DEVICE_ACTIVE_NSP,
+ "Active NSP",
+ "Active NSP",
+ NM_TYPE_WIMAX_NSP,
+ G_PARAM_READABLE));
+
+ /* signals */
+
+ /**
+ * NMWimaxDevice::nsp-added:
+ * @self: the wimax device that received the signal
+ * @nsp: the new NSP
+ *
+ * Notifies that a #NMWimaxNsp is added to the wimax device.
+ **/
+ signals[NSP_ADDED] =
+ g_signal_new ("nsp-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMWimaxDeviceClass, nsp_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+
+ /**
+ * NMWimaxDevice::nsp-removed:
+ * @self: the wimax device that received the signal
+ * @nsp: the removed NSP
+ *
+ * Notifies that a #NMWimaxNsp is removed from the wimax device.
+ **/
+ signals[NSP_REMOVED] =
+ g_signal_new ("nsp-removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMWimaxDeviceClass, nsp_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+}
diff --git a/libnm-glib/nm-wimax-device.h b/libnm-glib/nm-wimax-device.h
new file mode 100644
index 0000000000..1e59fd0d52
--- /dev/null
+++ b/libnm-glib/nm-wimax-device.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_DEVICE_H
+#define NM_WIMAX_DEVICE_H
+
+#include "nm-device.h"
+#include "nm-wimax-nsp.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_WIMAX_DEVICE (nm_wimax_device_get_type ())
+#define NM_WIMAX_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIMAX_DEVICE, NMWimaxDevice))
+#define NM_WIMAX_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIMAX_DEVICE, NMWimaxDeviceClass))
+#define NM_IS_WIMAX_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIMAX_DEVICE))
+#define NM_IS_WIMAX_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_WIMAX_DEVICE))
+#define NM_WIMAX_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIMAX_DEVICE, NMWimaxDeviceClass))
+
+#define NM_WIMAX_DEVICE_HW_ADDRESS "hw-address"
+#define NM_WIMAX_DEVICE_ACTIVE_NSP "active-nsp"
+
+typedef struct {
+ NMDevice parent;
+} NMWimaxDevice;
+
+typedef struct {
+ NMDeviceClass parent;
+
+ /* Signals */
+ void (*nsp_added) (NMWimaxDevice *self, NMWimaxNsp *nsp);
+ void (*nsp_removed) (NMWimaxDevice *self, NMWimaxNsp *nsp);
+} NMWimaxDeviceClass;
+
+GType nm_wimax_device_get_type (void);
+
+GObject *nm_wimax_device_new (DBusGConnection *connection,
+ const char *path);
+
+const char *nm_wimax_device_get_hw_address (NMWimaxDevice *wimax);
+NMWimaxNsp *nm_wimax_device_get_active_nsp (NMWimaxDevice *wimax);
+NMWimaxNsp *nm_wimax_device_get_nsp_by_path (NMWimaxDevice *wimax,
+ const char *path);
+
+const GPtrArray *nm_wimax_device_get_nsps (NMWimaxDevice *wimax);
+
+G_END_DECLS
+
+#endif /* NM_WIMAX_DEVICE_H */
diff --git a/libnm-glib/nm-wimax-nsp.c b/libnm-glib/nm-wimax-nsp.c
new file mode 100644
index 0000000000..0c2cbca8f6
--- /dev/null
+++ b/libnm-glib/nm-wimax-nsp.c
@@ -0,0 +1,301 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#include
+
+#include "nm-wimax-nsp.h"
+#include "NetworkManager.h"
+#include "nm-types-private.h"
+#include "nm-object-private.h"
+
+G_DEFINE_TYPE (NMWimaxNsp, nm_wimax_nsp, NM_TYPE_OBJECT)
+
+#define NM_WIMAX_NSP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_WIMAX_NSP, NMWimaxNspPrivate))
+
+typedef struct {
+ gboolean disposed;
+ DBusGProxy *proxy;
+
+ char *name;
+ guint8 signal_quality;
+ NMWimaxNspNetworkType network_type;
+} NMWimaxNspPrivate;
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ PROP_SIGNAL_QUALITY,
+ PROP_NETWORK_TYPE,
+
+ LAST_PROP
+};
+
+#define DBUS_PROP_NAME "Name"
+#define DBUS_PROP_SIGNAL_QUALITY "SignalQuality"
+#define DBUS_PROP_NETWORK_TYPE "NetworkType"
+
+/**
+ * nm_wimax_nsp_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBusobject path of the wimax NSP
+ *
+ * Creates a new #NMWimaxNsp.
+ *
+ * Returns: a new wimax nsp
+ **/
+GObject *
+nm_wimax_nsp_new (DBusGConnection *connection, const char *path)
+{
+ g_return_val_if_fail (connection != NULL, NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ return (GObject *) g_object_new (NM_TYPE_WIMAX_NSP,
+ NM_OBJECT_DBUS_CONNECTION, connection,
+ NM_OBJECT_DBUS_PATH, path,
+ NULL);
+}
+
+/**
+ * nm_wimax_nsp_get_name:
+ * @nsp: a #NMWimaxNsp
+ *
+ * Gets the name of the wimax NSP
+ *
+ * Returns: the name
+ **/
+const char *
+nm_wimax_nsp_get_name (NMWimaxNsp *nsp)
+{
+ NMWimaxNspPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (nsp), NULL);
+
+ priv = NM_WIMAX_NSP_GET_PRIVATE (nsp);
+ if (!priv->name)
+ priv->name = _nm_object_get_string_property (NM_OBJECT (nsp),
+ NM_DBUS_INTERFACE_WIMAX_NSP,
+ DBUS_PROP_NAME);
+
+ return priv->name;
+}
+
+/**
+ * nm_wimax_nsp_get_signal_quality:
+ * @nsp: a #NMWimaxNsp
+ *
+ * Gets the WPA signal quality of the wimax NSP.
+ *
+ * Returns: the signal quality
+ **/
+guint8
+nm_wimax_nsp_get_signal_quality (NMWimaxNsp *nsp)
+{
+ NMWimaxNspPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (nsp), 0);
+
+ priv = NM_WIMAX_NSP_GET_PRIVATE (nsp);
+ if (!priv->signal_quality)
+ priv->signal_quality = _nm_object_get_byte_property (NM_OBJECT (nsp),
+ NM_DBUS_INTERFACE_WIMAX_NSP,
+ DBUS_PROP_SIGNAL_QUALITY);
+
+ return priv->signal_quality;
+}
+
+/**
+ * nm_wimax_nsp_get_network_type:
+ * @nsp: a #NMWimaxNsp
+ *
+ * Gets the network type of the wimax NSP.
+ *
+ * Returns: the network type
+ **/
+NMWimaxNspNetworkType
+nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp)
+{
+ NMWimaxNspPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (nsp), NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN);
+
+ priv = NM_WIMAX_NSP_GET_PRIVATE (nsp);
+ if (!priv->network_type)
+ priv->network_type = _nm_object_get_uint_property (NM_OBJECT (nsp),
+ NM_DBUS_INTERFACE_WIMAX_NSP,
+ DBUS_PROP_NETWORK_TYPE);
+
+ return priv->network_type;
+}
+
+/************************************************************/
+
+static void
+nm_wimax_nsp_init (NMWimaxNsp *nsp)
+{
+}
+
+static void
+dispose (GObject *object)
+{
+ NMWimaxNspPrivate *priv = NM_WIMAX_NSP_GET_PRIVATE (object);
+
+ if (priv->disposed) {
+ G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->dispose (object);
+ return;
+ }
+
+ priv->disposed = TRUE;
+
+ g_object_unref (priv->proxy);
+
+ G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+ NMWimaxNspPrivate *priv = NM_WIMAX_NSP_GET_PRIVATE (object);
+
+ g_free (priv->name);
+
+ G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->finalize (object);
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (object);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, nm_wimax_nsp_get_name (nsp));
+ break;
+ case PROP_SIGNAL_QUALITY:
+ g_value_set_uint (value, nm_wimax_nsp_get_signal_quality (nsp));
+ break;
+ case PROP_NETWORK_TYPE:
+ g_value_set_uint (value, nm_wimax_nsp_get_network_type (nsp));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+register_for_property_changed (NMWimaxNsp *nsp)
+{
+ NMWimaxNspPrivate *priv = NM_WIMAX_NSP_GET_PRIVATE (nsp);
+ const NMPropertiesChangedInfo property_changed_info[] = {
+ { NM_WIMAX_NSP_SIGNAL_QUALITY, _nm_object_demarshal_generic, &priv->signal_quality },
+ { NULL },
+ };
+
+ _nm_object_handle_properties_changed (NM_OBJECT (nsp),
+ priv->proxy,
+ property_changed_info);
+}
+
+static GObject*
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ NMObject *object;
+ NMWimaxNspPrivate *priv;
+
+ object = (NMObject *) G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+ if (!object)
+ return NULL;
+
+ priv = NM_WIMAX_NSP_GET_PRIVATE (object);
+
+ priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
+ NM_DBUS_SERVICE,
+ nm_object_get_path (object),
+ NM_DBUS_INTERFACE_WIMAX_NSP);
+
+ register_for_property_changed (NM_WIMAX_NSP (object));
+
+ return G_OBJECT (object);
+}
+
+
+static void
+nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (nsp_class);
+
+ g_type_class_add_private (nsp_class, sizeof (NMWimaxNspPrivate));
+
+ /* virtual methods */
+ object_class->constructor = constructor;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+ object_class->finalize = finalize;
+
+ /* properties */
+
+ /**
+ * NMWimaxNsp:name:
+ *
+ * The name of the wimax NSP.
+ **/
+ g_object_class_install_property
+ (object_class, PROP_NAME,
+ g_param_spec_string (NM_WIMAX_NSP_NAME,
+ "Name",
+ "Name",
+ NULL,
+ G_PARAM_READABLE));
+
+ /**
+ * NMWimaxNsp:signal-quality:
+ *
+ * The signal quality of the wimax NSP.
+ **/
+ g_object_class_install_property
+ (object_class, PROP_SIGNAL_QUALITY,
+ g_param_spec_uchar (NM_WIMAX_NSP_SIGNAL_QUALITY,
+ "Signal Quality",
+ "Signal Quality",
+ 0, G_MAXUINT8, 0,
+ G_PARAM_READABLE));
+
+ /**
+ * NMWimaxNsp:network-type:
+ *
+ * The network type of the wimax NSP.
+ **/
+ g_object_class_install_property
+ (object_class, PROP_NETWORK_TYPE,
+ g_param_spec_uint (NM_WIMAX_NSP_NETWORK_TYPE,
+ "Network Type",
+ "Network Type",
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READABLE));
+}
diff --git a/libnm-glib/nm-wimax-nsp.h b/libnm-glib/nm-wimax-nsp.h
new file mode 100644
index 0000000000..654b49c75e
--- /dev/null
+++ b/libnm-glib/nm-wimax-nsp.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * libnm_glib -- Access network status & information from glib applications
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_NSP_H
+#define NM_WIMAX_NSP_H
+
+#include
+#include
+#include
+#include "nm-object.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_WIMAX_NSP (nm_wimax_nsp_get_type ())
+#define NM_WIMAX_NSP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIMAX_NSP, NMWimaxNsp))
+#define NM_WIMAX_NSP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIMAX_NSP, NMWimaxNspClass))
+#define NM_IS_WIMAX_NSP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIMAX_NSP))
+#define NM_IS_WIMAX_NSP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_WIMAX_NSP))
+#define NM_WIMAX_NSP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIMAX_NSP, NMWimaxNspClass))
+
+#define NM_WIMAX_NSP_NAME "name"
+#define NM_WIMAX_NSP_SIGNAL_QUALITY "signal-quality"
+#define NM_WIMAX_NSP_NETWORK_TYPE "network-type"
+
+typedef enum {
+ NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN = 0,
+ NM_WIMAX_NSP_NETWORK_TYPE_HOME = 1,
+ NM_WIMAX_NSP_NETWORK_TYPE_PARTNER = 2,
+ NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER = 3
+} NMWimaxNspNetworkType;
+
+typedef struct {
+ NMObject parent;
+} NMWimaxNsp;
+
+typedef struct {
+ NMObjectClass parent;
+
+ /* Padding for future expansion */
+ void (*_reserved1) (void);
+ void (*_reserved2) (void);
+ void (*_reserved3) (void);
+ void (*_reserved4) (void);
+ void (*_reserved5) (void);
+ void (*_reserved6) (void);
+} NMWimaxNspClass;
+
+GType nm_wimax_nsp_get_type (void);
+
+GObject *nm_wimax_nsp_new (DBusGConnection *connection, const char *path);
+
+const char * nm_wimax_nsp_get_name (NMWimaxNsp *nsp);
+guint8 nm_wimax_nsp_get_signal_quality (NMWimaxNsp *nsp);
+NMWimaxNspNetworkType nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp);
+
+G_END_DECLS
+
+#endif /* NM_WIMAX_NSP_H */
diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am
index 2aa4c4ed6e..70c09402a0 100644
--- a/libnm-util/Makefile.am
+++ b/libnm-util/Makefile.am
@@ -24,6 +24,7 @@ libnm_util_include_HEADERS = \
nm-setting-gsm.h \
nm-setting-cdma.h \
nm-setting-olpc-mesh.h \
+ nm-setting-wimax.h \
nm-setting-wired.h \
nm-setting-wireless.h \
nm-setting-wireless-security.h \
@@ -48,6 +49,7 @@ libnm_util_la_SOURCES= \
nm-setting-gsm.c \
nm-setting-cdma.c \
nm-setting-olpc-mesh.c \
+ nm-setting-wimax.c \
nm-setting-wired.c \
nm-setting-wireless.c \
nm-setting-wireless-security.c \
diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver
index 17ce1749ff..ba0086264f 100644
--- a/libnm-util/libnm-util.ver
+++ b/libnm-util/libnm-util.ver
@@ -273,6 +273,12 @@ global:
nm_setting_vpn_foreach_secret;
nm_setting_vpn_get_secret;
nm_setting_vpn_remove_secret;
+ nm_setting_wimax_error_get_type;
+ nm_setting_wimax_error_quark;
+ nm_setting_wimax_get_type;
+ nm_setting_wimax_new;
+ nm_setting_wimax_get_network_name;
+ nm_setting_wimax_get_mac_address;
nm_setting_wired_error_get_type;
nm_setting_wired_error_quark;
nm_setting_wired_get_type;
diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c
index f4cb787ee9..d70b94f996 100644
--- a/libnm-util/nm-connection.c
+++ b/libnm-util/nm-connection.c
@@ -37,6 +37,7 @@
#include "nm-setting-ip6-config.h"
#include "nm-setting-ppp.h"
#include "nm-setting-pppoe.h"
+#include "nm-setting-wimax.h"
#include "nm-setting-wired.h"
#include "nm-setting-wireless.h"
#include "nm-setting-wireless-security.h"
@@ -141,7 +142,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
static GHashTable *registered_settings = NULL;
-#define DEFAULT_MAP_SIZE 15
+#define DEFAULT_MAP_SIZE 16
static struct SettingInfo {
const char *name;
@@ -237,6 +238,11 @@ register_default_settings (void)
NM_SETTING_BLUETOOTH_ERROR,
1);
+ register_one_setting (NM_SETTING_WIMAX_SETTING_NAME,
+ NM_TYPE_SETTING_WIMAX,
+ NM_SETTING_WIMAX_ERROR,
+ 1);
+
register_one_setting (NM_SETTING_WIRELESS_SECURITY_SETTING_NAME,
NM_TYPE_SETTING_WIRELESS_SECURITY,
NM_SETTING_WIRELESS_SECURITY_ERROR,
diff --git a/libnm-util/nm-setting-wimax.c b/libnm-util/nm-setting-wimax.c
new file mode 100644
index 0000000000..349a3ae8ea
--- /dev/null
+++ b/libnm-util/nm-setting-wimax.c
@@ -0,0 +1,229 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2009 Novell, Inc.
+ */
+
+#include
+#include
+#include "nm-setting-wimax.h"
+#include "nm-param-spec-specialized.h"
+
+GQuark
+nm_setting_wimax_error_quark (void)
+{
+ static GQuark quark;
+
+ if (G_UNLIKELY (!quark))
+ quark = g_quark_from_static_string ("nm-setting-wimax-error-quark");
+ return quark;
+}
+
+/* This should really be standard. */
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GType
+nm_setting_wimax_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ /* Unknown error. */
+ ENUM_ENTRY (NM_SETTING_WIMAX_ERROR_UNKNOWN, "UnknownError"),
+ /* The specified property was invalid. */
+ ENUM_ENTRY (NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, "InvalidProperty"),
+ /* The specified property was missing and is required. */
+ ENUM_ENTRY (NM_SETTING_WIMAX_ERROR_MISSING_PROPERTY, "MissingProperty"),
+ { 0, 0, 0 }
+ };
+ etype = g_enum_register_static ("NMSettingWimaxError", values);
+ }
+ return etype;
+}
+
+
+G_DEFINE_TYPE (NMSettingWimax, nm_setting_wimax, NM_TYPE_SETTING)
+
+#define NM_SETTING_WIMAX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_WIMAX, NMSettingWimaxPrivate))
+
+typedef struct {
+ char *network_name;
+ GByteArray *mac_address;
+} NMSettingWimaxPrivate;
+
+enum {
+ PROP_0,
+ PROP_NETWORK_NAME,
+ PROP_MAC_ADDRESS,
+
+ LAST_PROP
+};
+
+NMSetting *
+nm_setting_wimax_new (void)
+{
+ return (NMSetting *) g_object_new (NM_TYPE_SETTING_WIMAX, NULL);
+}
+
+const char *
+nm_setting_wimax_get_network_name (NMSettingWimax *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_WIMAX (setting), NULL);
+
+ return NM_SETTING_WIMAX_GET_PRIVATE (setting)->network_name;
+}
+
+const GByteArray *
+nm_setting_wimax_get_mac_address (NMSettingWimax *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_WIMAX (setting), NULL);
+
+ return NM_SETTING_WIMAX_GET_PRIVATE (setting)->mac_address;
+}
+
+static gboolean
+verify (NMSetting *setting, GSList *all_settings, GError **error)
+{
+ NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (setting);
+
+ if (!priv->network_name) {
+ g_set_error (error,
+ NM_SETTING_WIMAX_ERROR,
+ NM_SETTING_WIMAX_ERROR_MISSING_PROPERTY,
+ NM_SETTING_WIMAX_NETWORK_NAME);
+
+ return FALSE;
+ }
+
+ if (priv->mac_address && priv->mac_address->len != ETH_ALEN) {
+ g_set_error (error,
+ NM_SETTING_WIMAX_ERROR,
+ NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY,
+ NM_SETTING_WIMAX_MAC_ADDRESS);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+nm_setting_wimax_init (NMSettingWimax *setting)
+{
+ g_object_set (setting, NM_SETTING_NAME, NM_SETTING_WIMAX_SETTING_NAME, NULL);
+}
+
+static void
+finalize (GObject *object)
+{
+ NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (object);
+
+ g_free (priv->network_name);
+ if (priv->mac_address)
+ g_byte_array_free (priv->mac_address, TRUE);
+
+ G_OBJECT_CLASS (nm_setting_wimax_parent_class)->finalize (object);
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMSettingWimaxPrivate *priv = NM_SETTING_WIMAX_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_NETWORK_NAME:
+ g_free (priv->network_name);
+ priv->network_name = g_value_dup_string (value);
+ break;
+ case PROP_MAC_ADDRESS:
+ if (priv->mac_address)
+ g_byte_array_free (priv->mac_address, TRUE);
+ priv->mac_address = g_value_dup_boxed (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMSettingWimax *setting = NM_SETTING_WIMAX (object);
+
+ switch (prop_id) {
+ case PROP_NETWORK_NAME:
+ g_value_set_string (value, nm_setting_wimax_get_network_name (setting));
+ break;
+ case PROP_MAC_ADDRESS:
+ g_value_set_boxed (value, nm_setting_wimax_get_mac_address (setting));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+nm_setting_wimax_class_init (NMSettingWimaxClass *setting_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
+ NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
+
+ g_type_class_add_private (setting_class, sizeof (NMSettingWimaxPrivate));
+
+ /* virtual methods */
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+ parent_class->verify = verify;
+
+ /* Properties */
+ /**
+ * NMSettingWimax:network-name:
+ *
+ * Network name of the WiMAX network.
+ **/
+ g_object_class_install_property
+ (object_class, PROP_NETWORK_NAME,
+ g_param_spec_string (NM_SETTING_WIMAX_NETWORK_NAME,
+ "NetworkName",
+ "Network name",
+ NULL,
+ G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+
+ /**
+ * NMSettingWimax:mac-address:
+ *
+ * If specified, this connection will only apply to the WiMAX device
+ * whose MAC address matches. This property does not change the MAC address
+ * of the device (known as MAC spoofing).
+ **/
+ g_object_class_install_property
+ (object_class, PROP_MAC_ADDRESS,
+ _nm_param_spec_specialized (NM_SETTING_WIMAX_MAC_ADDRESS,
+ "MAC Address",
+ "If specified, this connection will only apply to "
+ "the WiMAX device whose MAC address matches. "
+ "This property does not change the MAC address "
+ "of the device (known as MAC spoofing).",
+ DBUS_TYPE_G_UCHAR_ARRAY,
+ G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
+}
diff --git a/libnm-util/nm-setting-wimax.h b/libnm-util/nm-setting-wimax.h
new file mode 100644
index 0000000000..a3e500be51
--- /dev/null
+++ b/libnm-util/nm-setting-wimax.h
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2009 Novell, Inc.
+ */
+
+#ifndef NM_SETTING_WIMAX_H
+#define NM_SETTING_WIMAX_H
+
+#include
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_SETTING_WIMAX (nm_setting_wimax_get_type ())
+#define NM_SETTING_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_WIMAX, NMSettingWimax))
+#define NM_SETTING_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_WIMAX, NMSettingWimaxClass))
+#define NM_IS_SETTING_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_WIMAX))
+#define NM_IS_SETTING_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_SETTING_WIMAX))
+#define NM_SETTING_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_WIMAX, NMSettingWimaxClass))
+
+#define NM_SETTING_WIMAX_SETTING_NAME "wimax"
+
+typedef enum
+{
+ NM_SETTING_WIMAX_ERROR_UNKNOWN = 0,
+ NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY,
+ NM_SETTING_WIMAX_ERROR_MISSING_PROPERTY
+} NMSettingWimaxError;
+
+#define NM_TYPE_SETTING_WIMAX_ERROR (nm_setting_wimax_error_get_type ())
+GType nm_setting_wimax_error_get_type (void);
+
+#define NM_SETTING_WIMAX_ERROR nm_setting_wimax_error_quark ()
+GQuark nm_setting_wimax_error_quark (void);
+
+#define NM_SETTING_WIMAX_NETWORK_NAME "network-name"
+#define NM_SETTING_WIMAX_MAC_ADDRESS "mac-address"
+
+typedef struct {
+ NMSetting parent;
+} NMSettingWimax;
+
+typedef struct {
+ NMSettingClass parent;
+} NMSettingWimaxClass;
+
+GType nm_setting_wimax_get_type (void);
+
+NMSetting *nm_setting_wimax_new (void);
+const char *nm_setting_wimax_get_network_name (NMSettingWimax *setting);
+const GByteArray *nm_setting_wimax_get_mac_address (NMSettingWimax *setting);
+
+G_END_DECLS
+
+#endif /* NM_SETTING_WIMAX_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index f351c787d1..14ddec3abe 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,7 @@ SUBDIRS= \
dnsmasq-manager \
modem-manager \
bluez-manager \
+ wimax \
system-settings \
. \
tests
@@ -24,6 +25,7 @@ INCLUDES = -I${top_srcdir} \
-I${top_srcdir}/src/dnsmasq-manager \
-I${top_srcdir}/src/modem-manager \
-I$(top_srcdir)/src/bluez-manager \
+ -I$(top_srcdir)/src/wimax \
-I$(top_srcdir)/src/system-settings \
-I${top_srcdir}/libnm-util \
-I${top_srcdir}/libnm-glib \
@@ -169,6 +171,7 @@ NetworkManager_CPPFLAGS = \
$(OPENSSL_CFLAGS) \
$(LIBNL_CFLAGS) \
$(GMODULE_CFLAGS) \
+ $(WIMAX_CFLAGS) \
-DG_DISABLE_DEPRECATED \
-DBINDIR=\"$(bindir)\" \
-DSBINDIR=\"$(sbindir)\" \
@@ -191,6 +194,7 @@ NetworkManager_LDADD = \
./ppp-manager/libppp-manager.la \
./modem-manager/libmodem-manager.la \
./bluez-manager/libbluez-manager.la \
+ ./wimax/libwimax.la \
./system-settings/libsystem-settings.la \
./backends/libnmbackend.la \
$(top_builddir)/libnm-util/libnm-util.la \
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 14c2a907e0..6947cc295f 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -37,6 +37,7 @@
#include "nm-device-ethernet.h"
#include "nm-device-wifi.h"
#include "nm-device-olpc-mesh.h"
+#include "nm-wimax-device.h"
#include "NetworkManagerSystem.h"
#include "nm-properties-changed-signal.h"
#include "nm-setting-bluetooth.h"
@@ -1185,6 +1186,8 @@ manager_set_wireless_enabled (NMManager *manager, gboolean enabled)
for (iter = priv->devices; iter; iter = iter->next) {
if (NM_IS_DEVICE_WIFI (iter->data))
nm_device_wifi_set_enabled (NM_DEVICE_WIFI (iter->data), enabled);
+ else if (NM_IS_WIMAX_DEVICE (iter->data))
+ nm_wimax_device_set_enabled (NM_WIMAX_DEVICE (iter->data), enabled);
}
}
@@ -1372,7 +1375,8 @@ add_device (NMManager *self, NMDevice *device)
*/
nm_manager_rfkill_update (self);
nm_device_wifi_set_enabled (NM_DEVICE_WIFI (device), priv->wireless_enabled);
- }
+ } else if (NM_IS_WIMAX_DEVICE (device))
+ nm_wimax_device_set_enabled (NM_WIMAX_DEVICE (device), priv->wireless_enabled);
type_desc = nm_device_get_type_desc (device);
g_assert (type_desc);
@@ -2563,6 +2567,8 @@ impl_manager_sleep (NMManager *self, gboolean sleep, GError **error)
*/
if (NM_IS_DEVICE_WIFI (iter->data))
nm_device_wifi_set_enabled (NM_DEVICE_WIFI (iter->data), wifi_enabled);
+ else if (NM_IS_WIMAX_DEVICE (iter->data))
+ nm_wimax_device_set_enabled (NM_WIMAX_DEVICE (iter->data), wifi_enabled);
nm_device_clear_autoconnect_inhibit (device);
if (nm_device_interface_spec_match_list (NM_DEVICE_INTERFACE (device), unmanaged_specs))
diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c
index be0825c6b3..a907afc2ed 100644
--- a/src/nm-udev-manager.c
+++ b/src/nm-udev-manager.c
@@ -38,6 +38,7 @@
#include "nm-device-wifi.h"
#include "nm-device-olpc-mesh.h"
#include "nm-device-ethernet.h"
+#include "nm-wimax-manager.h"
typedef struct {
GUdevClient *client;
@@ -279,6 +280,12 @@ is_olpc_mesh (GUdevDevice *device)
return (prop != NULL);
}
+static gboolean
+is_wimax (const char *driver)
+{
+ return g_strcmp0 (driver, "i2400m_usb") == 0;
+}
+
static GObject *
device_creator (NMUdevManager *manager,
GUdevDevice *udev_device,
@@ -331,6 +338,8 @@ device_creator (NMUdevManager *manager,
device = (GObject *) nm_device_olpc_mesh_new (path, ifname, driver, ifindex);
else if (is_wireless (udev_device))
device = (GObject *) nm_device_wifi_new (path, ifname, driver, ifindex);
+ else if (is_wimax (driver))
+ device = (GObject *) nm_wimax_manager_create_device (path, ifname, driver, ifindex);
else
device = (GObject *) nm_device_ethernet_new (path, ifname, driver, ifindex);
diff --git a/src/wimax/Makefile.am b/src/wimax/Makefile.am
new file mode 100644
index 0000000000..2b915b4b03
--- /dev/null
+++ b/src/wimax/Makefile.am
@@ -0,0 +1,39 @@
+INCLUDES = \
+ -I${top_srcdir}/src \
+ -I${top_srcdir}/include \
+ -I${top_srcdir}/libnm-util \
+ -I${top_builddir}/marshallers
+
+noinst_LTLIBRARIES = libwimax.la
+
+libwimax_la_SOURCES = \
+ nm-wimax-device.c \
+ nm-wimax-device.h \
+ nm-wimax-manager.c \
+ nm-wimax-manager.h \
+ nm-wimax-nsp.c \
+ nm-wimax-nsp.h \
+ nm-wimax-types.h \
+ nm-wimax-util.c \
+ nm-wimax-util.h
+
+libwimax_la_CPPFLAGS = \
+ $(DBUS_CFLAGS) \
+ $(WIMAX_CFLAGS)
+
+libwimax_la_LIBADD = \
+ $(DBUS_LIBS) \
+ $(WIMAX_LIBS) \
+ $(top_builddir)/marshallers/libmarshallers.la
+
+nm-wimax-nsp-glue.h: $(top_srcdir)/introspection/nm-wimax-nsp.xml
+ dbus-binding-tool --prefix=nm_wimax_nsp --mode=glib-server --output=$@ $<
+
+nm-wimax-device-glue.h: $(top_srcdir)/introspection/nm-wimax-device.xml
+ dbus-binding-tool --prefix=nm_wimax_device --mode=glib-server --output=$@ $<
+
+BUILT_SOURCES = \
+ nm-wimax-nsp-glue.h \
+ nm-wimax-device-glue.h
+
+CLEANFILES = $(BUILT_SOURCES)
diff --git a/src/wimax/nm-wimax-device.c b/src/wimax/nm-wimax-device.c
new file mode 100644
index 0000000000..ffb0ab5fd0
--- /dev/null
+++ b/src/wimax/nm-wimax-device.c
@@ -0,0 +1,1055 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#include
+#include
+#include
+
+#include "nm-wimax-device.h"
+#include "nm-wimax-util.h"
+#include "nm-device-interface.h"
+#include "nm-device-private.h"
+#include "NetworkManagerSystem.h"
+#include "NetworkManagerUtils.h"
+#include "nm-properties-changed-signal.h"
+#include "nm-connection.h"
+#include "nm-setting-connection.h"
+#include "nm-setting-wimax.h"
+#include "nm-utils.h"
+
+static gboolean impl_device_get_nsp_list (NMWimaxDevice *device, GPtrArray **list, GError **error);
+
+#include "nm-wimax-device-glue.h"
+
+G_DEFINE_TYPE (NMWimaxDevice, nm_wimax_device, NM_TYPE_DEVICE)
+
+enum {
+ PROP_0,
+ PROP_INDEX,
+ PROP_IFINDEX,
+ PROP_HW_ADDRESS,
+ PROP_ACTIVE_NSP,
+
+ LAST_PROP
+};
+
+enum {
+ NSP_ADDED,
+ NSP_REMOVED,
+ PROPERTIES_CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_WIMAX_DEVICE, NMWimaxDevicePrivate))
+
+typedef struct {
+ struct WIMAX_API_DEVICE_ID device_id;
+ NMWimaxDevice *object;
+
+ gboolean enabled;
+ struct ether_addr hw_addr;
+ guint32 ifindex;
+ guint activation_timeout_id;
+
+ GSList *nsp_list;
+ NMWimaxNsp *current_nsp;
+ guint rf_update_id;
+} NMWimaxDevicePrivate;
+
+static void nm_wimax_api_close (NMWimaxDevice *self);
+static gboolean nm_wimax_api_open (NMWimaxDevice *self);
+static void real_update_hw_address (NMDevice *device);
+
+typedef enum
+{
+ NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX = 0,
+ NM_WIMAX_ERROR_CONNECTION_INVALID,
+ NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE,
+} NMWimaxError;
+
+#define NM_WIMAX_ERROR (nm_wimax_error_quark ())
+#define NM_TYPE_WIMAX_ERROR (nm_wimax_error_get_type ())
+
+static GQuark
+nm_wimax_error_quark (void)
+{
+ static GQuark quark = 0;
+ if (!quark)
+ quark = g_quark_from_static_string ("nm-wimax-error");
+ return quark;
+}
+
+/* This should really be standard. */
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+static GType
+nm_wimax_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ /* Connection was not a wired connection. */
+ ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX, "ConnectionNotWimax"),
+ /* Connection was not a valid wired connection. */
+ ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_INVALID, "ConnectionInvalid"),
+ /* Connection does not apply to this device. */
+ ENUM_ENTRY (NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE, "ConnectionIncompatible"),
+ { 0, 0, 0 }
+ };
+ etype = g_enum_register_static ("NMWimaxError", values);
+ }
+ return etype;
+}
+
+
+NMDevice *
+nm_wimax_device_new (const char *udi,
+ const char *iface,
+ const char *driver,
+ int ifindex,
+ guchar wimax_device_index)
+{
+ g_return_val_if_fail (udi != NULL, NULL);
+ g_return_val_if_fail (iface != NULL, NULL);
+ g_return_val_if_fail (driver != NULL, NULL);
+ g_return_val_if_fail (wimax_device_index != 0, NULL);
+
+ return NM_DEVICE (g_object_new (NM_TYPE_WIMAX_DEVICE,
+ NM_DEVICE_INTERFACE_UDI, udi,
+ NM_DEVICE_INTERFACE_IFACE, iface,
+ NM_DEVICE_INTERFACE_DRIVER, driver,
+ NM_DEVICE_INTERFACE_TYPE_DESC, "WiMAX",
+ NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_WIMAX,
+ NM_WIMAX_DEVICE_INDEX, wimax_device_index,
+ NM_WIMAX_DEVICE_IFINDEX, ifindex,
+ NULL));
+}
+
+void
+nm_wimax_device_get_hw_address (NMWimaxDevice *self, struct ether_addr *addr)
+{
+ g_return_if_fail (NM_IS_WIMAX_DEVICE (self));
+ g_return_if_fail (addr != NULL);
+
+ memcpy (addr, &(GET_PRIVATE (self)->hw_addr), sizeof (struct ether_addr));
+}
+
+guint32
+nm_wimax_device_get_ifindex (NMWimaxDevice *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_DEVICE (self), 0);
+
+ return GET_PRIVATE (self)->ifindex;
+}
+
+static gboolean
+rf_state_update (NMWimaxDevice *self)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+ WIMAX_API_DEVICE_STATUS status;
+ WIMAX_API_CONNECTION_PROGRESS_INFO pi;
+ WIMAX_API_RET result;
+ gboolean enable;
+
+ priv->rf_update_id = 0;
+
+ enable = priv->enabled;
+ if (enable) {
+ if (nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)) < NM_DEVICE_STATE_UNAVAILABLE)
+ enable = FALSE;
+ }
+
+ result = GetDeviceStatus (&priv->device_id, &status, &pi);
+ if (result != WIMAX_API_RET_SUCCESS)
+ nm_wimax_util_error (&priv->device_id, "Reading WiMax device status failed", result);
+
+ switch (status) {
+ case WIMAX_API_DEVICE_STATUS_UnInitialized:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
+ /* Can not enable the device */
+ if (enable)
+ nm_warning ("Can not enable the WiMAX device, it's RF killed");
+ goto out;
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
+ if (!enable)
+ /* Already matches */
+ goto out;
+ break;
+ case WIMAX_API_DEVICE_STATUS_Ready:
+ case WIMAX_API_DEVICE_STATUS_Scanning:
+ case WIMAX_API_DEVICE_STATUS_Connecting:
+ case WIMAX_API_DEVICE_STATUS_Data_Connected:
+ case WIMAX_API_DEVICE_STATUS_Connection_Idle:
+ if (enable)
+ /* Already matches */
+ goto out;
+ break;
+ default:
+ nm_warning ("Unhandled WiMAX device state");
+ goto out;
+ }
+
+ g_debug ("Changing wimax device RF state: %d", enable);
+ result = CmdControlPowerManagement (&priv->device_id, enable ? WIMAX_API_RF_ON : WIMAX_API_RF_OFF);
+ if (result != WIMAX_API_RET_SUCCESS)
+ nm_wimax_util_error (&priv->device_id, "WiMax device RF change failed", result);
+
+ out:
+ return FALSE;
+}
+
+static void
+schedule_rf_state_update (NMWimaxDevice *self)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+
+ /* This is scheduled because on startup we get nm_wimax_device_set_enabled()
+ while the device state is still unmanaged. It'll change to unavailable right
+ after it, so it would result in enabling RF kill, followed by disabling it again.
+ Pretty lame.
+ */
+
+ if (priv->rf_update_id == 0)
+ priv->rf_update_id = g_idle_add ((GSourceFunc) rf_state_update, self);
+}
+
+void
+nm_wimax_device_set_enabled (NMWimaxDevice *self, gboolean enabled)
+{
+ NMWimaxDevicePrivate *priv;
+
+ g_return_if_fail (NM_IS_WIMAX_DEVICE (self));
+
+ priv = GET_PRIVATE (self);
+ if (priv->enabled == enabled)
+ return;
+
+ priv->enabled = enabled;
+ schedule_rf_state_update (self);
+}
+
+GSList *
+nm_wimax_device_get_nsps (NMWimaxDevice *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_DEVICE (self), NULL);
+
+ return GET_PRIVATE (self)->nsp_list;
+}
+
+static gboolean
+impl_device_get_nsp_list (NMWimaxDevice *device, GPtrArray **nsps, GError **error)
+{
+ GSList *list;
+ GSList *iter;
+
+ list = nm_wimax_device_get_nsps (device);
+ *nsps = g_ptr_array_sized_new (g_slist_length (list));
+ for (iter = list; iter; iter = iter->next) {
+ const char *path;
+
+ path = nm_wimax_nsp_get_dbus_path (NM_WIMAX_NSP (iter->data));
+ if (path)
+ g_ptr_array_add (*nsps, g_strdup (path));
+ }
+
+ return TRUE;
+}
+
+static void
+set_current_nsp (NMWimaxDevice *self, NMWimaxNsp *new_nsp)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+ NMWimaxNsp *old_nsp;
+ char *old_path = NULL;
+
+ old_nsp = priv->current_nsp;
+ if (old_nsp) {
+ old_path = g_strdup (nm_wimax_nsp_get_dbus_path (old_nsp));
+ priv->current_nsp = NULL;
+ }
+
+ if (new_nsp)
+ priv->current_nsp = g_object_ref (new_nsp);
+
+ if (old_nsp)
+ g_object_unref (old_nsp);
+
+ /* 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))))
+ g_object_notify (G_OBJECT (self), NM_WIMAX_DEVICE_ACTIVE_NSP);
+
+ g_free (old_path);
+}
+
+NMWimaxNsp *
+nm_wimax_device_get_active_nsp (NMWimaxDevice *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_DEVICE (self), NULL);
+
+ return GET_PRIVATE (self)->current_nsp;
+}
+
+static gboolean
+activation_timed_out (gpointer data)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (data);
+
+ priv->activation_timeout_id = 0;
+ nm_device_state_changed (NM_DEVICE (data), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
+
+ return FALSE;
+}
+
+static void
+wimax_status_change_cb (struct WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_DEVICE_STATUS status,
+ WIMAX_API_STATUS_REASON reason,
+ WIMAX_API_CONNECTION_PROGRESS_INFO progress)
+{
+ NMWimaxDevicePrivate *priv = (NMWimaxDevicePrivate *) device_id;
+ NMWimaxDevice *self = priv->object;
+ NMDeviceState device_state;
+
+ device_state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self));
+ g_debug ("wimax status changed: %s (device state %d)", nm_wimax_util_device_status_to_str (status), device_state);
+
+ switch (status) {
+ case WIMAX_API_DEVICE_STATUS_UnInitialized:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
+ priv->enabled = FALSE;
+ if (device_state >= NM_DEVICE_STATE_DISCONNECTED)
+ nm_device_state_changed (NM_DEVICE (self),
+ NM_DEVICE_STATE_UNAVAILABLE,
+ NM_DEVICE_STATE_REASON_NONE);
+ break;
+ case WIMAX_API_DEVICE_STATUS_Ready:
+ case WIMAX_API_DEVICE_STATUS_Scanning:
+ case WIMAX_API_DEVICE_STATUS_Connecting:
+ case WIMAX_API_DEVICE_STATUS_Data_Connected:
+ case WIMAX_API_DEVICE_STATUS_Connection_Idle:
+ priv->enabled = TRUE;
+ if (device_state < NM_DEVICE_STATE_DISCONNECTED)
+ nm_device_state_changed (NM_DEVICE (self),
+ NM_DEVICE_STATE_DISCONNECTED,
+ NM_DEVICE_STATE_REASON_NONE);
+ break;
+ default:
+ nm_warning ("Unhandled WiMAX device state");
+ }
+}
+
+static void
+remove_all_nsps (NMWimaxDevice *self)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+
+ while (g_slist_length (priv->nsp_list)) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (priv->nsp_list->data);
+
+ priv->nsp_list = g_slist_remove (priv->nsp_list, nsp);
+ g_signal_emit (self, signals[NSP_REMOVED], 0, nsp);
+ g_object_unref (nsp);
+ }
+
+ g_slist_free (priv->nsp_list);
+ priv->nsp_list = NULL;
+}
+
+static void
+remove_outdated_nsps (NMWimaxDevice *self,
+ struct WIMAX_API_NSP_INFO_EX *nsp_list,
+ guint32 list_size)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+ GSList *iter;
+ GSList *to_remove = NULL;
+
+ for (iter = priv->nsp_list; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+ int i;
+ gboolean found = FALSE;
+
+ for (i = 0; i < list_size; i++) {
+ struct WIMAX_API_NSP_INFO_EX *info = &nsp_list[i];
+
+ if (!g_strcmp0 (nm_wimax_nsp_get_name (nsp), (char *) info->NSPName)) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ to_remove = g_slist_prepend (to_remove, nsp);
+ }
+
+ for (iter = to_remove; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+
+ g_signal_emit (self, signals[NSP_REMOVED], 0, nsp);
+ priv->nsp_list = g_slist_remove (priv->nsp_list, nsp);
+ g_object_unref (nsp);
+ }
+
+ g_slist_free (to_remove);
+}
+
+static NMWimaxNsp *
+get_nsp_by_name (NMWimaxDevice *self, const char *name)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+ GSList *iter;
+
+ for (iter = priv->nsp_list; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+
+ if (!g_strcmp0 (nm_wimax_nsp_get_name (nsp), name))
+ return nsp;
+ }
+
+ return NULL;
+}
+
+static void
+wimax_scan_cb (struct WIMAX_API_DEVICE_ID *device_id,
+ struct WIMAX_API_NSP_INFO_EX *nsp_list,
+ guint32 list_size,
+ guint32 progress)
+{
+ NMWimaxDevicePrivate *priv = (NMWimaxDevicePrivate *) device_id;
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (priv->object);
+ int i;
+
+ remove_outdated_nsps (self, nsp_list, list_size);
+
+ for (i = 0; i < list_size; i++) {
+ struct WIMAX_API_NSP_INFO_EX *info = &nsp_list[i];
+ NMWimaxNsp *nsp;
+ gboolean new_nsp;
+ guint32 quality;
+
+ nsp = get_nsp_by_name (self, (char *) info->NSPName);
+ new_nsp = nsp == NULL;
+ if (new_nsp)
+ nsp = nm_wimax_nsp_new ((char *) info->NSPName);
+
+ quality = info->linkQuality;
+ if (quality == 0) {
+ /* This is borrowed from connman */
+ quality = nm_wimax_util_cinr_to_percentage (info->CINR - 10);
+ }
+
+ g_object_set (nsp,
+ NM_WIMAX_NSP_SIGNAL_QUALITY, quality,
+ NM_WIMAX_NSP_NETWORK_TYPE, nm_wimax_util_convert_network_type (info->networkType),
+ NULL);
+
+ if (new_nsp) {
+ priv->nsp_list = g_slist_append (priv->nsp_list, nsp);
+ nm_wimax_nsp_export_to_dbus (nsp);
+ g_signal_emit (self, signals[NSP_ADDED], 0, nsp);
+ }
+ }
+}
+
+static void
+wimax_wide_scan_cb (struct WIMAX_API_DEVICE_ID *device_id,
+ struct WIMAX_API_NSP_INFO_EX *nsp_list,
+ guint32 list_size)
+{
+ wimax_scan_cb (device_id, nsp_list, list_size, 0);
+}
+
+static void
+wimax_connect_cb (struct WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_NETWORK_CONNECTION_RESP response)
+{
+ NMWimaxDevicePrivate *priv = (NMWimaxDevicePrivate *) device_id;
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (priv->object);
+
+ if (priv->activation_timeout_id == 0) {
+ g_warning ("WiMax device activated from outside");
+ return;
+ }
+
+ g_source_remove (priv->activation_timeout_id);
+ priv->activation_timeout_id = 0;
+
+ if (response == WIMAX_API_CONNECTION_SUCCESS)
+ nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self));
+ else
+ nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
+}
+
+static void
+wimax_disconnect_cb (struct WIMAX_API_DEVICE_ID *device_id,
+ WIMAX_API_NETWORK_CONNECTION_RESP response)
+{
+ if (response == WIMAX_API_CONNECTION_SUCCESS) {
+ } else {
+ g_warning ("WiMax device disconnect failed");
+ }
+}
+
+static void
+nm_wimax_api_close (NMWimaxDevice *self)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+
+ nm_debug ("Closing wimax device API");
+
+ UnsubscribeDisconnectToNetwork (&priv->device_id);
+ UnsubscribeConnectToNetwork (&priv->device_id);
+ UnsubscribeNetworkSearchWideScanEx (&priv->device_id);
+ UnsubscribeNetworkSearchEx (&priv->device_id);
+ UnsubscribeDeviceStatusChange (&priv->device_id);
+ WiMaxDeviceClose (&priv->device_id);
+}
+
+static gboolean
+nm_wimax_api_open (NMWimaxDevice *self)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+ WIMAX_API_RET result;
+ gboolean success = FALSE;
+
+ nm_debug ("Opening wimax device API");
+
+ result = WiMaxDeviceOpen (&priv->device_id);
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&priv->device_id, "WiMax device open failed", result);
+ goto err;
+ }
+
+ result = SetConnectionMode (&priv->device_id, WIMAX_API_CONNECTION_AUTO_SCAN_MANUAL_CONNECT);
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&priv->device_id, "WiMax device connection mode setting failed", result);
+ goto err;
+ }
+
+ result = SubscribeDeviceStatusChange (&priv->device_id, wimax_status_change_cb);
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&priv->device_id, "WiMax subscription to device status changes failed", result);
+ goto err;
+ }
+
+ result = SubscribeNetworkSearchEx (&priv->device_id, wimax_scan_cb);
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&priv->device_id, "WiMax subscription to network scanning failed", result);
+ goto err;
+ }
+
+ result = SubscribeNetworkSearchWideScanEx (&priv->device_id, wimax_wide_scan_cb);
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&priv->device_id, "WiMax subscription to wide network scanning failed", result);
+ goto err;
+ }
+
+ result = SubscribeConnectToNetwork (&priv->device_id, wimax_connect_cb);
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&priv->device_id, "WiMax subscription to connected messages failed", result);
+ goto err;
+ }
+
+ result = SubscribeDisconnectToNetwork (&priv->device_id, wimax_disconnect_cb);
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&priv->device_id, "WiMax subscription to disconnected messages failed", result);
+ goto err;
+ }
+
+ success = TRUE;
+
+ err:
+ if (!success)
+ nm_wimax_api_close (self);
+
+ return success;
+}
+
+static void
+device_state_changed (NMDevice *device,
+ NMDeviceState new_state,
+ NMDeviceState old_state,
+ NMDeviceStateReason reason,
+ gpointer user_data)
+{
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (device);
+
+ switch (new_state) {
+ case NM_DEVICE_STATE_UNMANAGED:
+ case NM_DEVICE_STATE_UNAVAILABLE:
+ case NM_DEVICE_STATE_DISCONNECTED:
+ remove_all_nsps (self);
+ schedule_rf_state_update (self);
+ break;
+ default:
+ break;
+ }
+}
+
+/* NMDevice methods */
+
+static void
+real_take_down (NMDevice *device)
+{
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (device);
+
+ set_current_nsp (self, NULL);
+ remove_all_nsps (self);
+}
+
+static gboolean
+real_hw_is_up (NMDevice *device)
+{
+ return nm_system_device_is_up (device);
+}
+
+static gboolean
+real_hw_bring_up (NMDevice *dev, gboolean *no_firmware)
+{
+ return nm_system_device_set_up_down (dev, TRUE, no_firmware);
+}
+
+static void
+real_hw_take_down (NMDevice *dev)
+{
+ nm_system_device_set_up_down (dev, FALSE, NULL);
+}
+
+static void
+real_update_hw_address (NMDevice *device)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (device);
+ struct WIMAX_API_DEVICE_INFO info = { 0, };
+ WIMAX_API_RET result;
+
+ result = GetDeviceInformation (&priv->device_id, &info);
+ if (result != WIMAX_API_RET_SUCCESS)
+ nm_wimax_util_error (&priv->device_id, "Could not read WiMax device hardware address", result);
+
+ if (memcmp (&priv->hw_addr, info.macAddress, sizeof (struct ether_addr))) {
+ memcpy (&priv->hw_addr, info.macAddress, sizeof (struct ether_addr));
+ g_object_notify (G_OBJECT (device), NM_WIMAX_DEVICE_HW_ADDRESS);
+ }
+}
+
+static gboolean
+real_check_connection_compatible (NMDevice *device,
+ NMConnection *connection,
+ GError **error)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (device);
+ NMSettingConnection *s_con;
+ NMSettingWimax *s_wimax;
+ const char *connection_type;
+ const GByteArray *mac;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ g_assert (s_con);
+
+ connection_type = nm_setting_connection_get_connection_type (s_con);
+ if (strcmp (connection_type, NM_SETTING_WIMAX_SETTING_NAME)) {
+ g_set_error (error,
+ NM_WIMAX_ERROR, NM_WIMAX_ERROR_CONNECTION_NOT_WIMAX,
+ "The connection was not a WiMAX connection.");
+ return FALSE;
+ }
+
+ s_wimax = (NMSettingWimax *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX);
+ if (!s_wimax) {
+ g_set_error (error,
+ NM_WIMAX_ERROR, NM_WIMAX_ERROR_CONNECTION_INVALID,
+ "The connection was not a valid WiMAX connection.");
+ return FALSE;
+ }
+
+ mac = nm_setting_wimax_get_mac_address (s_wimax);
+ if (mac && memcmp (mac->data, &(priv->hw_addr.ether_addr_octet), ETH_ALEN)) {
+ g_set_error (error,
+ NM_WIMAX_ERROR, NM_WIMAX_ERROR_CONNECTION_INCOMPATIBLE,
+ "The connection's MAC address did not match this device.");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static NMConnection *
+real_get_best_auto_connection (NMDevice *device,
+ GSList *connections,
+ char **specific_object)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (device);
+ GSList *iter;
+
+ for (iter = connections; iter; iter = g_slist_next (iter)) {
+ NMConnection *connection = NM_CONNECTION (iter->data);
+ NMSettingConnection *s_con;
+ NMSettingWimax *s_wimax;
+ const char *connection_type;
+ const GByteArray *mac;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ g_assert (s_con);
+
+ if (!nm_setting_connection_get_autoconnect (s_con))
+ continue;
+
+ connection_type = nm_setting_connection_get_connection_type (s_con);
+ if (strcmp (connection_type, NM_SETTING_WIMAX_SETTING_NAME))
+ continue;
+
+ s_wimax = (NMSettingWimax *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX);
+ if (!s_wimax)
+ continue;
+
+ mac = nm_setting_wimax_get_mac_address (s_wimax);
+ if (mac && memcmp (mac->data, priv->hw_addr.ether_addr_octet, ETH_ALEN))
+ continue;
+
+ for (iter = priv->nsp_list; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+
+ if (nm_wimax_nsp_check_compatible (nsp, connection)) {
+ *specific_object = (char *) nm_wimax_nsp_get_dbus_path (nsp);
+ return connection;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static guint32
+real_get_generic_capabilities (NMDevice *dev)
+{
+ return NM_DEVICE_CAP_NM_SUPPORTED;
+}
+
+static gboolean
+real_is_available (NMDevice *device)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (device);
+ WIMAX_API_DEVICE_STATUS status;
+ WIMAX_API_CONNECTION_PROGRESS_INFO pi;
+ WIMAX_API_RET result;
+
+ if (!priv->enabled)
+ return FALSE;
+
+ result = GetDeviceStatus (&priv->device_id, &status, &pi);
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&priv->device_id, "Reading WiMax device status failed", result);
+ return FALSE;
+ }
+
+ return status >= WIMAX_API_DEVICE_STATUS_Ready;
+}
+
+static NMActStageReturn
+real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (device);
+ NMActRequest *req;
+ GSList *iter;
+ const char *path;
+
+ req = nm_device_get_act_request (device);
+ if (!req)
+ goto err;
+
+ path = nm_act_request_get_specific_object (req);
+ if (!path)
+ goto err;
+
+ for (iter = priv->nsp_list; iter; iter = iter->next) {
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data);
+
+ if (!strcmp (path, nm_wimax_nsp_get_dbus_path (nsp))) {
+ set_current_nsp (NM_WIMAX_DEVICE (device), nsp);
+ return NM_ACT_STAGE_RETURN_SUCCESS;
+ }
+ }
+
+ err:
+ *reason = NM_DEVICE_STATE_REASON_NONE;
+ return NM_ACT_STAGE_RETURN_FAILURE;
+}
+
+static NMActStageReturn
+real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (device);
+ NMConnection *connection;
+ NMSettingWimax *s_wimax;
+ WIMAX_API_RET result;
+
+ connection = nm_act_request_get_connection (nm_device_get_act_request (device));
+ g_assert (connection);
+
+ s_wimax = NM_SETTING_WIMAX (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX));
+ g_assert (s_wimax);
+
+ result = CmdConnectToNetwork (&priv->device_id,
+ (WIMAX_API_ASTRING) nm_setting_wimax_get_network_name (s_wimax),
+ 0, NULL);
+
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&priv->device_id, "WiMax connect to network failed", result);
+ *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
+ return NM_ACT_STAGE_RETURN_FAILURE;
+ }
+
+ /* FIXME: Is 60 seconds good estimation? I have no idea */
+ priv->activation_timeout_id = g_timeout_add_seconds (60, activation_timed_out, device);
+
+ return NM_ACT_STAGE_RETURN_POSTPONE;
+}
+
+static void
+real_deactivate_quickly (NMDevice *device)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (device);
+ WIMAX_API_DEVICE_STATUS status;
+ WIMAX_API_CONNECTION_PROGRESS_INFO pi;
+ WIMAX_API_RET result;
+
+ if (priv->activation_timeout_id) {
+ g_source_remove (priv->activation_timeout_id);
+ priv->activation_timeout_id = 0;
+ }
+
+ set_current_nsp (NM_WIMAX_DEVICE (device), NULL);
+
+ result = GetDeviceStatus (&priv->device_id, &status, &pi);
+ if (result != WIMAX_API_RET_SUCCESS)
+ nm_wimax_util_error (&priv->device_id, "Reading WiMax device status failed", result);
+
+ if (status == WIMAX_API_DEVICE_STATUS_Connecting ||
+ status == WIMAX_API_DEVICE_STATUS_Data_Connected ||
+ status == WIMAX_API_DEVICE_STATUS_Connection_Idle) {
+
+ result = CmdDisconnectFromNetwork (&priv->device_id);
+ if (result != WIMAX_API_RET_SUCCESS)
+ nm_wimax_util_error (&priv->device_id, "WiMax disconnect from network failed", result);
+ }
+}
+
+/* GObject methods */
+
+static void
+nm_wimax_device_init (NMWimaxDevice *self)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+
+ priv->object = self;
+ priv->device_id.structureSize = sizeof (NMWimaxDevicePrivate);
+ priv->device_id.privilege = WIMAX_API_PRIVILEGE_READ_WRITE;
+
+ g_signal_connect (self, "state-changed", G_CALLBACK (device_state_changed), NULL);
+}
+
+static GObject*
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ NMWimaxDevicePrivate *priv;
+
+ object = G_OBJECT_CLASS (nm_wimax_device_parent_class)->constructor (type, n_construct_params, construct_params);
+ if (!object)
+ return NULL;
+
+ priv = GET_PRIVATE (object);
+ if (priv->device_id.deviceIndex == 0) {
+ g_warning ("Invalid or missing constructor arguments");
+ g_object_unref (object);
+ object = NULL;
+ }
+
+ if (!nm_wimax_api_open (NM_WIMAX_DEVICE (object))) {
+ g_object_unref (object);
+ object = NULL;
+ }
+
+ return object;
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_INDEX:
+ priv->device_id.deviceIndex = g_value_get_uchar (value);
+ break;
+ case PROP_IFINDEX:
+ priv->ifindex = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (object);
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+ struct ether_addr hw_addr;
+
+ switch (prop_id) {
+ case PROP_HW_ADDRESS:
+ nm_wimax_device_get_hw_address (self, &hw_addr);
+ g_value_take_string (value, nm_ether_ntop (&hw_addr));
+ break;
+ case PROP_ACTIVE_NSP:
+ if (priv->current_nsp)
+ g_value_set_boxed (value, nm_wimax_nsp_get_dbus_path (priv->current_nsp));
+ else
+ g_value_set_boxed (value, "/");
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+finalize (GObject *object)
+{
+ NMWimaxDevice *self = NM_WIMAX_DEVICE (object);
+ NMWimaxDevicePrivate *priv = GET_PRIVATE (self);
+
+ if (priv->rf_update_id)
+ g_source_remove (priv->rf_update_id);
+
+ set_current_nsp (self, NULL);
+
+ g_slist_foreach (priv->nsp_list, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->nsp_list);
+
+ nm_wimax_api_close (self);
+
+ G_OBJECT_CLASS (nm_wimax_device_parent_class)->finalize (object);
+}
+
+static void
+nm_wimax_device_class_init (NMWimaxDeviceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMDeviceClass *device_class = NM_DEVICE_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMWimaxDevicePrivate));
+
+ /* Virtual methods */
+ object_class->constructor = constructor;
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+
+ device_class->take_down = real_take_down;
+ device_class->hw_is_up = real_hw_is_up;
+ device_class->hw_bring_up = real_hw_bring_up;
+ device_class->hw_take_down = real_hw_take_down;
+ device_class->update_hw_address = real_update_hw_address;
+ device_class->check_connection_compatible = real_check_connection_compatible;
+ device_class->get_best_auto_connection = real_get_best_auto_connection;
+ device_class->get_generic_capabilities = real_get_generic_capabilities;
+ device_class->is_available = real_is_available;
+ device_class->act_stage1_prepare = real_act_stage1_prepare;
+ device_class->act_stage2_config = real_act_stage2_config;
+ device_class->deactivate_quickly = real_deactivate_quickly;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_INDEX,
+ g_param_spec_uchar (NM_WIMAX_DEVICE_INDEX,
+ "Index",
+ "Index",
+ 0, 1, 0,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
+
+ g_object_class_install_property
+ (object_class, PROP_IFINDEX,
+ g_param_spec_uint (NM_WIMAX_DEVICE_IFINDEX,
+ "Ifindex",
+ "Interface index",
+ 0, G_MAXUINT32, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
+
+ g_object_class_install_property
+ (object_class, PROP_HW_ADDRESS,
+ g_param_spec_string (NM_WIMAX_DEVICE_HW_ADDRESS,
+ "MAC Address",
+ "Hardware MAC address",
+ NULL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (object_class, PROP_ACTIVE_NSP,
+ g_param_spec_boxed (NM_WIMAX_DEVICE_ACTIVE_NSP,
+ "Active NSP",
+ "Currently active NSP",
+ DBUS_TYPE_G_OBJECT_PATH,
+ G_PARAM_READABLE));
+
+ /* Signals */
+ signals[NSP_ADDED] =
+ g_signal_new ("nsp-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMWimaxDeviceClass, nsp_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+
+ signals[NSP_REMOVED] =
+ g_signal_new ("nsp-removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMWimaxDeviceClass, nsp_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+
+ signals[PROPERTIES_CHANGED] =
+ nm_properties_changed_signal_new (object_class, G_STRUCT_OFFSET (NMWimaxDeviceClass, properties_changed));
+
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+ &dbus_glib_nm_wimax_device_object_info);
+
+ dbus_g_error_domain_register (NM_WIMAX_ERROR, NULL, NM_TYPE_WIMAX_ERROR);
+}
diff --git a/src/wimax/nm-wimax-device.h b/src/wimax/nm-wimax-device.h
new file mode 100644
index 0000000000..e381dddfc2
--- /dev/null
+++ b/src/wimax/nm-wimax-device.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_DEVICE_H
+#define NM_WIMAX_DEVICE_H
+
+#include
+#include
+#include "nm-device.h"
+#include "nm-wimax-nsp.h"
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_WIMAX_DEVICE (nm_wimax_device_get_type ())
+#define NM_WIMAX_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIMAX_DEVICE, NMWimaxDevice))
+#define NM_WIMAX_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIMAX_DEVICE, NMWimaxDeviceClass))
+#define NM_IS_WIMAX_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIMAX_DEVICE))
+#define NM_IS_WIMAX_DEVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIMAX_DEVICE))
+#define NM_WIMAX_DEVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIMAX_DEVICE, NMWimaxDeviceClass))
+
+#define NM_WIMAX_DEVICE_INDEX "index"
+#define NM_WIMAX_DEVICE_IFINDEX "ifindex"
+#define NM_WIMAX_DEVICE_HW_ADDRESS "hw-address"
+#define NM_WIMAX_DEVICE_ACTIVE_NSP "active-nsp"
+
+typedef struct {
+ NMDevice parent;
+} NMWimaxDevice;
+
+typedef struct {
+ NMDeviceClass parent;
+
+ /* Signals */
+ void (*nsp_added) (NMWimaxDevice *wimax, NMWimaxNsp *nsp);
+ void (*nsp_removed) (NMWimaxDevice *wimax, NMWimaxNsp *nsp);
+ void (*properties_changed) (NMWimaxDevice *wimax, GHashTable *properties);
+} NMWimaxDeviceClass;
+
+GType nm_wimax_device_get_type (void);
+
+NMDevice *nm_wimax_device_new (const char *udi,
+ const char *iface,
+ const char *driver,
+ int ifindex,
+ guchar wimax_device_index);
+
+void nm_wimax_device_get_hw_address (NMWimaxDevice *self,
+ struct ether_addr *addr);
+
+guint32 nm_wimax_device_get_ifindex (NMWimaxDevice *self);
+void nm_wimax_device_set_enabled (NMWimaxDevice *self,
+ gboolean enabled);
+
+GSList *nm_wimax_device_get_nsps (NMWimaxDevice *self);
+NMWimaxNsp *nm_wimax_device_get_active_nsp (NMWimaxDevice *self);
+
+G_END_DECLS
+
+#endif /* NM_WIMAX_DEVICE_H */
diff --git a/src/wimax/nm-wimax-manager.c b/src/wimax/nm-wimax-manager.c
new file mode 100644
index 0000000000..1cba7c57d5
--- /dev/null
+++ b/src/wimax/nm-wimax-manager.c
@@ -0,0 +1,139 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#include
+#include
+#include
+
+#include "nm-wimax-manager.h"
+#include "nm-wimax-device.h"
+#include "nm-wimax-util.h"
+
+typedef struct {
+ struct WIMAX_API_DEVICE_ID device_id;
+ int refs;
+} NMWimaxManager;
+
+static NMWimaxManager *global_wimax_manager = NULL;
+
+static NMWimaxManager *
+nm_wimax_manager_get (void)
+{
+ WIMAX_API_RET result;
+
+ if (!global_wimax_manager) {
+ global_wimax_manager = g_new (NMWimaxManager, 1);
+ global_wimax_manager->refs = 1;
+
+ g_debug ("Opening WiMAX API");
+ global_wimax_manager->device_id.structureSize = sizeof (NMWimaxManager);
+ global_wimax_manager->device_id.privilege = WIMAX_API_PRIVILEGE_READ_WRITE;
+ result = WiMaxAPIOpen (&global_wimax_manager->device_id);
+ if (result != WIMAX_API_RET_SUCCESS) {
+ nm_wimax_util_error (&global_wimax_manager->device_id, "Could not initialize WiMax", result);
+ g_free (global_wimax_manager);
+ global_wimax_manager = NULL;
+ }
+ } else
+ global_wimax_manager->refs++;
+
+ return global_wimax_manager;
+}
+
+static void
+nm_wimax_manager_unref (NMWimaxManager *manager)
+{
+ if (--manager->refs == 0) {
+ g_debug ("Closing WiMAX API");
+ WiMaxAPIClose (&manager->device_id);
+ g_free (manager);
+ global_wimax_manager = NULL;
+ }
+}
+
+static gboolean
+wimax_device_matches (struct WIMAX_API_HW_DEVICE_ID *hw_id,
+ const char *ifname,
+ int ifindex)
+{
+ const char *device_name;
+ char *s;
+ char hw_ifname[16];
+
+ if (!hw_id)
+ return FALSE;
+
+ device_name = (const char *) hw_id->deviceName;
+ if (!device_name)
+ return FALSE;
+
+ s = g_strrstr (device_name, "if:");
+ if (s == NULL || sscanf (s, "if:%15[^ \f\n\r\t\v]", hw_ifname) != 1)
+ return FALSE;
+
+ if (g_strcmp0 (ifname, hw_ifname))
+ return FALSE;
+
+ if (if_nametoindex (hw_ifname) != ifindex)
+ return FALSE;
+
+ return TRUE;
+}
+
+NMDevice *
+nm_wimax_manager_create_device (const char *path,
+ const char *ifname,
+ const char *driver,
+ int ifindex)
+{
+ NMWimaxManager *manager;
+ struct WIMAX_API_HW_DEVICE_ID device_id_list[5];
+ NMDevice *device = NULL;
+ gsize device_id_list_size = 5;
+ WIMAX_API_RET result;
+
+ g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (ifname != NULL, NULL);
+ g_return_val_if_fail (driver != NULL, NULL);
+
+ manager = nm_wimax_manager_get ();
+ if (!manager)
+ return NULL;
+
+ result = GetListDevice (&manager->device_id, device_id_list, &device_id_list_size);
+ if (result == WIMAX_API_RET_SUCCESS) {
+ int i;
+
+ for (i = 0; i < device_id_list_size; i++) {
+ if (wimax_device_matches (&device_id_list[i], ifname, ifindex)) {
+ device = nm_wimax_device_new (path, ifname, driver, ifindex, device_id_list[0].deviceIndex);
+ break;
+ }
+ }
+ } else
+ nm_wimax_util_error (&manager->device_id, "Could not get WiMax device list", result);
+
+ if (device)
+ g_object_weak_ref (G_OBJECT (device), (GWeakNotify) nm_wimax_manager_unref, manager);
+ else
+ nm_wimax_manager_unref (manager);
+
+ return device;
+}
diff --git a/src/wimax/nm-wimax-manager.h b/src/wimax/nm-wimax-manager.h
new file mode 100644
index 0000000000..e0427dd152
--- /dev/null
+++ b/src/wimax/nm-wimax-manager.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_MANAGER_H
+#define NM_WIMAX_MANAGER_H
+
+#include "nm-device.h"
+
+NMDevice *nm_wimax_manager_create_device (const char *path,
+ const char *ifname,
+ const char *driver,
+ int ifindex);
+
+#endif /* NM_WIMAX_MANAGER_H */
diff --git a/src/wimax/nm-wimax-nsp.c b/src/wimax/nm-wimax-nsp.c
new file mode 100644
index 0000000000..e69fc95efb
--- /dev/null
+++ b/src/wimax/nm-wimax-nsp.c
@@ -0,0 +1,249 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+
+#include "nm-wimax-nsp.h"
+#include "NetworkManager.h"
+#include "nm-dbus-manager.h"
+#include "nm-setting-wimax.h"
+#include "nm-properties-changed-signal.h"
+#include "nm-wimax-nsp-glue.h"
+#include "nm-utils.h"
+
+G_DEFINE_TYPE (NMWimaxNsp, nm_wimax_nsp, G_TYPE_OBJECT)
+
+enum {
+ PROPERTIES_CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+enum {
+ PROP_0,
+
+ PROP_NAME,
+ PROP_SIGNAL_QUALITY,
+ PROP_NETWORK_TYPE,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_WIMAX_NSP, NMWimaxNspPrivate))
+
+typedef struct {
+ char *dbus_path;
+
+ char *name;
+ guint32 signal_quality;
+ NMWimaxNspNetworkType network_type;
+} NMWimaxNspPrivate;
+
+NMWimaxNsp *
+nm_wimax_nsp_new (const char *name)
+{
+ g_return_val_if_fail (name != NULL, NULL);
+
+ return NM_WIMAX_NSP (g_object_new (NM_TYPE_WIMAX_NSP,
+ NM_WIMAX_NSP_NAME, name,
+ NULL));
+}
+
+const char *
+nm_wimax_nsp_get_name (NMWimaxNsp *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), NULL);
+
+ return GET_PRIVATE (self)->name;
+}
+
+guint32
+nm_wimax_nsp_get_signal_quality (NMWimaxNsp *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), 0);
+
+ return GET_PRIVATE (self)->signal_quality;
+}
+
+NMWimaxNspNetworkType
+nm_wimax_nsp_get_network_type (NMWimaxNsp *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), 0);
+
+ return GET_PRIVATE (self)->network_type;
+}
+
+void
+nm_wimax_nsp_export_to_dbus (NMWimaxNsp *self)
+{
+ NMWimaxNspPrivate *priv;
+ NMDBusManager *mgr;
+ DBusGConnection *g_connection;
+ static guint32 counter = 0;
+
+ g_return_if_fail (NM_IS_WIMAX_NSP (self));
+
+ priv = GET_PRIVATE (self);
+
+ if (priv->dbus_path) {
+ nm_warning ("NSP already exported.");
+ return;
+ }
+
+ mgr = nm_dbus_manager_get ();
+ g_assert (mgr);
+
+ g_connection = nm_dbus_manager_get_connection (mgr);
+ g_assert (g_connection);
+
+ priv->dbus_path = g_strdup_printf (NM_DBUS_PATH_WIMAX_NSP "/%d", counter++);
+ dbus_g_connection_register_g_object (g_connection, priv->dbus_path, G_OBJECT (self));
+
+ g_object_unref (mgr);
+}
+
+const char *
+nm_wimax_nsp_get_dbus_path (NMWimaxNsp *self)
+{
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), NULL);
+
+ return GET_PRIVATE (self)->dbus_path;
+}
+
+gboolean
+nm_wimax_nsp_check_compatible (NMWimaxNsp *self,
+ NMConnection *connection)
+{
+ NMWimaxNspPrivate *priv;
+ NMSettingWimax *s_wimax;
+
+ g_return_val_if_fail (NM_IS_WIMAX_NSP (self), FALSE);
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+
+ priv = GET_PRIVATE (self);
+
+ s_wimax = NM_SETTING_WIMAX (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX));
+ if (!s_wimax)
+ return FALSE;
+
+ return g_strcmp0 (nm_wimax_nsp_get_name (self), nm_setting_wimax_get_network_name (s_wimax)) == 0;
+}
+
+static void
+nm_wimax_nsp_init (NMWimaxNsp *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMWimaxNspPrivate *priv = GET_PRIVATE (object);
+ guint32 quality;
+ guchar network_type;
+
+ switch (prop_id) {
+ case PROP_NAME:
+ /* Construct only */
+ priv->name = g_value_dup_string (value);
+ break;
+ case PROP_SIGNAL_QUALITY:
+ quality = g_value_get_uint (value);
+ if (quality != priv->signal_quality) {
+ priv->signal_quality = quality;
+ g_object_notify (object, NM_WIMAX_NSP_SIGNAL_QUALITY);
+ }
+ break;
+ case PROP_NETWORK_TYPE:
+ network_type = g_value_get_uchar (value);
+ if (network_type != priv->network_type) {
+ priv->network_type = network_type;
+ g_object_notify (object, NM_WIMAX_NSP_NETWORK_TYPE);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMWimaxNsp *self = NM_WIMAX_NSP (object);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, nm_wimax_nsp_get_name (self));
+ break;
+ case PROP_SIGNAL_QUALITY:
+ g_value_set_uint (value, nm_wimax_nsp_get_signal_quality (self));
+ break;
+ case PROP_NETWORK_TYPE:
+ g_value_set_uchar (value, nm_wimax_nsp_get_network_type (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+finalize (GObject *object)
+{
+ NMWimaxNspPrivate *priv = GET_PRIVATE (object);
+
+ g_free (priv->name);
+ g_free (priv->dbus_path);
+
+ G_OBJECT_CLASS (nm_wimax_nsp_parent_class)->finalize (object);
+}
+
+static void
+nm_wimax_nsp_class_init (NMWimaxNspClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMWimaxNspPrivate));
+
+ /* Virtual methods */
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+
+ g_object_class_install_property
+ (object_class, PROP_NAME,
+ g_param_spec_string (NM_WIMAX_NSP_NAME,
+ "Name",
+ "Name",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
+ (object_class, PROP_SIGNAL_QUALITY,
+ g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY,
+ "SignalQuality",
+ "SignalQuality",
+ 0,
+ 100,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class, PROP_NETWORK_TYPE,
+ g_param_spec_uchar (NM_WIMAX_NSP_NETWORK_TYPE,
+ "NetworkType",
+ "NetworkType",
+ NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN,
+ NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER,
+ NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN,
+ G_PARAM_READWRITE));
+
+ /* Signals */
+ signals[PROPERTIES_CHANGED] =
+ nm_properties_changed_signal_new (object_class,
+ G_STRUCT_OFFSET (NMWimaxNspClass, properties_changed));
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+ &dbus_glib_nm_wimax_nsp_object_info);
+}
diff --git a/src/wimax/nm-wimax-nsp.h b/src/wimax/nm-wimax-nsp.h
new file mode 100644
index 0000000000..a74b68a79d
--- /dev/null
+++ b/src/wimax/nm-wimax-nsp.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_NSP_H
+#define NM_WIMAX_NSP_H
+
+#include
+#include "nm-wimax-types.h"
+#include "nm-connection.h"
+
+#define NM_TYPE_WIMAX_NSP (nm_wimax_nsp_get_type ())
+#define NM_WIMAX_NSP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIMAX_NSP, NMWimaxNsp))
+#define NM_WIMAX_NSP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIMAX_NSP, NMWimaxNspClass))
+#define NM_IS_WIMAX_NSP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIMAX_NSP))
+#define NM_IS_WIMAX_NSP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIMAX_NSP))
+#define NM_WIMAX_NSP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIMAX_NSP, NMWimaxNspClass))
+
+#define NM_WIMAX_NSP_NAME "name"
+#define NM_WIMAX_NSP_SIGNAL_QUALITY "signal-quality"
+#define NM_WIMAX_NSP_NETWORK_TYPE "network-type"
+
+typedef struct {
+ GObject parent;
+} NMWimaxNsp;
+
+typedef struct {
+ GObjectClass parent;
+
+ /* Signals */
+ void (*properties_changed) (NMWimaxNsp *nsp, GHashTable *properties);
+} NMWimaxNspClass;
+
+GType nm_wimax_nsp_get_type (void);
+
+NMWimaxNsp *nm_wimax_nsp_new (const char *name);
+const char *nm_wimax_nsp_get_name (NMWimaxNsp *self);
+guint32 nm_wimax_nsp_get_signal_quality (NMWimaxNsp *self);
+NMWimaxNspNetworkType nm_wimax_nsp_get_network_type (NMWimaxNsp *self);
+
+void nm_wimax_nsp_export_to_dbus (NMWimaxNsp *self);
+const char *nm_wimax_nsp_get_dbus_path (NMWimaxNsp *self);
+
+gboolean nm_wimax_nsp_check_compatible (NMWimaxNsp *self,
+ NMConnection *connection);
+
+#endif /* NM_WIMAX_NSP_H */
diff --git a/src/wimax/nm-wimax-types.h b/src/wimax/nm-wimax-types.h
new file mode 100644
index 0000000000..8c807fd8a4
--- /dev/null
+++ b/src/wimax/nm-wimax-types.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_TYPES_H
+#define NM_WIMAX_TYPES_H
+
+typedef enum {
+ NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN,
+ NM_WIMAX_NSP_NETWORK_TYPE_HOME,
+ NM_WIMAX_NSP_NETWORK_TYPE_PARTNER,
+ NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER
+} NMWimaxNspNetworkType;
+
+#endif /* NM_WIMAX_TYPES_H */
diff --git a/src/wimax/nm-wimax-util.c b/src/wimax/nm-wimax-util.c
new file mode 100644
index 0000000000..ca1b0dcea8
--- /dev/null
+++ b/src/wimax/nm-wimax-util.c
@@ -0,0 +1,117 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#include
+#include "nm-wimax-util.h"
+#include "nm-utils.h"
+
+void
+nm_wimax_util_error (struct WIMAX_API_DEVICE_ID *device_id,
+ const char *message,
+ WIMAX_API_RET result)
+{
+ char *warning_msg;
+ char str[MAX_SIZE_OF_STRING_BUFFER];
+ gsize str_len = MAX_SIZE_OF_STRING_BUFFER;
+
+ GetErrorString (device_id, result, str, &str_len);
+ warning_msg = g_strconcat (message, ": %s (%d)", NULL);
+ g_warning (warning_msg, str, result);
+ g_free (warning_msg);
+}
+
+NMWimaxNspNetworkType
+nm_wimax_util_convert_network_type (WIMAX_API_NETWORK_TYPE wimax_network_type)
+{
+ NMWimaxNspNetworkType type;
+
+ switch (wimax_network_type) {
+ case WIMAX_API_HOME:
+ type = NM_WIMAX_NSP_NETWORK_TYPE_HOME;
+ break;
+ case WIMAX_API_PARTNER:
+ type = NM_WIMAX_NSP_NETWORK_TYPE_PARTNER;
+ break;
+ case WIMAX_API_ROAMING_PARTNER:
+ type = NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER;
+ break;
+ default:
+ type = NM_WIMAX_NSP_NETWORK_TYPE_UNKNOWN;
+ break;
+ }
+
+ return type;
+}
+
+/* cinr_to_percentage() and the comment is borrowed from connman */
+
+/*
+ * FIXME: pulled it it out of some hole
+ *
+ * the cinr to percentage computation comes from the L3/L4 doc
+ *
+ * But some other places (L4 code) have a more complex, seemingly
+ * logarithmical computation.
+ *
+ * Oh well...
+ *
+ */
+
+int
+nm_wimax_util_cinr_to_percentage (int cinr)
+{
+ int strength;
+
+ if (cinr <= -5)
+ strength = 0;
+ else if (cinr >= 25)
+ strength = 100;
+ else /* Calc percentage on the value from -5 to 25 */
+ strength = ((100UL * (cinr - -5)) / (25 - -5));
+
+ return strength;
+}
+
+const char *
+nm_wimax_util_device_status_to_str (WIMAX_API_DEVICE_STATUS status)
+{
+ switch (status) {
+ case WIMAX_API_DEVICE_STATUS_UnInitialized:
+ return "Device is uninitialized";
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW:
+ return "Device RF Off(both H/W and S/W)";
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_HW:
+ return "Device RF Off(via H/W switch)";
+ case WIMAX_API_DEVICE_STATUS_RF_OFF_SW:
+ return "Device RF Off(via S/W switch)";
+ case WIMAX_API_DEVICE_STATUS_Ready:
+ return "Device is ready";
+ case WIMAX_API_DEVICE_STATUS_Scanning:
+ return "Device is scanning";
+ case WIMAX_API_DEVICE_STATUS_Connecting:
+ return "Connection in progress";
+ case WIMAX_API_DEVICE_STATUS_Data_Connected:
+ return "Layer 2 connected";
+ case WIMAX_API_DEVICE_STATUS_Connection_Idle:
+ return "Idle connection";
+ }
+
+ return "Unknown device state";
+}
diff --git a/src/wimax/nm-wimax-util.h b/src/wimax/nm-wimax-util.h
new file mode 100644
index 0000000000..e40ed46dbf
--- /dev/null
+++ b/src/wimax/nm-wimax-util.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager -- Network link manager
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_UTIL_H
+#define NM_WIMAX_UTIL_H
+
+#include
+#include "nm-wimax-types.h"
+
+void nm_wimax_util_error (struct WIMAX_API_DEVICE_ID *device_id,
+ const char *message,
+ WIMAX_API_RET result);
+
+NMWimaxNspNetworkType nm_wimax_util_convert_network_type (WIMAX_API_NETWORK_TYPE wimax_network_type);
+int nm_wimax_util_cinr_to_percentage (int cinr);
+
+const char *nm_wimax_util_device_status_to_str (WIMAX_API_DEVICE_STATUS status);
+
+#endif /* NM_WIMAX_UTIL_H */
diff --git a/test/nm-tool.c b/test/nm-tool.c
index 9d1a245718..dc4efb8c9d 100644
--- a/test/nm-tool.c
+++ b/test/nm-tool.c
@@ -38,6 +38,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -192,6 +193,46 @@ detail_access_point (gpointer data, gpointer user_data)
g_free (tmp);
}
+static const char *
+wimax_network_type_to_str (NMWimaxNspNetworkType type)
+{
+ switch (type) {
+ case NM_WIMAX_NSP_NETWORK_TYPE_HOME:
+ return "Home network";
+ case NM_WIMAX_NSP_NETWORK_TYPE_PARTNER:
+ return "Partner network";
+ case NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER:
+ return "Roaming partner network";
+ default:
+ return "Unknown network";
+ }
+}
+
+static void
+detail_nsp (gpointer data, gpointer user_data)
+{
+ NMWimaxNsp *nsp = NM_WIMAX_NSP (data);
+ const char *active_name = (const char *) user_data;
+ const char *name;
+ char *label;
+ char *data_str;
+ gboolean active = FALSE;
+
+ name = nm_wimax_nsp_get_name (nsp);
+
+ if (active_name)
+ active = g_strcmp0 (active_name, name) == 0;
+
+ label = g_strdup_printf (" %s%s", active ? "*" : "", name);
+ data_str = g_strdup_printf ("%s, Signal quality: %d",
+ wimax_network_type_to_str (nm_wimax_nsp_get_network_type (nsp)),
+ nm_wimax_nsp_get_signal_quality (nsp));
+
+ print_string (label, data);
+ g_free (label);
+ g_free (data_str);
+}
+
static gchar *
ip4_address_as_string (guint32 ip)
{
@@ -315,6 +356,8 @@ detail_device (gpointer data, gpointer user_data)
print_string ("Type", "Mobile Broadband (CDMA)");
else if (NM_IS_DEVICE_BT (device))
print_string ("Type", "Bluetooth");
+ else if (NM_IS_WIMAX_DEVICE (device))
+ print_string ("Type", "WiMAX");
print_string ("Driver", nm_device_get_driver (device) ? nm_device_get_driver (device) : "(unknown)");
@@ -330,6 +373,8 @@ detail_device (gpointer data, gpointer user_data)
tmp = g_strdup (nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)));
else if (NM_IS_DEVICE_WIFI (device))
tmp = g_strdup (nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device)));
+ else if (NM_IS_WIMAX_DEVICE (device))
+ tmp = g_strdup (nm_wimax_device_get_hw_address (NM_WIMAX_DEVICE (device)));
if (tmp) {
print_string ("HW Address", tmp);
@@ -395,6 +440,21 @@ detail_device (gpointer data, gpointer user_data)
print_string (" Carrier", "on");
else
print_string (" Carrier", "off");
+ } else if (NM_IS_WIMAX_DEVICE (device)) {
+ NMWimaxNsp *active_nsp = NULL;
+ const char *active_name = NULL;
+ const GPtrArray *nsps;
+
+ if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
+ active_nsp = nm_wimax_device_get_active_nsp (NM_WIMAX_DEVICE (device));
+ active_name = active_nsp ? nm_wimax_nsp_get_name (active_nsp) : NULL;
+ }
+
+ printf ("\n WiMAX NSPs %s\n", active_nsp ? "(* current NSP)" : "");
+
+ nsps = nm_wimax_device_get_nsps (NM_WIMAX_DEVICE (device));
+ if (nsps && nsps->len)
+ g_ptr_array_foreach ((GPtrArray *) nsps, detail_nsp, (gpointer) active_name);
}
/* IP Setup info */