[network-manager-netbook/wimax] Implement support for WiMAX



commit 632f1d9f4d52fce9201384dee789e2cbe6c9c835
Author: Tambet Ingo <tambet gmail com>
Date:   Tue Dec 22 14:09:04 2009 +0200

    Implement support for WiMAX

 libnm-gtk/Makefile.am         |    4 +
 libnm-gtk/nm-device-handler.c |    3 +
 libnm-gtk/nm-list-item.h      |    7 +-
 libnm-gtk/nm-wimax-item.c     |  264 +++++++++++++++++++++++++++++++++++++++++
 libnm-gtk/nm-wimax-item.h     |   57 +++++++++
 libnm-gtk/nm-wimax-provider.c |  229 +++++++++++++++++++++++++++++++++++
 libnm-gtk/nm-wimax-provider.h |   51 ++++++++
 libnm-gtk/utils.c             |   61 ++++++++++
 src/nmn-applet.c              |   40 ++++++
 src/nmn-model.c               |   68 +++++++++++
 src/nmn-model.h               |    7 +
 11 files changed, 788 insertions(+), 3 deletions(-)
---
diff --git a/libnm-gtk/Makefile.am b/libnm-gtk/Makefile.am
index 369a909..8d15ba5 100644
--- a/libnm-gtk/Makefile.am
+++ b/libnm-gtk/Makefile.am
@@ -45,6 +45,8 @@ noinst_HEADERS = \
 	nm-status-model.h \
 	nm-wifi-item.h \
 	nm-wifi-provider.h \
+	nm-wimax-item.h \
+	nm-wimax-provider.h \
 	$(NULL)
 
 libnm_gtk_la_SOURCES = \
@@ -78,6 +80,8 @@ libnm_gtk_la_SOURCES = \
 	nm-status-model.c \
 	nm-wifi-item.c \
 	nm-wifi-provider.c \
+	nm-wimax-item.c \
+	nm-wimax-provider.c \
 	utils.c \
 	utils.h \
 	wireless-dialog.c \
diff --git a/libnm-gtk/nm-device-handler.c b/libnm-gtk/nm-device-handler.c
index feda6eb..c231060 100644
--- a/libnm-gtk/nm-device-handler.c
+++ b/libnm-gtk/nm-device-handler.c
@@ -29,6 +29,7 @@
 #include "nm-gsm-provider.h"
 #include "nm-cdma-provider.h"
 #include "nm-bt-provider.h"
+#include "nm-wimax-provider.h"
 
 G_DEFINE_TYPE (NMDeviceHandler, nm_device_handler, G_TYPE_OBJECT)
 
@@ -95,6 +96,8 @@ create_provider (NMDeviceHandler *self, NMDevice *device)
         provider = nm_cdma_provider_new (priv->client, NM_CDMA_DEVICE (device));
     else if (type == NM_TYPE_DEVICE_BT)
         provider = nm_bt_provider_new (priv->client, NM_DEVICE_BT (device));
+    else if (type == NM_TYPE_WIMAX_DEVICE)
+        provider = nm_wimax_provider_new (priv->client, NM_WIMAX_DEVICE (device));
     else {
         g_warning ("Unknown device type %s", G_OBJECT_TYPE_NAME (device));
         provider = NULL;
diff --git a/libnm-gtk/nm-list-item.h b/libnm-gtk/nm-list-item.h
index 02d6045..6a88f14 100644
--- a/libnm-gtk/nm-list-item.h
+++ b/libnm-gtk/nm-list-item.h
@@ -51,9 +51,10 @@ typedef enum {
 #define NM_LIST_ITEM_PRIORITY_CONFIGURED    100
 #define NM_LIST_ITEM_PRIORITY_DEV_ETHERNET  99
 #define NM_LIST_ITEM_PRIORITY_DEV_WIFI      98
-#define NM_LIST_ITEM_PRIORITY_DEV_GSM       97
-#define NM_LIST_ITEM_PRIORITY_DEV_CDMA      96
-#define NM_LIST_ITEM_PRIORITY_DEV_BT        95
+#define NM_LIST_ITEM_PRIORITY_DEV_WIMAX     97
+#define NM_LIST_ITEM_PRIORITY_DEV_GSM       96
+#define NM_LIST_ITEM_PRIORITY_DEV_CDMA      95
+#define NM_LIST_ITEM_PRIORITY_DEV_BT        94
 
 typedef struct {
     GInitiallyUnowned parent;
diff --git a/libnm-gtk/nm-wimax-item.c b/libnm-gtk/nm-wimax-item.c
new file mode 100644
index 0000000..a446d5c
--- /dev/null
+++ b/libnm-gtk/nm-wimax-item.c
@@ -0,0 +1,264 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* 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.
+ *
+ * (C) Copyright 2009 Novell, Inc.
+ */
+
+#include <glib/gi18n.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wimax.h>
+#include <nm-utils.h>
+#include "nm-wimax-item.h"
+#include "nm-icon-cache.h"
+
+G_DEFINE_TYPE (NMWimaxItem, nm_wimax_item, NM_TYPE_DEVICE_ITEM)
+
+enum {
+    PROP_0,
+    PROP_NSP,
+
+    LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_WIMAX_ITEM, NMWimaxItemPrivate))
+
+typedef struct {
+    NMWimaxNsp *nsp;
+
+    gboolean disposed;
+} NMWimaxItemPrivate;
+
+NMListItem *
+nm_wimax_item_new (NMClient *client,
+                   NMWimaxDevice *device,
+                   NMWimaxNsp *nsp,
+                   NMSettingsConnectionInterface *connection)
+{
+    g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+    g_return_val_if_fail (NM_IS_WIMAX_DEVICE (device), NULL);
+    g_return_val_if_fail (NM_IS_WIMAX_NSP (nsp), NULL);
+
+    return (NMListItem *) g_object_new (NM_TYPE_WIMAX_ITEM,
+                                        NM_LIST_ITEM_TYPE_NAME, _("WiMAX"),
+                                        NM_CONNECTION_ITEM_CLIENT, client,
+                                        NM_CONNECTION_ITEM_CONNECTION, connection,
+                                        NM_DEVICE_ITEM_DEVICE, device,
+                                        NM_WIMAX_ITEM_NSP, nsp,
+                                        NULL);
+}
+
+NMWimaxNsp *
+nm_wimax_item_get_nsp (NMWimaxItem *self)
+{
+    g_return_val_if_fail (NM_IS_WIMAX_ITEM (self), NULL);
+
+    return GET_PRIVATE (self)->nsp;
+}
+
+static void
+signal_quality_changed (NMWimaxItem *self)
+{
+    NMWimaxItemPrivate *priv = GET_PRIVATE (self);
+    const char *icon;
+    guint quality;
+
+    quality = CLAMP (nm_wimax_nsp_get_signal_quality (priv->nsp), 0, 100);
+    if (quality > 80)
+        icon = "nm-signal-100-active";
+    else if (quality > 55)
+        icon = "nm-signal-75-active";
+    else if (quality > 30)
+        icon = "nm-signal-50-active";
+    else if (quality > 5)
+        icon = "nm-signal-25-active";
+    else
+        icon = "nm-signal-00-active";
+
+    if (icon)
+        g_object_set (self, NM_LIST_ITEM_ICON, icon, NULL);
+}
+
+static void
+nm_wimax_item_set_nsp (NMWimaxItem *self,
+                       NMWimaxNsp *nsp)
+{
+    NMWimaxItemPrivate *priv = GET_PRIVATE (self);
+
+    if (priv->nsp) {
+        g_signal_handlers_disconnect_by_func (priv->nsp, signal_quality_changed, self);
+        priv->nsp = NULL;
+    }
+
+    if (nsp) {
+        priv->nsp = g_object_ref (nsp);
+        g_signal_connect_swapped (priv->nsp, "notify::" NM_WIMAX_NSP_SIGNAL_QUALITY,
+                                  G_CALLBACK (signal_quality_changed),
+                                  self);
+
+        signal_quality_changed (self);
+    }
+}
+
+static char *
+wimax_get_specific_object (NMDeviceItem *item)
+{
+    NMWimaxNsp *nsp;
+
+    nsp = nm_wimax_item_get_nsp (NM_WIMAX_ITEM (item));
+
+    return g_strdup (nm_object_get_path (NM_OBJECT (nsp)));
+}
+
+static int
+priority (NMListItem *item)
+{
+    return NM_LIST_ITEM_PRIORITY_DEV_WIMAX + NM_LIST_ITEM_CLASS (nm_wimax_item_parent_class)->priority (item);
+}
+
+static NMConnection *
+create_new_connection (NMWimaxDevice *device, NMWimaxNsp *nsp)
+{
+    NMConnection *connection;
+    NMSetting *setting;
+
+    connection = nm_connection_new ();
+
+    setting = nm_setting_connection_new ();
+    g_object_set (setting,
+                  NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIMAX_SETTING_NAME,
+                  NM_SETTING_CONNECTION_AUTOCONNECT, TRUE,
+                  NULL);
+
+    nm_connection_add_setting (connection, setting);
+
+    setting = nm_setting_wimax_new ();
+    g_object_set (setting,
+                  NM_SETTING_WIMAX_NETWORK_NAME, nm_wimax_nsp_get_name (nsp),
+                  NULL);
+
+    nm_connection_add_setting (connection, setting);
+
+    return connection;
+}
+
+static void
+connect (NMListItem *item)
+{
+    NMConnection *connection;
+
+    connection = (NMConnection *) nm_connection_item_get_connection (NM_CONNECTION_ITEM (item));
+    if (connection) {
+        NM_LIST_ITEM_CLASS (nm_wimax_item_parent_class)->connect (item);
+    } else {
+        /* We don't have a connection yet, so create one */
+        connection = create_new_connection (NM_WIMAX_DEVICE (nm_device_item_get_device (NM_DEVICE_ITEM (item))),
+                                            nm_wimax_item_get_nsp (NM_WIMAX_ITEM (item)));
+
+        if (connection) {
+            nm_connection_item_new_connection (NM_CONNECTION_ITEM (item), connection, TRUE);
+            g_object_unref (connection);
+        }
+    }
+}
+
+/*****************************************************************************/
+
+static void
+nm_wimax_item_init (NMWimaxItem *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+              const GValue *value, GParamSpec *pspec)
+{
+    NMWimaxItem *self = NM_WIMAX_ITEM (object);
+
+    switch (prop_id) {
+    case PROP_NSP:
+        nm_wimax_item_set_nsp (self, NM_WIMAX_NSP (g_value_dup_object (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)
+{
+    NMWimaxItemPrivate *priv = GET_PRIVATE (object);
+
+    switch (prop_id) {
+    case PROP_NSP:
+        g_value_set_object (value, priv->nsp);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+constructed (GObject *object)
+{
+    g_object_set (object,
+                  NM_LIST_ITEM_NAME, nm_wimax_nsp_get_name (nm_wimax_item_get_nsp (NM_WIMAX_ITEM (object))),
+                  NULL);
+}
+
+static void
+dispose (GObject *object)
+{
+    NMWimaxItemPrivate *priv = GET_PRIVATE (object);
+
+    if (!priv->disposed) {
+        nm_wimax_item_set_nsp (NM_WIMAX_ITEM (object), NULL);
+        priv->disposed = TRUE;
+    }
+
+    G_OBJECT_CLASS (nm_wimax_item_parent_class)->dispose (object);
+}
+
+static void
+nm_wimax_item_class_init (NMWimaxItemClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    NMListItemClass *list_class = NM_LIST_ITEM_CLASS (klass);
+    NMDeviceItemClass *device_class = NM_DEVICE_ITEM_CLASS (klass);
+
+    g_type_class_add_private (object_class, sizeof (NMWimaxItemPrivate));
+
+    object_class->set_property = set_property;
+    object_class->get_property = get_property;
+    object_class->constructed = constructed;
+    object_class->dispose = dispose;
+
+    list_class->priority = priority;
+    list_class->connect = connect;
+
+    device_class->get_specific_object = wimax_get_specific_object;
+
+    /* Properties */
+    g_object_class_install_property
+        (object_class, PROP_NSP,
+         g_param_spec_object (NM_WIMAX_ITEM_NSP,
+                              "NMWimaxNsp",
+                              "NMWimaxNsp",
+                              NM_TYPE_WIMAX_NSP,
+                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/libnm-gtk/nm-wimax-item.h b/libnm-gtk/nm-wimax-item.h
new file mode 100644
index 0000000..cfb32a8
--- /dev/null
+++ b/libnm-gtk/nm-wimax-item.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* 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.
+ *
+ * (C) Copyright 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_ITEM_H
+#define NM_WIMAX_ITEM_H
+
+#include <glib-object.h>
+#include <nm-wimax-device.h>
+#include <nm-device-item.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_WIMAX_ITEM            (nm_wimax_item_get_type ())
+#define NM_WIMAX_ITEM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIMAX_ITEM, NMWimaxItem))
+#define NM_WIMAX_ITEM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIMAX_ITEM, NMWimaxItemClass))
+#define NM_IS_WIMAX_ITEM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIMAX_ITEM))
+#define NM_IS_WIMAX_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_WIMAX_ITEM))
+#define NM_WIMAX_ITEM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIMAX_ITEM, NMWimaxItemClass))
+
+#define NM_WIMAX_ITEM_NSP "nsp"
+
+typedef struct {
+    NMDeviceItem parent;
+} NMWimaxItem;
+
+typedef struct {
+    NMDeviceItemClass parent_class;
+} NMWimaxItemClass;
+
+GType nm_wimax_item_get_type (void);
+
+NMListItem *nm_wimax_item_new (NMClient *client,
+                               NMWimaxDevice *device,
+                               NMWimaxNsp *nsp,
+                               NMSettingsConnectionInterface *connection);
+
+NMWimaxNsp *nm_wimax_item_get_nsp (NMWimaxItem *self);
+
+G_END_DECLS
+
+#endif /* NM_WIMAX_ITEM_H */
diff --git a/libnm-gtk/nm-wimax-provider.c b/libnm-gtk/nm-wimax-provider.c
new file mode 100644
index 0000000..0e68715
--- /dev/null
+++ b/libnm-gtk/nm-wimax-provider.c
@@ -0,0 +1,229 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* 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.
+ *
+ * (C) Copyright 2009 Novell, Inc.
+ */
+
+#include <nm-utils.h>
+#include "nm-wimax-provider.h"
+#include "nm-wimax-item.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (NMWimaxProvider, nm_wimax_provider, NM_TYPE_DEVICE_PROVIDER)
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_WIMAX_PROVIDER, NMWimaxProviderPrivate))
+
+typedef struct {
+    gulong nsp_added_id;
+    gulong nsp_removed_id;
+
+    gboolean disposed;
+} NMWimaxProviderPrivate;
+
+NMItemProvider *
+nm_wimax_provider_new (NMClient *client,
+                       NMWimaxDevice *device)
+{
+    g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+    g_return_val_if_fail (NM_IS_WIMAX_DEVICE (device), NULL);
+
+    return (NMItemProvider *) g_object_new (NM_TYPE_WIMAX_PROVIDER,
+                                            NM_ITEM_PROVIDER_CLIENT, client,
+                                            NM_DEVICE_PROVIDER_DEVICE, device,
+                                            NULL);
+}
+
+static void
+wimax_added (NMItemProvider *provider,
+             NMSettingsConnectionInterface *connection)
+{
+    NMDeviceProvider *device_provider = NM_DEVICE_PROVIDER (provider);
+    NMWimaxDevice *device;
+    GSList *list;
+    GSList *iter;
+    const GPtrArray *nsp_list;
+    int i;
+
+    if (!nm_device_provider_ready (device_provider))
+        return;
+
+    device = NM_WIMAX_DEVICE (nm_device_provider_get_device (device_provider));
+
+    /* First, see if we have a NSP item already which has
+       no connection and is compatible with this connection */
+    list = nm_item_provider_get_items (provider);
+    for (iter = list; iter; iter = iter->next) {
+        NMListItem *item = (NMListItem *) iter->data;
+        NMSettingsConnectionInterface *item_connection;
+        NMWimaxNsp *nsp;
+
+        item_connection = nm_connection_item_get_connection (NM_CONNECTION_ITEM (item));
+        if (item_connection == connection) {
+            /* Already have this same connection why do we get called??? */
+            g_warning ("Connection already in the list, something is broken");
+            return;
+        }
+
+        if (item_connection)
+            continue;
+
+        nsp = nm_wimax_item_get_nsp (NM_WIMAX_ITEM (item));
+        if (utils_connection_valid_for_device (NM_CONNECTION (connection), NM_DEVICE (device), nsp)) {
+            g_object_set (item, NM_CONNECTION_ITEM_CONNECTION, connection, NULL);
+            return;
+        }
+    }
+
+    /* That didn't work. let's see if we have a compatible NSP so we can still
+       show this connection. This happens when there's multiple connections which
+       match an NSP and we want to have an item for each connection */
+
+    nsp_list = nm_wimax_device_get_nsps (device);
+    for (i = 0; nsp_list && nsp_list->len > i; i++) {
+        NMWimaxNsp *nsp = (NMWimaxNsp *) g_ptr_array_index (nsp_list, i);
+
+        if (utils_connection_valid_for_device (NM_CONNECTION (connection), NM_DEVICE (device), nsp)) {
+            NMListItem *item;
+
+            item = nm_wimax_item_new (nm_item_provider_get_client (provider), device, nsp, connection);
+            nm_item_provider_item_added (provider, item);
+            break;
+        }
+    }
+}
+
+static void
+nsp_added (NMWimaxDevice *device,
+           NMWimaxNsp *nsp,
+           gpointer user_data)
+{
+    NMItemProvider *provider = NM_ITEM_PROVIDER (user_data);
+    GSList *list;
+    GSList *iter;
+    NMListItem *item;
+    gboolean added = FALSE;
+
+    /* Check for duplicates */
+    list = nm_item_provider_get_items (provider);
+    for (iter = list; iter; iter = iter->next) {
+        NMWimaxItem *wimax_item = (NMWimaxItem *) iter->data;
+        NMWimaxNsp *item_nsp;
+
+        item_nsp = nm_wimax_item_get_nsp (wimax_item);
+        if (!g_strcmp0 (nm_wimax_nsp_get_name (nsp), nm_wimax_nsp_get_name (item_nsp)))
+            return;
+    }
+
+    list = nm_item_provider_get_connections (provider);
+    for (iter = list; iter; iter = iter->next) {
+        NMSettingsConnectionInterface *connection = (NMSettingsConnectionInterface *) iter->data;
+
+        if (!utils_connection_valid_for_device (NM_CONNECTION (connection), NM_DEVICE (device), nsp))
+            continue;
+
+        item = nm_wimax_item_new (nm_item_provider_get_client (provider), device, nsp, connection);
+        nm_item_provider_item_added (provider, item);
+        added = TRUE;
+    }
+
+    g_slist_free (list);
+
+    if (added)
+        return;
+
+    /* There's no connection for this NSP. Create a connectionless item */
+    item = nm_wimax_item_new (nm_item_provider_get_client (provider), device, nsp, NULL);
+    nm_item_provider_item_added (provider, item);
+}
+
+static void
+nsp_removed (NMWimaxDevice *device,
+             NMWimaxNsp *nsp,
+             gpointer user_data)
+{
+    NMItemProvider *provider = NM_ITEM_PROVIDER (user_data);
+    GSList *list;
+    GSList *iter;
+
+    list = nm_item_provider_get_items (provider);
+    for (iter = list; iter; iter = iter->next) {
+        NMWimaxItem *item = (NMWimaxItem *) iter->data;
+        NMWimaxNsp *item_nsp;
+
+        item_nsp = nm_wimax_item_get_nsp (item);
+        if (!g_strcmp0 (nm_wimax_nsp_get_name (nsp), nm_wimax_nsp_get_name (item_nsp)))
+            nm_list_item_request_remove (NM_LIST_ITEM (item));
+    }
+}
+
+/*****************************************************************************/
+
+static void
+nm_wimax_provider_init (NMWimaxProvider *self)
+{
+}
+
+static void
+constructed (GObject *object)
+{
+    NMWimaxProviderPrivate *priv = GET_PRIVATE (object);
+    NMWimaxDevice *device;
+    const GPtrArray *nsp_list;
+    int i;
+
+    if (G_OBJECT_CLASS (nm_wimax_provider_parent_class)->constructed)
+        G_OBJECT_CLASS (nm_wimax_provider_parent_class)->constructed (object);
+
+    device = NM_WIMAX_DEVICE (nm_device_provider_get_device (NM_DEVICE_PROVIDER (object)));
+    priv->nsp_added_id = g_signal_connect (device, "nsp-added", G_CALLBACK (nsp_added), object);
+    priv->nsp_removed_id = g_signal_connect (device, "nsp-removed", G_CALLBACK (nsp_removed), object);
+
+    nsp_list = nm_wimax_device_get_nsps (device);
+    for (i = 0; nsp_list && nsp_list->len > i; i++)
+        nsp_added (device, (NMWimaxNsp *) g_ptr_array_index (nsp_list, i), object);
+}
+
+static void
+dispose (GObject *object)
+{
+    NMWimaxProviderPrivate *priv = GET_PRIVATE (object);
+
+    if (!priv->disposed) {
+        NMDevice *device;
+
+        device = nm_device_provider_get_device (NM_DEVICE_PROVIDER (object));
+        g_signal_handler_disconnect (device, priv->nsp_added_id);
+        g_signal_handler_disconnect (device, priv->nsp_removed_id);
+
+        priv->disposed = TRUE;
+    }
+
+    G_OBJECT_CLASS (nm_wimax_provider_parent_class)->dispose (object);
+}
+
+static void
+nm_wimax_provider_class_init (NMWimaxProviderClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    NMItemProviderClass *item_class = NM_ITEM_PROVIDER_CLASS (klass);
+
+    g_type_class_add_private (object_class, sizeof (NMWimaxProviderPrivate));
+
+    object_class->constructed = constructed;
+    object_class->dispose = dispose;
+
+    item_class->connection_added = wimax_added;
+}
diff --git a/libnm-gtk/nm-wimax-provider.h b/libnm-gtk/nm-wimax-provider.h
new file mode 100644
index 0000000..7de4e81
--- /dev/null
+++ b/libnm-gtk/nm-wimax-provider.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* 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.
+ *
+ * (C) Copyright 2009 Novell, Inc.
+ */
+
+#ifndef NM_WIMAX_PROVIDER_H
+#define NM_WIMAX_PROVIDER_H
+
+#include <glib-object.h>
+#include <nm-wimax-device.h>
+#include <nm-device-provider.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_WIMAX_PROVIDER            (nm_wimax_provider_get_type ())
+#define NM_WIMAX_PROVIDER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIMAX_PROVIDER, NMWimaxProvider))
+#define NM_WIMAX_PROVIDER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIMAX_PROVIDER, NMWimaxProviderClass))
+#define NM_IS_WIMAX_PROVIDER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIMAX_PROVIDER))
+#define NM_IS_WIMAX_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_WIMAX_PROVIDER))
+#define NM_WIMAX_PROVIDER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIMAX_PROVIDER, NMWimaxProviderClass))
+
+typedef struct {
+    NMDeviceProvider parent;
+} NMWimaxProvider;
+
+typedef struct {
+    NMDeviceProviderClass parent_class;
+} NMWimaxProviderClass;
+
+GType nm_wimax_provider_get_type (void);
+
+NMItemProvider *nm_wimax_provider_new (NMClient *client,
+                                       NMWimaxDevice *device);
+
+G_END_DECLS
+
+#endif /* NM_WIMAX_PROVIDER_H */
diff --git a/libnm-gtk/utils.c b/libnm-gtk/utils.c
index 94ac317..f3dd1fc 100644
--- a/libnm-gtk/utils.c
+++ b/libnm-gtk/utils.c
@@ -28,6 +28,7 @@
 #include <nm-device-bt.h>
 #include <nm-gsm-device.h>
 #include <nm-cdma-device.h>
+#include <nm-wimax-device.h>
 #include <nm-access-point.h>
 
 #include <nm-setting-connection.h>
@@ -39,6 +40,7 @@
 #include <nm-setting-cdma.h>
 #include <nm-setting-pppoe.h>
 #include <nm-setting-bluetooth.h>
+#include <nm-setting-wimax.h>
 #include <nm-utils.h>
 
 #include "utils.h"
@@ -699,6 +701,63 @@ connection_valid_for_bt (NMConnection *connection,
 	return addr_match;
 }
 
+static gboolean
+utils_check_nsp_compatible (NMWimaxNsp *nsp,
+							NMConnection *connection)
+{
+	NMSettingWimax *s_wimax;
+
+	s_wimax = NM_SETTING_WIMAX (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX));
+	g_return_val_if_fail (s_wimax != NULL, FALSE);
+
+	return g_strcmp0 (nm_wimax_nsp_get_name (nsp), nm_setting_wimax_get_network_name (s_wimax)) == 0;
+}
+
+static gboolean
+connection_valid_for_wimax (NMConnection *connection,
+							NMSettingConnection *s_con,
+							NMDevice *device,
+							gpointer specific_object)
+{
+	NMSettingWimax *s_wimax;
+	const GByteArray *setting_mac;
+
+	if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIMAX_SETTING_NAME))
+		return FALSE;
+
+	s_wimax = NM_SETTING_WIMAX (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX));
+	g_return_val_if_fail (s_wimax != NULL, FALSE);
+
+	/* Match MAC address */
+	setting_mac = nm_setting_wimax_get_mac_address (s_wimax);
+	if (setting_mac) {
+		const char *str_mac;
+		struct ether_addr *bin_mac;
+
+		str_mac = nm_wimax_device_get_hw_address (NM_WIMAX_DEVICE (device));
+		g_return_val_if_fail (str_mac != NULL, FALSE);
+
+		bin_mac = ether_aton (str_mac);
+		g_return_val_if_fail (bin_mac != NULL, FALSE);
+
+		if (memcmp (bin_mac->ether_addr_octet, setting_mac->data, ETH_ALEN))
+			return FALSE;
+	}
+
+	/* If a NSP was given make sure that's compatible with the connection first */
+	if (specific_object) {
+		NMWimaxNsp *nsp;
+
+		nsp = NM_WIMAX_NSP (specific_object);
+		g_assert (nsp);
+
+		if (!utils_check_nsp_compatible (nsp, connection))
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
 gboolean
 utils_connection_valid_for_device (NMConnection *connection,
                                    NMDevice *device,
@@ -723,6 +782,8 @@ utils_connection_valid_for_device (NMConnection *connection,
 		return connection_valid_for_cdma (connection, s_con, device, specific_object);
 	else if (NM_IS_DEVICE_BT (device))
 		return connection_valid_for_bt (connection, s_con, device, specific_object);
+	else if (NM_IS_WIMAX_DEVICE (device))
+		return connection_valid_for_wimax (connection, s_con, device, specific_object);
 	else
 		g_warning ("Unknown device type '%s'", g_type_name (G_OBJECT_TYPE(device)));
 
diff --git a/src/nmn-applet.c b/src/nmn-applet.c
index b6229d5..a9d87e5 100644
--- a/src/nmn-applet.c
+++ b/src/nmn-applet.c
@@ -24,6 +24,7 @@
 #include <nm-device-wifi.h>
 #include <nm-serial-device.h>
 #include <nm-device-bt.h>
+#include <nm-wimax-device.h>
 #include "nmn-applet.h"
 #include "nmn-new-connection.h"
 
@@ -108,6 +109,8 @@ sensitize_switches (NmnApplet *applet)
                 modem++;
             else if (NM_IS_DEVICE_BT (device))
                 bt++;
+            else if (NM_IS_WIMAX_DEVICE (device))
+                wimax++;
         }
     }
 
@@ -286,6 +289,42 @@ enable_bt_setup (NmnApplet *applet)
     bt_toggled (priv->model, nmn_model_bt_get_active (priv->model), applet);
 }
 
+/* enable/disable WiMAX button */
+
+static void
+enable_wimax_toggled (NbtkGtkLightSwitch *w,
+                      gboolean active,
+                      gpointer user_data)
+{
+    NmnAppletPrivate *priv = GET_PRIVATE (user_data);
+
+    nmn_model_wimax_toggled (priv->model, active);
+}
+
+static void
+wimax_toggled (NmnModel *model,
+               gboolean active,
+               gpointer user_data)
+{
+    NmnAppletPrivate *priv = GET_PRIVATE (user_data);
+
+    g_signal_handlers_block_by_func (priv->model, enable_wimax_toggled, user_data);
+    nbtk_gtk_light_switch_set_active (NBTK_GTK_LIGHT_SWITCH (priv->enable_wimax), active);
+    g_signal_handlers_unblock_by_func (priv->model, enable_wimax_toggled, user_data);
+}
+
+static void
+enable_wimax_setup (NmnApplet *applet)
+{
+    NmnAppletPrivate *priv = GET_PRIVATE (applet);
+
+    g_signal_connect (priv->enable_wimax, "switch-flipped", G_CALLBACK (enable_wimax_toggled), applet);
+    gtk_widget_show (priv->enable_wimax);
+
+    g_signal_connect (priv->model, "wimax-toggled", G_CALLBACK (wimax_toggled), applet);
+    wimax_toggled (priv->model, nmn_model_wimax_get_active (priv->model), applet);
+}
+
 /* enable/disable Offline mode button */
 
 static void
@@ -504,6 +543,7 @@ constructor (GType type,
     enable_ethernet_setup (applet);
     enable_3g_setup (applet);
     enable_bt_setup (applet);
+    enable_wimax_setup (applet);
     enable_network_setup (applet);
     add_new_connection_setup (applet);
     add_new_connection_hide (NULL, applet);
diff --git a/src/nmn-model.c b/src/nmn-model.c
index 957f4f4..db42cbb 100644
--- a/src/nmn-model.c
+++ b/src/nmn-model.c
@@ -27,6 +27,7 @@
 #include "nm-gsm-item.h"
 #include "nm-cdma-item.h"
 #include "nm-bt-item.h"
+#include "nm-wimax-item.h"
 
 G_DEFINE_TYPE (NmnModel, nmn_model, GTK_TYPE_TREE_MODEL_FILTER)
 
@@ -35,6 +36,7 @@ enum {
     WIFI_TOGGLED,
     MODEMS_TOGGLED,
     BT_TOGGLED,
+    WIMAX_TOGGLED,
     OFFLINE_MODE_TOGGLED,
 
     LAST_SIGNAL
@@ -53,6 +55,7 @@ typedef struct {
     gboolean wifi_active;
     gboolean modems_active;
     gboolean bt_active;
+    gboolean wimax_active;
     gboolean offline_mode_active;
 
     gboolean disposed;
@@ -308,6 +311,58 @@ nmn_model_bt_toggled (NmnModel *self,
 }
 
 gboolean
+nmn_model_wimax_get_active (NmnModel *self)
+{
+    g_return_val_if_fail (NMN_IS_MODEL (self), FALSE);
+
+    return GET_PRIVATE (self)->wimax_active;
+}
+
+static void
+wimax_deactive (NmnModel *self)
+{
+    GtkTreeModel *child_model;
+    GtkTreeIter iter;
+    gboolean valid;
+
+    child_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (self));
+    valid = gtk_tree_model_get_iter_first (child_model, &iter);
+    while (valid) {
+        NMListItem *item = NULL;
+
+        gtk_tree_model_get (child_model, &iter, NM_LIST_MODEL_COL_ITEM, &item, -1);
+        if (item) {
+            if (NM_IS_WIMAX_ITEM (item) && nm_list_item_get_status (item) != NM_LIST_ITEM_STATUS_DISCONNECTED)
+                nm_list_item_disconnect (item);
+
+            g_object_unref (item);
+        }
+
+        valid = gtk_tree_model_iter_next (child_model, &iter);
+    }
+}
+
+void
+nmn_model_wimax_toggled (NmnModel *self,
+                         gboolean active)
+{
+    NmnModelPrivate *priv;
+
+    g_return_if_fail (NMN_IS_MODEL (self));
+
+    priv = GET_PRIVATE (self);
+    if (priv->wimax_active != active) {
+        /* FIXME: Save in gconf? */
+        priv->wimax_active = active;
+        gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (self));
+        if (!active)
+            wimax_deactive (self);
+
+        g_signal_emit (self, signals[WIMAX_TOGGLED], 0, active);
+    }
+}
+
+gboolean
 nmn_model_offline_mode_get_active (NmnModel *self)
 {
     g_return_val_if_fail (NMN_IS_MODEL (self), FALSE);
@@ -379,6 +434,8 @@ model_row_visible_func (GtkTreeModel *model,
             visible = priv->modems_active;
         else if (NM_IS_BT_ITEM (item))
             visible = priv->bt_active;
+        else if (NM_IS_WIMAX_ITEM (item))
+            visible = priv->wimax_active;
 
         g_object_unref (item);
     }
@@ -436,6 +493,7 @@ nmn_model_init (NmnModel *model)
     priv->wifi_active = TRUE;
     priv->modems_active = TRUE;
     priv->bt_active = TRUE;
+    priv->wimax_active = TRUE;
     priv->offline_mode_active = FALSE;
 }
 
@@ -550,6 +608,16 @@ nmn_model_class_init (NmnModelClass *class)
          G_TYPE_NONE, 1,
          G_TYPE_BOOLEAN);
 
+    signals[WIMAX_TOGGLED] = g_signal_new 
+        ("wimax-toggled",
+         G_OBJECT_CLASS_TYPE (class),
+         G_SIGNAL_RUN_LAST,
+         G_STRUCT_OFFSET (NmnModelClass, wimax_toggled),
+         NULL, NULL,
+         g_cclosure_marshal_VOID__BOOLEAN,
+         G_TYPE_NONE, 1,
+         G_TYPE_BOOLEAN);
+
     signals[OFFLINE_MODE_TOGGLED] = g_signal_new 
         ("offline-mode-toggled",
          G_OBJECT_CLASS_TYPE (class),
diff --git a/src/nmn-model.h b/src/nmn-model.h
index c5f3615..07a50a6 100644
--- a/src/nmn-model.h
+++ b/src/nmn-model.h
@@ -51,6 +51,9 @@ typedef struct {
     void (*bt_toggled) (NmnModel *self,
                         gboolean active);
 
+    void (*wimax_toggled) (NmnModel *self,
+                           gboolean active);
+
     void (*offline_mode_toggled) (NmnModel *self,
                                   gboolean active);
 } NmnModelClass;
@@ -80,6 +83,10 @@ gboolean    nmn_model_bt_get_active           (NmnModel *self);
 void        nmn_model_bt_toggled              (NmnModel *self,
                                                gboolean active);
 
+gboolean    nmn_model_wimax_get_active        (NmnModel *self); 
+void        nmn_model_wimax_toggled           (NmnModel *self,
+                                               gboolean active);
+
 gboolean    nmn_model_offline_mode_get_active (NmnModel *self);
 void        nmn_model_offline_mode_toggled    (NmnModel *self,
                                                gboolean active);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]