From 75c734f1a914efea424f8c1ea1f3156021ae9572 Mon Sep 17 00:00:00 2001 From: Tambet Ingo Date: Mon, 14 Dec 2009 13:51:50 +0200 Subject: [PATCH 001/102] wimax: Implement WiMAX support --- configure.ac | 3 + include/NetworkManager.h | 4 + introspection/Makefile.am | 4 +- introspection/all.xml | 2 + introspection/nm-wimax-device.xml | 63 ++ introspection/nm-wimax-nsp.xml | 44 ++ libnm-glib/Makefile.am | 14 +- libnm-glib/libnm-glib.ver | 11 + libnm-glib/nm-device.c | 4 + libnm-glib/nm-wimax-device.c | 567 ++++++++++++++++ libnm-glib/nm-wimax-device.h | 67 ++ libnm-glib/nm-wimax-nsp.c | 301 ++++++++ libnm-glib/nm-wimax-nsp.h | 77 +++ libnm-util/Makefile.am | 2 + libnm-util/libnm-util.ver | 6 + libnm-util/nm-connection.c | 8 +- libnm-util/nm-setting-wimax.c | 229 +++++++ libnm-util/nm-setting-wimax.h | 70 ++ src/Makefile.am | 4 + src/nm-manager.c | 8 +- src/nm-udev-manager.c | 9 + src/wimax/Makefile.am | 39 ++ src/wimax/nm-wimax-device.c | 1055 +++++++++++++++++++++++++++++ src/wimax/nm-wimax-device.h | 76 +++ src/wimax/nm-wimax-manager.c | 139 ++++ src/wimax/nm-wimax-manager.h | 31 + src/wimax/nm-wimax-nsp.c | 249 +++++++ src/wimax/nm-wimax-nsp.h | 63 ++ src/wimax/nm-wimax-types.h | 31 + src/wimax/nm-wimax-util.c | 117 ++++ src/wimax/nm-wimax-util.h | 36 + test/nm-tool.c | 60 ++ 32 files changed, 3387 insertions(+), 6 deletions(-) create mode 100644 introspection/nm-wimax-device.xml create mode 100644 introspection/nm-wimax-nsp.xml create mode 100644 libnm-glib/nm-wimax-device.c create mode 100644 libnm-glib/nm-wimax-device.h create mode 100644 libnm-glib/nm-wimax-nsp.c create mode 100644 libnm-glib/nm-wimax-nsp.h create mode 100644 libnm-util/nm-setting-wimax.c create mode 100644 libnm-util/nm-setting-wimax.h create mode 100644 src/wimax/Makefile.am create mode 100644 src/wimax/nm-wimax-device.c create mode 100644 src/wimax/nm-wimax-device.h create mode 100644 src/wimax/nm-wimax-manager.c create mode 100644 src/wimax/nm-wimax-manager.h create mode 100644 src/wimax/nm-wimax-nsp.c create mode 100644 src/wimax/nm-wimax-nsp.h create mode 100644 src/wimax/nm-wimax-types.h create mode 100644 src/wimax/nm-wimax-util.c create mode 100644 src/wimax/nm-wimax-util.h 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 */ From 20a4c6c6b6a9f590f050ef074ebbffbfb0887dce Mon Sep 17 00:00:00 2001 From: Tambet Ingo Date: Tue, 29 Dec 2009 11:27:10 +0200 Subject: [PATCH 002/102] wimax: Implement RFKILL handling Implement and export over DBus WiMAX enable/disable and hardware state query. --- introspection/nm-manager-client.xml | 2 + introspection/nm-manager.xml | 12 +++ libnm-glib/libnm-glib.ver | 3 + libnm-glib/nm-client.c | 142 ++++++++++++++++++++++++++++ libnm-glib/nm-client.h | 6 ++ src/NetworkManager.c | 18 +++- src/nm-device-olpc-mesh.c | 2 +- src/nm-manager.c | 51 ++++++++++ src/nm-manager.h | 1 + src/wimax/nm-wimax-device.c | 42 ++++---- src/wimax/nm-wimax-device.h | 3 - 11 files changed, 258 insertions(+), 24 deletions(-) diff --git a/introspection/nm-manager-client.xml b/introspection/nm-manager-client.xml index 9a0d4da214..a3e89f34b7 100644 --- a/introspection/nm-manager-client.xml +++ b/introspection/nm-manager-client.xml @@ -43,6 +43,8 @@ object. dbus-glib generates the same bound function names for D-Bus the methods + + diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml index 8303f4d469..61d57e0717 100644 --- a/introspection/nm-manager.xml +++ b/introspection/nm-manager.xml @@ -120,6 +120,18 @@ + + + Indicates if WiMAX devices are currently enabled or not. + + + + + + Indicates if the WiMAX hardware is currently enabled, i.e. the state of the RF kill switch. + + + List of active connection object paths. diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 4b1b09c421..f396e95dfa 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -43,6 +43,9 @@ global: nm_client_wwan_get_enabled; nm_client_wwan_hardware_get_enabled; nm_client_wwan_set_enabled; + nm_client_wimax_get_enabled; + nm_client_wimax_hardware_get_enabled; + nm_client_wimax_set_enabled; nm_dbus_settings_get_connection_by_path; nm_dbus_settings_get_type; nm_dbus_settings_new; diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 05fa4dbf24..8365d0907c 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -63,6 +63,9 @@ typedef struct { gboolean wwan_enabled; gboolean wwan_hw_enabled; + + gboolean wimax_enabled; + gboolean wimax_hw_enabled; } NMClientPrivate; enum { @@ -73,6 +76,8 @@ enum { PROP_WIRELESS_HARDWARE_ENABLED, PROP_WWAN_ENABLED, PROP_WWAN_HARDWARE_ENABLED, + PROP_WIMAX_ENABLED, + PROP_WIMAX_HARDWARE_ENABLED, PROP_ACTIVE_CONNECTIONS, LAST_PROP @@ -188,6 +193,36 @@ update_wwan_status (NMClient *client, gboolean notify) } } +static void +update_wimax_status (NMClient *client, gboolean notify) +{ + NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client); + gboolean val; + + val = _nm_object_get_boolean_property (NM_OBJECT (client), + NM_DBUS_INTERFACE, + "WimaxHardwareEnabled"); + if (val != priv->wimax_hw_enabled) { + priv->wimax_hw_enabled = val; + if (notify) + _nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_WIMAX_HARDWARE_ENABLED); + } + + if (priv->wimax_hw_enabled == FALSE) + val = FALSE; + else { + val = _nm_object_get_boolean_property (NM_OBJECT (client), + NM_DBUS_INTERFACE, + "WimaxEnabled"); + } + + if (val != priv->wimax_enabled) { + priv->wimax_enabled = val; + if (notify) + _nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_WIMAX_ENABLED); + } +} + static GObject * new_active_connection (DBusGConnection *connection, const char *path) { @@ -254,6 +289,8 @@ register_for_property_changed (NMClient *client) { NM_CLIENT_WIRELESS_HARDWARE_ENABLED, _nm_object_demarshal_generic, &priv->wireless_hw_enabled }, { NM_CLIENT_WWAN_ENABLED, _nm_object_demarshal_generic, &priv->wwan_enabled }, { NM_CLIENT_WWAN_HARDWARE_ENABLED, _nm_object_demarshal_generic, &priv->wwan_hw_enabled }, + { NM_CLIENT_WIMAX_ENABLED, _nm_object_demarshal_generic, &priv->wimax_enabled }, + { NM_CLIENT_WIMAX_HARDWARE_ENABLED, _nm_object_demarshal_generic, &priv->wimax_hw_enabled }, { NM_CLIENT_ACTIVE_CONNECTIONS, demarshal_active_connections, &priv->active_connections }, { NULL }, }; @@ -329,6 +366,7 @@ constructor (GType type, if (priv->manager_running) { update_wireless_status (NM_CLIENT (object), FALSE); update_wwan_status (NM_CLIENT (object), FALSE); + update_wimax_status (NM_CLIENT (object), FALSE); nm_client_get_state (NM_CLIENT (object)); } @@ -405,6 +443,20 @@ set_property (GObject *object, guint prop_id, _nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WWAN_HARDWARE_ENABLED); } break; + case PROP_WIMAX_ENABLED: + b = g_value_get_boolean (value); + if (priv->wimax_enabled != b) { + priv->wimax_enabled = b; + _nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WIMAX_ENABLED); + } + break; + case PROP_WIMAX_HARDWARE_ENABLED: + b = g_value_get_boolean (value); + if (priv->wimax_hw_enabled != b) { + priv->wimax_hw_enabled = b; + _nm_object_queue_notify (NM_OBJECT (object), NM_CLIENT_WIMAX_HARDWARE_ENABLED); + } + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -439,6 +491,12 @@ get_property (GObject *object, case PROP_WWAN_HARDWARE_ENABLED: g_value_set_boolean (value, priv->wwan_hw_enabled); break; + case PROP_WIMAX_ENABLED: + g_value_set_boolean (value, priv->wimax_enabled); + break; + case PROP_WIMAX_HARDWARE_ENABLED: + g_value_set_boolean (value, priv->wimax_hw_enabled); + break; case PROP_ACTIVE_CONNECTIONS: g_value_set_boxed (value, nm_client_get_active_connections (self)); break; @@ -541,6 +599,32 @@ nm_client_class_init (NMClientClass *client_class) TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /** + * NMClient::wimax-enabled: + * + * Whether WiMAX functionality is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WIMAX_ENABLED, + g_param_spec_boolean (NM_CLIENT_WIMAX_ENABLED, + "WimaxEnabled", + "Is WiMAX enabled", + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + /** + * NMClient::wimax-hardware-enabled: + * + * Whether the WiMAX hardware is enabled. + **/ + g_object_class_install_property + (object_class, PROP_WIMAX_HARDWARE_ENABLED, + g_param_spec_boolean (NM_CLIENT_WIMAX_HARDWARE_ENABLED, + "WimaxHardwareEnabled", + "Is WiMAX hardware enabled", + TRUE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + /** * NMClient::active-connections: * @@ -652,10 +736,13 @@ proxy_name_owner_changed (DBusGProxy *proxy, priv->wireless_hw_enabled = FALSE; priv->wwan_enabled = FALSE; priv->wwan_hw_enabled = FALSE; + priv->wimax_enabled = FALSE; + priv->wimax_hw_enabled = FALSE; } else { _nm_object_queue_notify (NM_OBJECT (client), NM_CLIENT_MANAGER_RUNNING); update_wireless_status (client, TRUE); update_wwan_status (client, TRUE); + update_wimax_status (client, TRUE); } } @@ -1015,6 +1102,61 @@ nm_client_wwan_hardware_get_enabled (NMClient *client) return NM_CLIENT_GET_PRIVATE (client)->wwan_hw_enabled; } +/** + * nm_client_wimax_get_enabled: + * @client: a #NMClient + * + * Determines whether WiMAX is enabled. + * + * Returns: %TRUE if WiMAX is enabled + **/ +gboolean +nm_client_wimax_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return NM_CLIENT_GET_PRIVATE (client)->wimax_enabled; +} + +/** + * nm_client_wimax_set_enabled: + * @client: a #NMClient + * @enabled: %TRUE to enable WiMAX + * + * Enables or disables WiMAX devices. + **/ +void +nm_client_wimax_set_enabled (NMClient *client, gboolean enabled) +{ + GValue value = {0,}; + + g_return_if_fail (NM_IS_CLIENT (client)); + + g_value_init (&value, G_TYPE_BOOLEAN); + g_value_set_boolean (&value, enabled); + + _nm_object_set_property (NM_OBJECT (client), + NM_DBUS_INTERFACE, + "WimaxEnabled", + &value); +} + +/** + * nm_client_wimax_hardware_get_enabled: + * @client: a #NMClient + * + * Determines whether the WiMAX hardware is enabled. + * + * Returns: %TRUE if the WiMAX hardware is enabled + **/ +gboolean +nm_client_wimax_hardware_get_enabled (NMClient *client) +{ + g_return_val_if_fail (NM_IS_CLIENT (client), FALSE); + + return NM_CLIENT_GET_PRIVATE (client)->wimax_hw_enabled; +} + /** * nm_client_get_state: * @client: a #NMClient diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 6aafc0872c..b75bf2231a 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -47,6 +47,8 @@ G_BEGIN_DECLS #define NM_CLIENT_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled" #define NM_CLIENT_WWAN_ENABLED "wwan-enabled" #define NM_CLIENT_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled" +#define NM_CLIENT_WIMAX_ENABLED "wimax-enabled" +#define NM_CLIENT_WIMAX_HARDWARE_ENABLED "wimax-hardware-enabled" #define NM_CLIENT_ACTIVE_CONNECTIONS "active-connections" typedef struct { @@ -96,6 +98,10 @@ gboolean nm_client_wwan_get_enabled (NMClient *client); void nm_client_wwan_set_enabled (NMClient *client, gboolean enabled); gboolean nm_client_wwan_hardware_get_enabled (NMClient *client); +gboolean nm_client_wimax_get_enabled (NMClient *client); +void nm_client_wimax_set_enabled (NMClient *client, gboolean enabled); +gboolean nm_client_wimax_hardware_get_enabled (NMClient *client); + NMState nm_client_get_state (NMClient *client); gboolean nm_client_get_manager_running (NMClient *client); const GPtrArray *nm_client_get_active_connections (NMClient *client); diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 09a4320c78..e815745ca2 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -330,15 +330,17 @@ parse_state_file (const char *filename, gboolean *net_enabled, gboolean *wifi_enabled, gboolean *wwan_enabled, + gboolean *wimax_enabled, GError **error) { GKeyFile *state_file; GError *tmp_error = NULL; - gboolean wifi, net, wwan; + gboolean wifi, net, wwan, wimax; g_return_val_if_fail (net_enabled != NULL, FALSE); g_return_val_if_fail (wifi_enabled != NULL, FALSE); g_return_val_if_fail (wwan_enabled != NULL, FALSE); + g_return_val_if_fail (wimax_enabled != NULL, FALSE); state_file = g_key_file_new (); if (!state_file) { @@ -377,6 +379,7 @@ parse_state_file (const char *filename, g_key_file_set_boolean (state_file, "main", "NetworkingEnabled", *net_enabled); g_key_file_set_boolean (state_file, "main", "WirelessEnabled", *wifi_enabled); g_key_file_set_boolean (state_file, "main", "WWANEnabled", *wwan_enabled); + g_key_file_set_boolean (state_file, "main", "WimaxEnabled", *wimax_enabled); data = g_key_file_to_data (state_file, &len, NULL); if (data) @@ -419,6 +422,14 @@ parse_state_file (const char *filename, *wwan_enabled = wwan; g_clear_error (&tmp_error); + wimax = g_key_file_get_boolean (state_file, "main", "WimaxEnabled", &tmp_error); + if (tmp_error) { + g_clear_error (error); + g_set_error_literal (error, tmp_error->domain, tmp_error->code, tmp_error->message); + } else + *wimax_enabled = wimax; + g_clear_error (&tmp_error); + g_key_file_free (state_file); return TRUE; @@ -437,7 +448,7 @@ main (int argc, char *argv[]) char *pidfile = NULL, *user_pidfile = NULL; char *config = NULL, *plugins = NULL; char *state_file = NM_DEFAULT_SYSTEM_STATE_FILE; - gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE; + gboolean wifi_enabled = TRUE, net_enabled = TRUE, wwan_enabled = TRUE, wimax_enabled = TRUE; gboolean success; NMPolicy *policy = NULL; NMVPNManager *vpn_manager = NULL; @@ -520,7 +531,7 @@ main (int argc, char *argv[]) g_clear_error (&error); /* Parse the state file */ - if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &error)) { + if (!parse_state_file (state_file, &net_enabled, &wifi_enabled, &wwan_enabled, &wimax_enabled, &error)) { g_warning ("State file %s parsing failed: (%d) %s.", state_file, error ? error->code : -1, @@ -600,6 +611,7 @@ main (int argc, char *argv[]) net_enabled, wifi_enabled, wwan_enabled, + wimax_enabled, &error); if (manager == NULL) { nm_error ("Failed to initialize the network manager: %s", diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index ad81a5a78b..b326dfe80a 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -909,7 +909,7 @@ check_companion_cb (gpointer user_data) if (priv->device_added_cb != 0) return FALSE; - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL); priv->device_added_cb = g_signal_connect (manager, "device-added", G_CALLBACK (device_added_cb), self); diff --git a/src/nm-manager.c b/src/nm-manager.c index 7eecbe0ba8..c98254cf12 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -63,6 +63,8 @@ #define NM_MANAGER_WIRELESS_HARDWARE_ENABLED "wireless-hardware-enabled" #define NM_MANAGER_WWAN_ENABLED "wwan-enabled" #define NM_MANAGER_WWAN_HARDWARE_ENABLED "wwan-hardware-enabled" +#define NM_MANAGER_WIMAX_ENABLED "wimax-enabled" +#define NM_MANAGER_WIMAX_HARDWARE_ENABLED "wimax-hardware-enabled" #define NM_MANAGER_ACTIVE_CONNECTIONS "active-connections" static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err); @@ -231,6 +233,8 @@ enum { PROP_WIRELESS_HARDWARE_ENABLED, PROP_WWAN_ENABLED, PROP_WWAN_HARDWARE_ENABLED, + PROP_WIMAX_ENABLED, + PROP_WIMAX_HARDWARE_ENABLED, PROP_ACTIVE_CONNECTIONS, /* Not exported */ @@ -1339,6 +1343,12 @@ rfkill_wwan_filter (GObject *object) return NM_IS_MODEM (object); } +static gboolean +rfkill_wimax_filter (GObject *object) +{ + return NM_IS_WIMAX_DEVICE (object); +} + static void manager_rfkill_update_one_type (NMManager *self, RadioState *rstate, @@ -1484,6 +1494,10 @@ add_device (NMManager *self, NMDevice *device) nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), priv->radio_states[RFKILL_TYPE_WWAN].enabled); */ + } else if (NM_IS_WIMAX_DEVICE (device)) { + nm_manager_rfkill_update (self, RFKILL_TYPE_WIMAX); + nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), + priv->radio_states[RFKILL_TYPE_WIMAX].enabled); } type_desc = nm_device_get_type_desc (device); @@ -2872,6 +2886,7 @@ nm_manager_get (const char *config_file, gboolean initial_net_enabled, gboolean initial_wifi_enabled, gboolean initial_wwan_enabled, + gboolean initial_wimax_enabled, GError **error) { static NMManager *singleton = NULL; @@ -2904,6 +2919,7 @@ nm_manager_get (const char *config_file, priv->radio_states[RFKILL_TYPE_WLAN].enabled = initial_wifi_enabled; priv->radio_states[RFKILL_TYPE_WWAN].enabled = initial_wwan_enabled; + priv->radio_states[RFKILL_TYPE_WIMAX].enabled = initial_wimax_enabled; g_signal_connect (priv->sys_settings, "notify::" NM_SYSCONFIG_SETTINGS_UNMANAGED_SPECS, G_CALLBACK (system_unmanaged_devices_changed_cb), singleton); @@ -3034,6 +3050,11 @@ set_property (GObject *object, guint prop_id, &priv->radio_states[RFKILL_TYPE_WWAN], g_value_get_boolean (value)); break; + case PROP_WIMAX_ENABLED: + manager_set_radio_enabled (NM_MANAGER (object), + &priv->radio_states[RFKILL_TYPE_WIMAX], + g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3064,6 +3085,12 @@ get_property (GObject *object, guint prop_id, case PROP_WWAN_HARDWARE_ENABLED: g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled); break; + case PROP_WIMAX_ENABLED: + g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WIMAX].enabled); + break; + case PROP_WIMAX_HARDWARE_ENABLED: + g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WIMAX].hw_enabled); + break; case PROP_ACTIVE_CONNECTIONS: g_value_take_boxed (value, get_active_connections (self, NULL)); break; @@ -3105,6 +3132,14 @@ nm_manager_init (NMManager *manager) priv->radio_states[RFKILL_TYPE_WWAN].other_enabled_func = nm_manager_get_modem_enabled_state; priv->radio_states[RFKILL_TYPE_WWAN].object_filter_func = rfkill_wwan_filter; + priv->radio_states[RFKILL_TYPE_WIMAX].enabled = TRUE; + priv->radio_states[RFKILL_TYPE_WIMAX].key = "WimaxEnabled"; + priv->radio_states[RFKILL_TYPE_WIMAX].prop = NM_MANAGER_WIMAX_ENABLED; + priv->radio_states[RFKILL_TYPE_WIMAX].hw_prop = NM_MANAGER_WIMAX_HARDWARE_ENABLED; + priv->radio_states[RFKILL_TYPE_WIMAX].desc = "WiMAX"; + priv->radio_states[RFKILL_TYPE_WIMAX].other_enabled_func = NULL; + priv->radio_states[RFKILL_TYPE_WIMAX].object_filter_func = rfkill_wimax_filter; + for (i = 0; i < RFKILL_TYPE_MAX; i++) priv->radio_states[i].hw_enabled = TRUE; @@ -3215,6 +3250,22 @@ nm_manager_class_init (NMManagerClass *manager_class) TRUE, G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_WIMAX_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIMAX_ENABLED, + "WimaxEnabled", + "Is WiMAX enabled", + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property + (object_class, PROP_WIMAX_HARDWARE_ENABLED, + g_param_spec_boolean (NM_MANAGER_WIMAX_HARDWARE_ENABLED, + "WimaxHardwareEnabled", + "Whether WiMAX is disabled by a hardware switch or not", + TRUE, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_ACTIVE_CONNECTIONS, g_param_spec_boxed (NM_MANAGER_ACTIVE_CONNECTIONS, diff --git a/src/nm-manager.h b/src/nm-manager.h index 1090409a9b..bebd9217b7 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -75,6 +75,7 @@ NMManager *nm_manager_get (const char *config_file, gboolean initial_net_enabled, gboolean initial_wifi_enabled, gboolean initial_wwan_enabled, + gboolean initial_wimax_enabled, GError **error); void nm_manager_start (NMManager *manager); diff --git a/src/wimax/nm-wimax-device.c b/src/wimax/nm-wimax-device.c index ffb0ab5fd0..66a7b65c88 100644 --- a/src/wimax/nm-wimax-device.c +++ b/src/wimax/nm-wimax-device.c @@ -38,7 +38,10 @@ static gboolean impl_device_get_nsp_list (NMWimaxDevice *device, GPtrArray **lis #include "nm-wimax-device-glue.h" -G_DEFINE_TYPE (NMWimaxDevice, nm_wimax_device, NM_TYPE_DEVICE) +static void device_interface_init (NMDeviceInterface *iface_class); + +G_DEFINE_TYPE_EXTENDED (NMWimaxDevice, nm_wimax_device, NM_TYPE_DEVICE, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init)) enum { PROP_0, @@ -225,7 +228,7 @@ schedule_rf_state_update (NMWimaxDevice *self) { NMWimaxDevicePrivate *priv = GET_PRIVATE (self); - /* This is scheduled because on startup we get nm_wimax_device_set_enabled() + /* This is scheduled because on startup we get nm_device_interface_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. @@ -235,21 +238,6 @@ schedule_rf_state_update (NMWimaxDevice *self) 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) { @@ -612,6 +600,20 @@ device_state_changed (NMDevice *device, } } +/* NMDeviceInterface interface */ + +static void +real_set_enabled (NMDeviceInterface *device, gboolean enabled) +{ + NMWimaxDevicePrivate *priv = GET_PRIVATE (device); + + if (priv->enabled == enabled) + return; + + priv->enabled = enabled; + schedule_rf_state_update (NM_WIMAX_DEVICE (device)); +} + /* NMDevice methods */ static void @@ -862,6 +864,12 @@ real_deactivate_quickly (NMDevice *device) /* GObject methods */ +static void +device_interface_init (NMDeviceInterface *iface_class) +{ + iface_class->set_enabled = real_set_enabled; +} + static void nm_wimax_device_init (NMWimaxDevice *self) { diff --git a/src/wimax/nm-wimax-device.h b/src/wimax/nm-wimax-device.h index e381dddfc2..301ebdd8db 100644 --- a/src/wimax/nm-wimax-device.h +++ b/src/wimax/nm-wimax-device.h @@ -65,9 +65,6 @@ 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); From b2f9747dba513fd34dac2b427ad1e0ac6ccb31e9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 20 May 2010 01:23:11 -0700 Subject: [PATCH 003/102] wimax: make it build against Intel v1.5 SDK --- src/nm-device-olpc-mesh.c | 4 ++-- src/wimax/nm-wimax-device.c | 33 +++++++++++++++------------------ src/wimax/nm-wimax-manager.c | 16 ++++++---------- src/wimax/nm-wimax-util.c | 6 ++---- src/wimax/nm-wimax-util.h | 3 ++- 5 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index ec9f5394e8..244780d6fa 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -652,7 +652,7 @@ dispose (GObject *object) device_cleanup (self); - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL); if (priv->device_added_id) g_signal_handler_disconnect (manager, priv->device_added_id); g_object_unref (manager); @@ -850,7 +850,7 @@ is_companion (NMDeviceOlpcMesh *self, NMDevice *other) priv->companion = other; /* When we've found the companion, stop listening for other devices */ - manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL); + manager = nm_manager_get (NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL); if (priv->device_added_id) { g_signal_handler_disconnect (manager, priv->device_added_id); priv->device_added_id = 0; diff --git a/src/wimax/nm-wimax-device.c b/src/wimax/nm-wimax-device.c index 6a5aed934a..a98bee7d40 100644 --- a/src/wimax/nm-wimax-device.c +++ b/src/wimax/nm-wimax-device.c @@ -26,7 +26,7 @@ #include "nm-wimax-util.h" #include "nm-device-interface.h" #include "nm-device-private.h" -#include "NetworkManagerSystem.h" +#include "nm-system.h" #include "NetworkManagerUtils.h" #include "nm-properties-changed-signal.h" #include "nm-connection.h" @@ -65,7 +65,7 @@ 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; + WIMAX_API_DEVICE_ID device_id; NMWimaxDevice *object; gboolean enabled; @@ -192,7 +192,6 @@ rf_state_update (NMWimaxDevice *self) 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; @@ -301,7 +300,7 @@ activation_timed_out (gpointer data) } static void -wimax_status_change_cb (struct WIMAX_API_DEVICE_ID *device_id, +wimax_status_change_cb (WIMAX_API_DEVICE_ID *device_id, WIMAX_API_DEVICE_STATUS status, WIMAX_API_STATUS_REASON reason, WIMAX_API_CONNECTION_PROGRESS_INFO progress) @@ -328,7 +327,6 @@ wimax_status_change_cb (struct WIMAX_API_DEVICE_ID *device_id, 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), @@ -359,7 +357,7 @@ remove_all_nsps (NMWimaxDevice *self) static void remove_outdated_nsps (NMWimaxDevice *self, - struct WIMAX_API_NSP_INFO_EX *nsp_list, + WIMAX_API_NSP_INFO_EX *nsp_list, guint32 list_size) { NMWimaxDevicePrivate *priv = GET_PRIVATE (self); @@ -372,7 +370,7 @@ remove_outdated_nsps (NMWimaxDevice *self, gboolean found = FALSE; for (i = 0; i < list_size; i++) { - struct WIMAX_API_NSP_INFO_EX *info = &nsp_list[i]; + WIMAX_API_NSP_INFO_EX *info = &nsp_list[i]; if (!g_strcmp0 (nm_wimax_nsp_get_name (nsp), (char *) info->NSPName)) { found = TRUE; @@ -412,8 +410,8 @@ get_nsp_by_name (NMWimaxDevice *self, const char *name) } static void -wimax_scan_cb (struct WIMAX_API_DEVICE_ID *device_id, - struct WIMAX_API_NSP_INFO_EX *nsp_list, +wimax_scan_cb (WIMAX_API_DEVICE_ID *device_id, + WIMAX_API_NSP_INFO_EX *nsp_list, guint32 list_size, guint32 progress) { @@ -424,7 +422,7 @@ wimax_scan_cb (struct WIMAX_API_DEVICE_ID *device_id, 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]; + WIMAX_API_NSP_INFO_EX *info = &nsp_list[i]; NMWimaxNsp *nsp; gboolean new_nsp; guint32 quality; @@ -454,15 +452,15 @@ wimax_scan_cb (struct WIMAX_API_DEVICE_ID *device_id, } static void -wimax_wide_scan_cb (struct WIMAX_API_DEVICE_ID *device_id, - struct WIMAX_API_NSP_INFO_EX *nsp_list, +wimax_wide_scan_cb (WIMAX_API_DEVICE_ID *device_id, + 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_connect_cb (WIMAX_API_DEVICE_ID *device_id, WIMAX_API_NETWORK_CONNECTION_RESP response) { NMWimaxDevicePrivate *priv = (NMWimaxDevicePrivate *) device_id; @@ -483,7 +481,7 @@ wimax_connect_cb (struct WIMAX_API_DEVICE_ID *device_id, } static void -wimax_disconnect_cb (struct WIMAX_API_DEVICE_ID *device_id, +wimax_disconnect_cb (WIMAX_API_DEVICE_ID *device_id, WIMAX_API_NETWORK_CONNECTION_RESP response) { if (response == WIMAX_API_CONNECTION_SUCCESS) { @@ -635,7 +633,7 @@ static void real_update_hw_address (NMDevice *device) { NMWimaxDevicePrivate *priv = GET_PRIVATE (device); - struct WIMAX_API_DEVICE_INFO info = { 0, }; + WIMAX_API_DEVICE_INFO info = { 0, }; WIMAX_API_RET result; result = GetDeviceInformation (&priv->device_id, &info); @@ -806,7 +804,7 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) g_assert (s_wimax); result = CmdConnectToNetwork (&priv->device_id, - (WIMAX_API_ASTRING) nm_setting_wimax_get_network_name (s_wimax), + (WIMAX_API_WSTRING) nm_setting_wimax_get_network_name (s_wimax), 0, NULL); if (result != WIMAX_API_RET_SUCCESS) { @@ -841,8 +839,7 @@ real_deactivate_quickly (NMDevice *device) 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) { + status == WIMAX_API_DEVICE_STATUS_Data_Connected) { result = CmdDisconnectFromNetwork (&priv->device_id); if (result != WIMAX_API_RET_SUCCESS) diff --git a/src/wimax/nm-wimax-manager.c b/src/wimax/nm-wimax-manager.c index e223ee3d70..e571f96d9d 100644 --- a/src/wimax/nm-wimax-manager.c +++ b/src/wimax/nm-wimax-manager.c @@ -27,7 +27,7 @@ #include "nm-wimax-util.h" typedef struct { - struct WIMAX_API_DEVICE_ID device_id; + WIMAX_API_DEVICE_ID device_id; int refs; } NMWimaxManager; @@ -69,9 +69,8 @@ nm_wimax_manager_unref (NMWimaxManager *manager) } static gboolean -wimax_device_matches (struct WIMAX_API_HW_DEVICE_ID *hw_id, - const char *ifname, - int ifindex) +wimax_device_matches (WIMAX_API_HW_DEVICE_ID *hw_id, + const char *ifname) { const char *device_name; char *s; @@ -91,9 +90,6 @@ wimax_device_matches (struct WIMAX_API_HW_DEVICE_ID *hw_id, if (g_strcmp0 (ifname, hw_ifname)) return FALSE; - if (if_nametoindex (hw_ifname) != ifindex) - return FALSE; - return TRUE; } @@ -103,9 +99,9 @@ nm_wimax_manager_create_device (const char *path, const char *driver) { NMWimaxManager *manager; - struct WIMAX_API_HW_DEVICE_ID device_id_list[5]; + WIMAX_API_HW_DEVICE_ID device_id_list[5]; NMDevice *device = NULL; - gsize device_id_list_size = 5; + guint32 device_id_list_size = 5; WIMAX_API_RET result; g_return_val_if_fail (path != NULL, NULL); @@ -121,7 +117,7 @@ nm_wimax_manager_create_device (const char *path, int i; for (i = 0; i < device_id_list_size; i++) { - if (wimax_device_matches (&device_id_list[i], ifname, ifindex)) { + if (wimax_device_matches (&device_id_list[i], ifname)) { device = nm_wimax_device_new (path, ifname, driver, device_id_list[0].deviceIndex); break; } diff --git a/src/wimax/nm-wimax-util.c b/src/wimax/nm-wimax-util.c index ca1b0dcea8..fcb11f1dc8 100644 --- a/src/wimax/nm-wimax-util.c +++ b/src/wimax/nm-wimax-util.c @@ -23,13 +23,13 @@ #include "nm-utils.h" void -nm_wimax_util_error (struct WIMAX_API_DEVICE_ID *device_id, +nm_wimax_util_error (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; + guint32 str_len = MAX_SIZE_OF_STRING_BUFFER; GetErrorString (device_id, result, str, &str_len); warning_msg = g_strconcat (message, ": %s (%d)", NULL); @@ -109,8 +109,6 @@ nm_wimax_util_device_status_to_str (WIMAX_API_DEVICE_STATUS status) 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 index e40ed46dbf..30c5bb68e6 100644 --- a/src/wimax/nm-wimax-util.h +++ b/src/wimax/nm-wimax-util.h @@ -22,9 +22,10 @@ #define NM_WIMAX_UTIL_H #include +#include #include "nm-wimax-types.h" -void nm_wimax_util_error (struct WIMAX_API_DEVICE_ID *device_id, +void nm_wimax_util_error (WIMAX_API_DEVICE_ID *device_id, const char *message, WIMAX_API_RET result); From 3992c7db507d586ffeffa214edc4b9a399b8b396 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 16:30:00 -0600 Subject: [PATCH 004/102] dhcpcd: prevent dhcpcd from messing with routing (bgo #634983) Since NM is already handling that. --- src/dhcp-manager/nm-dhcp-dhcpcd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index 378a97b611..4fb703c480 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -128,6 +128,8 @@ real_ip4_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) "-L"); /* Disable built-in IPv4LL since we use avahi-autoipd */ + g_ptr_array_add (argv, (gpointer) "-G"); /* Let NM handle routing */ + g_ptr_array_add (argv, (gpointer) "-c"); /* Set script file */ g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH ); From 02a1da41c6bef08e6be3f98f590fa7b97898baee Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 18 Nov 2010 17:02:04 -0600 Subject: [PATCH 005/102] supplicant: convert add/remove to new supplicant dbus interface --- .../nm-supplicant-interface.c | 22 ++++++++++++------- .../nm-supplicant-manager.c | 2 +- .../nm-supplicant-manager.h | 6 ++--- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index bad8f26634..996eb65087 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -37,7 +37,7 @@ #define WPAS_DBUS_IFACE_BSSID WPAS_DBUS_INTERFACE ".BSSID" #define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network" #define WPAS_ERROR_INVALID_IFACE WPAS_DBUS_INTERFACE ".InvalidInterface" -#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".ExistsError" +#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".InterfaceExists" static void wpas_iface_handle_state_change (DBusGProxy *proxy, @@ -580,7 +580,7 @@ interface_get (NMSupplicantInterface *self) DBusGProxyCall *call; info = nm_supplicant_info_new (self, priv->wpas_proxy, priv->other_pcalls); - call = dbus_g_proxy_begin_call (priv->wpas_proxy, "getInterface", + call = dbus_g_proxy_begin_call (priv->wpas_proxy, "GetInterface", interface_get_cb, info, nm_supplicant_info_destroy, @@ -622,7 +622,7 @@ interface_add (NMSupplicantInterface *self, gboolean is_wireless) DBusGProxyCall *call; NMSupplicantInfo *info; GHashTable *hash; - GValue *driver; + GValue *driver, *ifname; /* Can only start the interface from INIT state */ g_return_if_fail (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT); @@ -639,24 +639,30 @@ interface_add (NMSupplicantInterface *self, gboolean is_wireless) info = nm_supplicant_info_new (self, priv->wpas_proxy, priv->other_pcalls); + hash = g_hash_table_new (g_str_hash, g_str_equal); + driver = g_new0 (GValue, 1); g_value_init (driver, G_TYPE_STRING); - g_value_set_string (driver, is_wireless ? "wext" : "wired"); + g_value_set_string (driver, is_wireless ? "nl80211,wext" : "wired"); + g_hash_table_insert (hash, "Driver", driver); - hash = g_hash_table_new (g_str_hash, g_str_equal); - g_hash_table_insert (hash, "driver", driver); + ifname = g_new0 (GValue, 1); + g_value_init (ifname, G_TYPE_STRING); + g_value_set_string (ifname, priv->dev); + g_hash_table_insert (hash, "Ifname", ifname); - call = dbus_g_proxy_begin_call (priv->wpas_proxy, "addInterface", + call = dbus_g_proxy_begin_call (priv->wpas_proxy, "CreateInterface", interface_add_cb, info, nm_supplicant_info_destroy, - G_TYPE_STRING, priv->dev, DBUS_TYPE_G_MAP_OF_VARIANT, hash, G_TYPE_INVALID); g_hash_table_destroy (hash); g_value_unset (driver); g_free (driver); + g_value_unset (ifname); + g_free (ifname); nm_supplicant_info_set_call (info, call); } diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c index 35ef749cb6..19ee5730f9 100644 --- a/src/supplicant-manager/nm-supplicant-manager.c +++ b/src/supplicant-manager/nm-supplicant-manager.c @@ -114,7 +114,7 @@ nm_supplicant_manager_iface_release (NMSupplicantManager *self, /* Ask wpa_supplicant to remove this interface */ op = nm_supplicant_interface_get_object_path (iface); if (priv->running && priv->proxy && op) { - dbus_g_proxy_call_no_reply (priv->proxy, "removeInterface", + dbus_g_proxy_call_no_reply (priv->proxy, "RemoveInterface", DBUS_TYPE_G_OBJECT_PATH, op, G_TYPE_INVALID); } diff --git a/src/supplicant-manager/nm-supplicant-manager.h b/src/supplicant-manager/nm-supplicant-manager.h index e9c31a997b..9e2f3b21b1 100644 --- a/src/supplicant-manager/nm-supplicant-manager.h +++ b/src/supplicant-manager/nm-supplicant-manager.h @@ -26,9 +26,9 @@ #include "nm-supplicant-types.h" #include "nm-device.h" -#define WPAS_DBUS_SERVICE "fi.epitest.hostap.WPASupplicant" -#define WPAS_DBUS_PATH "/fi/epitest/hostap/WPASupplicant" -#define WPAS_DBUS_INTERFACE "fi.epitest.hostap.WPASupplicant" +#define WPAS_DBUS_SERVICE "fi.w1.wpa_supplicant1" +#define WPAS_DBUS_PATH "/fi/w1/wpa_supplicant1" +#define WPAS_DBUS_INTERFACE "fi.w1.wpa_supplicant1" G_BEGIN_DECLS From 3951942fa1f505e5ab2d7802004c8b6708da469e Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Fri, 19 Nov 2010 16:17:40 -0600 Subject: [PATCH 006/102] wired: fix uninitialized variable --- src/nm-device-ethernet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 13139542fa..00e8a2167a 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -295,7 +295,7 @@ _update_s390_subchannels (NMDeviceEthernet *self) const char *iface; GUdevClient *client; GUdevDevice *dev; - GUdevDevice *parent; + GUdevDevice *parent = NULL; const char *parent_path, *item, *driver; const char *subsystems[] = { "net", NULL }; GDir *dir; From 92b58e56f5cc01b484af36623e17ee4ea386e53a Mon Sep 17 00:00:00 2001 From: Mikhail Efremov Date: Fri, 19 Nov 2010 16:52:55 -0600 Subject: [PATCH 007/102] dhcp: ensure that dhcp client is exited On restart ensure that the client we're trying to kill has actually exited even if it's not our child. --- src/dhcp-manager/nm-dhcp-client.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 0c7f3d49b5..3a8b194081 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -156,11 +156,15 @@ stop_process (GPid pid, const char *iface) if (ret == -1) { /* Child already exited */ - if (errno == ECHILD) + if (errno == ECHILD) { + /* Was it really our child and it exited? */ + if (kill (pid, 0) < 0 && errno == ESRCH) + break; + } else { + /* Took too long; shoot it in the head */ + i = 0; break; - /* Took too long; shoot it in the head */ - i = 0; - break; + } } g_usleep (G_USEC_PER_SEC / 5); } From 528e0876082f563e6fbafc3f7c2c44c5ef184750 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 22 Nov 2010 08:22:50 -0600 Subject: [PATCH 008/102] wifi: handle new supplicant AP property formats --- src/nm-wifi-ap.c | 169 +++++++++++++++++++++++++++-------------------- src/nm-wifi-ap.h | 4 -- 2 files changed, 97 insertions(+), 76 deletions(-) diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c index 7770b8bc42..642b6d978e 100644 --- a/src/nm-wifi-ap.c +++ b/src/nm-wifi-ap.c @@ -369,10 +369,69 @@ NMAccessPoint *nm_ap_new (void) return (NMAccessPoint *) object; } +static guint32 +pair_to_flags (const char *str) +{ + g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE); -#define IEEE80211_CAP_ESS 0x0001 -#define IEEE80211_CAP_IBSS 0x0002 -#define IEEE80211_CAP_PRIVACY 0x0010 + if (strcmp (str, "wep40") == 0) + return NM_802_11_AP_SEC_PAIR_WEP40; + if (strcmp (str, "wep104") == 0) + return NM_802_11_AP_SEC_PAIR_WEP104; + if (strcmp (str, "tkip") == 0) + return NM_802_11_AP_SEC_PAIR_TKIP; + if (strcmp (str, "ccmp") == 0) + return NM_802_11_AP_SEC_PAIR_CCMP; + return NM_802_11_AP_SEC_NONE; +} + +static guint32 +group_to_flags (const char *str) +{ + g_return_val_if_fail (str != NULL, NM_802_11_AP_SEC_NONE); + + if (strcmp (str, "wep40") == 0) + return NM_802_11_AP_SEC_GROUP_WEP40; + if (strcmp (str, "wep104") == 0) + return NM_802_11_AP_SEC_GROUP_WEP104; + if (strcmp (str, "tkip") == 0) + return NM_802_11_AP_SEC_GROUP_TKIP; + if (strcmp (str, "ccmp") == 0) + return NM_802_11_AP_SEC_GROUP_CCMP; + return NM_802_11_AP_SEC_NONE; +} + +static guint32 +security_from_dict (GHashTable *security) +{ + GValue *value; + guint32 flags = NM_802_11_AP_SEC_NONE; + const char **items, **iter; + + value = g_hash_table_lookup (security, "KeyMgmt"); + if (value) { + items = g_value_get_boxed (value); + for (iter = items; iter && *iter; iter++) { + if (strcmp (*iter, "wpa-psk") == 0) + flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK; + else if (strcmp (*iter, "wpa-eap") == 0) + flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X; + } + } + + value = g_hash_table_lookup (security, "Pairwise"); + if (value) { + items = g_value_get_boxed (value); + for (iter = items; iter && *iter; iter++) + flags |= pair_to_flags (*iter); + } + + value = g_hash_table_lookup (security, "Group"); + if (value) + flags |= group_to_flags (g_value_get_string (value)); + + return flags; +} static void foreach_property_cb (gpointer key, gpointer value, gpointer user_data) @@ -383,9 +442,9 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) if (G_VALUE_HOLDS_BOXED (variant)) { GArray *array = g_value_get_boxed (variant); - if (!strcmp (key, "ssid")) { + if (!strcmp (key, "SSID")) { guint32 len = MIN (IW_ESSID_MAX_SIZE, array->len); - GByteArray * ssid; + GByteArray *ssid; /* Stupid ieee80211 layer uses */ if (((len == 8) || (len == 9)) @@ -399,7 +458,7 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) g_byte_array_append (ssid, (const guint8 *) array->data, len); nm_ap_set_ssid (ap, ssid); g_byte_array_free (ssid, TRUE); - } else if (!strcmp (key, "bssid")) { + } else if (!strcmp (key, "BSSID")) { struct ether_addr addr; if (array->len != ETH_ALEN) @@ -407,43 +466,49 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) memset (&addr, 0, sizeof (struct ether_addr)); memcpy (&addr, array->data, ETH_ALEN); nm_ap_set_address (ap, &addr); - } else if (!strcmp (key, "wpaie")) { - guint8 * ie = (guint8 *) array->data; + } else if (!strcmp (key, "Rates")) { + guint32 maxrate = 0; + int i; + + /* Find the max AP rate */ + for (i = 0; i < array->len; i++) { + guint32 r = g_array_index (array, guint32, i); + + if (r > maxrate) { + maxrate = r; + nm_ap_set_max_bitrate (ap, r / 1000); + } + } + } else if (!strcmp (key, "WPA")) { guint32 flags = nm_ap_get_wpa_flags (ap); - if (array->len <= 0 || array->len > WPA_MAX_IE_LEN) - return; - flags = nm_ap_add_security_from_ie (flags, ie, array->len); + flags |= security_from_dict (g_value_get_boxed (variant)); nm_ap_set_wpa_flags (ap, flags); - } else if (!strcmp (key, "rsnie")) { - guint8 * ie = (guint8 *) array->data; + } else if (!strcmp (key, "RSN")) { guint32 flags = nm_ap_get_rsn_flags (ap); - if (array->len <= 0 || array->len > WPA_MAX_IE_LEN) - return; - flags = nm_ap_add_security_from_ie (flags, ie, array->len); + flags |= security_from_dict (g_value_get_boxed (variant)); nm_ap_set_rsn_flags (ap, flags); } - } else if (G_VALUE_HOLDS_INT (variant)) { - gint32 int_val = g_value_get_int (variant); - - if (!strcmp (key, "frequency")) { - nm_ap_set_freq (ap, (guint32) int_val); - } else if (!strcmp (key, "maxrate")) { - /* Supplicant reports as b/s, we use Kb/s internally */ - nm_ap_set_max_bitrate (ap, int_val / 1000); - } } else if (G_VALUE_HOLDS_UINT (variant)) { guint32 val = g_value_get_uint (variant); - if (!strcmp (key, "capabilities")) { - if (val & IEEE80211_CAP_ESS) { - nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); - } else if (val & IEEE80211_CAP_IBSS) { - nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); - } + if (!strcmp (key, "Frequency")) + nm_ap_set_freq (ap, val); + } else if (G_VALUE_HOLDS_STRING (variant)) { + const char *val = g_value_get_string (variant); - if (val & IEEE80211_CAP_PRIVACY) { + if (val && !strcmp (key, "Mode")) { + if (strcmp (val, "infrastructure") == 0) + nm_ap_set_mode (ap, NM_802_11_MODE_INFRA); + else if (strcmp (val, "ad-hoc") == 0) + nm_ap_set_mode (ap, NM_802_11_MODE_ADHOC); + } + } else if (G_VALUE_HOLDS_BOOLEAN (variant)) { + gboolean val = g_value_get_boolean (variant); + + if (strcmp (key, "Privacy") == 0) { + if (val) { guint32 flags = nm_ap_get_flags (ap); nm_ap_set_flags (ap, flags | NM_802_11_AP_FLAGS_PRIVACY); } @@ -451,7 +516,6 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) } } - NMAccessPoint * nm_ap_new_from_properties (GHashTable *properties) { @@ -1170,45 +1234,6 @@ void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list) } -guint32 -nm_ap_add_security_from_ie (guint32 flags, - const guint8 *wpa_ie, - guint32 length) -{ - wpa_ie_data * cap_data; - - if (!(cap_data = wpa_parse_wpa_ie (wpa_ie, length))) - return NM_802_11_AP_SEC_NONE; - - /* Pairwise cipher flags */ - if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_WEP40) - flags |= NM_802_11_AP_SEC_PAIR_WEP40; - if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_WEP104) - flags |= NM_802_11_AP_SEC_PAIR_WEP104; - if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_TKIP) - flags |= NM_802_11_AP_SEC_PAIR_TKIP; - if (cap_data->pairwise_cipher & IW_AUTH_CIPHER_CCMP) - flags |= NM_802_11_AP_SEC_PAIR_CCMP; - - /* Group cipher flags */ - if (cap_data->group_cipher & IW_AUTH_CIPHER_WEP40) - flags |= NM_802_11_AP_SEC_GROUP_WEP40; - if (cap_data->group_cipher & IW_AUTH_CIPHER_WEP104) - flags |= NM_802_11_AP_SEC_GROUP_WEP104; - if (cap_data->group_cipher & IW_AUTH_CIPHER_TKIP) - flags |= NM_802_11_AP_SEC_GROUP_TKIP; - if (cap_data->group_cipher & IW_AUTH_CIPHER_CCMP) - flags |= NM_802_11_AP_SEC_GROUP_CCMP; - - if (cap_data->key_mgmt & IW_AUTH_KEY_MGMT_802_1X) - flags |= NM_802_11_AP_SEC_KEY_MGMT_802_1X; - if (cap_data->key_mgmt & IW_AUTH_KEY_MGMT_PSK) - flags |= NM_802_11_AP_SEC_KEY_MGMT_PSK; - - g_slice_free (wpa_ie_data, cap_data); - return flags; -} - gboolean nm_ap_check_compatible (NMAccessPoint *self, NMConnection *connection) diff --git a/src/nm-wifi-ap.h b/src/nm-wifi-ap.h index 86b785a316..09c87d970a 100644 --- a/src/nm-wifi-ap.h +++ b/src/nm-wifi-ap.h @@ -110,10 +110,6 @@ void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created); GSList * nm_ap_get_user_addresses (const NMAccessPoint *ap); void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list); -guint32 nm_ap_add_security_from_ie (guint32 flags, - const guint8 *wpa_ie, - guint32 length); - gboolean nm_ap_check_compatible (NMAccessPoint *self, NMConnection *connection); From 8bbbd3edc30dd44f13d6b468d162696b6ab3d1cc Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 22 Nov 2010 08:25:09 -0600 Subject: [PATCH 009/102] wifi: convert AP handling to new supplicant interface --- src/nm-device-wifi.c | 60 +-- .../nm-supplicant-interface.c | 472 +++++++----------- .../nm-supplicant-interface.h | 20 +- 3 files changed, 224 insertions(+), 328 deletions(-) diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 49529708b2..3644ccfc4c 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -188,17 +188,13 @@ static void supplicant_iface_state_cb (NMSupplicantInterface *iface, guint32 old_state, gpointer user_data); -static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface, - GHashTable *properties, - NMDeviceWifi * self); +static void supplicant_iface_new_bss_cb (NMSupplicantInterface * iface, + GHashTable *properties, + NMDeviceWifi * self); -static void supplicant_iface_scan_request_result_cb (NMSupplicantInterface * iface, - gboolean success, - NMDeviceWifi * self); - -static void supplicant_iface_scan_results_cb (NMSupplicantInterface * iface, - guint32 num_bssids, - NMDeviceWifi * self); +static void supplicant_iface_scan_done_cb (NMSupplicantInterface * iface, + gboolean success, + NMDeviceWifi * self); static void supplicant_iface_notify_scanning_cb (NMSupplicantInterface * iface, GParamSpec * pspec, @@ -646,26 +642,20 @@ supplicant_interface_acquire (NMDeviceWifi *self) memset (priv->supplicant.sig_ids, 0, sizeof (priv->supplicant.sig_ids)); id = g_signal_connect (priv->supplicant.iface, - "state", + NM_SUPPLICANT_INTERFACE_STATE, G_CALLBACK (supplicant_iface_state_cb), self); priv->supplicant.sig_ids[i++] = id; id = g_signal_connect (priv->supplicant.iface, - "scanned-ap", - G_CALLBACK (supplicant_iface_scanned_ap_cb), + NM_SUPPLICANT_INTERFACE_NEW_BSS, + G_CALLBACK (supplicant_iface_new_bss_cb), self); priv->supplicant.sig_ids[i++] = id; id = g_signal_connect (priv->supplicant.iface, - "scan-req-result", - G_CALLBACK (supplicant_iface_scan_request_result_cb), - self); - priv->supplicant.sig_ids[i++] = id; - - id = g_signal_connect (priv->supplicant.iface, - "scan-results", - G_CALLBACK (supplicant_iface_scan_results_cb), + NM_SUPPLICANT_INTERFACE_SCAN_DONE, + G_CALLBACK (supplicant_iface_scan_done_cb), self); priv->supplicant.sig_ids[i++] = id; @@ -1910,28 +1900,19 @@ cancel_pending_scan (NMDeviceWifi *self) } } - static void -supplicant_iface_scan_request_result_cb (NMSupplicantInterface *iface, - gboolean success, - NMDeviceWifi *self) +supplicant_iface_scan_done_cb (NMSupplicantInterface *iface, + gboolean success, + NMDeviceWifi *self) { - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan request %s", + nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan %s", nm_device_get_iface (NM_DEVICE (self)), success ? "successful" : "failed"); if (check_scanning_allowed (self)) schedule_scan (self, TRUE); -} -static void -supplicant_iface_scan_results_cb (NMSupplicantInterface *iface, - guint32 num_results, - NMDeviceWifi *self) -{ - nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan results available (%d APs found)", - nm_device_get_iface (NM_DEVICE (self)), - num_results); +#if 0 if (num_results == 0) { /* ensure that old APs get culled, which otherwise only * happens when there are actual scan results to process. @@ -1939,6 +1920,7 @@ supplicant_iface_scan_results_cb (NMSupplicantInterface *iface, cull_scan_list (self); nm_device_wifi_ap_list_print (self); } +#endif } static gboolean @@ -2197,9 +2179,9 @@ set_ap_strength_from_properties (NMDeviceWifi *self, } static void -supplicant_iface_scanned_ap_cb (NMSupplicantInterface *iface, - GHashTable *properties, - NMDeviceWifi *self) +supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, + GHashTable *properties, + NMDeviceWifi *self) { NMDeviceState state; NMAccessPoint *ap; @@ -3075,7 +3057,7 @@ real_act_stage2_config (NMDevice *dev, NMDeviceStateReason *reason) /* Hook up error signal handler to capture association errors */ id = g_signal_connect (priv->supplicant.iface, - "connection-error", + NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR, G_CALLBACK (supplicant_iface_connection_error_cb), self); priv->supplicant.iface_error_id = id; diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 996eb65087..ae6630ea67 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -34,24 +34,21 @@ #include "nm-glib-compat.h" #define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface" -#define WPAS_DBUS_IFACE_BSSID WPAS_DBUS_INTERFACE ".BSSID" +#define WPAS_DBUS_IFACE_BSS WPAS_DBUS_INTERFACE ".BSS" #define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network" #define WPAS_ERROR_INVALID_IFACE WPAS_DBUS_INTERFACE ".InvalidInterface" #define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".InterfaceExists" - -static void wpas_iface_handle_state_change (DBusGProxy *proxy, - const char *str_new_state, - const char *str_old_state, - gpointer user_data); - -static void wpas_iface_handle_scanning (DBusGProxy *proxy, - gboolean scanning, - gpointer user_data); - - G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT) +static void wpas_iface_properties_changed (DBusGProxy *proxy, + GHashTable *props, + gpointer user_data); + +static void wpas_iface_scan_done (DBusGProxy *proxy, + gboolean success, + gpointer user_data); + #define NM_SUPPLICANT_INTERFACE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ NM_TYPE_SUPPLICANT_INTERFACE, \ NMSupplicantInterfacePrivate)) @@ -60,9 +57,8 @@ G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT) enum { STATE, /* change in the interface's state */ REMOVED, /* interface was removed by the supplicant */ - SCANNED_AP, /* interface saw a new access point from a scan */ - SCAN_REQ_RESULT, /* result of a wireless scan request */ - SCAN_RESULTS, /* scan results returned from supplicant */ + NEW_BSS, /* interface saw a new access point from a scan */ + SCAN_DONE, /* wifi scan is complete */ CONNECTION_ERROR, /* an error occurred during a connection request */ LAST_SIGNAL }; @@ -72,7 +68,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; /* Properties */ enum { PROP_0 = 0, - PROP_STATE, PROP_SCANNING, LAST_PROP }; @@ -94,9 +89,9 @@ typedef struct { DBusGProxy * wpas_proxy; DBusGProxy * iface_proxy; + DBusGProxy * props_proxy; DBusGProxy * net_proxy; - guint scan_results_timeout; guint32 last_scan; NMSupplicantConfig * cfg; @@ -199,143 +194,80 @@ static void bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; - GError *err = NULL; - GHashTable *hash = NULL; + GError *error = NULL; + GHashTable *props = NULL; - if (!dbus_g_proxy_end_call (proxy, call_id, &err, - DBUS_TYPE_G_MAP_OF_VARIANT, &hash, - G_TYPE_INVALID)) { - if (!strstr (err->message, "The BSSID requested was invalid")) { + if (dbus_g_proxy_end_call (proxy, call_id, &error, + DBUS_TYPE_G_MAP_OF_VARIANT, &props, + G_TYPE_INVALID)) { + g_signal_emit (info->interface, signals[NEW_BSS], 0, props); + g_hash_table_destroy (props); + } else { + if (!strstr (error->message, "The BSSID requested was invalid")) { nm_log_warn (LOGD_SUPPLICANT, "Couldn't retrieve BSSID properties: %s.", - err->message); + error->message); } - g_error_free (err); - } else { - g_signal_emit (info->interface, signals[SCANNED_AP], 0, hash); - g_hash_table_destroy (hash); + g_error_free (error); } } static void -request_bssid_properties (NMSupplicantInterface * self, - const char * op) +request_bss_properties (NMSupplicantInterface *self, + GPtrArray *paths) { NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - NMSupplicantInfo *info; - DBusGProxy *proxy; - DBusGProxyCall *call; + int i; - proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), - WPAS_DBUS_SERVICE, - op, - WPAS_DBUS_IFACE_BSSID); - info = nm_supplicant_info_new (self, proxy, priv->other_pcalls); - call = dbus_g_proxy_begin_call (proxy, "properties", - bssid_properties_cb, - info, - nm_supplicant_info_destroy, - G_TYPE_INVALID); - nm_supplicant_info_set_call (info, call); - g_object_unref (proxy); -} + /* Fire off a "properties" call for each returned BSSID */ + for (i = 0; i < paths->len; i++) { + NMSupplicantInfo *info; + DBusGProxy *proxy; + DBusGProxyCall *call; -static void -scan_results_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - GError *err = NULL; - GPtrArray *array = NULL; - - if (!dbus_g_proxy_end_call (proxy, call_id, &err, - DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &array, - G_TYPE_INVALID)) { - nm_log_warn (LOGD_SUPPLICANT, "could not get scan results: %s.", err->message); - g_error_free (err); - } else { - int i; - NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; - - /* Notify listeners of the result of the scan */ - g_signal_emit (info->interface, signals[SCAN_RESULTS], 0, array->len); - - /* Fire off a "properties" call for each returned BSSID */ - for (i = 0; i < array->len; i++) { - char *op = g_ptr_array_index (array, i); - - request_bssid_properties (info->interface, op); - g_free (op); - } - - g_ptr_array_free (array, TRUE); + proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + g_ptr_array_index (paths, i), + DBUS_INTERFACE_PROPERTIES); + info = nm_supplicant_info_new (self, proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (proxy, "GetAll", + bssid_properties_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_STRING, WPAS_DBUS_IFACE_BSS, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); + g_object_unref (proxy); } } -static gboolean -request_scan_results (gpointer user_data) -{ - NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - NMSupplicantInfo *info; - DBusGProxyCall *call; - GTimeVal cur_time; - - priv->scan_results_timeout = 0; - - g_return_val_if_fail (priv->iface_proxy != NULL, FALSE); - - info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); - call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanResults", - scan_results_cb, - info, - nm_supplicant_info_destroy, - G_TYPE_INVALID); - nm_supplicant_info_set_call (info, call); - - g_get_current_time (&cur_time); - priv->last_scan = cur_time.tv_sec; - return FALSE; -} - static void -wpas_iface_query_scan_results (DBusGProxy *proxy, gpointer user_data) +wpas_iface_bss_added (DBusGProxy *proxy, + const char *object_path, + GHashTable *props, + gpointer user_data) { - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data); - GTimeVal cur_time; - - /* Only query scan results if a query is not queued */ - if (priv->scan_results_timeout) - return; - - g_get_current_time (&cur_time); - - /* Only fetch scan results every 4s max, but initially do it right away */ - if (priv->last_scan + 4 < cur_time.tv_sec) { - priv->scan_results_timeout = g_idle_add (request_scan_results, - user_data); - } else { - priv->scan_results_timeout = - g_timeout_add_seconds ((4 - (cur_time.tv_sec - priv->last_scan)), - request_scan_results, user_data); - } +g_message ("%s: here op %s props %p", __func__, object_path, props); + g_signal_emit (NM_SUPPLICANT_INTERFACE (user_data), signals[NEW_BSS], 0, props); } static int wpas_state_string_to_enum (const char *str_state) { - if (!strcmp (str_state, "DISCONNECTED")) + if (!strcmp (str_state, "disconnected")) return NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED; - else if (!strcmp (str_state, "INACTIVE")) + else if (!strcmp (str_state, "inactive")) return NM_SUPPLICANT_INTERFACE_STATE_INACTIVE; - else if (!strcmp (str_state, "SCANNING")) + else if (!strcmp (str_state, "scanning")) return NM_SUPPLICANT_INTERFACE_STATE_SCANNING; - else if (!strcmp (str_state, "ASSOCIATING")) + else if (!strcmp (str_state, "associating")) return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATING; - else if (!strcmp (str_state, "ASSOCIATED")) + else if (!strcmp (str_state, "associated")) return NM_SUPPLICANT_INTERFACE_STATE_ASSOCIATED; - else if (!strcmp (str_state, "4WAY_HANDSHAKE")) + else if (!strcmp (str_state, "4way_handshake")) return NM_SUPPLICANT_INTERFACE_STATE_4WAY_HANDSHAKE; - else if (!strcmp (str_state, "GROUP_HANDSHAKE")) + else if (!strcmp (str_state, "group_handshake")) return NM_SUPPLICANT_INTERFACE_STATE_GROUP_HANDSHAKE; - else if (!strcmp (str_state, "COMPLETED")) + else if (!strcmp (str_state, "completed")) return NM_SUPPLICANT_INTERFACE_STATE_COMPLETED; return -1; @@ -372,18 +304,16 @@ set_state (NMSupplicantInterface *self, guint32 new_state) if (priv->iface_proxy) { dbus_g_proxy_disconnect_signal (priv->iface_proxy, - "StateChange", - G_CALLBACK (wpas_iface_handle_state_change), + "PropertiesChanged", + G_CALLBACK (wpas_iface_properties_changed), self); - dbus_g_proxy_disconnect_signal (priv->iface_proxy, - "ScanResultsAvailable", - G_CALLBACK (wpas_iface_query_scan_results), + "ScanDone", + G_CALLBACK (wpas_iface_scan_done), self); - dbus_g_proxy_disconnect_signal (priv->iface_proxy, - "Scanning", - G_CALLBACK (wpas_iface_handle_scanning), + "BSSAdded", + G_CALLBACK (wpas_iface_bss_added), self); } } @@ -392,103 +322,32 @@ set_state (NMSupplicantInterface *self, guint32 new_state) g_signal_emit (self, signals[STATE], 0, priv->state, old_state); } -/* Supplicant state signal handler */ static void -wpas_iface_handle_state_change (DBusGProxy *proxy, - const char *str_new_state, - const char *str_old_state, - gpointer user_data) +set_state_from_string (NMSupplicantInterface *self, const char *new_state) { - int enum_state = wpas_state_string_to_enum (str_new_state); + int state; - g_return_if_fail (enum_state > 0); - - set_state (NM_SUPPLICANT_INTERFACE (user_data), (guint32) enum_state); -} - -/* Explicit state request reply handler */ -static void -iface_state_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; - GError *err = NULL; - char *state_str = NULL; - int enum_state; - - if (!dbus_g_proxy_end_call (proxy, call_id, &err, - G_TYPE_STRING, &state_str, - G_TYPE_INVALID)) { - nm_log_warn (LOGD_SUPPLICANT, "could not get interface state: %s.", err->message); - g_error_free (err); - } else { - enum_state = wpas_state_string_to_enum (state_str); - g_warn_if_fail (enum_state > 0); - - if (enum_state > 0) - set_state (info->interface, (guint32) enum_state); - g_free (state_str); - } + state = wpas_state_string_to_enum (new_state); + g_warn_if_fail (state > 0); + if (state > 0) + set_state (self, (guint32) state); } static void -wpas_iface_get_state (NMSupplicantInterface *self) +set_scanning (NMSupplicantInterface *self, gboolean new_scanning) { NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - NMSupplicantInfo *info; - DBusGProxyCall *call; + GTimeVal cur_time; - info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); - call = dbus_g_proxy_begin_call (priv->iface_proxy, "state", - iface_state_cb, - info, - nm_supplicant_info_destroy, - G_TYPE_INVALID); - nm_supplicant_info_set_call (info, call); -} + if (priv->scanning != new_scanning) { + priv->scanning = new_scanning; -static void -iface_scanning_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) -{ - NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); - gboolean scanning = FALSE; - - if (dbus_g_proxy_end_call (proxy, call_id, NULL, - G_TYPE_BOOLEAN, &scanning, - G_TYPE_INVALID)) { - if (scanning != priv->scanning) { - priv->scanning = scanning; - g_object_notify (G_OBJECT (info->interface), "scanning"); + /* Cache time of last scan completion */ + if (priv->scanning == FALSE) { + g_get_current_time (&cur_time); + priv->last_scan = cur_time.tv_sec; } - } -} -static void -wpas_iface_get_scanning (NMSupplicantInterface *self) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - NMSupplicantInfo *info; - DBusGProxyCall *call; - - info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); - call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanning", - iface_scanning_cb, - info, - nm_supplicant_info_destroy, - G_TYPE_INVALID); - nm_supplicant_info_set_call (info, call); -} - -static void -wpas_iface_handle_scanning (DBusGProxy *proxy, - gboolean scanning, - gpointer user_data) -{ - NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - - if (scanning != priv->scanning) { - priv->scanning = scanning; g_object_notify (G_OBJECT (self), "scanning"); } } @@ -508,6 +367,78 @@ nm_supplicant_interface_get_scanning (NMSupplicantInterface *self) return FALSE; } +static void +wpas_iface_scan_done (DBusGProxy *proxy, + gboolean success, + gpointer user_data) +{ + NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + GTimeVal cur_time; + + /* Cache last scan completed time */ + g_get_current_time (&cur_time); + priv->last_scan = cur_time.tv_sec; + + g_signal_emit (self, signals[SCAN_DONE], 0, success); +} + +static void +wpas_iface_properties_changed (DBusGProxy *proxy, + GHashTable *props, + gpointer user_data) +{ + NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); + GValue *value; + + value = g_hash_table_lookup (props, "Scanning"); + if (value && G_VALUE_HOLDS_BOOLEAN (value)) + set_scanning (self, g_value_get_boolean (value)); + + value = g_hash_table_lookup (props, "State"); + if (value && G_VALUE_HOLDS_STRING (value)) + set_state_from_string (self, g_value_get_string (value)); + + value = g_hash_table_lookup (props, "BSSs"); + if (value && G_VALUE_HOLDS (value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) + request_bss_properties (self, g_value_get_boxed (value)); +} + +static void +iface_get_props_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GHashTable *props = NULL; + GError *error = NULL; + + if (dbus_g_proxy_end_call (proxy, call_id, &error, + DBUS_TYPE_G_MAP_OF_VARIANT, &props, + G_TYPE_INVALID)) { + wpas_iface_properties_changed (NULL, props, info->interface); + } else { + nm_log_warn (LOGD_SUPPLICANT, "could not get interface properties: %s.", + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); + } +} + +static void +wpas_iface_get_props (NMSupplicantInterface *self) +{ + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxyCall *call; + + info = nm_supplicant_info_new (self, priv->props_proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (priv->props_proxy, "GetAll", + iface_get_props_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); +} + static void interface_add_done (NMSupplicantInterface *self, char *path) { @@ -522,31 +453,38 @@ interface_add_done (NMSupplicantInterface *self, char *path) path, WPAS_DBUS_IFACE_INTERFACE); - dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_STRING, + dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, - G_TYPE_STRING, G_TYPE_STRING, + DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); - dbus_g_proxy_add_signal (priv->iface_proxy, "StateChange", G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->iface_proxy, "StateChange", - G_CALLBACK (wpas_iface_handle_state_change), + dbus_g_proxy_add_signal (priv->iface_proxy, "PropertiesChanged", + DBUS_TYPE_G_MAP_OF_VARIANT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->iface_proxy, "PropertiesChanged", + G_CALLBACK (wpas_iface_properties_changed), + self, NULL); + + dbus_g_proxy_add_signal (priv->iface_proxy, "ScanDone", G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanDone", + G_CALLBACK (wpas_iface_scan_done), self, NULL); - dbus_g_proxy_add_signal (priv->iface_proxy, "ScanResultsAvailable", G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->iface_proxy, "ScanResultsAvailable", - G_CALLBACK (wpas_iface_query_scan_results), + dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED, + G_TYPE_NONE, + G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT, + G_TYPE_INVALID); + dbus_g_proxy_add_signal (priv->iface_proxy, "BSSAdded", G_TYPE_INVALID); + dbus_g_proxy_connect_signal (priv->iface_proxy, "BSSAdded", + G_CALLBACK (wpas_iface_bss_added), self, NULL); - dbus_g_proxy_add_signal (priv->iface_proxy, "Scanning", G_TYPE_BOOLEAN, G_TYPE_INVALID); - dbus_g_proxy_connect_signal (priv->iface_proxy, "Scanning", - G_CALLBACK (wpas_iface_handle_scanning), - self, - NULL); - - /* Interface added to the supplicant; get its initial state. */ - wpas_iface_get_state (self); - wpas_iface_get_scanning (self); + priv->props_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + path, + DBUS_INTERFACE_PROPERTIES); + /* Get initial properties */ + wpas_iface_get_props (self); set_state (self, NM_SUPPLICANT_INTERFACE_STATE_READY); } @@ -743,7 +681,7 @@ nm_supplicant_interface_disconnect (NMSupplicantInterface * self) /* Remove any network that was added by NetworkManager */ if (priv->net_proxy) { - dbus_g_proxy_begin_call (priv->iface_proxy, "removeNetwork", + dbus_g_proxy_begin_call (priv->iface_proxy, "RemoveNetwork", remove_network_cb, NULL, NULL, DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (priv->net_proxy), @@ -753,7 +691,7 @@ nm_supplicant_interface_disconnect (NMSupplicantInterface * self) priv->net_proxy = NULL; } - dbus_g_proxy_begin_call (priv->iface_proxy, "disconnect", + dbus_g_proxy_begin_call (priv->iface_proxy, "Disconnect", disconnect_cb, NULL, NULL, G_TYPE_INVALID); @@ -789,7 +727,7 @@ set_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) DBusGProxyCall *call; info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls); - call = dbus_g_proxy_begin_call (priv->iface_proxy, "selectNetwork", + call = dbus_g_proxy_begin_call (priv->iface_proxy, "SelectNetwork", select_network_cb, info, nm_supplicant_info_destroy, @@ -1002,17 +940,12 @@ scan_request_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; GError *err = NULL; - guint32 success = 0; - if (!dbus_g_proxy_end_call (proxy, call_id, &err, - G_TYPE_UINT, &success, - G_TYPE_INVALID)) { + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) { nm_log_warn (LOGD_SUPPLICANT, "Could not get scan request result: %s", err->message); - g_error_free (err); } - - /* Notify listeners of the result of the scan */ - g_signal_emit (info->interface, signals[SCAN_REQ_RESULT], 0, !!success); + g_signal_emit (info->interface, signals[SCAN_DONE], 0, err ? FALSE : TRUE); + g_clear_error (&err); } gboolean @@ -1180,9 +1113,6 @@ get_property (GObject *object, GParamSpec *pspec) { switch (prop_id) { - case PROP_STATE: - g_value_set_uint (value, NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object)->state); - break; case PROP_SCANNING: g_value_set_boolean (value, NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object)->scanning); break; @@ -1210,6 +1140,9 @@ dispose (GObject *object) cancel_all_callbacks (priv->assoc_pcalls); nm_call_store_destroy (priv->assoc_pcalls); + if (priv->props_proxy) + g_object_unref (priv->props_proxy); + if (priv->iface_proxy) g_object_unref (priv->iface_proxy); @@ -1219,9 +1152,6 @@ dispose (GObject *object) if (priv->wpas_proxy) g_object_unref (priv->wpas_proxy); - if (priv->scan_results_timeout) - g_source_remove (priv->scan_results_timeout); - if (priv->smgr) { if (priv->smgr_avail_id) g_signal_handler_disconnect (priv->smgr, priv->smgr_avail_id); @@ -1254,15 +1184,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) object_class->get_property = get_property; /* Properties */ - g_object_class_install_property (object_class, PROP_STATE, - g_param_spec_uint ("state", - "State", - "State of the supplicant interface", - NM_SUPPLICANT_INTERFACE_STATE_INIT, - NM_SUPPLICANT_INTERFACE_STATE_LAST - 1, - NM_SUPPLICANT_INTERFACE_STATE_INIT, - G_PARAM_READABLE)); - g_object_class_install_property (object_class, PROP_SCANNING, g_param_spec_boolean ("scanning", "Scanning", @@ -1272,7 +1193,7 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) /* Signals */ signals[STATE] = - g_signal_new ("state", + g_signal_new (NM_SUPPLICANT_INTERFACE_STATE, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NMSupplicantInterfaceClass, state), @@ -1281,7 +1202,7 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); signals[REMOVED] = - g_signal_new ("removed", + g_signal_new (NM_SUPPLICANT_INTERFACE_REMOVED, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NMSupplicantInterfaceClass, removed), @@ -1289,35 +1210,26 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - signals[SCANNED_AP] = - g_signal_new ("scanned-ap", + signals[NEW_BSS] = + g_signal_new (NM_SUPPLICANT_INTERFACE_NEW_BSS, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scanned_ap), + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, new_bss), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - signals[SCAN_REQ_RESULT] = - g_signal_new ("scan-req-result", + signals[SCAN_DONE] = + g_signal_new (NM_SUPPLICANT_INTERFACE_SCAN_DONE, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_req_result), + G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_done), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - signals[SCAN_RESULTS] = - g_signal_new ("scan-results", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (NMSupplicantInterfaceClass, scan_results), - NULL, NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, 1, G_TYPE_UINT); - signals[CONNECTION_ERROR] = - g_signal_new ("connection-error", + g_signal_new (NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR, G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (NMSupplicantInterfaceClass, connection_error), diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h index 9471bd771b..44c92f19c6 100644 --- a/src/supplicant-manager/nm-supplicant-interface.h +++ b/src/supplicant-manager/nm-supplicant-interface.h @@ -53,6 +53,12 @@ enum { #define NM_IS_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_INTERFACE)) #define NM_SUPPLICANT_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass)) +#define NM_SUPPLICANT_INTERFACE_STATE "state" +#define NM_SUPPLICANT_INTERFACE_REMOVED "removed" +#define NM_SUPPLICANT_INTERFACE_NEW_BSS "new-bss" +#define NM_SUPPLICANT_INTERFACE_SCAN_DONE "scan-done" +#define NM_SUPPLICANT_INTERFACE_CONNECTION_ERROR "connection-error" + struct _NMSupplicantInterface { GObject parent; }; @@ -70,18 +76,14 @@ typedef struct { /* interface was removed by the supplicant */ void (*removed) (NMSupplicantInterface * iface); - /* interface saw a new access point from a scan */ - void (*scanned_ap) (NMSupplicantInterface * iface, - DBusMessage * message); + /* interface saw a new BSS */ + void (*new_bss) (NMSupplicantInterface *iface, + GHashTable *props); - /* result of a wireless scan request */ - void (*scan_req_result) (NMSupplicantInterface * iface, + /* wireless scan is done */ + void (*scan_done) (NMSupplicantInterface *iface, gboolean success); - /* scan results returned from supplicant */ - void (*scan_results) (NMSupplicantInterface * iface, - guint num_bssids); - /* an error occurred during a connection request */ void (*connection_error) (NMSupplicantInterface * iface, const char * name, From 848f9f42610e39f1c49066082ad2541fe4303cc3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 22 Nov 2010 08:30:13 -0600 Subject: [PATCH 010/102] wifi: convert parts of association path to new supplicant interface --- src/supplicant-manager/nm-supplicant-interface.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index ae6630ea67..0fac765fb5 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -889,8 +889,8 @@ set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) nm_log_info (LOGD_SUPPLICANT, "Config: set interface ap_scan to %d", nm_supplicant_config_get_ap_scan (priv->cfg)); - info = nm_supplicant_info_new (info->interface, proxy, info->store); - call = dbus_g_proxy_begin_call (proxy, "addNetwork", + info = nm_supplicant_info_new (info->interface, priv->iface_proxy, info->store); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddNetwork", add_network_cb, info, nm_supplicant_info_destroy, @@ -922,12 +922,14 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self, g_object_ref (priv->cfg); - info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); + info = nm_supplicant_info_new (self, priv->props_proxy, priv->other_pcalls); ap_scan = nm_supplicant_config_get_ap_scan (priv->cfg); - call = dbus_g_proxy_begin_call (priv->iface_proxy, "setAPScan", + call = dbus_g_proxy_begin_call (priv->props_proxy, "Set", set_ap_scan_cb, info, nm_supplicant_info_destroy, + G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE, + G_TYPE_STRING, "ApScan", G_TYPE_UINT, ap_scan, G_TYPE_INVALID); nm_supplicant_info_set_call (info, call); From 6ecb45ddf07718cf41c22a5c3a5038923fadcbfe Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 22 Nov 2010 08:40:21 -0600 Subject: [PATCH 011/102] wifi: convert scanning to new supplicant interface --- .../nm-supplicant-interface.c | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 0fac765fb5..36faab7034 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -950,23 +950,49 @@ scan_request_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) g_clear_error (&err); } +static void +destroy_gvalue (gpointer data) +{ + GValue *value = (GValue *) data; + + g_value_unset (value); + g_slice_free (GValue, value); +} + +static GValue * +string_to_gvalue (const char *str) +{ + GValue *val = g_slice_new0 (GValue); + + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, str); + return val; +} + gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self) { NMSupplicantInterfacePrivate *priv; NMSupplicantInfo *info; DBusGProxyCall *call; + GHashTable *hash; g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE); priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + /* Scan parameters */ + hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_gvalue); + g_hash_table_insert (hash, "Type", string_to_gvalue ("active")); + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); - call = dbus_g_proxy_begin_call (priv->iface_proxy, "scan", + call = dbus_g_proxy_begin_call (priv->iface_proxy, "Scan", scan_request_cb, info, nm_supplicant_info_destroy, + DBUS_TYPE_G_MAP_OF_VARIANT, hash, G_TYPE_INVALID); + g_hash_table_destroy (hash); nm_supplicant_info_set_call (info, call); return call != NULL; From f5e084c668dc3cbd1a8f968644e2da1caffd1838 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 22 Nov 2010 09:05:09 -0600 Subject: [PATCH 012/102] supplicant: convert association paths to new supplicant interface --- .../nm-supplicant-interface.c | 132 +++++++----------- 1 file changed, 48 insertions(+), 84 deletions(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 36faab7034..cd2d2b5e7b 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -90,7 +90,7 @@ typedef struct { DBusGProxy * wpas_proxy; DBusGProxy * iface_proxy; DBusGProxy * props_proxy; - DBusGProxy * net_proxy; + char * net_path; guint32 last_scan; @@ -672,23 +672,20 @@ nm_supplicant_interface_disconnect (NMSupplicantInterface * self) /* Don't try to disconnect if the supplicant interface is already disconnected */ if ( priv->state == NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED || priv->state == NM_SUPPLICANT_INTERFACE_STATE_INACTIVE) { - if (priv->net_proxy) { - g_object_unref (priv->net_proxy); - priv->net_proxy = NULL; - } + g_free (priv->net_path); + priv->net_path = NULL; return; } /* Remove any network that was added by NetworkManager */ - if (priv->net_proxy) { + if (priv->net_path) { dbus_g_proxy_begin_call (priv->iface_proxy, "RemoveNetwork", remove_network_cb, NULL, NULL, - DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (priv->net_proxy), + DBUS_TYPE_G_OBJECT_PATH, priv->net_path, G_TYPE_INVALID); - - g_object_unref (priv->net_proxy); - priv->net_proxy = NULL; + g_free (priv->net_path); + priv->net_path = NULL; } dbus_g_proxy_begin_call (priv->iface_proxy, "Disconnect", @@ -702,9 +699,8 @@ select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_dat { NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; GError *err = NULL; - guint tmp; - if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) { nm_log_warn (LOGD_SUPPLICANT, "Couldn't select network config: %s.", err->message); emit_error_helper (info->interface, err); g_error_free (err); @@ -712,54 +708,26 @@ select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_dat } static void -set_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +call_select_network (NMSupplicantInterface *self) { - NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); - GError *err = NULL; - guint tmp; - - if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { - nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network config: %s.", err->message); - emit_error_helper (info->interface, err); - g_error_free (err); - } else { - DBusGProxyCall *call; - - info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls); - call = dbus_g_proxy_begin_call (priv->iface_proxy, "SelectNetwork", - select_network_cb, - info, - nm_supplicant_info_destroy, - DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (proxy), - G_TYPE_INVALID); - nm_supplicant_info_set_call (info, call); - } -} - -static void -call_set_network (NMSupplicantInfo *info) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); - GHashTable *config_hash; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); DBusGProxyCall *call; + NMSupplicantInfo *info; - config_hash = nm_supplicant_config_get_hash (priv->cfg); - call = dbus_g_proxy_begin_call (priv->net_proxy, "set", - set_network_cb, + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->assoc_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "SelectNetwork", + select_network_cb, info, nm_supplicant_info_destroy, - DBUS_TYPE_G_MAP_OF_VARIANT, config_hash, + DBUS_TYPE_G_OBJECT_PATH, priv->net_path, G_TYPE_INVALID); nm_supplicant_info_set_call (info, call); - g_hash_table_destroy (config_hash); } static void set_blobs_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); GError *err = NULL; guint tmp; @@ -767,10 +735,8 @@ set_blobs_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network certificates: %s.", err->message); emit_error_helper (info->interface, err); g_error_free (err); - } else { - info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls); - call_set_network (info); - } + } else + call_select_network (info->interface); } static GValue * @@ -802,11 +768,12 @@ convert_blob (const char *key, const GByteArray *value, GHashTable *hash) } static void -call_set_blobs (NMSupplicantInfo *info, GHashTable *orig_blobs) +call_set_blobs (NMSupplicantInterface *self, GHashTable *orig_blobs) { - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); DBusGProxyCall *call; GHashTable *blobs; + NMSupplicantInfo *info; blobs = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, @@ -815,12 +782,13 @@ call_set_blobs (NMSupplicantInfo *info, GHashTable *orig_blobs) const char *msg = "Not enough memory to create blob table."; nm_log_warn (LOGD_SUPPLICANT, "%s", msg); - g_signal_emit (info->interface, signals[CONNECTION_ERROR], 0, "SendBlobError", msg); + g_signal_emit (self, signals[CONNECTION_ERROR], 0, "SendBlobError", msg); return; } g_hash_table_foreach (orig_blobs, (GHFunc) convert_blob, blobs); + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->assoc_pcalls); call = dbus_g_proxy_begin_call (priv->iface_proxy, "setBlobs", set_blobs_cb, info, @@ -835,38 +803,29 @@ static void add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); GError *err = NULL; - char *path = NULL; + GHashTable *blobs; + + g_free (priv->net_path); + priv->net_path = NULL; if (!dbus_g_proxy_end_call (proxy, call_id, &err, - DBUS_TYPE_G_OBJECT_PATH, &path, + DBUS_TYPE_G_OBJECT_PATH, &priv->net_path, G_TYPE_INVALID)) { nm_log_warn (LOGD_SUPPLICANT, "Couldn't add a network to the supplicant interface: %s.", err->message); emit_error_helper (info->interface, err); g_error_free (err); - } else { - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); - GHashTable *blobs; - - priv->net_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), - WPAS_DBUS_SERVICE, - path, - WPAS_DBUS_IFACE_NETWORK); - g_free (path); - - info = nm_supplicant_info_new (info->interface, - priv->net_proxy, - priv->assoc_pcalls); - /* Send any blobs first; if there aren't any jump to sending the - * config settings. - */ - blobs = nm_supplicant_config_get_blobs (priv->cfg); - if (g_hash_table_size (blobs) > 0) - call_set_blobs (info, blobs); - else - call_set_network (info); + return; } + + /* Send blobs first; otherwise jump to sending the config settings */ + blobs = nm_supplicant_config_get_blobs (priv->cfg); + if (g_hash_table_size (blobs) > 0) + call_set_blobs (info->interface, blobs); + else + call_select_network (info->interface); } static void @@ -875,10 +834,10 @@ set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); GError *err = NULL; - guint32 tmp; DBusGProxyCall *call; + GHashTable *config_hash; - if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_INVALID)) { nm_log_warn (LOGD_SUPPLICANT, "Couldn't send AP scan mode to the supplicant interface: %s.", err->message); emit_error_helper (info->interface, err); @@ -890,11 +849,14 @@ set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) nm_supplicant_config_get_ap_scan (priv->cfg)); info = nm_supplicant_info_new (info->interface, priv->iface_proxy, info->store); + config_hash = nm_supplicant_config_get_hash (priv->cfg); call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddNetwork", add_network_cb, info, nm_supplicant_info_destroy, + DBUS_TYPE_G_MAP_OF_VARIANT, config_hash, G_TYPE_INVALID); + g_hash_table_destroy (config_hash); nm_supplicant_info_set_call (info, call); } @@ -905,7 +867,7 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self, NMSupplicantInterfacePrivate *priv; NMSupplicantInfo *info; DBusGProxyCall *call; - guint32 ap_scan; + GValue value = { 0, }; g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE); @@ -922,18 +884,21 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self, g_object_ref (priv->cfg); + g_value_init (&value, G_TYPE_UINT); + g_value_set_uint (&value, nm_supplicant_config_get_ap_scan (priv->cfg)); + info = nm_supplicant_info_new (self, priv->props_proxy, priv->other_pcalls); - ap_scan = nm_supplicant_config_get_ap_scan (priv->cfg); call = dbus_g_proxy_begin_call (priv->props_proxy, "Set", set_ap_scan_cb, info, nm_supplicant_info_destroy, G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE, G_TYPE_STRING, "ApScan", - G_TYPE_UINT, ap_scan, + G_TYPE_VALUE, &value, G_TYPE_INVALID); nm_supplicant_info_set_call (info, call); + g_value_unset (&value); return call != NULL; } @@ -1174,8 +1139,7 @@ dispose (GObject *object) if (priv->iface_proxy) g_object_unref (priv->iface_proxy); - if (priv->net_proxy) - g_object_unref (priv->net_proxy); + g_free (priv->net_path); if (priv->wpas_proxy) g_object_unref (priv->wpas_proxy); From fb6cde508c1417765684ae940f72d639067ddf0a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 22 Nov 2010 22:34:04 -0600 Subject: [PATCH 013/102] supplicant: convert blob handling to new supplicant interface --- .../nm-supplicant-interface.c | 94 ++++++------------- 1 file changed, 28 insertions(+), 66 deletions(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index cd2d2b5e7b..a92268c3d4 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -91,6 +91,7 @@ typedef struct { DBusGProxy * iface_proxy; DBusGProxy * props_proxy; char * net_path; + guint32 blobs_left; guint32 last_scan; @@ -246,7 +247,6 @@ wpas_iface_bss_added (DBusGProxy *proxy, GHashTable *props, gpointer user_data) { -g_message ("%s: here op %s props %p", __func__, object_path, props); g_signal_emit (NM_SUPPLICANT_INTERFACE (user_data), signals[NEW_BSS], 0, props); } @@ -714,6 +714,10 @@ call_select_network (NMSupplicantInterface *self) DBusGProxyCall *call; NMSupplicantInfo *info; + /* We only select the network after all blobs (if any) have been set */ + if (priv->blobs_left > 0) + return; + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->assoc_pcalls); call = dbus_g_proxy_begin_call (priv->iface_proxy, "SelectNetwork", select_network_cb, @@ -725,12 +729,15 @@ call_select_network (NMSupplicantInterface *self) } static void -set_blobs_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +add_blob_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); GError *err = NULL; guint tmp; + priv->blobs_left--; + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { nm_log_warn (LOGD_SUPPLICANT, "Couldn't set network certificates: %s.", err->message); emit_error_helper (info->interface, err); @@ -739,66 +746,6 @@ set_blobs_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) call_select_network (info->interface); } -static GValue * -byte_array_to_gvalue (const GByteArray *array) -{ - GValue *val; - - val = g_slice_new0 (GValue); - g_value_init (val, DBUS_TYPE_G_UCHAR_ARRAY); - g_value_set_boxed (val, array); - - return val; -} - -static void -blob_free (GValue *val) -{ - g_value_unset (val); - g_slice_free (GValue, val); -} - -static void -convert_blob (const char *key, const GByteArray *value, GHashTable *hash) -{ - GValue *val; - - val = byte_array_to_gvalue (value); - g_hash_table_insert (hash, g_strdup (key), val); -} - -static void -call_set_blobs (NMSupplicantInterface *self, GHashTable *orig_blobs) -{ - NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - DBusGProxyCall *call; - GHashTable *blobs; - NMSupplicantInfo *info; - - blobs = g_hash_table_new_full (g_str_hash, g_str_equal, - (GDestroyNotify) g_free, - (GDestroyNotify) blob_free); - if (!blobs) { - const char *msg = "Not enough memory to create blob table."; - - nm_log_warn (LOGD_SUPPLICANT, "%s", msg); - g_signal_emit (self, signals[CONNECTION_ERROR], 0, "SendBlobError", msg); - return; - } - - g_hash_table_foreach (orig_blobs, (GHFunc) convert_blob, blobs); - - info = nm_supplicant_info_new (self, priv->iface_proxy, priv->assoc_pcalls); - call = dbus_g_proxy_begin_call (priv->iface_proxy, "setBlobs", - set_blobs_cb, - info, - nm_supplicant_info_destroy, - DBUS_TYPE_G_MAP_OF_VARIANT, blobs, - G_TYPE_INVALID); - nm_supplicant_info_set_call (info, call); - g_hash_table_destroy (blobs); -} - static void add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { @@ -806,6 +753,10 @@ add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); GError *err = NULL; GHashTable *blobs; + GHashTableIter iter; + gpointer name, data; + DBusGProxyCall *call; + NMSupplicantInfo *blob_info; g_free (priv->net_path); priv->net_path = NULL; @@ -822,10 +773,21 @@ add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) /* Send blobs first; otherwise jump to sending the config settings */ blobs = nm_supplicant_config_get_blobs (priv->cfg); - if (g_hash_table_size (blobs) > 0) - call_set_blobs (info->interface, blobs); - else - call_select_network (info->interface); + priv->blobs_left = g_hash_table_size (blobs); + g_hash_table_iter_init (&iter, blobs); + while (g_hash_table_iter_next (&iter, &name, &data)) { + blob_info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "AddBlob", + add_blob_cb, + blob_info, + nm_supplicant_info_destroy, + DBUS_TYPE_STRING, name, + DBUS_TYPE_G_UCHAR_ARRAY, blobs, + G_TYPE_INVALID); + nm_supplicant_info_set_call (blob_info, call); + } + + call_select_network (info->interface); } static void From bfbb71b763378df7620381f5b98fc60573feb5aa Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 23 Nov 2010 00:02:46 -0600 Subject: [PATCH 014/102] wifi: update signal quality calculation for new supplicant interface --- src/nm-device-wifi.c | 40 ---------------------------------------- src/nm-wifi-ap.c | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 40 deletions(-) diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 3644ccfc4c..a2b3b4c1e2 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -2140,44 +2140,6 @@ cull_scan_list (NMDeviceWifi *self) removed, total); } -#define SET_QUALITY_MEMBER(qual_item, lc_member, uc_member) \ - if (lc_member != -1) { \ - qual_item.lc_member = lc_member; \ - qual_item.updated |= IW_QUAL_##uc_member##_UPDATED; \ - } else { \ - qual_item.updated |= IW_QUAL_##uc_member##_INVALID; \ - } - -static void -set_ap_strength_from_properties (NMDeviceWifi *self, - NMAccessPoint *ap, - GHashTable *properties) -{ - NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self); - int qual, level, noise; - struct iw_quality quality; - GValue *value; - gint8 strength; - - value = (GValue *) g_hash_table_lookup (properties, "quality"); - qual = value ? g_value_get_int (value) : -1; - - value = (GValue *) g_hash_table_lookup (properties, "level"); - level = value ? g_value_get_int (value) : -1; - - value = (GValue *) g_hash_table_lookup (properties, "noise"); - noise = value ? g_value_get_int (value) : -1; - - /* Calculate and set the AP's signal quality */ - memset (&quality, 0, sizeof (struct iw_quality)); - SET_QUALITY_MEMBER (quality, qual, QUAL); - SET_QUALITY_MEMBER (quality, level, LEVEL); - SET_QUALITY_MEMBER (quality, noise, NOISE); - - strength = wireless_qual_to_percent (&quality, &priv->max_qual); - nm_ap_set_strength (ap, strength); -} - static void supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, GHashTable *properties, @@ -2197,8 +2159,6 @@ supplicant_iface_new_bss_cb (NMSupplicantInterface *iface, ap = nm_ap_new_from_properties (properties); if (ap) { - set_ap_strength_from_properties (self, ap, properties); - nm_ap_print_self (ap, "AP: "); /* Add the AP to the device's AP list */ diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c index 642b6d978e..4438118729 100644 --- a/src/nm-wifi-ap.c +++ b/src/nm-wifi-ap.c @@ -22,6 +22,7 @@ #include "wireless-helper.h" #include +#include #include "nm-wifi-ap.h" #include "NetworkManagerUtils.h" @@ -495,6 +496,19 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data) if (!strcmp (key, "Frequency")) nm_ap_set_freq (ap, val); + } else if (G_VALUE_HOLDS_INT (variant)) { + gint val = g_value_get_int (variant); + + if (!strcmp (key, "Signal")) { + if (val < 0) { + /* Rough conversion: best = -40, worst = -100 */ + val = abs (CLAMP (val, -100, -40) + 40); + val = 100 - (int) ((100.0 * (double) val) / 60.0); + } else + val /= 100; + + nm_ap_set_strength (ap, val); + } } else if (G_VALUE_HOLDS_STRING (variant)) { const char *val = g_value_get_string (variant); From 8c9a124e72ca5ff4e648e91001fd540f0c179f4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 23 Nov 2010 16:27:21 +0100 Subject: [PATCH 015/102] keyfile: allow uppercase MAC addresses in unmanaged-devices in config file (rh #654714) --- system-settings/plugins/keyfile/plugin.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c index 5a927ce75d..da6456d983 100644 --- a/system-settings/plugins/keyfile/plugin.c +++ b/system-settings/plugins/keyfile/plugin.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -418,8 +419,23 @@ get_unmanaged_specs (NMSystemConfigInterface *config) udis = g_strsplit (str, ";", -1); g_free (str); - for (i = 0; udis[i] != NULL; i++) - specs = g_slist_append (specs, udis[i]); + for (i = 0; udis[i] != NULL; i++) { + /* Verify unmanaged specification and add it to the list */ + if (strlen (udis[i]) > 4 && !strncmp (udis[i], "mac:", 4) && ether_aton (udis[i] + 4)) { + char *p = udis[i]; + + /* To accept uppercase MACs in configuration file, we have to convert values to lowercase here. + * Unmanaged MACs in specs are always in lowercase. */ + while (*p) { + *p = g_ascii_tolower (*p); + p++; + } + specs = g_slist_append (specs, udis[i]); + } else { + g_warning ("Error in file '%s': invalid unmanaged-devices entry: '%s'", priv->conf_file, udis[i]); + g_free (udis[i]); + } + } g_free (udis); /* Yes, g_free, not g_strfreev because we need the strings in the list */ } From 5c9e82d17b936c17eae16b4cb37497e68054470f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 23 Nov 2010 16:45:04 +0100 Subject: [PATCH 016/102] man: update NetworkManager.conf man page --- man/NetworkManager.conf.5.in | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/man/NetworkManager.conf.5.in b/man/NetworkManager.conf.5.in index ba575c9415..c866f1b337 100644 --- a/man/NetworkManager.conf.5.in +++ b/man/NetworkManager.conf.5.in @@ -2,7 +2,7 @@ .\" .\" Copyright (C) 2010 Red Hat, Inc. .\" -.TH "NetworkManager.conf" "5" "16 September 2010" "" +.TH "NetworkManager.conf" "5" "23 November 2010" "" .SH NAME NetworkManager.conf \- NetworkManager configuration file .SH SYNOPSIS @@ -129,10 +129,12 @@ Set a persistent hostname when using the \fIkeyfile\fP plugin. .B unmanaged-devices=\fImac:\fP;\fImac:\fP;... Set devices that should be ignored by NetworkManager when using the \fIkeyfile\fP plugin. Devices are specified in the following format: "mac:", where - is MAC address of the device to be ignored, in lowercase. Multiple -entries are separated by a semicolon. Example: + is MAC address of the device to be ignored, in hex-digits-and-colons notation. +Multiple entries are separated by a semicolon. No spaces are allowed in the value. +.br +Example: .nf -unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1e:65:30:d1:c4 +unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4 .fi .SS [ifupdown] This section contains ifupdown-specific options and thus only has effect when using \fIifupdown\fP plugin. From 4b022ed32bb3d729fd21d2e33483fda03c6a6333 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Tue, 23 Nov 2010 19:06:58 +0100 Subject: [PATCH 017/102] core: correct TIMESTAMP type; fixes potential crash when time() is 32bit The Crash appeared on some platforms in glib while processing variable arguments. --- src/system-settings/nm-default-wired-connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/system-settings/nm-default-wired-connection.c b/src/system-settings/nm-default-wired-connection.c index 1cda3d9e23..0d19dea014 100644 --- a/src/system-settings/nm-default-wired-connection.c +++ b/src/system-settings/nm-default-wired-connection.c @@ -163,7 +163,7 @@ constructor (GType type, NM_SETTING_CONNECTION_AUTOCONNECT, TRUE, NM_SETTING_CONNECTION_UUID, uuid, NM_SETTING_CONNECTION_READ_ONLY, priv->read_only, - NM_SETTING_CONNECTION_TIMESTAMP, time (NULL), + NM_SETTING_CONNECTION_TIMESTAMP, (guint64) time (NULL), NULL); g_free (id); From 608783c5b773a30139158ef3b00c211dcc255ee8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 23 Nov 2010 13:10:01 -0600 Subject: [PATCH 018/102] core: handle device removal when properties are unreadable By the time we get the udev device removal notification we may not be able to read properties, since the device has already been removed from sysfs. That means we can't get the ifindex, so we need to fall back to the interface name. But we always want to prefer the ifindex since that will never change as long as the device is connected, unlike the interface name. --- src/nm-manager.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/nm-manager.c b/src/nm-manager.c index eb393facc4..48f2173d87 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2426,6 +2426,14 @@ udev_device_removed_cb (NMUdevManager *manager, ifindex = g_udev_device_get_property_as_int (udev_device, "IFINDEX"); device = find_device_by_ifindex (self, ifindex); + if (!device) { + /* On removal we won't always be able to read properties anymore, as + * they may have already been removed from sysfs. Instead, we just + * have to fall back to the device's interface name. + */ + device = find_device_by_iface (self, g_udev_device_get_name (udev_device)); + } + if (device) priv->devices = remove_one_device (self, priv->devices, device, FALSE); } From 40bbd4e2f2b221ca2894e0ad2026c0bf231479bd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 23 Nov 2010 16:28:25 -0600 Subject: [PATCH 019/102] examples: fix querying active connections --- examples/python/nm-state.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/python/nm-state.py b/examples/python/nm-state.py index fddd2da629..2bbdd2db4a 100644 --- a/examples/python/nm-state.py +++ b/examples/python/nm-state.py @@ -47,13 +47,13 @@ active = manager_prop_iface.Get("org.freedesktop.NetworkManager", "ActiveConnect for a in active: ac_proxy = bus.get_object("org.freedesktop.NetworkManager", a) prop_iface = dbus.Interface(ac_proxy, "org.freedesktop.DBus.Properties") - state = prop_iface.Get("org.freedesktop.NetworkManager.ActiveConnection", "State") + state = prop_iface.Get("org.freedesktop.NetworkManager.Connection.Active", "State") # Connections in NM are a collection of settings that describe everything # needed to connect to a specific network. Lets get those details so we # can find the user-readable name of the connection. - con_path = prop_iface.Get("org.freedesktop.NetworkManager.ActiveConnection", "Connection") - con_service = prop_iface.Get("org.freedesktop.NetworkManager.ActiveConnection", "ServiceName") + con_path = prop_iface.Get("org.freedesktop.NetworkManager.Connection.Active", "Connection") + con_service = prop_iface.Get("org.freedesktop.NetworkManager.Connection.Active", "ServiceName") # ask the provider of the connection for its details service_proxy = bus.get_object(con_service, con_path) From 4b37101ef4e91efb57525ad694169b48b56a0a61 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 23 Nov 2010 22:17:21 -0600 Subject: [PATCH 020/102] core: suppress error message when user settings service is not active Don't bother trying to initialize the user settings proxy when it isn't even active. Would trigger a warning to syslog if PolicyKit permissions changed via changes to /usr/share/polkit-1/actions/. --- src/nm-manager.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 48f2173d87..afcc6add54 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1356,6 +1356,12 @@ user_proxy_init (NMManager *self) g_return_if_fail (self != NULL); g_return_if_fail (priv->user_proxy == NULL); + /* Don't try to initialize the user settings proxy if the user + * settings service doesn't actually exist. + */ + if (!nm_dbus_manager_name_has_owner (priv->dbus_mgr, NM_DBUS_SERVICE_USER_SETTINGS)) + return; + bus = nm_dbus_manager_get_connection (priv->dbus_mgr); priv->user_proxy = dbus_g_proxy_new_for_name_owner (bus, NM_DBUS_SERVICE_USER_SETTINGS, @@ -3975,8 +3981,7 @@ nm_manager_start (NMManager *self) * they will be queried when the user settings service shows up on the * bus in nm_manager_name_owner_changed(). */ - if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, NM_DBUS_SERVICE_USER_SETTINGS)) - user_proxy_init (self); + user_proxy_init (self); nm_udev_manager_query_devices (priv->udev_mgr); bluez_manager_resync_devices (self); From f6f8ef2f8a1f0c89c78f85f48bf88c62dcad5aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Wed, 24 Nov 2010 12:51:08 +0100 Subject: [PATCH 021/102] dns: fix a crash due to uninitialized nis_domain (novell #655685) Reported and tested by Raymond Wooninck. Thanks! --- src/dns-manager/nm-dns-manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/dns-manager/nm-dns-manager.c b/src/dns-manager/nm-dns-manager.c index 7a6fbbc9d9..b0cdcc267d 100644 --- a/src/dns-manager/nm-dns-manager.c +++ b/src/dns-manager/nm-dns-manager.c @@ -583,6 +583,7 @@ update_dns (NMDnsManager *self, rc.nameservers = g_ptr_array_new (); rc.domain = NULL; rc.searches = g_ptr_array_new (); + rc.nis_domain = NULL; rc.nis_servers = g_ptr_array_new (); if (priv->ip4_vpn_config) From 690357116017c190aab0cfed7612c3b16cb269df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Wed, 24 Nov 2010 17:24:28 +0100 Subject: [PATCH 022/102] ifcfg-rh: allow missing and 0.0.0.0 GATEWAYn lines in ifcfg-routes (rh #647992) GATEWAY0=0.0.0.0 was erroneously denied. Also, missing GATEWAY0 entry caused ifcfg-rh plugin to regard the connection as invalid. The commit fixes that and makes it behave in accordance with initscripts. --- system-settings/plugins/ifcfg-rh/reader.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index f25acc892d..b4ee1307b9 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -683,12 +683,7 @@ read_one_ip4_route (shvarFile *ifcfg, /* Next hop */ if (!read_ip4_address (ifcfg, gw_tag, &tmp, error)) goto out; - if (!tmp) { - g_set_error (error, IFCFG_PLUGIN_ERROR, 0, - "Missing or invalid IP4 gateway address '%d'", - tmp); - goto out; - } + /* No need to check tmp, because we don't make distinction between missing GATEWAY IP and 0.0.0.0 */ nm_ip4_route_set_next_hop (route, tmp); /* Prefix */ From bfbf5ef374a192c88488594d9f811007f5f6f831 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Mon, 6 Dec 2010 15:55:48 +0100 Subject: [PATCH 023/102] ifcfg-rh: fix missing connections when an unmanaged interface was present Don't emit "unmanaged-specs-changed" signal in read_one_connection(), because it causes that next connections are not listed (get_connections() is called prematurely and only connections read so far are available). Steps to reproduce the bug: 1) create ifcfg-fake DEVICE=loremipsum HWADDR=01:02:03:04:05:06 NM_CONTROLLED=no 2) restart NetworkManager 3) only connections read *before* ifcfg-fake are available Thanks to Robert Vogelgesang for updating the patch and analysis! --- system-settings/plugins/ifcfg-rh/plugin.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c index 37bf97280c..8dce0334a5 100644 --- a/system-settings/plugins/ifcfg-rh/plugin.c +++ b/system-settings/plugins/ifcfg-rh/plugin.c @@ -147,7 +147,6 @@ read_one_connection (SCPluginIfcfg *plugin, const char *filename) if (nm_ifcfg_connection_get_unmanaged_spec (connection)) { PLUGIN_PRINT (IFCFG_PLUGIN_NAME, "Ignoring connection '%s' and its " "device due to NM_CONTROLLED/BRIDGE/VLAN.", cid); - g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); } else { /* Wait for the connection to become unmanaged once it knows the * UDI of it's device, if/when the device gets plugged in. @@ -314,7 +313,9 @@ handle_connection_remove_or_new (SCPluginIfcfg *plugin, if (do_new) { connection = read_one_connection (plugin, path); if (connection) { - if (!nm_ifcfg_connection_get_unmanaged_spec (connection)) + if (nm_ifcfg_connection_get_unmanaged_spec (connection)) + g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED); + else g_signal_emit_by_name (plugin, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, connection); } } From 740dc88cb3db3f910948e50b9340016ab8c5e84c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Canek=20Pel=C3=A1ez=20Vald=C3=A9s?= Date: Mon, 6 Dec 2010 09:33:29 -0600 Subject: [PATCH 024/102] gentoo: handle both systemd and OpenRC loopback init at runtime See Gentoo #318365 --- src/backends/NetworkManagerGentoo.c | 49 +++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/backends/NetworkManagerGentoo.c b/src/backends/NetworkManagerGentoo.c index 8d9e68c59c..2854901a56 100644 --- a/src/backends/NetworkManagerGentoo.c +++ b/src/backends/NetworkManagerGentoo.c @@ -30,12 +30,22 @@ #include #include #include +#include #include "NetworkManagerGeneric.h" #include "nm-system.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" +#define BUFFER_SIZE 512 + +static void openrc_start_lo_if_necessary() +{ + /* No need to run net.lo if it is already running */ + if (nm_spawn_process ("/etc/init.d/net.lo status") != 0) + nm_spawn_process ("/etc/init.d/net.lo start"); +} + /* * nm_system_enable_loopback * @@ -44,9 +54,42 @@ */ void nm_system_enable_loopback (void) { - /* No need to run net.lo if it is already running */ - if (nm_spawn_process ("/etc/init.d/net.lo status") != 0) - nm_spawn_process("/etc/init.d/net.lo start"); + GFile *file; + GFileInputStream *in; + gchar buffer[BUFFER_SIZE]; + gchar *comm, *readed, *tmp; + gssize r; + + file = g_file_new_for_path ("/proc/1/comm"); + in = g_file_read (file, NULL, NULL); + + /* If anything goes wrong trying to open /proc/1/comm, + we will assume OpenRC. */ + if (!in) { + openrc_start_lo_if_necessary (); + return; + } + + comm = g_strdup(""); + while ((r = g_input_stream_read (G_INPUT_STREAM(in), buffer, BUFFER_SIZE, NULL, NULL)) > 0) { + readed = g_strndup (buffer, r); + tmp = g_strconcat (comm, readed, NULL); + g_free (comm); + g_free (readed); + comm = tmp; + } + + if (g_strstr_len (comm, -1, "systemd")) { + /* We use the generic loopback enabler if using systemd. */ + nm_log_info (LOGD_CORE, "NetworkManager is running with systemd..."); + nm_generic_enable_loopback (); + } else { + /* OpenRC otherwise. */ + nm_log_info (LOGD_CORE, "NetworkManager is running with OpenRC..."); + openrc_start_lo_if_necessary(); + } + + g_free (comm); } /* From fd3e8e45765c4606402d45d993c102b32dae6d8a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 6 Dec 2010 12:12:52 -0600 Subject: [PATCH 025/102] examples: build C examples --- examples/C/Makefile.am | 17 +++++++++++++++++ examples/C/add-connection-glib.c | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/examples/C/Makefile.am b/examples/C/Makefile.am index 68c0697b0b..7313de95dc 100644 --- a/examples/C/Makefile.am +++ b/examples/C/Makefile.am @@ -1,2 +1,19 @@ +INCLUDES = -I${top_srcdir}/libnm-util \ + -I${top_srcdir}/libnm-glib \ + -I${top_srcdir}/include + +AM_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) + +noinst_PROGRAMS = add-connection-glib + +add_connection_glib_SOURCES = add-connection-glib.c +add_connection_glib_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + EXTRA_DIST = \ add-connection-glib.c + diff --git a/examples/C/add-connection-glib.c b/examples/C/add-connection-glib.c index 0e8dc18036..4cdcfa2310 100644 --- a/examples/C/add-connection-glib.c +++ b/examples/C/add-connection-glib.c @@ -38,7 +38,8 @@ #define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) #define DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT)) -void add_connection (DBusGProxy *proxy, const char *con_name) +static void +add_connection (DBusGProxy *proxy, const char *con_name) { NMConnection *connection; NMSettingConnection *s_con; From c602487ff3872a5e524b3431339127c9d1eeb495 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 6 Dec 2010 12:14:06 -0600 Subject: [PATCH 026/102] test: add C example for printing active connection details --- examples/C/Makefile.am | 13 +- examples/C/get-active-connections.c | 225 ++++++++++++++++++++++++++++ 2 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 examples/C/get-active-connections.c diff --git a/examples/C/Makefile.am b/examples/C/Makefile.am index 7313de95dc..461d1c3403 100644 --- a/examples/C/Makefile.am +++ b/examples/C/Makefile.am @@ -6,7 +6,7 @@ AM_CPPFLAGS = \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) -noinst_PROGRAMS = add-connection-glib +noinst_PROGRAMS = add-connection-glib get-active-connections add_connection_glib_SOURCES = add-connection-glib.c add_connection_glib_LDADD = \ @@ -14,6 +14,13 @@ add_connection_glib_LDADD = \ $(DBUS_LIBS) \ $(GLIB_LIBS) -EXTRA_DIST = \ - add-connection-glib.c +get_active_connections_SOURCES = get-active-connections.c +get_active_connections_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + +EXTRA_DIST = \ + add-connection-glib.c \ + get-active-connections.c diff --git a/examples/C/get-active-connections.c b/examples/C/get-active-connections.c new file mode 100644 index 0000000000..3053a82b96 --- /dev/null +++ b/examples/C/get-active-connections.c @@ -0,0 +1,225 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; 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 2010 Red Hat, Inc. + */ + +/* + * The example shows how to call the D-Bus properties interface to get the + * list of currently active connections known to NetworkManager. It uses + * dbus-glib and libnm-util libraries. + * + * Compile with: + * gcc -Wall `pkg-config --libs --cflags glib-2.0 dbus-glib-1 libnm-util` get-active-connections.c -o get-active-connections + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE)) +#define DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, DBUS_TYPE_G_MAP_OF_VARIANT)) +#define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH)) + +static void +print_connection (DBusGConnection *bus, const char *service, const char *path) +{ + DBusGProxy *proxy; + GError *error = NULL; + GHashTable *hash = NULL; + NMConnection *connection = NULL; + + /* Create a D-Bus proxy; NM_DBUS_* defined in NetworkManager.h */ + proxy = dbus_g_proxy_new_for_name (bus, + service, + path, + NM_DBUS_IFACE_SETTINGS_CONNECTION); + g_assert (proxy); + + if (!dbus_g_proxy_call (proxy, "GetSettings", &error, + G_TYPE_INVALID, + DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &hash, + G_TYPE_INVALID)) { + g_warning ("Failed to get active connection Connection property: %s", + error->message); + g_error_free (error); + goto out; + } + + connection = nm_connection_new_from_hash (hash, &error); + if (!connection) { + g_warning ("Received invalid connection data: %s", error->message); + g_error_free (error); + goto out; + } + + g_message ("%s => %s", service, path); + nm_connection_dump (connection); + +out: + if (connection) + g_object_unref (connection); + if (hash) + g_hash_table_destroy (hash); + g_object_unref (proxy); +} + +static void +get_active_connection_details (DBusGConnection *bus, const char *obj_path) +{ + DBusGProxy *props_proxy; + GValue path_value = { 0 }; + GValue serv_value = { 0 }; + GError *error = NULL; + const char *path = NULL, *service = NULL; + + /* Create a D-Bus proxy; NM_DBUS_* defined in NetworkManager.h */ + props_proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE, + obj_path, + DBUS_INTERFACE_PROPERTIES); + g_assert (props_proxy); + + /* Get the object path of the Connection details */ + if (!dbus_g_proxy_call (props_proxy, "Get", &error, + G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + G_TYPE_STRING, "Connection", + G_TYPE_INVALID, + G_TYPE_VALUE, &path_value, + G_TYPE_INVALID)) { + g_warning ("Failed to get active connection Connection property: %s", + error->message); + g_error_free (error); + goto out; + } + + if (!G_VALUE_HOLDS (&path_value, DBUS_TYPE_G_OBJECT_PATH)) { + g_warning ("Unexpected type returned getting Connection property: %s", + G_VALUE_TYPE_NAME (&path_value)); + goto out; + } + + path = g_value_get_boxed (&path_value); + if (!path) { + g_warning ("Missing connection path!"); + goto out; + } + + /* Get the service name of the D-Bus service that provides the Connection */ + if (!dbus_g_proxy_call (props_proxy, "Get", &error, + G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + G_TYPE_STRING, "ServiceName", + G_TYPE_INVALID, + G_TYPE_VALUE, &serv_value, + G_TYPE_INVALID)) { + g_warning ("Failed to get active connection ServiceName property: %s", + error->message); + g_error_free (error); + goto out; + } + + if (!G_VALUE_HOLDS (&serv_value, G_TYPE_STRING)) { + g_warning ("Unexpected type returned getting Connection property: %s", + G_VALUE_TYPE_NAME (&serv_value)); + goto out; + } + + service = g_value_get_string (&serv_value); + if (!service) { + g_warning ("Missing connection service name!"); + goto out; + } + + print_connection (bus, service, path); + +out: + g_value_unset (&path_value); + g_value_unset (&serv_value); + g_object_unref (props_proxy); +} + +static void +get_active_connections (DBusGConnection *bus, DBusGProxy *proxy) +{ + GError *error = NULL; + GValue value = { 0 }; + GPtrArray *paths = NULL; + int i; + + /* Call AddConnection with the hash as argument */ + if (!dbus_g_proxy_call (proxy, "Get", &error, + G_TYPE_STRING, NM_DBUS_INTERFACE, + G_TYPE_STRING, "ActiveConnections", + G_TYPE_INVALID, + G_TYPE_VALUE, &value, + G_TYPE_INVALID)) { + g_warning ("Failed to get ActiveConnections property: %s", error->message); + g_error_free (error); + return; + } + + if (!G_VALUE_HOLDS (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) { + g_warning ("Unexpected type returned getting ActiveConnections: %s", + G_VALUE_TYPE_NAME (&value)); + goto out; + } + + paths = g_value_get_boxed (&value); + if (!paths) { + g_warning ("Could not retrieve active connections property"); + goto out; + } + + for (i = 0; i < paths->len; i++) + get_active_connection_details (bus, g_ptr_array_index (paths, i)); + +out: + g_value_unset (&value); +} + + +int main (int argc, char *argv[]) +{ + DBusGConnection *bus; + DBusGProxy *props_proxy; + + /* Initialize GType system */ + g_type_init (); + + /* Get system bus */ + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); + + /* Create a D-Bus proxy; NM_DBUS_* defined in NetworkManager.h */ + props_proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE, + NM_DBUS_PATH, + DBUS_INTERFACE_PROPERTIES); + g_assert (props_proxy); + + /* Add a connection */ + get_active_connections (bus, props_proxy); + + g_object_unref (props_proxy); + dbus_g_connection_unref (bus); + + return 0; +} From e821e619924eaf06ddfa40f78a56e72fb8a82299 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 6 Dec 2010 12:27:50 -0600 Subject: [PATCH 027/102] examples: update comments --- examples/C/get-active-connections.c | 32 +++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/examples/C/get-active-connections.c b/examples/C/get-active-connections.c index 3053a82b96..689b7ff6e2 100644 --- a/examples/C/get-active-connections.c +++ b/examples/C/get-active-connections.c @@ -48,13 +48,20 @@ print_connection (DBusGConnection *bus, const char *service, const char *path) GHashTable *hash = NULL; NMConnection *connection = NULL; - /* Create a D-Bus proxy; NM_DBUS_* defined in NetworkManager.h */ + /* This function asks the Settings Service that provides this network + * configuration for the details of that configuration. + */ + + /* Create the D-Bus proxy for the Settings Service so we can ask it for the + * connection configuration details. + */ proxy = dbus_g_proxy_new_for_name (bus, service, path, NM_DBUS_IFACE_SETTINGS_CONNECTION); g_assert (proxy); + /* Request the all the configuration of the Connection */ if (!dbus_g_proxy_call (proxy, "GetSettings", &error, G_TYPE_INVALID, DBUS_TYPE_G_MAP_OF_MAP_OF_VARIANT, &hash, @@ -65,6 +72,9 @@ print_connection (DBusGConnection *bus, const char *service, const char *path) goto out; } + /* Using the raw configuration, create an NMConnection object for it. This + * step also verifies that the data we got from the settings service is + * valid. */ connection = nm_connection_new_from_hash (hash, &error); if (!connection) { g_warning ("Received invalid connection data: %s", error->message); @@ -72,6 +82,7 @@ print_connection (DBusGConnection *bus, const char *service, const char *path) goto out; } + /* And finally dump all the configuration to stdout */ g_message ("%s => %s", service, path); nm_connection_dump (connection); @@ -92,7 +103,13 @@ get_active_connection_details (DBusGConnection *bus, const char *obj_path) GError *error = NULL; const char *path = NULL, *service = NULL; - /* Create a D-Bus proxy; NM_DBUS_* defined in NetworkManager.h */ + /* This function gets the backing Connection object that describes the + * network configuration that the ActiveConnection object is actually using. + * The ActiveConnection object contains the mapping between the configuration + * and the actual network interfaces that are using that configuration. + */ + + /* Create a D-Bus object proxy for the active connection object's properties */ props_proxy = dbus_g_proxy_new_for_name (bus, NM_DBUS_SERVICE, obj_path, @@ -149,6 +166,7 @@ get_active_connection_details (DBusGConnection *bus, const char *obj_path) goto out; } + /* Print out the actual connection details */ print_connection (bus, service, path); out: @@ -165,7 +183,7 @@ get_active_connections (DBusGConnection *bus, DBusGProxy *proxy) GPtrArray *paths = NULL; int i; - /* Call AddConnection with the hash as argument */ + /* Get the ActiveConnections property from the NM Manager object */ if (!dbus_g_proxy_call (proxy, "Get", &error, G_TYPE_STRING, NM_DBUS_INTERFACE, G_TYPE_STRING, "ActiveConnections", @@ -177,20 +195,24 @@ get_active_connections (DBusGConnection *bus, DBusGProxy *proxy) return; } + /* Make sure the ActiveConnections property is the type we expect it to be */ if (!G_VALUE_HOLDS (&value, DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH)) { g_warning ("Unexpected type returned getting ActiveConnections: %s", G_VALUE_TYPE_NAME (&value)); goto out; } + /* Extract the active connections array from the GValue */ paths = g_value_get_boxed (&value); if (!paths) { g_warning ("Could not retrieve active connections property"); goto out; } + /* And print out the details of each active connection */ for (i = 0; i < paths->len; i++) get_active_connection_details (bus, g_ptr_array_index (paths, i)); + g_ptr_array_free (paths, TRUE); out: g_value_unset (&value); @@ -208,7 +230,9 @@ int main (int argc, char *argv[]) /* Get system bus */ bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); - /* Create a D-Bus proxy; NM_DBUS_* defined in NetworkManager.h */ + /* Create a D-Bus proxy to get the object properties from the NM Manager + * object. NM_DBUS_* defines are from NetworkManager.h. + */ props_proxy = dbus_g_proxy_new_for_name (bus, NM_DBUS_SERVICE, NM_DBUS_PATH, From 9e9a46b405baefe7a7b011862e57eeb472d9e3a7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 6 Dec 2010 15:55:30 -0600 Subject: [PATCH 028/102] wifi: remove useless warning --- src/nm-device-wifi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index a2b3b4c1e2..5141a8f7d6 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -3477,12 +3477,11 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled) /* Wait for some drivers like ipw3945 to come back to life */ success = wireless_get_range (self, &range, NULL); - /* iface should be NULL here, but handle it anyway if it's not */ - g_warn_if_fail (priv->supplicant.iface == NULL); + /* Re-initialize the supplicant interface and wait for it to be ready */ if (priv->supplicant.iface) supplicant_interface_release (self); - supplicant_interface_acquire (self); + nm_log_dbg (LOGD_WIFI, "(%s): enable waiting on supplicant state", nm_device_get_iface (NM_DEVICE (device))); } else { From a08dd2c39d14ce933e1adb3cf0377e84ca84925e Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 7 Dec 2010 13:58:49 -0600 Subject: [PATCH 029/102] supplicant: fix handling when supplicant cannot be service activated If the supplicant cannot be service activated, wait until it shows up on the bus instead of sitting around doing nothing. This fixes a small regression introduced when the _READY state was added to the supplicant interface object. --- .../nm-supplicant-interface.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index a92268c3d4..777d46abe9 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -287,8 +287,8 @@ set_state (NMSupplicantInterface *self, guint32 new_state) /* DOWN is a terminal state */ g_return_if_fail (priv->state != NM_SUPPLICANT_INTERFACE_STATE_DOWN); - /* Cannot regress to READY or INIT from higher states */ - if (priv->state <= NM_SUPPLICANT_INTERFACE_STATE_READY) + /* Cannot regress to READY, STARTING, or INIT from higher states */ + if (priv->state >= NM_SUPPLICANT_INTERFACE_STATE_READY) g_return_if_fail (new_state > priv->state); if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { @@ -504,9 +504,10 @@ interface_get_cb (DBusGProxy *proxy, G_TYPE_INVALID)) { interface_add_done (info->interface, path); } else { - nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s", + nm_log_err (LOGD_SUPPLICANT, "(%s): error getting interface: %s", priv->dev, error->message); g_clear_error (&error); + set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_DOWN); } } @@ -545,9 +546,19 @@ interface_add_cb (DBusGProxy *proxy, if (dbus_g_error_has_name (error, WPAS_ERROR_EXISTS_ERROR)) { /* Interface already added, just get its object path */ interface_get (info->interface); + } else if ( g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN) + || dbus_g_error_has_name (error, DBUS_ERROR_SPAWN_SERVICE_NOT_FOUND)) { + /* Supplicant wasn't running and could be launched via service + * activation. Wait for it to start by moving back to the INIT + * state. + */ + nm_log_dbg (LOGD_SUPPLICANT, "(%s): failed to activate supplicant: %s", + priv->dev, error->message); + set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_INIT); } else { nm_log_err (LOGD_SUPPLICANT, "(%s): error adding interface: %s", priv->dev, error->message); + set_state (info->interface, NM_SUPPLICANT_INTERFACE_STATE_DOWN); } g_clear_error (&error); } From af406bdc9657c1fa53556c892b7edb0b4b256b1c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 7 Dec 2010 14:12:55 -0600 Subject: [PATCH 030/102] libnm-glib: actually define the "ip-interface" property Looks like it got left out of 6ab5a9597a26235c9839df346fc3ce95f35a240f --- libnm-glib/nm-device.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index ea2a91d1ce..b8998f70b8 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -476,6 +476,20 @@ nm_device_class_init (NMDeviceClass *device_class) NULL, G_PARAM_READABLE)); + /** + * NMDevice:ip-interface: + * + * The IP interface of the device which should be used for all IP-related + * operations like addressing and routing. + **/ + g_object_class_install_property + (object_class, PROP_IP_INTERFACE, + g_param_spec_string (NM_DEVICE_IP_INTERFACE, + "IP Interface", + "IP Interface name", + NULL, + G_PARAM_READABLE)); + /** * NMDevice:udi: * From 12345affa58604994123ea92f77059d8e6cdda75 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 7 Dec 2010 14:18:44 -0600 Subject: [PATCH 031/102] wifi: move wireless_qual_to_percent() to get rid of prototype Now that it's only used in one place we can get rid of the prototype. --- src/nm-device-wifi.c | 205 +++++++++++++++++++++---------------------- 1 file changed, 101 insertions(+), 104 deletions(-) diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 5141a8f7d6..38631d7552 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -175,9 +175,6 @@ static void schedule_scan (NMDeviceWifi *self, gboolean backoff); static void cancel_pending_scan (NMDeviceWifi *self); -static int wireless_qual_to_percent (const struct iw_quality *qual, - const struct iw_quality *max_qual); - static void cleanup_association_attempt (NMDeviceWifi * self, gboolean disconnect); @@ -294,6 +291,107 @@ ipw_rfkill_state_work (gpointer user_data) return TRUE; } +/* + * wireless_qual_to_percent + * + * Convert an iw_quality structure from SIOCGIWSTATS into a magical signal + * strength percentage. + * + */ +static int +wireless_qual_to_percent (const struct iw_quality *qual, + const struct iw_quality *max_qual) +{ + int percent = -1; + int level_percent = -1; + + g_return_val_if_fail (qual != NULL, -1); + g_return_val_if_fail (max_qual != NULL, -1); + + nm_log_dbg (LOGD_WIFI, + "QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X ** MAX: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X", + (__s8) qual->qual, qual->qual, qual->qual, + (__s8) qual->level, qual->level, qual->level, + (__s8) qual->noise, qual->noise, qual->noise, + qual->updated, + (__s8) max_qual->qual, max_qual->qual, max_qual->qual, + (__s8) max_qual->level, max_qual->level, max_qual->level, + (__s8) max_qual->noise, max_qual->noise, max_qual->noise, + max_qual->updated); + + /* Try using the card's idea of the signal quality first as long as it tells us what the max quality is. + * Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be + * bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers + * are free to use whatever they want to calculate "Link Quality". + */ + if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID)) + percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual)); + + /* If the driver doesn't specify a complete and valid quality, we have two options: + * + * 1) dBm: driver must specify max_qual->level = 0, and have valid values for + * qual->level and (qual->noise OR max_qual->noise) + * 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for + * qual->level and max_qual->level + * + * This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise, + * If drivers don't conform to it, they are wrong and need to be fixed. + */ + + if ( (max_qual->level == 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */ + && !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */ + && ( ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */ + || ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */ + ) { + /* Absolute power values (dBm) */ + + /* Reasonable fallbacks for dumb drivers that don't specify either level. */ + #define FALLBACK_NOISE_FLOOR_DBM -90 + #define FALLBACK_SIGNAL_MAX_DBM -20 + int max_level = FALLBACK_SIGNAL_MAX_DBM; + int noise = FALLBACK_NOISE_FLOOR_DBM; + int level = qual->level - 0x100; + + level = CLAMP (level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); + + if ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID)) + noise = qual->noise - 0x100; + else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) + noise = max_qual->noise - 0x100; + noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); + + /* A sort of signal-to-noise ratio calculation */ + level_percent = (int)(100 - 70 *( + ((double)max_level - (double)level) / + ((double)max_level - (double)noise))); + nm_log_dbg (LOGD_WIFI, "QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.", + level_percent, max_level, level, noise); + } else if ( (max_qual->level != 0) + && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */ + && !(qual->updated & IW_QUAL_LEVEL_INVALID)) { + /* Relative power values (RSSI) */ + + int level = qual->level; + + /* Signal level is relavtive (0 -> max_qual->level) */ + level = CLAMP (level, 0, max_qual->level); + level_percent = (int)(100 * ((double)level / (double)max_qual->level)); + nm_log_dbg (LOGD_WIFI, "QL2: level_percent is %d. max_level %d, level %d.", + level_percent, max_qual->level, level); + } else if (percent == -1) { + nm_log_dbg (LOGD_WIFI, "QL: Could not get quality %% value from driver. Driver is probably buggy."); + } + + /* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */ + if ((percent < 1) && (level_percent >= 0)) + percent = level_percent; + + nm_log_dbg (LOGD_WIFI, "QL: Final quality percent is %d (%d).", + percent, CLAMP (percent, 0, 100)); + return (CLAMP (percent, 0, 100)); +} + + /* * nm_device_wifi_update_signal_strength * @@ -1490,107 +1588,6 @@ nm_device_wifi_get_frequency (NMDeviceWifi *self) return freq; } -/* - * wireless_stats_to_percent - * - * Convert an iw_stats structure from a scan or the card into - * a magical signal strength percentage. - * - */ -static int -wireless_qual_to_percent (const struct iw_quality *qual, - const struct iw_quality *max_qual) -{ - int percent = -1; - int level_percent = -1; - - g_return_val_if_fail (qual != NULL, -1); - g_return_val_if_fail (max_qual != NULL, -1); - - nm_log_dbg (LOGD_WIFI, - "QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X ** MAX: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X, updated: 0x%X", - (__s8) qual->qual, qual->qual, qual->qual, - (__s8) qual->level, qual->level, qual->level, - (__s8) qual->noise, qual->noise, qual->noise, - qual->updated, - (__s8) max_qual->qual, max_qual->qual, max_qual->qual, - (__s8) max_qual->level, max_qual->level, max_qual->level, - (__s8) max_qual->noise, max_qual->noise, max_qual->noise, - max_qual->updated); - - /* Try using the card's idea of the signal quality first as long as it tells us what the max quality is. - * Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be - * bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers - * are free to use whatever they want to calculate "Link Quality". - */ - if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID)) - percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual)); - - /* If the driver doesn't specify a complete and valid quality, we have two options: - * - * 1) dBm: driver must specify max_qual->level = 0, and have valid values for - * qual->level and (qual->noise OR max_qual->noise) - * 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for - * qual->level and max_qual->level - * - * This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise, - * If drivers don't conform to it, they are wrong and need to be fixed. - */ - - if ( (max_qual->level == 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */ - && !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */ - && ( ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */ - || ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */ - ) { - /* Absolute power values (dBm) */ - - /* Reasonable fallbacks for dumb drivers that don't specify either level. */ - #define FALLBACK_NOISE_FLOOR_DBM -90 - #define FALLBACK_SIGNAL_MAX_DBM -20 - int max_level = FALLBACK_SIGNAL_MAX_DBM; - int noise = FALLBACK_NOISE_FLOOR_DBM; - int level = qual->level - 0x100; - - level = CLAMP (level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); - - if ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID)) - noise = qual->noise - 0x100; - else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) - noise = max_qual->noise - 0x100; - noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM); - - /* A sort of signal-to-noise ratio calculation */ - level_percent = (int)(100 - 70 *( - ((double)max_level - (double)level) / - ((double)max_level - (double)noise))); - nm_log_dbg (LOGD_WIFI, "QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.", - level_percent, max_level, level, noise); - } else if ( (max_qual->level != 0) - && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */ - && !(qual->updated & IW_QUAL_LEVEL_INVALID)) { - /* Relative power values (RSSI) */ - - int level = qual->level; - - /* Signal level is relavtive (0 -> max_qual->level) */ - level = CLAMP (level, 0, max_qual->level); - level_percent = (int)(100 * ((double)level / (double)max_qual->level)); - nm_log_dbg (LOGD_WIFI, "QL2: level_percent is %d. max_level %d, level %d.", - level_percent, max_qual->level, level); - } else if (percent == -1) { - nm_log_dbg (LOGD_WIFI, "QL: Could not get quality %% value from driver. Driver is probably buggy."); - } - - /* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */ - if ((percent < 1) && (level_percent >= 0)) - percent = level_percent; - - nm_log_dbg (LOGD_WIFI, "QL: Final quality percent is %d (%d).", - percent, CLAMP (percent, 0, 100)); - return (CLAMP (percent, 0, 100)); -} - - /* * nm_device_wifi_get_ssid * From 19392097593e49ac6de1e2e5dc9557256175bc1b Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 9 Dec 2010 00:13:37 -0600 Subject: [PATCH 032/102] ifupdown: Correctly mark unmanaged devices (debian #569215) If we find a "iface ..." line, add the interface to well_known_interfaces no matter if there is a connection for it or not. Otherwise we fail to mark devices as unmageded in cases like iface wlan0 inet manual wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf as NM does not know how to parse such a interface configuration. Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=569215 --- system-settings/plugins/ifupdown/plugin.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system-settings/plugins/ifupdown/plugin.c b/system-settings/plugins/ifupdown/plugin.c index 33c058e5b4..7daa06a000 100644 --- a/system-settings/plugins/ifupdown/plugin.c +++ b/system-settings/plugins/ifupdown/plugin.c @@ -368,6 +368,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) /* Remove any connection for this block that was previously found */ exported = g_hash_table_lookup (priv->iface_connections, block->name); if (exported) { + PLUGIN_PRINT("SCPlugin-Ifupdown", "deleting %s from iface_connections", block->name); nm_settings_connection_interface_delete (NM_SETTINGS_CONNECTION_INTERFACE (exported), ignore_cb, NULL); @@ -377,11 +378,14 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) /* add the new connection */ exported = nm_ifupdown_connection_new (block); if (exported) { + PLUGIN_PRINT("SCPlugin-Ifupdown", "adding %s to iface_connections", block->name); g_hash_table_insert (priv->iface_connections, block->name, exported); - g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); } + PLUGIN_PRINT("SCPlugin-Ifupdown", "adding iface %s to well_known_interfaces", block->name); + g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); } else if (!strcmp ("mapping", block->type)) { g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); + PLUGIN_PRINT("SCPlugin-Ifupdown", "adding mapping %s to well_known_interfaces", block->name); } block = block->next; } From 898e08eef1ae4e255d5808bb17443874073f3641 Mon Sep 17 00:00:00 2001 From: Michael Biebl Date: Thu, 9 Dec 2010 00:15:17 -0600 Subject: [PATCH 033/102] ifupdown: Allow to mark bridge ports as unmanaged (debian #530335) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parse bridge configurations in /etc/network/interfaces and add interfaces defined via bridge_ports to well_known_interfaces. This allows to mark those interfaces as unmanaged if managed=false. The "all" keyword and regexes are not supported and simply skipped. Example: iface br0 inet manual bridge_ports eth0 eth1 (→ eth0/1 will be marked as unmanaged) See also: http://manpages.ubuntu.com/manpages/maverick/man5/bridge-utils-interfaces.5.html Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=530335 --- system-settings/plugins/ifupdown/plugin.c | 45 ++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/system-settings/plugins/ifupdown/plugin.c b/system-settings/plugins/ifupdown/plugin.c index 7daa06a000..8cfbedcd64 100644 --- a/system-settings/plugins/ifupdown/plugin.c +++ b/system-settings/plugins/ifupdown/plugin.c @@ -362,9 +362,51 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) while (block) { if(!strcmp ("auto", block->type) || !strcmp ("allow-hotplug", block->type)) g_hash_table_insert (auto_ifaces, block->name, GUINT_TO_POINTER (1)); - else if (!strcmp ("iface", block->type) && strcmp ("lo", block->name)) { + else if (!strcmp ("iface", block->type)) { NMIfupdownConnection *exported; + /* Bridge configuration */ + if(!strncmp ("br", block->name, 2)) { + /* Try to find bridge ports */ + const char *ports = ifparser_getkey (block, "bridge_ports"); + if (ports) { + int i; + int state = 0; + char **port_ifaces; + + PLUGIN_PRINT("SCPlugin-Ifupdown", "found bridge ports %s for %s", ports, block->name); + + port_ifaces = g_strsplit_set (ports, " \t", -1); + for (i = 0; i < g_strv_length (port_ifaces); i++) { + char *token = port_ifaces[i]; + /* Skip crazy stuff like regex or all */ + if (!strcmp ("all", token)) { + continue; + } + /* Small SM to skip everything inside regex */ + if (!strcmp ("regex", token)) { + state++; + continue; + } + if (!strcmp ("noregex", token)) { + state--; + continue; + } + if (state == 0 && strlen (token) > 0) { + PLUGIN_PRINT("SCPlugin-Ifupdown", "adding bridge port %s to well_known_interfaces", token); + g_hash_table_insert (priv->well_known_interfaces, g_strdup (token), "known"); + } + } + g_strfreev (port_ifaces); + } + goto next; + } + + /* Skip loopback configuration */ + if(!strcmp ("lo", block->name)) { + goto next; + } + /* Remove any connection for this block that was previously found */ exported = g_hash_table_lookup (priv->iface_connections, block->name); if (exported) { @@ -387,6 +429,7 @@ SCPluginIfupdown_init (NMSystemConfigInterface *config) g_hash_table_insert (priv->well_known_interfaces, block->name, "known"); PLUGIN_PRINT("SCPlugin-Ifupdown", "adding mapping %s to well_known_interfaces", block->name); } + next: block = block->next; } From fd5e8c2f05144d05f4dbafd0efc17253288927c8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 10 Dec 2010 18:50:49 -0600 Subject: [PATCH 034/102] core: fix leak parsing config file --- src/main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main.c b/src/main.c index 7e75f05efb..7a8e7e88ee 100644 --- a/src/main.c +++ b/src/main.c @@ -306,6 +306,7 @@ parse_config_file (const char *filename, GError **error) { GKeyFile *config; + gboolean success = FALSE; config = g_key_file_new (); if (!config) { @@ -316,11 +317,11 @@ parse_config_file (const char *filename, g_key_file_set_list_separator (config, ','); if (!g_key_file_load_from_file (config, filename, G_KEY_FILE_NONE, error)) - return FALSE; + goto out; *plugins = g_key_file_get_value (config, "main", "plugins", error); if (*error) - return FALSE; + goto out; *dhcp_client = g_key_file_get_value (config, "main", "dhcp", NULL); *dns_plugins = g_key_file_get_string_list (config, "main", "dns", NULL, NULL); @@ -328,8 +329,11 @@ parse_config_file (const char *filename, *log_level = g_key_file_get_value (config, "logging", "level", NULL); *log_domains = g_key_file_get_value (config, "logging", "domains", NULL); + success = TRUE; + +out: g_key_file_free (config); - return TRUE; + return success; } static gboolean From 1cd17ac8969ae200b4d30aa5afeb9e5823ab18c6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 11 Dec 2010 11:59:40 -0600 Subject: [PATCH 035/102] supplicant: fix leak updating BSS properties --- src/supplicant-manager/nm-supplicant-interface.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 777d46abe9..24c3b85a12 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -415,6 +415,7 @@ iface_get_props_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_da DBUS_TYPE_G_MAP_OF_VARIANT, &props, G_TYPE_INVALID)) { wpas_iface_properties_changed (NULL, props, info->interface); + g_hash_table_destroy (props); } else { nm_log_warn (LOGD_SUPPLICANT, "could not get interface properties: %s.", error && error->message ? error->message : "(unknown)"); From ea16af7c18ca18101a1be937f951ffe8c9e18165 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 11 Dec 2010 12:31:10 -0600 Subject: [PATCH 036/102] supplicant: fix up return arguments for Disconnect and RemoveNetwork --- .../nm-supplicant-interface.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 24c3b85a12..11064a1904 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -640,26 +640,24 @@ smgr_avail_cb (NMSupplicantManager *smgr, static void remove_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - GError *err = NULL; - guint tmp; + GError *error = NULL; - if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { nm_log_dbg (LOGD_SUPPLICANT, "Couldn't remove network from supplicant interface: %s.", - err->message); - g_error_free (err); + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); } } static void disconnect_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - GError *err = NULL; - guint tmp; + GError *error = NULL; - if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + if (!dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_INVALID)) { nm_log_warn (LOGD_SUPPLICANT, "Couldn't disconnect supplicant interface: %s.", - err->message); - g_error_free (err); + error && error->message ? error->message : "(unknown)"); + g_clear_error (&error); } } From e3ba9162c2ede4ab2cc6eb42021909bc11722562 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 11 Dec 2010 12:33:15 -0600 Subject: [PATCH 037/102] supplicant: fix state handling after READY has been reached We only want to prevent regression to > READY after READY has been reached, since the interface state will track the supplicant connection state which legitimately jumps around. --- src/supplicant-manager/nm-supplicant-interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index 11064a1904..93807b9360 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -289,7 +289,7 @@ set_state (NMSupplicantInterface *self, guint32 new_state) /* Cannot regress to READY, STARTING, or INIT from higher states */ if (priv->state >= NM_SUPPLICANT_INTERFACE_STATE_READY) - g_return_if_fail (new_state > priv->state); + g_return_if_fail (new_state > NM_SUPPLICANT_INTERFACE_STATE_READY); if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { /* Cancel all pending calls when going down */ From ca6e6b620df910b0c1da5aecb17419e18b53f0eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Mon, 13 Dec 2010 16:18:35 +0100 Subject: [PATCH 038/102] examples: add C examples for listing connections from system settings service --- examples/C/Makefile.am | 23 ++- examples/C/list-connections-dbus.c | 83 +++++++++++ examples/C/list-connections-libnm-glib.c | 178 +++++++++++++++++++++++ 3 files changed, 282 insertions(+), 2 deletions(-) create mode 100644 examples/C/list-connections-dbus.c create mode 100644 examples/C/list-connections-libnm-glib.c diff --git a/examples/C/Makefile.am b/examples/C/Makefile.am index 461d1c3403..88f1e48421 100644 --- a/examples/C/Makefile.am +++ b/examples/C/Makefile.am @@ -6,7 +6,11 @@ AM_CPPFLAGS = \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) -noinst_PROGRAMS = add-connection-glib get-active-connections +noinst_PROGRAMS = \ + add-connection-glib \ + get-active-connections \ + list-connections-dbus \ + list-connections-libnm-glib add_connection_glib_SOURCES = add-connection-glib.c add_connection_glib_LDADD = \ @@ -20,7 +24,22 @@ get_active_connections_LDADD = \ $(DBUS_LIBS) \ $(GLIB_LIBS) +list_connections_dbus_SOURCES = list-connections-dbus.c +list_connections_dbus_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + +list_connections_libnm_glib_SOURCES = list-connections-libnm-glib.c +list_connections_libnm_glib_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + EXTRA_DIST = \ add-connection-glib.c \ - get-active-connections.c + get-active-connections.c \ + list-connections-dbus.c \ + list-connections-libnm-glib.c diff --git a/examples/C/list-connections-dbus.c b/examples/C/list-connections-dbus.c new file mode 100644 index 0000000000..957723c4e9 --- /dev/null +++ b/examples/C/list-connections-dbus.c @@ -0,0 +1,83 @@ +/* + * 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 2010 Red Hat, Inc. + */ + +/* + * The example shows how to list connections from System Settings service using direct + * D-Bus call of ListConnections method. + * The example uses dbus-glib, libnm-util libraries. + * + * Compile with: + * gcc -Wall `pkg-config --libs --cflags glib-2.0 dbus-glib-1 libnm-util` list-connections-dbus.c -o list-connections-dbus + */ + +#include +#include +#include + +#include +#include + +#define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH)) + +static void +list_connections (DBusGProxy *proxy) +{ + int i; + GError *error = NULL; + GPtrArray *con_array; + + /* Call ListConnections D-Bus method */ + dbus_g_proxy_call (proxy, "ListConnections", &error, + /* No input arguments */ + G_TYPE_INVALID, + DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH, &con_array, /* Return values */ + G_TYPE_INVALID); + + for (i = 0; con_array && i < con_array->len; i++) { + char *connection_path = g_ptr_array_index (con_array, i); + printf ("%s\n", connection_path); + g_free (connection_path); + } + g_ptr_array_free (con_array, TRUE); +} + +int main (int argc, char *argv[]) +{ + DBusGConnection *bus; + DBusGProxy *proxy; + + /* Initialize GType system */ + g_type_init (); + + /* Get system bus */ + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); + + /* Create a D-Bus proxy; NM_DBUS_* defined in NetworkManager.h */ + proxy = dbus_g_proxy_new_for_name (bus, + NM_DBUS_SERVICE_SYSTEM_SETTINGS, + NM_DBUS_PATH_SETTINGS, + NM_DBUS_IFACE_SETTINGS); + + /* List connections of system settings service */ + list_connections (proxy); + + g_object_unref (proxy); + dbus_g_connection_unref (bus); + + return 0; +} diff --git a/examples/C/list-connections-libnm-glib.c b/examples/C/list-connections-libnm-glib.c new file mode 100644 index 0000000000..4fc2556a4c --- /dev/null +++ b/examples/C/list-connections-libnm-glib.c @@ -0,0 +1,178 @@ +/* + * 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 2010 Red Hat, Inc. + */ + +/* + * The example shows how to list connections from System Settings service using libnm-glib + * (that wraps direct D-Bus calls). + * The example uses dbus-glib, libnm-util and libnm-glib libraries. + * + * Compile with: + * gcc -Wall `pkg-config --libs --cflags glib-2.0 dbus-glib-1 libnm-util libnm-glib` list-connections-libnm-glib.c -o list-connections-libnm-glib + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +/* Global variables */ +GMainLoop *loop = NULL; /* Main loop variable - needed for waiting for signal */ +int result = EXIT_SUCCESS; + +static void +signal_handler (int signo) +{ + if (signo == SIGINT || signo == SIGTERM) { + g_message ("Caught signal %d, shutting down...", signo); + g_main_loop_quit (loop); + } +} + +static void +setup_signals (void) +{ + struct sigaction action; + sigset_t mask; + + sigemptyset (&mask); + action.sa_handler = signal_handler; + action.sa_mask = mask; + action.sa_flags = 0; + sigaction (SIGTERM, &action, NULL); + sigaction (SIGINT, &action, NULL); +} + +/* Print details of connection */ +static void +show_connection (NMConnection *data, gpointer user_data) +{ + NMConnection *connection = (NMConnection *) data; + NMSettingConnection *s_con; + guint64 timestamp; + char *timestamp_str; + char timestamp_real_str[64]; + const char *val1, *val2, *val3, *val4, *val5; + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + if (s_con) { + /* Get various info from NMSettingConnection and show it */ + timestamp = nm_setting_connection_get_timestamp (s_con); + timestamp_str = g_strdup_printf ("%" G_GUINT64_FORMAT, timestamp); + strftime (timestamp_real_str, sizeof (timestamp_real_str), "%c", localtime ((time_t *) ×tamp)); + + val1 = nm_setting_connection_get_id (s_con); + val2 = nm_setting_connection_get_uuid (s_con); + val3 = nm_setting_connection_get_connection_type (s_con); + val4 = nm_connection_get_path (connection); + val5 = timestamp ? timestamp_real_str : "never"; + + printf ("%-25s | %s | %-15s | %-43s | %s\n", val1, val2, val3, val4, val5); + + g_free (timestamp_str); + } +} + +/* This callback is called when connections from the settings service are ready. + * Now the connections can be listed. + */ +static void +get_connections_cb (NMSettingsInterface *settings, gpointer user_data) +{ + GSList *system_connections; + + system_connections = nm_settings_interface_list_connections (settings); + + printf ("System connections:\n===================\n"); + + g_slist_foreach (system_connections, (GFunc) show_connection, NULL); + + g_slist_free (system_connections); + g_object_unref (settings); + + /* We are done, exit main loop */ + g_main_loop_quit (loop); +} + +/* Get system settings and then connect to connections-read signal */ +static gboolean +list_connections (gpointer data) +{ + DBusGConnection *bus = (DBusGConnection *) data; + NMRemoteSettingsSystem *system_settings; + gboolean system_settings_running; + + /* Get system settings */ + if (!(system_settings = nm_remote_settings_system_new (bus))) { + g_message ("Error: Could not get system settings."); + result = EXIT_FAILURE; + g_main_loop_quit (loop); + return FALSE; + } + + /* Find out whether setting service is running */ + g_object_get (system_settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &system_settings_running, NULL); + + if (!system_settings_running) { + g_message ("Error: Can't obtain connections: settings service is not running."); + result = EXIT_FAILURE; + g_main_loop_quit (loop); + return FALSE; + } + + /* Connect to signal "connections-read" - emitted when connections are fetched and ready */ + g_signal_connect (system_settings, NM_SETTINGS_INTERFACE_CONNECTIONS_READ, + G_CALLBACK (get_connections_cb), NULL); + + return FALSE; +} + +int main (int argc, char *argv[]) +{ + DBusGConnection *bus; + + /* Initialize GType system */ + g_type_init (); + + /* Get system bus */ + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); + + /* Run list_connections from main loop, because we need to wait for "connections-read" + * signal to have connections ready. The execution will be finished in get_connections_cb() + * callback on the signal. + */ + g_idle_add (list_connections, bus); + + loop = g_main_loop_new (NULL, FALSE); /* Create main loop */ + setup_signals (); /* Setup UNIX signals */ + g_main_loop_run (loop); /* Run main loop */ + + g_main_loop_unref (loop); + dbus_g_connection_unref (bus); + + return result; +} From 1beb2632a0ce5acb1bb2df35a6fb0cc5d4ad83b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Mon, 13 Dec 2010 16:36:46 +0100 Subject: [PATCH 039/102] examples: fix double free() error in get-active-connections --- examples/C/get-active-connections.c | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/C/get-active-connections.c b/examples/C/get-active-connections.c index 689b7ff6e2..a605c2ac4b 100644 --- a/examples/C/get-active-connections.c +++ b/examples/C/get-active-connections.c @@ -212,7 +212,6 @@ get_active_connections (DBusGConnection *bus, DBusGProxy *proxy) /* And print out the details of each active connection */ for (i = 0; i < paths->len; i++) get_active_connection_details (bus, g_ptr_array_index (paths, i)); - g_ptr_array_free (paths, TRUE); out: g_value_unset (&value); From a6dccad94c49a5a9adc845f039e66ea9da034460 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Mon, 13 Dec 2010 17:13:16 +0100 Subject: [PATCH 040/102] examples: trivial comment fix --- examples/C/get-active-connections.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/C/get-active-connections.c b/examples/C/get-active-connections.c index a605c2ac4b..36224d29ad 100644 --- a/examples/C/get-active-connections.c +++ b/examples/C/get-active-connections.c @@ -238,7 +238,7 @@ int main (int argc, char *argv[]) DBUS_INTERFACE_PROPERTIES); g_assert (props_proxy); - /* Add a connection */ + /* Get active connections */ get_active_connections (bus, props_proxy); g_object_unref (props_proxy); From d4ac3cd5936b44021c75dcad00f9249448ae7247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Mon, 13 Dec 2010 20:55:02 +0100 Subject: [PATCH 041/102] libnm-util: fix a memory leaks in nm_setting_to_string() --- libnm-util/nm-setting.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 06994c73de..190199c121 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -620,6 +620,8 @@ nm_setting_to_string (NMSetting *setting) is_serializable = prop_spec->flags & NM_SETTING_PARAM_SERIALIZE; is_default = g_param_value_defaults (prop_spec, &value); + g_value_unset (&value); + if (is_serializable || is_default) { g_string_append (string, " ("); From 5281c9231199dfc62f00e4266452bec3a6169191 Mon Sep 17 00:00:00 2001 From: Kristjan SCHMIDT Date: Wed, 15 Dec 2010 15:17:48 -0600 Subject: [PATCH 042/102] po: add Esperanto translation (bgo #637011) --- po/LINGUAS | 1 + po/eo.po | 1766 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1767 insertions(+) create mode 100644 po/eo.po diff --git a/po/LINGUAS b/po/LINGUAS index 2428598623..f77d9c0d23 100644 --- a/po/LINGUAS +++ b/po/LINGUAS @@ -14,6 +14,7 @@ dz el en_CA en_GB +eo es et eu diff --git a/po/eo.po b/po/eo.po new file mode 100644 index 0000000000..c099b86cd0 --- /dev/null +++ b/po/eo.po @@ -0,0 +1,1766 @@ +# Esperanto translation for NetworkManager +# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010 +# This file is distributed under the same license as the network-manager package. +# +# Patrick (Petriko) OUDEJANS < >, 2010. +# Aisano < >, 2010. +# Kim RIBEIRO < >, 2010. +# Serge LEBLANC < >, 2010. +# Kristjan SCHMIDT , 2010. +# +msgid "" +msgstr "" +"Project-Id-Version: network-manager\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" +"product=NetworkManager&component=general\n" +"POT-Creation-Date: 2010-12-10 15:25+0000\n" +"PO-Revision-Date: 2010-12-11 10:32+0100\n" +"Last-Translator: Kristjan SCHMIDT \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"X-Launchpad-Export-Date: 2010-12-10 16:56+0000\n" +"X-Generator: Launchpad (build Unknown)\n" + +#: ../cli/src/connections.c:60 ../cli/src/connections.c:76 +#: ../cli/src/devices.c:89 ../cli/src/devices.c:102 ../cli/src/devices.c:112 +#: ../cli/src/devices.c:122 ../cli/src/devices.c:135 ../cli/src/devices.c:146 +#: ../cli/src/devices.c:157 ../cli/src/devices.c:166 ../cli/src/devices.c:175 +msgid "NAME" +msgstr "NOMO" + +#. 0 +#: ../cli/src/connections.c:61 ../cli/src/connections.c:77 +msgid "UUID" +msgstr "UUID" + +#. 1 +#: ../cli/src/connections.c:62 +msgid "DEVICES" +msgstr "APARATOJ" + +#. 2 +#: ../cli/src/connections.c:63 ../cli/src/connections.c:79 +msgid "SCOPE" +msgstr "AMPLEKSO" + +#. 3 +#: ../cli/src/connections.c:64 +msgid "DEFAULT" +msgstr "DEFAŬLTA" + +#. 4 +#: ../cli/src/connections.c:65 +msgid "DBUS-SERVICE" +msgstr "DBUS-SERVO" + +#. 5 +#: ../cli/src/connections.c:66 +msgid "SPEC-OBJECT" +msgstr "SPEC-OBJEKTO" + +#. 6 +#: ../cli/src/connections.c:67 +msgid "VPN" +msgstr "VPN" + +#. 7 +#. 2 +#: ../cli/src/connections.c:68 ../cli/src/connections.c:84 +#: ../cli/src/devices.c:64 +msgid "DBUS-PATH" +msgstr "DBUS-VOJO" + +#. 1 +#. 0 +#. 1 +#: ../cli/src/connections.c:78 ../cli/src/devices.c:62 ../cli/src/devices.c:91 +msgid "TYPE" +msgstr "SPECO" + +#. 3 +#: ../cli/src/connections.c:80 +msgid "TIMESTAMP" +msgstr "TEMPINDIKO" + +#. 4 +#: ../cli/src/connections.c:81 +msgid "TIMESTAMP-REAL" +msgstr "REALA-TEMPINDIKO" + +#. 5 +#: ../cli/src/connections.c:82 +msgid "AUTOCONNECT" +msgstr "AŬTOMATA-KONEKTO" + +#. 6 +#: ../cli/src/connections.c:83 +msgid "READONLY" +msgstr "NUR-LEGI" + +#: ../cli/src/connections.c:160 +#, c-format +msgid "" +"Usage: nmcli con { COMMAND | help }\n" +" COMMAND := { list | status | up | down }\n" +"\n" +" list [id | uuid | system | user]\n" +" status\n" +" up id | uuid [iface ] [ap ] [--nowait] [--timeout " +"]\n" +" down id | uuid \n" +msgstr "" +"Uzo: nmcli con { KOMANDO | help }\n" +" KOMANDO := { list | status | up | down }\n" +"\n" +" list [id | uuid | system | user]\n" +" status\n" +" up id | uuid [iface ] [ap ] [--nowait] [--timeout " +"]\n" +" down id | uuid \n" + +#: ../cli/src/connections.c:200 ../cli/src/connections.c:541 +#, c-format +msgid "Error: 'con list': %s" +msgstr "Eraro: 'con list': %s" + +#: ../cli/src/connections.c:202 ../cli/src/connections.c:543 +#, c-format +msgid "Error: 'con list': %s; allowed fields: %s" +msgstr "Eraro: 'con list': %s; permesataj kampoj: %s" + +#: ../cli/src/connections.c:210 +msgid "Connection details" +msgstr "Konektodetaloj" + +#: ../cli/src/connections.c:385 ../cli/src/connections.c:606 +msgid "system" +msgstr "sistemo" + +#: ../cli/src/connections.c:385 ../cli/src/connections.c:606 +msgid "user" +msgstr "uzanto" + +#: ../cli/src/connections.c:387 +msgid "never" +msgstr "neniam" + +#. "CAPABILITIES" +#. Print header +#. "WIFI-PROPERTIES" +#: ../cli/src/connections.c:388 ../cli/src/connections.c:389 +#: ../cli/src/connections.c:607 ../cli/src/connections.c:610 +#: ../cli/src/devices.c:433 ../cli/src/devices.c:558 ../cli/src/devices.c:584 +#: ../cli/src/devices.c:585 ../cli/src/devices.c:586 ../cli/src/devices.c:587 +#: ../cli/src/devices.c:588 ../cli/src/settings.c:508 +#: ../cli/src/settings.c:551 ../cli/src/settings.c:652 +#: ../cli/src/settings.c:926 ../cli/src/settings.c:927 +#: ../cli/src/settings.c:929 ../cli/src/settings.c:931 +#: ../cli/src/settings.c:1056 ../cli/src/settings.c:1057 +#: ../cli/src/settings.c:1058 ../cli/src/settings.c:1137 +#: ../cli/src/settings.c:1138 ../cli/src/settings.c:1139 +#: ../cli/src/settings.c:1140 ../cli/src/settings.c:1141 +#: ../cli/src/settings.c:1142 ../cli/src/settings.c:1143 +#: ../cli/src/settings.c:1144 ../cli/src/settings.c:1145 +#: ../cli/src/settings.c:1146 ../cli/src/settings.c:1147 +#: ../cli/src/settings.c:1148 ../cli/src/settings.c:1149 +#: ../cli/src/settings.c:1224 +msgid "yes" +msgstr "jes" + +#: ../cli/src/connections.c:388 ../cli/src/connections.c:389 +#: ../cli/src/connections.c:607 ../cli/src/connections.c:610 +#: ../cli/src/devices.c:433 ../cli/src/devices.c:558 ../cli/src/devices.c:584 +#: ../cli/src/devices.c:585 ../cli/src/devices.c:586 ../cli/src/devices.c:587 +#: ../cli/src/devices.c:588 ../cli/src/settings.c:508 +#: ../cli/src/settings.c:510 ../cli/src/settings.c:551 +#: ../cli/src/settings.c:652 ../cli/src/settings.c:926 +#: ../cli/src/settings.c:927 ../cli/src/settings.c:929 +#: ../cli/src/settings.c:931 ../cli/src/settings.c:1056 +#: ../cli/src/settings.c:1057 ../cli/src/settings.c:1058 +#: ../cli/src/settings.c:1137 ../cli/src/settings.c:1138 +#: ../cli/src/settings.c:1139 ../cli/src/settings.c:1140 +#: ../cli/src/settings.c:1141 ../cli/src/settings.c:1142 +#: ../cli/src/settings.c:1143 ../cli/src/settings.c:1144 +#: ../cli/src/settings.c:1145 ../cli/src/settings.c:1146 +#: ../cli/src/settings.c:1147 ../cli/src/settings.c:1148 +#: ../cli/src/settings.c:1149 ../cli/src/settings.c:1224 +msgid "no" +msgstr "ne" + +#: ../cli/src/connections.c:462 ../cli/src/connections.c:505 +msgid "System connections" +msgstr "Sistemkonektoj" + +#: ../cli/src/connections.c:467 ../cli/src/connections.c:518 +msgid "User connections" +msgstr "Uzanto-konektoj" + +#: ../cli/src/connections.c:479 ../cli/src/connections.c:1342 +#: ../cli/src/connections.c:1358 ../cli/src/connections.c:1367 +#: ../cli/src/connections.c:1378 ../cli/src/connections.c:1463 +#: ../cli/src/devices.c:964 ../cli/src/devices.c:974 ../cli/src/devices.c:1076 +#: ../cli/src/devices.c:1083 +#, c-format +msgid "Error: %s argument is missing." +msgstr "Eraro: argumento %s mankas." + +#: ../cli/src/connections.c:492 +#, c-format +msgid "Error: %s - no such connection." +msgstr "Eraro: %s - neniu tia konekto" + +#: ../cli/src/connections.c:524 ../cli/src/connections.c:1391 +#: ../cli/src/connections.c:1481 ../cli/src/devices.c:787 +#: ../cli/src/devices.c:854 ../cli/src/devices.c:988 ../cli/src/devices.c:1089 +#, c-format +msgid "Unknown parameter: %s\n" +msgstr "Nekonata parametro: %s\n" + +#: ../cli/src/connections.c:533 +#, c-format +msgid "Error: no valid parameter specified." +msgstr "Eraro: neniu valida parametro difinita." + +#: ../cli/src/connections.c:548 ../cli/src/connections.c:1584 +#: ../cli/src/devices.c:1295 ../cli/src/network-manager.c:359 +#, c-format +msgid "Error: %s." +msgstr "Eraro: %s." + +#: ../cli/src/connections.c:655 +#, c-format +msgid "Error: 'con status': %s" +msgstr "Eraro: 'con status': %s" + +#: ../cli/src/connections.c:657 +#, c-format +msgid "Error: 'con status': %s; allowed fields: %s" +msgstr "Eraro: 'con status': %s; permesataj kampoj: %s" + +#: ../cli/src/connections.c:664 +msgid "Active connections" +msgstr "Aktivaj konektoj" + +#: ../cli/src/connections.c:1034 +#, c-format +msgid "no active connection on device '%s'" +msgstr "neniu aktiva konekto sur aparato '%s'" + +#: ../cli/src/connections.c:1042 +#, c-format +msgid "no active connection or device" +msgstr "neniu aktiva konekto aŭ aparato" + +#: ../cli/src/connections.c:1092 +#, c-format +msgid "device '%s' not compatible with connection '%s'" +msgstr "aparato '%s' ne kongruas kun konekto '%s'" + +#: ../cli/src/connections.c:1094 +#, c-format +msgid "no device found for connection '%s'" +msgstr "neniu aparato trovita por konekto '%s'" + +#: ../cli/src/connections.c:1105 +msgid "activating" +msgstr "enŝaltas" + +#: ../cli/src/connections.c:1107 +msgid "activated" +msgstr "enŝaltite" + +#: ../cli/src/connections.c:1110 ../cli/src/connections.c:1133 +#: ../cli/src/connections.c:1166 ../cli/src/devices.c:247 +#: ../cli/src/devices.c:559 ../cli/src/network-manager.c:94 +#: ../cli/src/network-manager.c:149 ../cli/src/settings.c:473 +msgid "unknown" +msgstr "nekonate" + +#: ../cli/src/connections.c:1119 +msgid "VPN connecting (prepare)" +msgstr "VPN konektas (preparo)" + +#: ../cli/src/connections.c:1121 +msgid "VPN connecting (need authentication)" +msgstr "VPN konektas (bezonas aŭtentigon)" + +#: ../cli/src/connections.c:1123 +msgid "VPN connecting" +msgstr "VPN konektas" + +#: ../cli/src/connections.c:1125 +msgid "VPN connecting (getting IP configuration)" +msgstr "VPN konektas (akiras IP-agordaron)" + +#: ../cli/src/connections.c:1127 +msgid "VPN connected" +msgstr "VPN konektita" + +#: ../cli/src/connections.c:1129 +msgid "VPN connection failed" +msgstr "VPN-konekto fiaskis" + +#: ../cli/src/connections.c:1131 +msgid "VPN disconnected" +msgstr "VPN malkonektis" + +#: ../cli/src/connections.c:1142 +msgid "unknown reason" +msgstr "nekonata kialo" + +#: ../cli/src/connections.c:1144 +msgid "none" +msgstr "nenio" + +#: ../cli/src/connections.c:1146 +msgid "the user was disconnected" +msgstr "la uzanto estis malkonektita" + +#: ../cli/src/connections.c:1148 +msgid "the base network connection was interrupted" +msgstr "la baza retkonekto estis interrompita" + +#: ../cli/src/connections.c:1150 +msgid "the VPN service stopped unexpectedly" +msgstr "la VPN-servo neatendite ĉesis" + +#: ../cli/src/connections.c:1152 +msgid "the VPN service returned invalid configuration" +msgstr "la VPN-servo revenigis nevalidan agordaron" + +#: ../cli/src/connections.c:1154 +msgid "the connection attempt timed out" +msgstr "la konektoprovo eltempiĝis" + +#: ../cli/src/connections.c:1156 +msgid "the VPN service did not start in time" +msgstr "la VPN-servo ne startis ĝustatempe" + +#: ../cli/src/connections.c:1158 +msgid "the VPN service failed to start" +msgstr "la VPN-servo fiaskis starti" + +#: ../cli/src/connections.c:1160 +msgid "no valid VPN secrets" +msgstr "neniu valida VPN-sekreto" + +#: ../cli/src/connections.c:1162 +msgid "invalid VPN secrets" +msgstr "nevalidaj VPN-sekretoj" + +#: ../cli/src/connections.c:1164 +msgid "the connection was removed" +msgstr "la konekto estis forigita" + +#: ../cli/src/connections.c:1178 +#, c-format +msgid "state: %s\n" +msgstr "stato: %s\n" + +#: ../cli/src/connections.c:1181 ../cli/src/connections.c:1207 +#, c-format +msgid "Connection activated\n" +msgstr "Konekto enŝaltita\n" + +#: ../cli/src/connections.c:1184 +#, c-format +msgid "Error: Connection activation failed." +msgstr "Eraro: Enŝalto de konekto fiaskis." + +#: ../cli/src/connections.c:1203 +#, c-format +msgid "state: %s (%d)\n" +msgstr "stato: %s (%d)\n" + +#: ../cli/src/connections.c:1213 +#, c-format +msgid "Error: Connection activation failed: %s." +msgstr "Eraro: Enŝalto de konekto fiaskis: %s." + +#: ../cli/src/connections.c:1230 ../cli/src/devices.c:911 +#, c-format +msgid "Error: Timeout %d sec expired." +msgstr "Eraro: Eltempiĝo finiĝis %d sek." + +#: ../cli/src/connections.c:1273 +#, c-format +msgid "Error: Connection activation failed: %s" +msgstr "Eraro: Enŝalto de konekto fiaskis: %s" + +#: ../cli/src/connections.c:1287 +#, c-format +msgid "Error: Obtaining active connection for '%s' failed." +msgstr "Eraro: Akiro de aktiva konekto por '%s' fiaskis." + +#: ../cli/src/connections.c:1296 +#, c-format +msgid "Active connection state: %s\n" +msgstr "Stato de aktiva konekto: %s\n" + +#: ../cli/src/connections.c:1297 +#, c-format +msgid "Active connection path: %s\n" +msgstr "Vojo de aktiva konekto: %s\n" + +#: ../cli/src/connections.c:1351 ../cli/src/connections.c:1472 +#, c-format +msgid "Error: Unknown connection: %s." +msgstr "Eraro: Nekonata konekto: %s." + +#: ../cli/src/connections.c:1386 ../cli/src/devices.c:982 +#, c-format +msgid "Error: timeout value '%s' is not valid." +msgstr "Eraro: eltempiĝa valoro '%s' ne validas." + +#: ../cli/src/connections.c:1399 ../cli/src/connections.c:1489 +#, c-format +msgid "Error: id or uuid has to be specified." +msgstr "Eraro: id aŭ uuid devas esti specifata." + +#: ../cli/src/connections.c:1419 +#, c-format +msgid "Error: No suitable device found: %s." +msgstr "Eraro: Trovis neniun taŭgan aparaton: %s." + +#: ../cli/src/connections.c:1421 +#, c-format +msgid "Error: No suitable device found." +msgstr "Eraro: Trovis neniun taŭgan aparaton." + +#: ../cli/src/connections.c:1516 +#, c-format +msgid "Warning: Connection not active\n" +msgstr "Atenton: Konekto ne aktivas\n" + +#: ../cli/src/connections.c:1573 +#, c-format +msgid "Error: 'con' command '%s' is not valid." +msgstr "Eraro: 'con'-komando '%s' ne validas." + +#: ../cli/src/connections.c:1609 +#, c-format +msgid "Error: could not connect to D-Bus." +msgstr "Eraro: ne povis konekti al D-Bus." + +#: ../cli/src/connections.c:1616 +#, c-format +msgid "Error: Could not get system settings." +msgstr "Eraro: Ne povis akiri sistemajn agordojn." + +#: ../cli/src/connections.c:1624 +#, c-format +msgid "Error: Could not get user settings." +msgstr "Eraro: Ne povis akiri uzanto-agordojn." + +#: ../cli/src/connections.c:1634 +#, c-format +msgid "Error: Can't obtain connections: settings services are not running." +msgstr "Eraro: Ne povas obteni konektojn: agordo-servoj ne aktivas." + +#. 0 +#. 9 +#: ../cli/src/devices.c:61 ../cli/src/devices.c:90 ../cli/src/devices.c:185 +msgid "DEVICE" +msgstr "APARATO" + +#. 1 +#. 4 +#. 0 +#: ../cli/src/devices.c:63 ../cli/src/devices.c:94 +#: ../cli/src/network-manager.c:36 +msgid "STATE" +msgstr "STATO" + +#: ../cli/src/devices.c:73 +msgid "GENERAL" +msgstr "ĜENERALA" + +#. 0 +#: ../cli/src/devices.c:74 +msgid "CAPABILITIES" +msgstr "KAPABLOJ" + +#. 1 +#: ../cli/src/devices.c:75 +msgid "WIFI-PROPERTIES" +msgstr "WIFI-ECOJ" + +#. 2 +#: ../cli/src/devices.c:76 +msgid "AP" +msgstr "AP" + +#. 3 +#: ../cli/src/devices.c:77 +msgid "WIRED-PROPERTIES" +msgstr "DRATA-ECOJ" + +#. 4 +#: ../cli/src/devices.c:78 +msgid "IP4-SETTINGS" +msgstr "IP4-AGORDOJ" + +#. 5 +#: ../cli/src/devices.c:79 +msgid "IP4-DNS" +msgstr "IP4-DNS" + +#. 6 +#: ../cli/src/devices.c:80 +msgid "IP6-SETTINGS" +msgstr "IP6-AGORDOJ" + +#. 7 +#: ../cli/src/devices.c:81 +msgid "IP6-DNS" +msgstr "IP6-DNS" + +#. 2 +#: ../cli/src/devices.c:92 +msgid "DRIVER" +msgstr "PELILO" + +#. 3 +#: ../cli/src/devices.c:93 +msgid "HWADDR" +msgstr "APARATADRESO" + +#. 0 +#: ../cli/src/devices.c:103 +msgid "CARRIER-DETECT" +msgstr "PORTANTO-REKONO" + +#. 1 +#: ../cli/src/devices.c:104 +msgid "SPEED" +msgstr "RAPIDO" + +#. 0 +#: ../cli/src/devices.c:113 +msgid "CARRIER" +msgstr "PORTANTO" + +#. 0 +#: ../cli/src/devices.c:123 +msgid "WEP" +msgstr "WEP" + +#. 1 +#: ../cli/src/devices.c:124 +msgid "WPA" +msgstr "WPA" + +#. 2 +#: ../cli/src/devices.c:125 +msgid "WPA2" +msgstr "WPA2" + +#. 3 +#: ../cli/src/devices.c:126 +msgid "TKIP" +msgstr "TKIP" + +#. 4 +#: ../cli/src/devices.c:127 +msgid "CCMP" +msgstr "CCMP" + +#. 0 +#: ../cli/src/devices.c:136 ../cli/src/devices.c:147 +msgid "ADDRESS" +msgstr "ADRESO" + +#. 1 +#: ../cli/src/devices.c:137 ../cli/src/devices.c:148 +msgid "PREFIX" +msgstr "PREFIKSO" + +#. 2 +#: ../cli/src/devices.c:138 ../cli/src/devices.c:149 +msgid "GATEWAY" +msgstr "KLUZO" + +#. 0 +#: ../cli/src/devices.c:158 ../cli/src/devices.c:167 +msgid "DNS" +msgstr "DNS" + +#. 0 +#: ../cli/src/devices.c:176 +msgid "SSID" +msgstr "SSID" + +#. 1 +#: ../cli/src/devices.c:177 +msgid "BSSID" +msgstr "BSSID" + +#. 2 +#: ../cli/src/devices.c:178 +msgid "MODE" +msgstr "REĜIMO" + +#. 3 +#: ../cli/src/devices.c:179 +msgid "FREQ" +msgstr "FREKV" + +#. 4 +#: ../cli/src/devices.c:180 +msgid "RATE" +msgstr "TRANSMETRAPIDO" + +#. 5 +#: ../cli/src/devices.c:181 +msgid "SIGNAL" +msgstr "SIGNALO" + +#. 6 +#: ../cli/src/devices.c:182 +msgid "SECURITY" +msgstr "SEKURECO" + +#. 7 +#: ../cli/src/devices.c:183 +msgid "WPA-FLAGS" +msgstr "WPA-FLAGOJ" + +#. 8 +#: ../cli/src/devices.c:184 +msgid "RSN-FLAGS" +msgstr "RSN-FLAGOJ" + +#. 10 +#: ../cli/src/devices.c:186 +msgid "ACTIVE" +msgstr "AKTIVA" + +#: ../cli/src/devices.c:209 +#, c-format +msgid "" +"Usage: nmcli dev { COMMAND | help }\n" +"\n" +" COMMAND := { status | list | disconnect | wifi }\n" +"\n" +" status\n" +" list [iface ]\n" +" disconnect iface [--nowait] [--timeout ]\n" +" wifi [list [iface ] [hwaddr ]]\n" +"\n" +msgstr "" +"Usage: nmcli dev { KOMANDO | help }\n" +"\n" +" KOMANDO := { status | list | disconnect | wifi }\n" +"\n" +" status\n" +" list [iface ]\n" +" disconnect iface [--nowait] [--timeout ]\n" +" wifi [list [iface ] [hwaddr ]]\n" +"\n" + +#: ../cli/src/devices.c:229 +msgid "unmanaged" +msgstr "nemastrumata" + +#: ../cli/src/devices.c:231 +msgid "unavailable" +msgstr "neatingebla" + +#: ../cli/src/devices.c:233 ../cli/src/network-manager.c:91 +msgid "disconnected" +msgstr "nekonektite" + +#: ../cli/src/devices.c:235 +msgid "connecting (prepare)" +msgstr "konektas (preparo)" + +#: ../cli/src/devices.c:237 +msgid "connecting (configuring)" +msgstr "konektas (agordado)" + +#: ../cli/src/devices.c:239 +msgid "connecting (need authentication)" +msgstr "konektas (bezonas aŭtentigon)" + +#: ../cli/src/devices.c:241 +msgid "connecting (getting IP configuration)" +msgstr "konektas (akiras IP-agordaron)" + +#: ../cli/src/devices.c:243 ../cli/src/network-manager.c:89 +msgid "connected" +msgstr "konektita" + +#: ../cli/src/devices.c:245 +msgid "connection failed" +msgstr "konekto fiaskis" + +#: ../cli/src/devices.c:268 ../cli/src/devices.c:425 +msgid "Unknown" +msgstr "Nekonata" + +#: ../cli/src/devices.c:300 +msgid "(none)" +msgstr "(nenio)" + +#: ../cli/src/devices.c:325 +#, c-format +msgid "%s: error converting IP4 address 0x%X" +msgstr "%s: eraro dum konverto de IP4-adreso 0x%X" + +#: ../cli/src/devices.c:394 +#, c-format +msgid "%u MHz" +msgstr "%u MHz" + +#: ../cli/src/devices.c:395 +#, c-format +msgid "%u MB/s" +msgstr "%u MB/s" + +#: ../cli/src/devices.c:404 +msgid "Encrypted: " +msgstr "Ĉifrita: " + +#: ../cli/src/devices.c:409 +msgid "WEP " +msgstr "WEP " + +#: ../cli/src/devices.c:411 +msgid "WPA " +msgstr "WPA " + +#: ../cli/src/devices.c:413 +msgid "WPA2 " +msgstr "WPA2 " + +#: ../cli/src/devices.c:416 +msgid "Enterprise " +msgstr "Entrepreno " + +#: ../cli/src/devices.c:425 +msgid "Ad-Hoc" +msgstr "Laŭcela" + +#: ../cli/src/devices.c:425 +msgid "Infrastructure" +msgstr "Infrastrukturo" + +#: ../cli/src/devices.c:487 +#, c-format +msgid "Error: 'dev list': %s" +msgstr "Eraro: 'dev list': %s" + +#: ../cli/src/devices.c:489 +#, c-format +msgid "Error: 'dev list': %s; allowed fields: %s" +msgstr "Eraro: 'dev list': %s; permesataj kampoj: %s" + +#: ../cli/src/devices.c:498 +msgid "Device details" +msgstr "Detaloj de aparato" + +#: ../cli/src/devices.c:528 ../cli/src/devices.c:927 +msgid "(unknown)" +msgstr "(nekonata)" + +#: ../cli/src/devices.c:529 +msgid "unknown)" +msgstr "nekonata)" + +#: ../cli/src/devices.c:555 +#, c-format +msgid "%u Mb/s" +msgstr "%u Mb/s" + +#. Print header +#. "WIRED-PROPERTIES" +#: ../cli/src/devices.c:628 +msgid "on" +msgstr "enŝaltite" + +#: ../cli/src/devices.c:628 +msgid "off" +msgstr "elŝaltite" + +#: ../cli/src/devices.c:810 +#, c-format +msgid "Error: 'dev status': %s" +msgstr "Eraro: 'dev status': %s" + +#: ../cli/src/devices.c:812 +#, c-format +msgid "Error: 'dev status': %s; allowed fields: %s" +msgstr "Eraro: 'dev status': %s; permesataj kampoj: %s" + +#: ../cli/src/devices.c:819 +msgid "Status of devices" +msgstr "Stato de aparatoj" + +#: ../cli/src/devices.c:847 +#, c-format +msgid "Error: '%s' argument is missing." +msgstr "Eraro: argumento '%s' mankas." + +#: ../cli/src/devices.c:876 ../cli/src/devices.c:1015 +#: ../cli/src/devices.c:1138 +#, c-format +msgid "Error: Device '%s' not found." +msgstr "Eraro: Aparato '%s' ne trovita." + +#: ../cli/src/devices.c:899 +#, c-format +msgid "Success: Device '%s' successfully disconnected." +msgstr "Sukceso: Aparato '%s' sukcese malkonektiĝis." + +#: ../cli/src/devices.c:924 +#, c-format +msgid "Error: Device '%s' (%s) disconnecting failed: %s" +msgstr "Eraro: Aparato '%s' (%s) eraro dum malkonektiĝo: %s" + +#: ../cli/src/devices.c:932 +#, c-format +msgid "Device state: %d (%s)\n" +msgstr "Stato de aparato: %d (%s)\n" + +#: ../cli/src/devices.c:996 +#, c-format +msgid "Error: iface has to be specified." +msgstr "Eraro: 'iface' devas esti specifata." + +#: ../cli/src/devices.c:1114 +#, c-format +msgid "Error: 'dev wifi': %s" +msgstr "Eraro: 'dev wifi': %s" + +#: ../cli/src/devices.c:1116 +#, c-format +msgid "Error: 'dev wifi': %s; allowed fields: %s" +msgstr "Eraro: 'dev wifi': %s; permesataj kampoj: %s" + +#: ../cli/src/devices.c:1123 +msgid "WiFi scan list" +msgstr "WiFi-skanlisto" + +#: ../cli/src/devices.c:1158 ../cli/src/devices.c:1212 +#, c-format +msgid "Error: Access point with hwaddr '%s' not found." +msgstr "Eraro: Retkaptejo kun 'hwaddr' '%s' ne trovita" + +#: ../cli/src/devices.c:1175 +#, c-format +msgid "Error: Device '%s' is not a WiFi device." +msgstr "Eraro: Aparato '%s' ne estas WiFi-aparato." + +#: ../cli/src/devices.c:1239 +#, c-format +msgid "Error: 'dev wifi' command '%s' is not valid." +msgstr "Eraro: 'dev wifi'-komando '%s' ne validas." + +#: ../cli/src/devices.c:1286 +#, c-format +msgid "Error: 'dev' command '%s' is not valid." +msgstr "Eraro: 'dev'-komando '%s' ne validas." + +#: ../cli/src/network-manager.c:35 +msgid "RUNNING" +msgstr "AKTIVA" + +#. 1 +#: ../cli/src/network-manager.c:37 +msgid "NET-ENABLED" +msgstr "RET-ENŜALTITE" + +#. 2 +#: ../cli/src/network-manager.c:38 +msgid "WIFI-HARDWARE" +msgstr "WIFI-APARATARO" + +#. 3 +#: ../cli/src/network-manager.c:39 +msgid "WIFI" +msgstr "WIFI" + +#. 4 +#: ../cli/src/network-manager.c:40 +msgid "WWAN-HARDWARE" +msgstr "WWAN-APARATARO" + +#. 5 +#: ../cli/src/network-manager.c:41 +msgid "WWAN" +msgstr "WWAN" + +#: ../cli/src/network-manager.c:64 +#, c-format +msgid "" +"Usage: nmcli nm { COMMAND | help }\n" +"\n" +" COMMAND := { status | enable | sleep | wifi | wwan }\n" +"\n" +" status\n" +" enable [true|false]\n" +" sleep [true|false]\n" +" wifi [on|off]\n" +" wwan [on|off]\n" +"\n" +msgstr "" +"Uzo: nmcli nm { KOMANDO | help }\n" +"\n" +" KOMANDO := { status | enable | sleep | wifi | wwan }\n" +"\n" +" status\n" +" enable [true|false]\n" +" sleep [true|false]\n" +" wifi [on|off]\n" +" wwan [on|off]\n" +"\n" + +#: ../cli/src/network-manager.c:85 +msgid "asleep" +msgstr "dormas" + +#: ../cli/src/network-manager.c:87 +msgid "connecting" +msgstr "konektas" + +#: ../cli/src/network-manager.c:128 +#, c-format +msgid "Error: 'nm status': %s" +msgstr "Eraro: 'nm status': %s" + +#: ../cli/src/network-manager.c:130 +#, c-format +msgid "Error: 'nm status': %s; allowed fields: %s" +msgstr "Eraro: 'nm status': %s; permesataj kampoj: %s" + +#: ../cli/src/network-manager.c:137 +msgid "NetworkManager status" +msgstr "Stato de NetworkManager" + +#. Print header +#: ../cli/src/network-manager.c:144 ../cli/src/network-manager.c:145 +#: ../cli/src/network-manager.c:146 ../cli/src/network-manager.c:147 +#: ../cli/src/network-manager.c:154 ../cli/src/network-manager.c:247 +#: ../cli/src/network-manager.c:296 ../cli/src/network-manager.c:328 +msgid "enabled" +msgstr "enŝaltita" + +#: ../cli/src/network-manager.c:144 ../cli/src/network-manager.c:145 +#: ../cli/src/network-manager.c:146 ../cli/src/network-manager.c:147 +#: ../cli/src/network-manager.c:154 ../cli/src/network-manager.c:247 +#: ../cli/src/network-manager.c:296 ../cli/src/network-manager.c:328 +msgid "disabled" +msgstr "elŝaltite" + +#: ../cli/src/network-manager.c:152 +msgid "running" +msgstr "aktiva" + +#: ../cli/src/network-manager.c:152 +msgid "not running" +msgstr "neaktiva" + +#: ../cli/src/network-manager.c:175 +#, c-format +msgid "Error: Couldn't connect to system bus: %s" +msgstr "Eraro: Ne povis konekti al sistem-buso: %s." + +#: ../cli/src/network-manager.c:186 +#, c-format +msgid "Error: Couldn't create D-Bus object proxy." +msgstr "Eraro: Ne povis krei D-busan objekt-prokurservilon." + +#: ../cli/src/network-manager.c:192 +#, c-format +msgid "Error in sleep: %s" +msgstr "Eraro dum dormo: %s" + +#: ../cli/src/network-manager.c:237 ../cli/src/network-manager.c:286 +#: ../cli/src/network-manager.c:318 +#, c-format +msgid "Error: '--fields' value '%s' is not valid here; allowed fields: %s" +msgstr "Eraro: valoro '--fields' '%s' ne validas tie ĉi; permesataj kampoj: %s" + +#: ../cli/src/network-manager.c:245 +msgid "Networking enabled" +msgstr "Retkonektado enŝaltita" + +#: ../cli/src/network-manager.c:256 +#, c-format +msgid "Error: invalid 'enable' parameter: '%s'; use 'true' or 'false'." +msgstr "Eraro: nevalida 'enŝalt'-parametro: '%s'; uzu 'true' aŭ 'false'." + +#: ../cli/src/network-manager.c:265 +#, c-format +msgid "Error: Sleeping status is not exported by NetworkManager." +msgstr "Eraro: Dorm-stato ne estas elportite de NetworkManager." + +#: ../cli/src/network-manager.c:273 +#, c-format +msgid "Error: invalid 'sleep' parameter: '%s'; use 'true' or 'false'." +msgstr "Eraro: nevalida 'dorm'-parametro: '%s'; uzu 'true' aŭ 'false'." + +#: ../cli/src/network-manager.c:294 +msgid "WiFi enabled" +msgstr "WiFi enŝaltita" + +#: ../cli/src/network-manager.c:305 +#, c-format +msgid "Error: invalid 'wifi' parameter: '%s'." +msgstr "Eraro: nevalida 'wifi'-parametro: '%s'." + +#: ../cli/src/network-manager.c:326 +msgid "WWAN enabled" +msgstr "WWAN enŝaltita" + +#: ../cli/src/network-manager.c:337 +#, c-format +msgid "Error: invalid 'wwan' parameter: '%s'." +msgstr "Eraro: nevalida 'wwan'-parametro: '%s'." + +#: ../cli/src/network-manager.c:348 +#, c-format +msgid "Error: 'nm' command '%s' is not valid." +msgstr "Eraro: 'nm'-komando '%s' ne validas." + +#: ../cli/src/nmcli.c:69 +#, c-format +msgid "" +"Usage: %s [OPTIONS] OBJECT { COMMAND | help }\n" +"\n" +"OPTIONS\n" +" -t[erse] terse output\n" +" -p[retty] pretty output\n" +" -m[ode] tabular|multiline output mode\n" +" -f[ields] |all|common specify fields to output\n" +" -e[scape] yes|no escape columns separators in " +"values\n" +" -v[ersion] show program version\n" +" -h[elp] print this help\n" +"\n" +"OBJECT\n" +" nm NetworkManager status\n" +" con NetworkManager connections\n" +" dev devices managed by NetworkManager\n" +"\n" +msgstr "" +"Uzo: %s [OPCIOJ] OBJEKTO { KOMANDO | help }\n" +"\n" +"OPCIOJ\n" +" -t[erse] konciza eligo\n" +" -p[retty] bela eligo\n" +" -m[ode] tabular|multiline eliga reĝimo\n" +" -f[ields] |all|common specifigi eligo-kampojn\n" +" -e[scape] yes|no eskapaj kolumno-separoj en " +"valoroj\n" +" -v[ersion] montri programversion\n" +" -h[elp] printi tiun ĉi help-paĝon\n" +"\n" +"OBJEKTO\n" +" nm stato de NetworkManager\n" +" con konektoj de NetworkManager\n" +" dev aparatoj mastrumataj de NetworkManager\n" +"\n" + +#: ../cli/src/nmcli.c:113 +#, c-format +msgid "Error: Object '%s' is unknown, try 'nmcli help'." +msgstr "Eraro: Objekto '%s' estas nekonata, provu: 'nmcli help'." + +#: ../cli/src/nmcli.c:143 +#, c-format +msgid "Error: Option '--terse' is specified the second time." +msgstr "Eraro: Opcio '--terse' specifiĝis duan fojon." + +#: ../cli/src/nmcli.c:148 +#, c-format +msgid "Error: Option '--terse' is mutually exclusive with '--pretty'." +msgstr "Eraro: Opcioj '--terse' kaj '--pretty' ekskludas unu la alian." + +#: ../cli/src/nmcli.c:156 +#, c-format +msgid "Error: Option '--pretty' is specified the second time." +msgstr "Eraro: Opcio '--pretty' specifiĝis duan fojon." + +#: ../cli/src/nmcli.c:161 +#, c-format +msgid "Error: Option '--pretty' is mutually exclusive with '--terse'." +msgstr "Eraro: Opcioj '--pretty' kaj '--terse' ekskludas unu la alian." + +#: ../cli/src/nmcli.c:171 ../cli/src/nmcli.c:187 +#, c-format +msgid "Error: missing argument for '%s' option." +msgstr "Eraro: mankas argumento por elektindaĵo '%s'." + +#: ../cli/src/nmcli.c:180 ../cli/src/nmcli.c:196 +#, c-format +msgid "Error: '%s' is not valid argument for '%s' option." +msgstr "Eraro: '%s' ne estas valida argumento por elektindaĵo '%s'." + +#: ../cli/src/nmcli.c:203 +#, c-format +msgid "Error: fields for '%s' options are missing." +msgstr "Eraro: kampoj por elektindaĵoj '%s' mankas." + +#: ../cli/src/nmcli.c:209 +#, c-format +msgid "nmcli tool, version %s\n" +msgstr "ilo 'nmcli', versio %s\n" + +#: ../cli/src/nmcli.c:215 +#, c-format +msgid "Error: Option '%s' is unknown, try 'nmcli -help'." +msgstr "Eraro: Opcio '%s' estas nekonata, provu: 'nmcli -help'." + +#: ../cli/src/nmcli.c:234 +#, c-format +msgid "Caught signal %d, shutting down..." +msgstr "Ricevis signalon '%d', elŝaltas..." + +#: ../cli/src/nmcli.c:259 +#, c-format +msgid "Error: Could not connect to NetworkManager." +msgstr "Eraro: Ne eblis konekti al NetworkManager" + +#: ../cli/src/nmcli.c:275 +msgid "Success" +msgstr "Sukceso" + +#: ../cli/src/settings.c:411 +#, c-format +msgid "%d (hex-ascii-key)" +msgstr "%d (heks-ascii-ŝlosilo)" + +#: ../cli/src/settings.c:413 +#, c-format +msgid "%d (104/128-bit passphrase)" +msgstr "%d (104/128-bita pasvorto)" + +#: ../cli/src/settings.c:416 +#, c-format +msgid "%d (unknown)" +msgstr "%d (nekonata)" + +#: ../cli/src/settings.c:442 +msgid "0 (unknown)" +msgstr "0 (nekonata)" + +#: ../cli/src/settings.c:448 +msgid "any, " +msgstr "ajna, " + +#: ../cli/src/settings.c:450 +msgid "900 MHz, " +msgstr "900 MHz, " + +#: ../cli/src/settings.c:452 +msgid "1800 MHz, " +msgstr "1800 MHz, " + +#: ../cli/src/settings.c:454 +msgid "1900 MHz, " +msgstr "1900 MHz, " + +#: ../cli/src/settings.c:456 +msgid "850 MHz, " +msgstr "850 MHz, " + +#: ../cli/src/settings.c:458 +msgid "WCDMA 3GPP UMTS 2100 MHz, " +msgstr "WCDMA 3GPP UMTS 2100 MHz, " + +#: ../cli/src/settings.c:460 +msgid "WCDMA 3GPP UMTS 1800 MHz, " +msgstr "WCDMA 3GPP UMTS 1800 MHz, " + +#: ../cli/src/settings.c:462 +msgid "WCDMA 3GPP UMTS 1700/2100 MHz, " +msgstr "WCDMA 3GPP UMTS 1700/2100 MHz, " + +#: ../cli/src/settings.c:464 +msgid "WCDMA 3GPP UMTS 800 MHz, " +msgstr "WCDMA 3GPP UMTS 800 MHz, " + +#: ../cli/src/settings.c:466 +msgid "WCDMA 3GPP UMTS 850 MHz, " +msgstr "WCDMA 3GPP UMTS 850 MHz, " + +#: ../cli/src/settings.c:468 +msgid "WCDMA 3GPP UMTS 900 MHz, " +msgstr "WCDMA 3GPP UMTS 900 MHz, " + +#: ../cli/src/settings.c:470 +msgid "WCDMA 3GPP UMTS 1700 MHz, " +msgstr "WCDMA 3GPP UMTS 1700 MHz, " + +#: ../cli/src/settings.c:554 ../cli/src/settings.c:721 +msgid "auto" +msgstr "aŭto" + +#: ../cli/src/settings.c:716 ../cli/src/settings.c:719 +#: ../cli/src/settings.c:720 ../cli/src/utils.c:172 +msgid "not set" +msgstr "neagordita" + +#: ../cli/src/utils.c:124 +#, c-format +msgid "field '%s' has to be alone" +msgstr "kampo '%s' devas esti sola" + +#: ../cli/src/utils.c:127 +#, c-format +msgid "invalid field '%s'" +msgstr "nevalida kampo '%s'" + +#: ../cli/src/utils.c:146 +#, c-format +msgid "Option '--terse' requires specifying '--fields'" +msgstr "Elektindaĵo '--terse' postulas specifigon de '--fields'" + +#: ../cli/src/utils.c:150 +#, c-format +msgid "Option '--terse' requires specific '--fields' option values , not '%s'" +msgstr "" +"Elektindaĵo '--terse' postulas specifajn elektindajn valorojn de '--fields', " +"ne '%s'" + +#: ../libnm-util/crypto.c:121 +#, c-format +msgid "PEM key file had no end tag '%s'." +msgstr "PEM-ŝlosil-dosiero ne havis finan etikedon '%s'." + +#: ../libnm-util/crypto.c:131 +#, c-format +msgid "Doesn't look like a PEM private key file." +msgstr "Tio ĉi ne aspektas kiel privat-ŝlosila PEM-dosiero." + +#: ../libnm-util/crypto.c:139 +#, c-format +msgid "Not enough memory to store PEM file data." +msgstr "Malsufiĉas memoro por stori datenojn de PEM-dosiero." + +#: ../libnm-util/crypto.c:155 +#, c-format +msgid "Malformed PEM file: Proc-Type was not first tag." +msgstr "Misforma PEM-dosiero: 'Proc-Type' ne estas la unua etikedo." + +#: ../libnm-util/crypto.c:163 +#, c-format +msgid "Malformed PEM file: unknown Proc-Type tag '%s'." +msgstr "Misforma PEM-dosiero: nekonata Proc-Type-etikedo \"%s\"." + +#: ../libnm-util/crypto.c:173 +#, c-format +msgid "Malformed PEM file: DEK-Info was not the second tag." +msgstr "Misforma PEM-dosiero: 'DEK-Info' ne estas la dua etikedo." + +#: ../libnm-util/crypto.c:184 +#, c-format +msgid "Malformed PEM file: no IV found in DEK-Info tag." +msgstr "Misforma PEM-dosiero: mi ne trovis IV en la etikedo \"DEK-Info\"." + +#: ../libnm-util/crypto.c:191 +#, c-format +msgid "Malformed PEM file: invalid format of IV in DEK-Info tag." +msgstr "" +"Misforma PEM-dosiero: nevalida struktturo de IV en la etikedo \"DEK-Info\"." + +#: ../libnm-util/crypto.c:204 +#, c-format +msgid "Malformed PEM file: unknown private key cipher '%s'." +msgstr "Misforma PEM-dosiero: nekonata privat-ŝlosila ĉifro \"%s\"." + +#: ../libnm-util/crypto.c:223 +#, c-format +msgid "Could not decode private key." +msgstr "Ne eblis malĉifri la privatan ŝlosilon." + +#: ../libnm-util/crypto.c:268 +#, c-format +msgid "PEM certificate '%s' had no end tag '%s'." +msgstr "La PEM-certigilo \"%s\" ne havas finan etikedon \"%s\"." + +#: ../libnm-util/crypto.c:278 +#, c-format +msgid "Failed to decode certificate." +msgstr "Malsuksesis malĉifri la certigilon." + +#: ../libnm-util/crypto.c:287 +#, c-format +msgid "Not enough memory to store certificate data." +msgstr "Malsufiĉas memoro por stori la datenojn de la certigilo." + +#: ../libnm-util/crypto.c:295 +#, c-format +msgid "Not enough memory to store file data." +msgstr "Malsufiĉas memoro por stori la datenojn de la dosiero." + +#: ../libnm-util/crypto.c:325 +#, c-format +msgid "IV must be an even number of bytes in length." +msgstr "IV nepre amkplesu paran nombron da bajtoj." + +#: ../libnm-util/crypto.c:334 +#, c-format +msgid "Not enough memory to store the IV." +msgstr "Malsufiĉas memoro por stori la IV-on." + +#: ../libnm-util/crypto.c:345 +#, c-format +msgid "IV contains non-hexadecimal digits." +msgstr "IV enhavas nedeksesumajn ciferojn" + +#: ../libnm-util/crypto.c:383 ../libnm-util/crypto_gnutls.c:148 +#: ../libnm-util/crypto_gnutls.c:266 ../libnm-util/crypto_nss.c:171 +#: ../libnm-util/crypto_nss.c:336 +#, c-format +msgid "Private key cipher '%s' was unknown." +msgstr "Privata Cipher-ŝlosilo '%s' estas nekonata." + +#: ../libnm-util/crypto.c:392 +#, c-format +msgid "Not enough memory to decrypt private key." +msgstr "Nesufiĉa memoro por malĉifri privatan ŝlosilon." + +#: ../libnm-util/crypto.c:512 +#, c-format +msgid "Unable to determine private key type." +msgstr "Ne eblas determini la tipon de la privata ŝlosilo." + +#: ../libnm-util/crypto.c:531 +#, c-format +msgid "Not enough memory to store decrypted private key." +msgstr "Nesufiĉa memoro por gardi privatan ŝlosilon malĉifritan." + +#: ../libnm-util/crypto_gnutls.c:49 +msgid "Failed to initialize the crypto engine." +msgstr "Pretigo de la kriptografia maŝino fiaskis." + +#: ../libnm-util/crypto_gnutls.c:93 +#, c-format +msgid "Failed to initialize the MD5 engine: %s / %s." +msgstr "Pretigo de la MD5-maŝino fiaskis: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:156 +#, c-format +msgid "Invalid IV length (must be at least %zd)." +msgstr "Nevalida amplekso por IV (devas esti almenaŭ %zd)." + +#: ../libnm-util/crypto_gnutls.c:165 ../libnm-util/crypto_nss.c:188 +#, c-format +msgid "Not enough memory for decrypted key buffer." +msgstr "Nesufiĉa memoro por bufro de la malĉifrita ŝlosilo." + +#: ../libnm-util/crypto_gnutls.c:173 +#, c-format +msgid "Failed to initialize the decryption cipher context: %s / %s." +msgstr "Fiaskis pravalorizi la malĉifran Cipher-kuntekston: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:182 +#, c-format +msgid "Failed to set symmetric key for decryption: %s / %s." +msgstr "Fiaskis agordi simetrian ŝlosilon por malĉifro: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:191 +#, c-format +msgid "Failed to set IV for decryption: %s / %s." +msgstr "Fiaskis agordi IV por malĉifro: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:200 +#, c-format +msgid "Failed to decrypt the private key: %s / %s." +msgstr "Fiaskis malĉifri la privatan ŝlosilon: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:210 ../libnm-util/crypto_nss.c:267 +#, c-format +msgid "Failed to decrypt the private key: unexpected padding length." +msgstr "Fiaskis malĉifri la privatan ŝlosilon: neatendita ŝtopada longo." + +#: ../libnm-util/crypto_gnutls.c:221 ../libnm-util/crypto_nss.c:278 +#, c-format +msgid "Failed to decrypt the private key." +msgstr "Fiaskis malĉifri la privatan ŝlosilon." + +#: ../libnm-util/crypto_gnutls.c:286 ../libnm-util/crypto_nss.c:356 +#, c-format +msgid "Could not allocate memory for encrypting." +msgstr "Ne eblis rezervi memoron por ĉifrado." + +#: ../libnm-util/crypto_gnutls.c:294 +#, c-format +msgid "Failed to initialize the encryption cipher context: %s / %s." +msgstr "Fiaskis valorizi la ĉifradan kuntekston: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:303 +#, c-format +msgid "Failed to set symmetric key for encryption: %s / %s." +msgstr "Fiaskis agordi simetrian ŝlosilon por ĉifrado: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:313 +#, c-format +msgid "Failed to set IV for encryption: %s / %s." +msgstr "Fiaskis agordi IV por ĉifrado: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:322 +#, c-format +msgid "Failed to encrypt the data: %s / %s." +msgstr "Ĉifrado de datumoj malsukcesis: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:362 +#, c-format +msgid "Error initializing certificate data: %s" +msgstr "Eraro dum pravalorizo de atestilaj datumoj: %s" + +#: ../libnm-util/crypto_gnutls.c:384 +#, c-format +msgid "Couldn't decode certificate: %s" +msgstr "Ne povis malkodi certigilon: %s" + +#: ../libnm-util/crypto_gnutls.c:408 +#, c-format +msgid "Couldn't initialize PKCS#12 decoder: %s" +msgstr "Ne povis pravalorizi PKCS#12-malkodilon: %s" + +#: ../libnm-util/crypto_gnutls.c:421 +#, c-format +msgid "Couldn't decode PKCS#12 file: %s" +msgstr "Ne eblis dekodi PKCS#12-dosieron: %s" + +#: ../libnm-util/crypto_gnutls.c:433 +#, c-format +msgid "Couldn't verify PKCS#12 file: %s" +msgstr "No povis kontroli PKCS#12-dosieron: %s" + +#: ../libnm-util/crypto_nss.c:56 +#, c-format +msgid "Failed to initialize the crypto engine: %d." +msgstr "Pravalorigo de la kriptografia maŝino fiaskis: %d." + +#: ../libnm-util/crypto_nss.c:111 +#, c-format +msgid "Failed to initialize the MD5 context: %d." +msgstr "Fiaskis pravalorizi la MD5-kuntekston: %d." + +#: ../libnm-util/crypto_nss.c:179 +#, c-format +msgid "Invalid IV length (must be at least %d)." +msgstr "Nevalida IV-longo (devas esti almenaŭ %d)." + +#: ../libnm-util/crypto_nss.c:196 +#, c-format +msgid "Failed to initialize the decryption cipher slot." +msgstr "Fiaskis pravalorizi la malĉifran Cipher-foldon." + +#: ../libnm-util/crypto_nss.c:206 +#, c-format +msgid "Failed to set symmetric key for decryption." +msgstr "Fiaskis agordi simetrian ŝlosilon por malĉifrado." + +#: ../libnm-util/crypto_nss.c:216 +#, c-format +msgid "Failed to set IV for decryption." +msgstr "Fiaskis agordi IV por malĉifrado." + +#: ../libnm-util/crypto_nss.c:224 +#, c-format +msgid "Failed to initialize the decryption context." +msgstr "Fiaskis pravalorizi la malĉifran kuntekston." + +#: ../libnm-util/crypto_nss.c:237 +#, c-format +msgid "Failed to decrypt the private key: %d." +msgstr "Fiaskis malĉifri la privatan ŝlosilon: %d." + +#: ../libnm-util/crypto_nss.c:245 +#, c-format +msgid "Failed to decrypt the private key: decrypted data too large." +msgstr "Fiaskis malĉifri la privatan ŝlosilon: malĉifritaj datumoj tro longas." + +#: ../libnm-util/crypto_nss.c:256 +#, c-format +msgid "Failed to finalize decryption of the private key: %d." +msgstr "Fiaskis fini malĉifradon de la privata ŝlosilo: %d." + +#: ../libnm-util/crypto_nss.c:364 +#, c-format +msgid "Failed to initialize the encryption cipher slot." +msgstr "Fiaskis pravalorizi la ĉifran Cipher-foldon." + +#: ../libnm-util/crypto_nss.c:372 +#, c-format +msgid "Failed to set symmetric key for encryption." +msgstr "Fiaskis agordi simetrian ŝlosilon por ĉifrado." + +#: ../libnm-util/crypto_nss.c:380 +#, c-format +msgid "Failed to set IV for encryption." +msgstr "Fiaskis agordi IV por ĉifrado." + +#: ../libnm-util/crypto_nss.c:388 +#, c-format +msgid "Failed to initialize the encryption context." +msgstr "Fiaskis pravalorizi la ĉifradan kuntekston." + +#: ../libnm-util/crypto_nss.c:396 +#, c-format +msgid "Failed to encrypt: %d." +msgstr "Fiaskis ĉifri: %d." + +#: ../libnm-util/crypto_nss.c:404 +#, c-format +msgid "Unexpected amount of data after encrypting." +msgstr "Neatendita nombro da datumoj post ĉifrado." + +#: ../libnm-util/crypto_nss.c:447 +#, c-format +msgid "Couldn't decode certificate: %d" +msgstr "Ne povis malkodigi atestilon: %d" + +#: ../libnm-util/crypto_nss.c:482 +#, c-format +msgid "Couldn't convert password to UCS2: %d" +msgstr "Ne povis konverti pasvorton al UCS2: %d" + +#: ../libnm-util/crypto_nss.c:510 +#, c-format +msgid "Couldn't initialize PKCS#12 decoder: %d" +msgstr "Ne povis pravalorizi PKCS#12-malkodilon: %d" + +#: ../libnm-util/crypto_nss.c:519 +#, c-format +msgid "Couldn't decode PKCS#12 file: %d" +msgstr "Ne povis malkodigi PKCS#12-dosieron: %d" + +#: ../libnm-util/crypto_nss.c:528 +#, c-format +msgid "Couldn't verify PKCS#12 file: %d" +msgstr "Ne povis kontroli PKCS#12-dosieron: %d" + +#: ../libnm-util/crypto_nss.c:557 +msgid "Could not generate random data." +msgstr "Ne povis generi hazardajn datumojn." + +#: ../libnm-util/nm-utils.c:1975 +#, c-format +msgid "Not enough memory to make encryption key." +msgstr "Nesufiĉa memoro por fari ĉifran ŝlosilon." + +#: ../libnm-util/nm-utils.c:2085 +msgid "Could not allocate memory for PEM file creation." +msgstr "Ne povis atribui memoron por kreo de PEM-dosiero." + +#: ../libnm-util/nm-utils.c:2097 +#, c-format +msgid "Could not allocate memory for writing IV to PEM file." +msgstr "Ne povis atribui memoron por konservi IV en PEM-dosieron." + +#: ../libnm-util/nm-utils.c:2109 +#, c-format +msgid "Could not allocate memory for writing encrypted key to PEM file." +msgstr "" +"Ne povis atribui memoron por konservi ĉifritan ŝlosilon en PEM-dosieron." + +#: ../libnm-util/nm-utils.c:2128 +#, c-format +msgid "Could not allocate memory for PEM file data." +msgstr "Ne povis atribui memoron por datumoj de PEM-dosiero." + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:1 +msgid "Connection sharing via a protected WiFi network" +msgstr "Kundivido de konektoj per protektita WiFi-reto" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:2 +msgid "Connection sharing via an open WiFi network" +msgstr "Kundivido de konektoj per malferma WiFi-reto" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:3 +msgid "Modify persistent system hostname" +msgstr "Modifi permanentan sisteman gastigan nomon" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:4 +msgid "Modify system connections" +msgstr "Modifi sistemajn konektojn" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:5 +msgid "System policy prevents modification of system settings" +msgstr "Sistempolico preventas modifadon de sistemagordoj" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:6 +msgid "System policy prevents modification of the persistent system hostname" +msgstr "Sistempolico preventas modifadon de la konstanta sistem-gastnomo" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:7 +msgid "System policy prevents sharing connections via a protected WiFi network" +msgstr "Sistempolico preventas kundividon de konektoj per protektita WiFi-reto" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:8 +msgid "System policy prevents sharing connections via an open WiFi network" +msgstr "Sistempolitiko preventas kundividon de konektoj per malferma WiFi-reto" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:1 +msgid "Allow control of network connections" +msgstr "Permesi kontrolon de retkonektoj" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:2 +msgid "Allow use of user-specific connections" +msgstr "Permesi uzon de specifaj konektoj por uzantoj" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:3 +msgid "Enable or disable WiFi devices" +msgstr "Enŝalti aŭ elŝalti WiFi-aparatojn" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:4 +msgid "Enable or disable mobile broadband devices" +msgstr "Enŝalti aŭ elŝalti poŝtelefonajn larĝkapacitajn aparatojn" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:5 +msgid "Enable or disable system networking" +msgstr "Enŝalti aŭ elŝalti sistemretkonektadon" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:6 +msgid "" +"Put NetworkManager to sleep or wake it up (should only be used by system " +"power management)" +msgstr "" +"Dormigi aŭ veki NetworkManager (estu uzata nur de sistema energimastumado)" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:7 +msgid "System policy prevents control of network connections" +msgstr "Sistempolitiko preventas kontrolon de retkonektoj" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:8 +msgid "System policy prevents enabling or disabling WiFi devices" +msgstr "Sistempolitiko preventas enŝalton aŭ malŝalton de WiFi-aparatoj" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:9 +msgid "System policy prevents enabling or disabling mobile broadband devices" +msgstr "" +"Sistempolitiko preventas enŝalton aŭ malŝalton de poŝtelefonaj larĝkapacitaj " +"aparatoj" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:10 +msgid "System policy prevents enabling or disabling system networking" +msgstr "Sistempolitiko preventas enŝalton aŭ malŝalton de sistema retkonektado" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:11 +msgid "System policy prevents putting NetworkManager to sleep or waking it up" +msgstr "Sistempolitiko preventas dormigi aŭ veki NetworkManager" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:12 +msgid "System policy prevents use of user-specific connections" +msgstr "Sistempolitiko preventas uzon de uzant-specifaj konektoj" + +#: ../src/nm-netlink-monitor.c:100 ../src/nm-netlink-monitor.c:231 +#: ../src/nm-netlink-monitor.c:653 +#, c-format +msgid "error processing netlink message: %s" +msgstr "eraro dum traktado de netlink-mesaĝo: %s" + +#: ../src/nm-netlink-monitor.c:214 +msgid "error occurred while waiting for data on socket" +msgstr "okazis eraro dum atendado je datumoj sur kontaktoskatolo" + +#: ../src/nm-netlink-monitor.c:254 +#, c-format +msgid "unable to connect to netlink for monitoring link status: %s" +msgstr "ne eblas konekti al netlink por kontroli ligilan staton: %s" + +#: ../src/nm-netlink-monitor.c:265 +#, c-format +msgid "unable to enable netlink handle credential passing: %s" +msgstr "ne povis aktivigi la netlink-tenilan legitimaĵo-pasadon: %s" + +#: ../src/nm-netlink-monitor.c:291 ../src/nm-netlink-monitor.c:353 +#, c-format +msgid "unable to allocate netlink handle for monitoring link status: %s" +msgstr "ne povis atribui retligiltenilon por kontroli ligilstaton: %s" + +#: ../src/nm-netlink-monitor.c:376 +#, c-format +msgid "unable to allocate netlink link cache for monitoring link status: %s" +msgstr "" +"ne povis atribui ligilan kaŝmemoron de netlink por kontroli ligilstaton: %s" + +#: ../src/nm-netlink-monitor.c:502 +#, c-format +msgid "unable to join netlink group: %s" +msgstr "ne eblas membriĝi al retligila grupo: %s" + +#: ../src/nm-netlink-monitor.c:629 ../src/nm-netlink-monitor.c:642 +#, c-format +msgid "error updating link cache: %s" +msgstr "eraro dum ĝisdatigo de ligila kaŝmemoro: %s" + +#: ../src/main.c:502 +#, c-format +msgid "Invalid option. Please use --help to see a list of valid options.\n" +msgstr "" +"Nevalida elektindaĵo. Bonvolu uzi --help por vidi liston da validaj " +"elektindaĵoj.\n" + +#: ../src/main.c:573 +#, c-format +msgid "%s. Please use --help to see a list of valid options.\n" +msgstr "%s. Bovolu uzi --help por vidi liston da validaj elektindaĵoj.\n" + +#: ../src/dhcp-manager/nm-dhcp-dhclient.c:328 +msgid "# Created by NetworkManager\n" +msgstr "# Kreita de NetworkManager\n" + +#: ../src/dhcp-manager/nm-dhcp-dhclient.c:344 +#, c-format +msgid "" +"# Merged from %s\n" +"\n" +msgstr "" +"# Kunfandita el %s\n" +"\n" + +#: ../src/dhcp-manager/nm-dhcp-manager.c:284 +msgid "no usable DHCP client could be found." +msgstr "neniu uzebla DHCP-kliento estis trovebla" + +#: ../src/dhcp-manager/nm-dhcp-manager.c:293 +msgid "'dhclient' could be found." +msgstr "'dhclient' povis esti trovita." + +#: ../src/dhcp-manager/nm-dhcp-manager.c:303 +msgid "'dhcpcd' could be found." +msgstr "'dhcpcd' povis esti trovita." + +#: ../src/dhcp-manager/nm-dhcp-manager.c:311 +#, c-format +msgid "unsupported DHCP client '%s'" +msgstr "nesubtenata DHCP-kliento '%s'" + +#: ../src/logging/nm-logging.c:146 +#, c-format +msgid "Unknown log level '%s'" +msgstr "Nekonata protokolnivelo '%s'" + +#: ../src/logging/nm-logging.c:171 +#, c-format +msgid "Unknown log domain '%s'" +msgstr "Nekonata protokola regiono '%s'" + +#: ../src/dns-manager/nm-dns-manager.c:367 +msgid "NOTE: the libc resolver may not support more than 3 nameservers." +msgstr "NOTO: la libc-solvilo eble ne povus subteni pli ol 3 nomservilojn." + +#: ../src/dns-manager/nm-dns-manager.c:369 +msgid "The nameservers listed below may not be recognized." +msgstr "La sube ligstigitaj nomserviloj eble ne estos rekonataj." + +#: ../src/system-settings/nm-default-wired-connection.c:157 +#, c-format +msgid "Auto %s" +msgstr "Aŭto %s" + +#: ../system-settings/plugins/ifcfg-rh/reader.c:3408 +#: ../system-settings/plugins/ifnet/connection_parser.c:49 +msgid "System" +msgstr "Sistemo" From 82291075893428fee425b773ea538dcb0a85ea5d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 12 Dec 2010 13:18:00 +0100 Subject: [PATCH 043/102] ip6: rdnss structure needs to be packed (bgo #637075) The code assumes this structure is packed, so let's make sure it actually is. --- src/ip6-manager/nm-ip6-manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index f6f6127ce7..e9540a0314 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -575,7 +575,7 @@ struct nd_opt_rdnss { uint16_t nd_opt_rdnss_reserved1; uint32_t nd_opt_rdnss_lifetime; /* followed by one or more IPv6 addresses */ -}; +} __attribute__ ((packed)); static NMIP6Device * process_nduseropt (NMIP6Manager *manager, struct nl_msg *msg) From 4e8cb2f193f90bdcde2e1eb1ddd875c57b5808ea Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Wed, 15 Dec 2010 17:37:14 -0600 Subject: [PATCH 044/102] ip6: restructure RDNSS code to be RFC compliant (bgo #637075) RFC5006/RFC6106 specifies fairly clearly how to handle multiple RDDNS options. Unfortunately the previous code didn't deal with this and hence would misbehave in all but the simplest setups. The new code should be fully compliant with the following exceptions: - Router lifetime not respected - No "sufficient number" management. - DHCPv6 servers might not be prioritised over RDDNS ones. --- src/ip6-manager/nm-ip6-manager.c | 163 +++++++++++++++++++------------ 1 file changed, 99 insertions(+), 64 deletions(-) diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index e9540a0314..ae748ca1b3 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -285,7 +285,7 @@ set_rdnss_timeout (NMIP6Device *device) nm_log_dbg (LOGD_IP6, "(%s): removing expired RA-provided nameserver %s", device->iface, buf); } - g_array_remove_index_fast (device->rdnss_servers, i--); + g_array_remove_index (device->rdnss_servers, i--); continue; } @@ -577,19 +577,106 @@ struct nd_opt_rdnss { /* followed by one or more IPv6 addresses */ } __attribute__ ((packed)); +static gboolean +process_nduseropt_rdnss (NMIP6Device *device, struct nd_opt_hdr *opt) +{ + size_t opt_len; + struct nd_opt_rdnss *rdnss_opt; + time_t now = time (NULL); + struct in6_addr *addr; + GArray *new_servers; + NMIP6RDNSS server, *cur_server; + gboolean changed = FALSE; + guint i; + + opt_len = opt->nd_opt_len; + + if (opt_len < 3 || (opt_len & 1) == 0) + return FALSE; + + rdnss_opt = (struct nd_opt_rdnss *) opt; + + new_servers = g_array_new (FALSE, FALSE, sizeof (NMIP6RDNSS)); + + /* Pad the DNS server expiry somewhat to give a bit of slack in cases + * where one RA gets lost or something (which can happen on unreliable + * links like WiFi where certain types of frames are not retransmitted). + * Note that 0 has special meaning and is therefore not adjusted. + */ + server.expires = ntohl (rdnss_opt->nd_opt_rdnss_lifetime); + if (server.expires > 0) + server.expires += now + 10; + + for (addr = (struct in6_addr *) (rdnss_opt + 1); opt_len >= 2; addr++, opt_len -= 2) { + char buf[INET6_ADDRSTRLEN + 1]; + + if (!inet_ntop (AF_INET6, addr, buf, sizeof (buf))) + strcpy(buf, "[invalid]"); + + for (i = 0; i < device->rdnss_servers->len; i++) { + cur_server = &(g_array_index (device->rdnss_servers, NMIP6RDNSS, i)); + + if (!IN6_ARE_ADDR_EQUAL (addr, &cur_server->addr)) + continue; + + cur_server->expires = server.expires; + + if (server.expires > 0) { + nm_log_dbg (LOGD_IP6, "(%s): refreshing RA-provided nameserver %s (expires in %d seconds)", + device->iface, buf, + server.expires - now); + break; + } + + nm_log_dbg (LOGD_IP6, "(%s): removing RA-provided nameserver %s on router request", + device->iface, buf); + + g_array_remove_index (device->rdnss_servers, i); + changed = TRUE; + break; + } + + if (server.expires == 0) + continue; + if (i < device->rdnss_servers->len) + continue; + + nm_log_dbg (LOGD_IP6, "(%s): found RA-provided nameserver %s (expires in %d seconds)", + device->iface, buf, server.expires - now); + + server.addr = *addr; + g_array_append_val (new_servers, server); + } + + /* New servers must be added in the order they are listed in the + * RA option and before any existing servers. + * + * Note: This is the place to remove servers if we want to cap the + * number of resolvers. The RFC states that the one to expire + * first of the existing servers should be removed. + */ + if (new_servers->len) { + g_array_prepend_vals (device->rdnss_servers, + new_servers->data, new_servers->len); + changed = TRUE; + } + + g_array_free (new_servers, TRUE); + + /* Timeouts may have changed even if IPs didn't */ + set_rdnss_timeout (device); + + return changed; +} + static NMIP6Device * process_nduseropt (NMIP6Manager *manager, struct nl_msg *msg) { NMIP6Device *device; struct nduseroptmsg *ndmsg; struct nd_opt_hdr *opt; - guint opts_len, i; - time_t now = time (NULL); - struct nd_opt_rdnss *rdnss_opt; - struct in6_addr *addr; - GArray *servers; - NMIP6RDNSS server, *sa, *sb; - gboolean changed; + guint opts_len; + gboolean changed = FALSE; nm_log_dbg (LOGD_IP6, "processing netlink nduseropt message"); @@ -608,8 +695,6 @@ process_nduseropt (NMIP6Manager *manager, struct nl_msg *msg) return NULL; } - servers = g_array_new (FALSE, FALSE, sizeof (NMIP6RDNSS)); - opt = (struct nd_opt_hdr *) (ndmsg + 1); opts_len = ndmsg->nduseropt_opts_len; @@ -619,66 +704,16 @@ process_nduseropt (NMIP6Manager *manager, struct nl_msg *msg) if (nd_opt_len == 0 || opts_len < (nd_opt_len << 3)) break; - if (opt->nd_opt_type != ND_OPT_RDNSS) - goto next; - - if (nd_opt_len < 3 || (nd_opt_len & 1) == 0) - goto next; - - rdnss_opt = (struct nd_opt_rdnss *) opt; - - /* Pad the DNS server expiry somewhat to give a bit of slack in cases - * where one RA gets lost or something (which can happen on unreliable - * links like wifi where certain types of frames are not retransmitted). - */ - server.expires = now + ntohl (rdnss_opt->nd_opt_rdnss_lifetime) + 10; - - for (addr = (struct in6_addr *) (rdnss_opt + 1); nd_opt_len >= 2; addr++, nd_opt_len -= 2) { - char buf[INET6_ADDRSTRLEN + 1]; - - if (inet_ntop (AF_INET6, addr, buf, sizeof (buf))) { - nm_log_dbg (LOGD_IP6, "(%s): found RA-provided nameserver %s (expires in %d seconds)", - device->iface, buf, - ntohl (rdnss_opt->nd_opt_rdnss_lifetime)); - } - - server.addr = *addr; - g_array_append_val (servers, server); + switch (opt->nd_opt_type) { + case ND_OPT_RDNSS: + changed = process_nduseropt_rdnss (device, opt); + break; } - next: opts_len -= opt->nd_opt_len << 3; opt = (struct nd_opt_hdr *) ((uint8_t *) opt + (opt->nd_opt_len << 3)); } - /* See if anything (other than expiration time) changed */ - if (servers->len != device->rdnss_servers->len) - changed = TRUE; - else { - for (i = 0; i < servers->len; i++) { - sa = &(g_array_index (servers, NMIP6RDNSS, i)); - sb = &(g_array_index (device->rdnss_servers, NMIP6RDNSS, i)); - if (IN6_ARE_ADDR_EQUAL (&sa->addr, &sb->addr) == FALSE) { - changed = TRUE; - break; - } - } - changed = FALSE; - } - - if (changed) { - nm_log_dbg (LOGD_IP6, "(%s): RA-provided nameservers changed", device->iface); - } - - /* Always copy in new servers (even if unchanged) to get their updated - * expiration times. - */ - g_array_free (device->rdnss_servers, TRUE); - device->rdnss_servers = servers; - - /* Timeouts may have changed even if IPs didn't */ - set_rdnss_timeout (device); - if (changed) return device; else From 83bc6639142831e864c4ce77cf7b1830bb2fcc74 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 13 Dec 2010 22:28:53 +0100 Subject: [PATCH 045/102] ip6: support for DNS Search List option (bgo #637077) RFC6101 adds the DNS Search List option to router advertisements. This allows stateless configuration of suffixes to try when doing DNS lookups. Make sure we catch these when provided by the kernel and reconfigure things appropriately. NOTE: this commit depends on a kernel patch: http://marc.info/?l=linux-netdev&m=129216173321352&w=2 --- src/ip6-manager/nm-ip6-manager.c | 233 +++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index ae748ca1b3..ea93f02c02 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -76,6 +76,11 @@ typedef struct { time_t expires; } NMIP6RDNSS; +typedef struct { + char domain[256]; + time_t expires; +} NMIP6DNSSL; + /******************************************************************/ typedef struct { @@ -97,6 +102,9 @@ typedef struct { GArray *rdnss_servers; guint rdnss_timeout_id; + GArray *dnssl_domains; + guint dnssl_timeout_id; + guint ip6flags_poll_id; guint32 ra_flags; @@ -122,6 +130,10 @@ nm_ip6_device_destroy (NMIP6Device *device) g_array_free (device->rdnss_servers, TRUE); if (device->rdnss_timeout_id) g_source_remove (device->rdnss_timeout_id); + if (device->dnssl_domains) + g_array_free (device->dnssl_domains, TRUE); + if (device->dnssl_timeout_id) + g_source_remove (device->dnssl_timeout_id); if (device->ip6flags_poll_id) g_source_remove (device->ip6flags_poll_id); @@ -155,6 +167,8 @@ nm_ip6_device_new (NMIP6Manager *manager, int ifindex) device->rdnss_servers = g_array_new (FALSE, FALSE, sizeof (NMIP6RDNSS)); + device->dnssl_domains = g_array_new (FALSE, FALSE, sizeof (NMIP6DNSSL)); + g_hash_table_replace (priv->devices, GINT_TO_POINTER (device->ifindex), device); /* and the original value of IPv6 enable/disable */ @@ -300,6 +314,61 @@ set_rdnss_timeout (NMIP6Device *device) } } +static void set_dnssl_timeout (NMIP6Device *device); + +static gboolean +dnssl_expired (gpointer user_data) +{ + NMIP6Device *device = user_data; + CallbackInfo info = { device, IP6_DHCP_OPT_NONE }; + + nm_log_dbg (LOGD_IP6, "(%s): IPv6 DNSSL information expired", device->iface); + + set_dnssl_timeout (device); + emit_config_changed (&info); + return FALSE; +} + +static void +set_dnssl_timeout (NMIP6Device *device) +{ + time_t expires = 0, now = time (NULL); + NMIP6DNSSL *dnssl; + int i; + + if (device->dnssl_timeout_id) { + g_source_remove (device->dnssl_timeout_id); + device->dnssl_timeout_id = 0; + } + + /* Find the soonest expiration time. */ + for (i = 0; i < device->dnssl_domains->len; i++) { + dnssl = &g_array_index (device->dnssl_domains, NMIP6DNSSL, i); + if (dnssl->expires == 0) + continue; + + /* If the entry has already expired, remove it; the "+ 1" is + * because g_timeout_add_seconds() might fudge the timing a + * bit. + */ + if (dnssl->expires <= now + 1) { + nm_log_dbg (LOGD_IP6, "(%s): removing expired RA-provided domain %s", + device->iface, dnssl->domain); + g_array_remove_index (device->dnssl_domains, i--); + continue; + } + + if (!expires || dnssl->expires < expires) + expires = dnssl->expires; + } + + if (expires) { + device->dnssl_timeout_id = g_timeout_add_seconds (expires - now, + dnssl_expired, + device); + } +} + static CallbackInfo * callback_info_new (NMIP6Device *device, guint dhcp_opts, gboolean success) { @@ -569,6 +638,8 @@ process_prefix (NMIP6Manager *manager, struct nl_msg *msg) */ #define ND_OPT_RDNSS 25 +#define ND_OPT_DNSSL 31 + struct nd_opt_rdnss { uint8_t nd_opt_rdnss_type; uint8_t nd_opt_rdnss_len; @@ -577,6 +648,14 @@ struct nd_opt_rdnss { /* followed by one or more IPv6 addresses */ } __attribute__ ((packed)); +struct nd_opt_dnssl { + uint8_t nd_opt_dnssl_type; + uint8_t nd_opt_dnssl_len; + uint16_t nd_opt_dnssl_reserved1; + uint32_t nd_opt_dnssl_lifetime; + /* followed by one or more suffixes */ +} __attribute__ ((packed)); + static gboolean process_nduseropt_rdnss (NMIP6Device *device, struct nd_opt_hdr *opt) { @@ -669,6 +748,149 @@ process_nduseropt_rdnss (NMIP6Device *device, struct nd_opt_hdr *opt) return changed; } +static const char * +parse_dnssl_domain (const unsigned char *buffer, size_t maxlen) +{ + static char domain[256]; + size_t label_len; + + domain[0] = '\0'; + + while (maxlen > 0) { + label_len = *buffer; + buffer++; + maxlen--; + + if (label_len == 0) + return domain; + + if (label_len > maxlen) + return NULL; + if ((sizeof (domain) - strlen (domain)) < (label_len + 2)) + return NULL; + + if (domain[0] != '\0') + strcat (domain, "."); + strncat (domain, (const char *)buffer, label_len); + buffer += label_len; + maxlen -= label_len; + } + + return NULL; +} + +static gboolean +process_nduseropt_dnssl (NMIP6Device *device, struct nd_opt_hdr *opt) +{ + size_t opt_len; + struct nd_opt_dnssl *dnssl_opt; + unsigned char *opt_ptr; + time_t now = time (NULL); + GArray *new_domains; + NMIP6DNSSL domain, *cur_domain; + gboolean changed; + guint i; + + opt_len = opt->nd_opt_len; + + if (opt_len < 2) + return FALSE; + + dnssl_opt = (struct nd_opt_dnssl *) opt; + + opt_ptr = (unsigned char *)(dnssl_opt + 1); + opt_len = (opt_len - 1) * 8; /* prefer bytes for later handling */ + + new_domains = g_array_new (FALSE, FALSE, sizeof (NMIP6DNSSL)); + + changed = FALSE; + + /* Pad the DNS server expiry somewhat to give a bit of slack in cases + * where one RA gets lost or something (which can happen on unreliable + * links like wifi where certain types of frames are not retransmitted). + * Note that 0 has special meaning and is therefore not adjusted. + */ + domain.expires = ntohl (dnssl_opt->nd_opt_dnssl_lifetime); + if (domain.expires > 0) + domain.expires += now + 10; + + while (opt_len) { + const char *domain_str; + + domain_str = parse_dnssl_domain (opt_ptr, opt_len); + if (domain_str == NULL) { + nm_log_dbg (LOGD_IP6, "(%s): invalid DNSSL option, parsing aborted", + device->iface); + break; + } + + /* The DNSSL encoding of domains happen to occupy the same size + * as the length of the resulting string, including terminating + * null. */ + opt_ptr += strlen (domain_str) + 1; + opt_len -= strlen (domain_str) + 1; + + /* Ignore empty domains. They're probably just padding... */ + if (domain_str[0] == '\0') + continue; + + for (i = 0; i < device->dnssl_domains->len; i++) { + cur_domain = &(g_array_index (device->dnssl_domains, NMIP6DNSSL, i)); + + if (strcmp (domain_str, cur_domain->domain) != 0) + continue; + + cur_domain->expires = domain.expires; + + if (domain.expires > 0) { + nm_log_dbg (LOGD_IP6, "(%s): refreshing RA-provided domain %s (expires in %d seconds)", + device->iface, domain_str, + domain.expires - now); + break; + } + + nm_log_dbg (LOGD_IP6, "(%s): removing RA-provided domain %s on router request", + device->iface, domain_str); + + g_array_remove_index (device->dnssl_domains, i); + changed = TRUE; + break; + } + + if (domain.expires == 0) + continue; + if (i < device->dnssl_domains->len) + continue; + + nm_log_dbg (LOGD_IP6, "(%s): found RA-provided domain %s (expires in %d seconds)", + device->iface, domain_str, domain.expires - now); + + g_assert (strlen (domain_str) < sizeof (domain.domain)); + strcpy (domain.domain, domain_str); + g_array_append_val (new_domains, domain); + } + + /* New domains must be added in the order they are listed in the + * RA option and before any existing domains. + * + * Note: This is the place to remove domains if we want to cap the + * number of domains. The RFC states that the one to expire + * first of the existing domains should be removed. + */ + if (new_domains->len) { + g_array_prepend_vals (device->dnssl_domains, + new_domains->data, new_domains->len); + changed = TRUE; + } + + g_array_free (new_domains, TRUE); + + /* Timeouts may have changed even if domains didn't */ + set_dnssl_timeout (device); + + return changed; +} + static NMIP6Device * process_nduseropt (NMIP6Manager *manager, struct nl_msg *msg) { @@ -708,6 +930,9 @@ process_nduseropt (NMIP6Manager *manager, struct nl_msg *msg) case ND_OPT_RDNSS: changed = process_nduseropt_rdnss (device, opt); break; + case ND_OPT_DNSSL: + changed = process_nduseropt_dnssl (device, opt); + break; } opts_len -= opt->nd_opt_len << 3; @@ -1049,6 +1274,14 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager, int ifindex) nm_ip6_config_add_nameserver (config, &rdnss[i].addr); } + /* Add DNS domains */ + if (device->dnssl_domains) { + NMIP6DNSSL *dnssl = (NMIP6DNSSL *)(device->dnssl_domains->data); + + for (i = 0; i < device->dnssl_domains->len; i++) + nm_ip6_config_add_domain (config, dnssl[i].domain); + } + return config; } From 9c7afa193c4c031e4cf9f2d7a2422afcb34ac4f9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 15 Dec 2010 17:52:55 -0600 Subject: [PATCH 046/102] libnm-glib: fix export of NMDHCP6Config symbols Found by Giovanni Campagna --- libnm-glib/libnm-glib.ver | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index 1596afaad9..0691ad9d03 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -95,6 +95,10 @@ global: nm_dhcp4_config_get_options; nm_dhcp4_config_get_type; nm_dhcp4_config_new; + nm_dhcp6_config_get_one_option; + nm_dhcp6_config_get_options; + nm_dhcp6_config_get_type; + nm_dhcp6_config_new; nm_exported_connection_export; nm_exported_connection_get_type; nm_exported_connection_new; From 7e5ab41d134a42be4d7d50e6b98b26dc270fa7d8 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 15 Dec 2010 18:03:49 -0600 Subject: [PATCH 047/102] build: remove random leftover bits of GConf stuff --- configure.ac | 2 +- libnm-glib/Makefile.am | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 9cb0e9c49c..0665886927 100644 --- a/configure.ac +++ b/configure.ac @@ -30,7 +30,7 @@ AC_SUBST([ACLOCAL_AMFLAGS]) dnl maintainer mode stuff if test $USE_MAINTAINER_MODE = yes; then - DISABLE_DEPRECATED="-DG_DISABLE_DEPRECATED -DGCONF_DISABLE_DEPRECATED" + DISABLE_DEPRECATED="-DG_DISABLE_DEPRECATED" else DISABLE_DEPRECATED="" fi diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index ec21a328e9..66b1c9fee6 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -52,7 +52,6 @@ lib_LTLIBRARIES = libnm-glib.la libnm-glib-vpn.la libnm_glib_la_CFLAGS = \ $(GLIB_CFLAGS) \ $(DBUS_CFLAGS) \ - $(GCONF_CFLAGS) \ $(GUDEV_CFLAGS) libnmincludedir = $(includedir)/libnm-glib @@ -128,7 +127,6 @@ libnm_glib_la_LIBADD = \ $(builddir)/libdeprecated-nm-glib.la \ $(GLIB_LIBS) \ $(DBUS_LIBS) \ - $(GCONF_LIBS) \ $(GUDEV_LIBS) libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib.ver \ From b3800183b434bbaf90d627a2e44c631cf04e8b71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Thu, 16 Dec 2010 13:49:28 +0100 Subject: [PATCH 048/102] libnm-util: fix nm_utils_security_valid() checks for Ad-Hoc APs (rh #632123) Without the fix fake Ad-Hoc APs created by nm-applet's "Create New Wireless Network..." don't pass the check and nm-applet can crash. --- libnm-util/nm-utils.c | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index ce13da3c86..9c3662f47f 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -1269,14 +1269,24 @@ nm_utils_security_valid (NMUtilsSecurityType type, if (!(wifi_caps & NM_WIFI_DEVICE_CAP_WPA)) return FALSE; if (have_ap) { - /* Ad-Hoc WPA APs won't necessarily have the PSK flag set */ - if ((ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) || adhoc) { - if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_TKIP) + /* Ad-Hoc WPA APs won't necessarily have the PSK flag set, and + * they don't have any pairwise ciphers. */ + if (adhoc) { + if ( (ap_wpa & NM_802_11_AP_SEC_GROUP_TKIP) && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) return TRUE; - if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_CCMP) + if ( (ap_wpa & NM_802_11_AP_SEC_GROUP_CCMP) && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) return TRUE; + } else { + if (ap_wpa & NM_802_11_AP_SEC_KEY_MGMT_PSK) { + if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_TKIP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) + return TRUE; + if ( (ap_wpa & NM_802_11_AP_SEC_PAIR_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + return TRUE; + } } return FALSE; } @@ -1285,14 +1295,22 @@ nm_utils_security_valid (NMUtilsSecurityType type, if (!(wifi_caps & NM_WIFI_DEVICE_CAP_RSN)) return FALSE; if (have_ap) { - /* Ad-Hoc WPA APs won't necessarily have the PSK flag set */ - if ((ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK) || adhoc) { - if ( (ap_rsn & NM_802_11_AP_SEC_PAIR_TKIP) - && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) + /* Ad-Hoc WPA APs won't necessarily have the PSK flag set, and + * they don't have any pairwise ciphers, nor any RSA flags yet. */ + if (adhoc) { + if (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP) return TRUE; - if ( (ap_rsn & NM_802_11_AP_SEC_PAIR_CCMP) - && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + if (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP) return TRUE; + } else { + if (ap_rsn & NM_802_11_AP_SEC_KEY_MGMT_PSK) { + if ( (ap_rsn & NM_802_11_AP_SEC_PAIR_TKIP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP)) + return TRUE; + if ( (ap_rsn & NM_802_11_AP_SEC_PAIR_CCMP) + && (wifi_caps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP)) + return TRUE; + } } return FALSE; } From 6f37a967eb3d6e7463672a1d72fa3d4f71ac5228 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 16 Dec 2010 17:47:59 -0600 Subject: [PATCH 049/102] dns: direct IPv4 reverse DNS queries to split DNS servers When split DNS is used for a local caching nameserver, make sure that reverse DNS queries for hosts within the VPN tunnel are directed to the VPN's nameservers, not to the public upstream nameservers. --- src/dns-manager/Makefile.am | 4 +- src/dns-manager/nm-dns-dnsmasq.c | 22 +++++-- src/dns-manager/nm-dns-utils.c | 99 ++++++++++++++++++++++++++++++++ src/dns-manager/nm-dns-utils.h | 28 +++++++++ 4 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 src/dns-manager/nm-dns-utils.c create mode 100644 src/dns-manager/nm-dns-utils.h diff --git a/src/dns-manager/Makefile.am b/src/dns-manager/Makefile.am index 1ffe62dcf0..7b5fc4f847 100644 --- a/src/dns-manager/Makefile.am +++ b/src/dns-manager/Makefile.am @@ -14,7 +14,9 @@ libdns_manager_la_SOURCES = \ nm-dns-dnsmasq.h \ nm-dns-dnsmasq.c \ nm-dns-bind.h \ - nm-dns-bind.c + nm-dns-bind.c \ + nm-dns-utils.h \ + nm-dns-utils.c libdns_manager_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ diff --git a/src/dns-manager/nm-dns-dnsmasq.c b/src/dns-manager/nm-dns-dnsmasq.c index 41c8e2a642..9cc019780b 100644 --- a/src/dns-manager/nm-dns-dnsmasq.c +++ b/src/dns-manager/nm-dns-dnsmasq.c @@ -33,6 +33,7 @@ #include "nm-logging.h" #include "nm-ip4-config.h" #include "nm-ip6-config.h" +#include "nm-dns-utils.h" G_DEFINE_TYPE (NMDnsDnsmasq, nm_dns_dnsmasq, NM_TYPE_DNS_PLUGIN) @@ -75,9 +76,11 @@ add_ip4_config (GString *str, NMIP4Config *ip4, gboolean split) gboolean added = FALSE; if (split) { + char **domains, **iter; + /* FIXME: it appears that dnsmasq can only handle one nameserver - * per domain (at the manpage seems to indicate that) so only use - * the first nameserver here. + * per domain (and the manpage says this too) so only use the first + * nameserver here. */ addr.s_addr = nm_ip4_config_get_nameserver (ip4, 0); memset (&buf[0], 0, sizeof (buf)); @@ -103,6 +106,17 @@ add_ip4_config (GString *str, NMIP4Config *ip4, gboolean split) added = TRUE; } } + + /* Ensure reverse-DNS works by directing queries for in-addr.arpa + * domains to the split domain's nameserver. + */ + domains = nm_dns_utils_get_ip4_rdns_domains (ip4); + if (domains) { + for (iter = domains; iter && *iter; iter++) + g_string_append_printf (str, "server=/%s/%s\n", *iter, buf); + g_strfreev (domains); + added = TRUE; + } } /* If no searches or domains, just add the namservers */ @@ -216,7 +230,7 @@ update (NMDnsPlugin *plugin, } /* Now add interface configs without split DNS */ - for (iter = (GSList *) dev_configs; iter;iter = g_slist_next (iter)) { + for (iter = (GSList *) dev_configs; iter; iter = g_slist_next (iter)) { if (NM_IS_IP4_CONFIG (iter->data)) add_ip4_config (conf, NM_IP4_CONFIG (iter->data), FALSE); else if (NM_IS_IP6_CONFIG (iter->data)) @@ -224,7 +238,7 @@ update (NMDnsPlugin *plugin, } /* And any other random configs */ - for (iter = (GSList *) other_configs; iter;iter = g_slist_next (iter)) { + for (iter = (GSList *) other_configs; iter; iter = g_slist_next (iter)) { if (NM_IS_IP4_CONFIG (iter->data)) add_ip4_config (conf, NM_IP4_CONFIG (iter->data), FALSE); else if (NM_IS_IP6_CONFIG (iter->data)) diff --git a/src/dns-manager/nm-dns-utils.c b/src/dns-manager/nm-dns-utils.c new file mode 100644 index 0000000000..615adfd151 --- /dev/null +++ b/src/dns-manager/nm-dns-utils.c @@ -0,0 +1,99 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; 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, 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) 2010 Red Hat, Inc. + * + */ + +#include +#include + +#include "nm-dns-utils.h" +#include "nm-utils.h" + +static void +add_ip4_to_rdns_array (guint32 ip, GPtrArray *domains) /* network byte order */ +{ + guint32 defprefix; + guchar *p; + char *str = NULL; + int i; + + defprefix = nm_utils_ip4_get_default_prefix (ip); + + /* Convert to host byte order, mask the host bits, and convert back */ + ip = ntohl (ip); + ip &= 0xFFFFFFFF << (32 - defprefix); + ip = htonl (ip); + p = (guchar *) &ip; + + if (defprefix == 8) + str = g_strdup_printf ("%u.in-addr.arpa", p[0] & 0xFF); + else if (defprefix == 16) + str = g_strdup_printf ("%u.%u.in-addr.arpa", p[1] & 0xFF, p[0] & 0xFF); + else if (defprefix == 24) + str = g_strdup_printf ("%u.%u.%u.in-addr.arpa", p[2] & 0xFF, p[1] & 0xFF, p[0] & 0xFF); + + g_return_if_fail (str != NULL); + + /* Suppress duplicates */ + for (i = 0; i < domains->len; i++) { + if (strcmp (str, g_ptr_array_index (domains, i)) == 0) + break; + } + + if (i == domains->len) + g_ptr_array_add (domains, str); + else + g_free (str); +} + +char ** +nm_dns_utils_get_ip4_rdns_domains (NMIP4Config *ip4) +{ + GPtrArray *domains = NULL; + int i; + + g_return_val_if_fail (ip4 != NULL, NULL); + + domains = g_ptr_array_sized_new (5); + + /* To calculate the reverse DNS domains for this IP4 config, we take + * all the IP addresses and routes in the config, calculate the network + * portion, and convert that to classful, and use the network bits for + * the final domain. FIXME: better handle classless routing, which might + * require us to add multiple domains for each actual network prefix to + * cover all the separate networks in that block. + */ + + for (i = 0; i < nm_ip4_config_get_num_addresses (ip4); i++) { + NMIP4Address *addr = nm_ip4_config_get_address (ip4, i); + + add_ip4_to_rdns_array (nm_ip4_address_get_address (addr), domains); + } + + for (i = 0; i < nm_ip4_config_get_num_routes (ip4); i++) { + NMIP4Route *route = nm_ip4_config_get_route (ip4, i); + + add_ip4_to_rdns_array (nm_ip4_route_get_dest (route), domains); + } + + /* Terminating NULL so we can use g_strfreev() to free it */ + g_ptr_array_add (domains, NULL); + + /* Free the array and return NULL if the only element was the ending NULL */ + return (char **) g_ptr_array_free (domains, (domains->len == 1)); +} + diff --git a/src/dns-manager/nm-dns-utils.h b/src/dns-manager/nm-dns-utils.h new file mode 100644 index 0000000000..daa6711cce --- /dev/null +++ b/src/dns-manager/nm-dns-utils.h @@ -0,0 +1,28 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; 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, 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) 2010 Red Hat, Inc. + * + */ + +#ifndef NM_DNS_UTILS_H +#define NM_DNS_UTILS_H + +#include "nm-ip4-config.h" + +char **nm_dns_utils_get_ip4_rdns_domains (NMIP4Config *ip4); + +#endif /* NM_DNS_UTILS_H */ + From 592a1d46680367130274b3bb94c6ff6f553bf2e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Fri, 17 Dec 2010 11:37:10 +0100 Subject: [PATCH 050/102] cli: add D-Bus object path field for APs (e.g.:nmcli -f NAME,SSID,BSSID,SIGNAL,DBUS-PATH dev wifi list) --- cli/src/devices.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cli/src/devices.c b/cli/src/devices.c index 436b4b6eb8..12da386c4d 100644 --- a/cli/src/devices.c +++ b/cli/src/devices.c @@ -184,9 +184,10 @@ static NmcOutputField nmc_fields_dev_wifi_list[] = { {"RSN-FLAGS", N_("RSN-FLAGS"), 25, NULL, 0}, /* 9 */ {"DEVICE", N_("DEVICE"), 10, NULL, 0}, /* 10 */ {"ACTIVE", N_("ACTIVE"), 8, NULL, 0}, /* 11 */ + {"DBUS-PATH", N_("DBUS-PATH"), 46, NULL, 0}, /* 12 */ {NULL, NULL, 0, NULL, 0} }; -#define NMC_FIELDS_DEV_WIFI_LIST_ALL "SSID,BSSID,MODE,FREQ,RATE,SIGNAL,SECURITY,WPA-FLAGS,RSN-FLAGS,DEVICE,ACTIVE" +#define NMC_FIELDS_DEV_WIFI_LIST_ALL "SSID,BSSID,MODE,FREQ,RATE,SIGNAL,SECURITY,WPA-FLAGS,RSN-FLAGS,DEVICE,ACTIVE,DBUS-PATH" #define NMC_FIELDS_DEV_WIFI_LIST_COMMON "SSID,BSSID,MODE,FREQ,RATE,SIGNAL,SECURITY,ACTIVE" #define NMC_FIELDS_DEV_WIFI_LIST_FOR_DEV_LIST "NAME,"NMC_FIELDS_DEV_WIFI_LIST_COMMON @@ -431,6 +432,7 @@ detail_access_point (gpointer data, gpointer user_data) info->nmc->allowed_fields[9].value = rsn_flags_str; info->nmc->allowed_fields[10].value = info->device; info->nmc->allowed_fields[11].value = active ? _("yes") : _("no"); + info->nmc->allowed_fields[12].value = nm_object_get_path (NM_OBJECT (ap)); info->nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */ print_fields (info->nmc->print_fields, info->nmc->allowed_fields); From 570585077950cb59e30a3c2dd4ea19befd80efbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Fri, 17 Dec 2010 13:42:07 +0100 Subject: [PATCH 051/102] examples: add C example showing APs' information --- examples/C/Makefile.am | 13 +- examples/C/get-ap-info-libnm-glib.c | 229 ++++++++++++++++++++++++++++ 2 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 examples/C/get-ap-info-libnm-glib.c diff --git a/examples/C/Makefile.am b/examples/C/Makefile.am index 88f1e48421..a8b5a64075 100644 --- a/examples/C/Makefile.am +++ b/examples/C/Makefile.am @@ -10,7 +10,8 @@ noinst_PROGRAMS = \ add-connection-glib \ get-active-connections \ list-connections-dbus \ - list-connections-libnm-glib + list-connections-libnm-glib \ + get-ap-info-libnm-glib add_connection_glib_SOURCES = add-connection-glib.c add_connection_glib_LDADD = \ @@ -37,9 +38,17 @@ list_connections_libnm_glib_LDADD = \ $(DBUS_LIBS) \ $(GLIB_LIBS) +get_ap_info_libnm_glib_SOURCES = get-ap-info-libnm-glib.c +get_ap_info_libnm_glib_LDADD = \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(top_builddir)/libnm-glib/libnm-glib.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + EXTRA_DIST = \ add-connection-glib.c \ get-active-connections.c \ list-connections-dbus.c \ - list-connections-libnm-glib.c + list-connections-libnm-glib.c \ + get-ap-info-libnm-glib.c diff --git a/examples/C/get-ap-info-libnm-glib.c b/examples/C/get-ap-info-libnm-glib.c new file mode 100644 index 0000000000..6ff310d821 --- /dev/null +++ b/examples/C/get-ap-info-libnm-glib.c @@ -0,0 +1,229 @@ +/* + * 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 2010 Red Hat, Inc. + */ + +/* + * The example shows how to get info about APs visible by Wi-Fi devices + * using libnm-glib (that wraps direct D-Bus calls). + * The example uses dbus-glib, libnm-util and libnm-glib libraries. + * + * Compile with: + * gcc -Wall `pkg-config --libs --cflags glib-2.0 dbus-glib-1 libnm-util libnm-glib` get-ap-info-libnm-glib.c -o get-ap-info-libnm-glib + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* Convert flags to string */ +static char * +ap_wpa_rsn_flags_to_string (guint32 flags) +{ + char *flags_str[16]; /* Enough space for flags and terminating NULL */ + char *ret_str; + int i = 0; + + if (flags & NM_802_11_AP_SEC_PAIR_WEP40) + flags_str[i++] = g_strdup ("pair_wpe40"); + if (flags & NM_802_11_AP_SEC_PAIR_WEP104) + flags_str[i++] = g_strdup ("pair_wpe104"); + if (flags & NM_802_11_AP_SEC_PAIR_TKIP) + flags_str[i++] = g_strdup ("pair_tkip"); + if (flags & NM_802_11_AP_SEC_PAIR_CCMP) + flags_str[i++] = g_strdup ("pair_ccmp"); + if (flags & NM_802_11_AP_SEC_GROUP_WEP40) + flags_str[i++] = g_strdup ("group_wpe40"); + if (flags & NM_802_11_AP_SEC_GROUP_WEP104) + flags_str[i++] = g_strdup ("group_wpe104"); + if (flags & NM_802_11_AP_SEC_GROUP_TKIP) + flags_str[i++] = g_strdup ("group_tkip"); + if (flags & NM_802_11_AP_SEC_GROUP_CCMP) + flags_str[i++] = g_strdup ("group_ccmp"); + if (flags & NM_802_11_AP_SEC_KEY_MGMT_PSK) + flags_str[i++] = g_strdup ("psk"); + if (flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) + flags_str[i++] = g_strdup ("802.1X"); + + if (i == 0) + flags_str[i++] = g_strdup ("none"); + + flags_str[i] = NULL; + + ret_str = g_strjoinv (" ", flags_str); + + i = 0; + while (flags_str[i]) + g_free (flags_str[i++]); + + return ret_str; +} + +static void +show_access_point_info (NMAccessPoint *ap) +{ + guint32 flags, wpa_flags, rsn_flags, freq, bitrate; + guint8 strength; + const GByteArray *ssid; + const char *hwaddr; + NM80211Mode mode; + char *freq_str, *ssid_str, *bitrate_str, *strength_str, *wpa_flags_str, *rsn_flags_str; + GString *security_str; + + /* Get AP properties */ + flags = nm_access_point_get_flags (ap); + wpa_flags = nm_access_point_get_wpa_flags (ap); + rsn_flags = nm_access_point_get_rsn_flags (ap); + ssid = nm_access_point_get_ssid (ap); + hwaddr = nm_access_point_get_hw_address (ap); + freq = nm_access_point_get_frequency (ap); + mode = nm_access_point_get_mode (ap); + bitrate = nm_access_point_get_max_bitrate (ap); + strength = nm_access_point_get_strength (ap); + + /* Convert to strings */ + ssid_str = nm_utils_ssid_to_utf8 ((const char *) ssid->data, ssid->len); + freq_str = g_strdup_printf ("%u MHz", freq); + bitrate_str = g_strdup_printf ("%u MB/s", bitrate/1000); + strength_str = g_strdup_printf ("%u", strength); + wpa_flags_str = ap_wpa_rsn_flags_to_string (wpa_flags); + rsn_flags_str = ap_wpa_rsn_flags_to_string (rsn_flags); + + security_str = g_string_new (NULL); + if ( !(flags & NM_802_11_AP_FLAGS_PRIVACY) + && (wpa_flags != NM_802_11_AP_SEC_NONE) + && (rsn_flags != NM_802_11_AP_SEC_NONE)) + g_string_append (security_str, "Encrypted: "); + + if ( (flags & NM_802_11_AP_FLAGS_PRIVACY) + && (wpa_flags == NM_802_11_AP_SEC_NONE) + && (rsn_flags == NM_802_11_AP_SEC_NONE)) + g_string_append (security_str, "WEP "); + if (wpa_flags != NM_802_11_AP_SEC_NONE) + g_string_append (security_str, "WPA "); + if (rsn_flags != NM_802_11_AP_SEC_NONE) + g_string_append (security_str, "WPA2 "); + if ( (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X) + || (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)) + g_string_append (security_str, "Enterprise "); + + if (security_str->len > 0) + g_string_truncate (security_str, security_str->len-1); /* Chop off last space */ + + printf ("SSID: %s\n", ssid_str); + printf ("BSSID: %s\n", hwaddr); + printf ("Mode: %s\n", mode == NM_802_11_MODE_ADHOC ? "Ad-Hoc" : mode == NM_802_11_MODE_INFRA ? "Infrastructure" : "Unknown"); + printf ("Freq: %s\n", freq_str); + printf ("Bitrate: %s\n", bitrate_str); + printf ("Strength: %s\n", strength_str); + printf ("Security: %s\n", security_str->str); + printf ("WPA flags: %s\n", wpa_flags_str); + printf ("RSN flags: %s\n", rsn_flags_str); + printf ("D-Bus path: %s\n\n", nm_object_get_path (NM_OBJECT (ap))); + + g_free (ssid_str); + g_free (freq_str); + g_free (bitrate_str); + g_free (strength_str); + g_free (wpa_flags_str); + g_free (rsn_flags_str); + g_string_free (security_str, TRUE); +} + +static void +show_wifi_device_info (NMDevice *device) +{ + NMAccessPoint *active_ap = NULL; + const GPtrArray *aps; + const char *iface; + const char *driver; + guint32 speed; + const GByteArray *active_ssid; + char *active_ssid_str = NULL; + int i; + + /* Get active AP */ + if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) { + if ((active_ap = nm_device_wifi_get_active_access_point (NM_DEVICE_WIFI (device)))) { + active_ssid = nm_access_point_get_ssid (active_ap); + active_ssid_str = nm_utils_ssid_to_utf8 ((const char *) active_ssid->data, active_ssid->len); + } + } + + iface = nm_device_get_iface (device); + driver = nm_device_get_driver (device); + speed = nm_device_wifi_get_bitrate (NM_DEVICE_WIFI (device)); + speed /= 1000; + + printf ("Device: %s ---- Driver: %s ---- Speed: %d MB/s ---- Active AP: %s\n", + iface, driver, speed, active_ssid_str ? active_ssid_str : "none"); + printf ("=================================================================================\n"); + g_free (active_ssid_str); + + /* Get all APs of the Wi-Fi device */ + aps = nm_device_wifi_get_access_points (NM_DEVICE_WIFI (device)); + + /* Print AP details */ + for (i = 0; aps && (i < aps->len); i++) { + NMAccessPoint *ap = g_ptr_array_index (aps, i); + show_access_point_info (ap); + } +} + +int main (int argc, char *argv[]) +{ + DBusGConnection *bus; + NMClient *client; + const GPtrArray *devices; + int i; + + /* Initialize GType system */ + g_type_init (); + + /* Get system bus */ + bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); + + /* Get NMClient object */ + client = nm_client_new (); + if (!client) { + dbus_g_connection_unref (bus); + g_message ("Error: Could not create NMClient."); + return EXIT_FAILURE; + } + + /* Get all devices managed by NetworkManager */ + devices = nm_client_get_devices (client); + + /* Go through the array and process Wi-Fi devices */ + for (i = 0; devices && (i < devices->len); i++) { + NMDevice *device = g_ptr_array_index (devices, i); + if (NM_IS_DEVICE_WIFI (device)) + show_wifi_device_info (device); + } + + g_object_unref (client); + dbus_g_connection_unref (bus); + + return EXIT_SUCCESS; +} From 39eed50e470d6f41222e40ce0276b898e8c84dc4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 17 Dec 2010 09:22:11 -0600 Subject: [PATCH 052/102] policy: stop touching /etc/hosts Handling of /etc/hosts is highly site- and admin- specific in many more complex cases, and it's exceedingly hard and error- prone for NetworkManager to handle all those cases. So remove this functionality entirely. That's not a big loss, as it turns out there's a much more elegant solution. The only requirement is that the machine's hostname map back to an IP address owned by the machine. That requirement can be satisifed by nss-myhostname or even possibly the distro's installer. If the user does not want nss-myhostname then it can be uninstalled. Distros should use a "recommends" feature in their packaging system so that the NetworkManager package does *not* have a hard requirement on nss-myhostname. Thus everyone is happy; things Just Work when nss-myhostname is installed, but more advanced users can uninstall it and customize /etc/hosts as they wish. Another alternative is a dispatcher script that listents for the 'hostname' event, and updates /etc/hosts according to the administrator's preference. --- src/main.c | 4 + src/nm-policy-hostname.c | 56 +-- src/nm-policy-hostname.h | 5 +- src/nm-policy-hosts.c | 526 ++--------------------- src/nm-policy-hosts.h | 20 +- src/nm-policy.c | 42 +- src/tests/test-policy-hosts.c | 765 ++-------------------------------- 7 files changed, 81 insertions(+), 1337 deletions(-) diff --git a/src/main.c b/src/main.c index 7a8e7e88ee..5591c505ce 100644 --- a/src/main.c +++ b/src/main.c @@ -49,6 +49,7 @@ #include "nm-netlink-monitor.h" #include "nm-vpn-manager.h" #include "nm-logging.h" +#include "nm-policy-hosts.h" #if !defined(NM_DIST_VERSION) # define NM_DIST_VERSION VERSION @@ -717,6 +718,9 @@ main (int argc, char *argv[]) goto done; } + /* Clean leftover "# Added by NetworkManager" entries from /etc/hosts */ + nm_policy_hosts_clean_etc_hosts (); + nm_manager_start (manager); /* Bring up the loopback interface. */ diff --git a/src/nm-policy-hostname.c b/src/nm-policy-hostname.c index 42a2e0f9a4..4fe69c5a9b 100644 --- a/src/nm-policy-hostname.c +++ b/src/nm-policy-hostname.c @@ -30,7 +30,6 @@ #include "nm-logging.h" #include "nm-policy-hostname.h" -#include "nm-policy-hosts.h" /************************************************************************/ @@ -206,74 +205,39 @@ hostname_thread_is_dead (HostnameThread *ht) /************************************************************************/ #define FALLBACK_HOSTNAME4 "localhost.localdomain" -#define FALLBACK_HOSTNAME6 "localhost6.localdomain6" gboolean -nm_policy_set_system_hostname (const char *new_hostname, - const char *ip4_addr, - const char *ip6_addr, - const char *msg) +nm_policy_set_system_hostname (const char *new_hostname, const char *msg) { char old_hostname[HOST_NAME_MAX + 1]; - int ret = 0; const char *name; - gboolean set_hostname = TRUE, changed = FALSE, old_valid = TRUE; + int ret; if (new_hostname) g_warn_if_fail (strlen (new_hostname)); - name = (new_hostname && strlen (new_hostname)) ? new_hostname : FALLBACK_HOSTNAME4; - old_hostname[HOST_NAME_MAX] = '\0'; errno = 0; ret = gethostname (old_hostname, HOST_NAME_MAX); if (ret != 0) { nm_log_warn (LOGD_DNS, "couldn't get the system hostname: (%d) %s", errno, strerror (errno)); - old_valid = FALSE; } else { /* Don't set the hostname if it isn't actually changing */ if ( (new_hostname && !strcmp (old_hostname, new_hostname)) || (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME4))) - set_hostname = FALSE; - - if (old_hostname[0] == '\0') - old_valid = FALSE; - } - - if (set_hostname) { - nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg); - ret = sethostname (name, strlen (name)); - if (ret != 0) { - nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s", - name, errno, strerror (errno)); return FALSE; - } } - /* But even if the hostname isn't changing, always try updating /etc/hosts - * just in case the hostname changed while NM wasn't running; we need to - * make sure that /etc/hosts has valid mappings for '127.0.0.1' and the - * current system hostname. If those exist, - * nm_policy_hosts_update_etc_hosts() will just return and won't touch - * /etc/hosts at all. - */ - if (!nm_policy_hosts_update_etc_hosts (name, - old_valid ? old_hostname : NULL, - FALLBACK_HOSTNAME4, - FALLBACK_HOSTNAME6, - ip4_addr, - ip6_addr, - &changed)) { - /* error updating /etc/hosts; fallback to localhost.localdomain */ - nm_log_info (LOGD_DNS, "Setting system hostname to '" FALLBACK_HOSTNAME4 "' (error updating /etc/hosts)"); - ret = sethostname (FALLBACK_HOSTNAME4, strlen (FALLBACK_HOSTNAME4)); - if (ret != 0) { - nm_log_warn (LOGD_DNS, "couldn't set the fallback system hostname (%s): (%d) %s", - FALLBACK_HOSTNAME4, errno, strerror (errno)); - } + name = (new_hostname && strlen (new_hostname)) ? new_hostname : FALLBACK_HOSTNAME4; + + nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg); + ret = sethostname (name, strlen (name)); + if (ret != 0) { + nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s", + name, errno, strerror (errno)); } - return changed; + return (ret == 0); } diff --git a/src/nm-policy-hostname.h b/src/nm-policy-hostname.h index 9c76884726..e76713f16d 100644 --- a/src/nm-policy-hostname.h +++ b/src/nm-policy-hostname.h @@ -24,10 +24,7 @@ #include -gboolean nm_policy_set_system_hostname (const char *new_hostname, - const char *ip4_addr, - const char *ip6_addr, - const char *msg); +gboolean nm_policy_set_system_hostname (const char *new_hostname, const char *msg); typedef struct HostnameThread HostnameThread; diff --git a/src/nm-policy-hosts.c b/src/nm-policy-hosts.c index 7f9cff8074..8bbd1d3b5f 100644 --- a/src/nm-policy-hosts.c +++ b/src/nm-policy-hosts.c @@ -20,526 +20,74 @@ #include #include -#include -#include -#include -#include -#include #include "nm-policy-hosts.h" #include "nm-logging.h" -#define IP4_LH "127.0.0.1" -#define IP6_LH "::1" - -gboolean -nm_policy_hosts_find_token (const char *line, const char *token) -{ - const char *start = line, *p = line; - - g_return_val_if_fail (line != NULL, FALSE); - g_return_val_if_fail (token != NULL, FALSE); - g_return_val_if_fail (strlen (token) > 0, FALSE); - - /* Walk through the line to find the next whitespace character */ - while (p <= line + strlen (line)) { - if (isblank (*p) || (*p == '\0')) { - /* Token starts with 'start' and ends with 'end' */ - if ((p > start) && *start && (p - start == strlen (token)) && !strncmp (start, token, (p - start))) - return TRUE; /* found */ - - /* not found; advance start and continue looking */ - start = p + 1; - } - p++; - } - - return FALSE; -} - -static gboolean -is_local_mapping (const char *str, gboolean ip6, const char *hostname) -{ - const char *addr = ip6 ? IP6_LH : IP4_LH; - const char *fallback = ip6 ? "localhost6" : "localhost"; - - return ( !strncmp (str, addr, strlen (addr)) - && nm_policy_hosts_find_token (str, hostname ? hostname : fallback)); -} - -static gboolean -is_ip4_addr (const char *str) -{ - struct in_addr found; - char buf[INET_ADDRSTRLEN + 2]; - const char *p = str; - guint32 i = 0; - - memset (buf, 0, sizeof (buf)); - while (*p && !isblank (*p) && (i < sizeof (buf))) - buf[i++] = *p++; - - return inet_pton (AF_INET, buf, &found) == 1 ? TRUE : FALSE; -} - -static gboolean -ip4_addr_matches (const char *str, const char *ip4_addr) -{ - struct in_addr found, given; - char buf[INET_ADDRSTRLEN + 2]; - const char *p = str; - guint32 i = 0; - - g_return_val_if_fail (ip4_addr != NULL, FALSE); - - memset (buf, 0, sizeof (buf)); - while (*p && !isblank (*p) && (i < sizeof (buf))) - buf[i++] = *p++; - - if (inet_pton (AF_INET, buf, &found) != 1) - return FALSE; - if (inet_pton (AF_INET, ip4_addr, &given) != 1) - return FALSE; - - return memcmp (&found, &given, sizeof (found)) == 0; -} - -static gboolean -is_ip6_addr (const char *str) -{ - struct in6_addr found; - char buf[INET6_ADDRSTRLEN + 2]; - const char *p = str; - guint32 i = 0; - - memset (buf, 0, sizeof (buf)); - while (*p && !isblank (*p) && (i < sizeof (buf))) - buf[i++] = *p++; - - return inet_pton (AF_INET6, buf, &found) == 1 ? TRUE : FALSE; -} - -static gboolean -ip6_addr_matches (const char *str, const char *ip6_addr) -{ - struct in6_addr found, given; - char buf[INET6_ADDRSTRLEN + 2]; - const char *p = str; - guint32 i = 0; - - g_return_val_if_fail (ip6_addr != NULL, FALSE); - - memset (buf, 0, sizeof (buf)); - while (*p && !isblank (*p) && (i < sizeof (buf))) - buf[i++] = *p++; - - if (inet_pton (AF_INET6, buf, &found) != 1) - return FALSE; - if (inet_pton (AF_INET6, ip6_addr, &given) != 1) - return FALSE; - - return memcmp (&found, &given, sizeof (found)) == 0; -} - -static char * -get_custom_hostnames (const char *line, - const char *hostname, - const char *old_hostname, - const char *short_hostname, - const char *fallback_hostname) -{ - char **items = NULL, **iter; - guint start = 0; - GString *str = NULL; - char *custom = NULL; - - g_return_val_if_fail (line != NULL, NULL); - - if (!strncmp (line, IP4_LH, strlen (IP4_LH))) - start = strlen (IP4_LH); - else if (!strncmp (line, IP6_LH, strlen (IP6_LH))) - start = strlen (IP6_LH); - - g_return_val_if_fail (start > 0, NULL); - - /* Split the line into tokens */ - items = g_strsplit_set (line + start, " \t", -1); - if (!items) - return NULL; - - str = g_string_sized_new (50); - /* Ignore current & old hostnames, and localhost-anything */ - for (iter = items; iter && *iter; iter++) { - if (*iter[0] == '\0') - continue; - if (hostname && !strcmp (*iter, hostname)) - continue; - if (old_hostname && !strcmp (*iter, old_hostname)) - continue; - if (short_hostname && !strcmp (*iter, short_hostname)) - continue; - if (fallback_hostname && !strcmp (*iter, fallback_hostname)) - continue; - if (!strcmp (*iter, "localhost")) - continue; - if (!strcmp (*iter, "localhost6")) - continue; - if (!strcmp (*iter, "localhost.localdomain")) - continue; - if (!strcmp (*iter, "localhost4.localdomain4")) - continue; - if (!strcmp (*iter, "localhost6.localdomain6")) - continue; - - /* Found a custom hostname */ - g_string_append_c (str, '\t'); - g_string_append (str, *iter); - } - - if (str->len) - custom = g_string_free (str, FALSE); - else - g_string_free (str, TRUE); - - g_strfreev (items); - return custom; -} - #define ADDED_TAG "# Added by NetworkManager" GString * -nm_policy_get_etc_hosts (const char **lines, - gsize existing_len, - const char *hostname, - const char *old_hostname, - const char *fallback_hostname4, - const char *fallback_hostname6, - const char *ip4_addr, - const char *ip6_addr, - GError **error) +nm_policy_get_etc_hosts (const char *contents, gsize contents_len) { - GString *contents = NULL; - const char **line; - gboolean found_localhost4 = FALSE; - gboolean found_localhost6 = FALSE; - gboolean found_host4 = FALSE; - gboolean found_host6 = FALSE; - gboolean found_user_host4 = FALSE; - gboolean found_user_host6 = FALSE; - gboolean initial_comments = TRUE; - gboolean added = FALSE; - gboolean hostname4_is_fallback; - gboolean hostname6_is_fallback; - gboolean host4_before = FALSE; - gboolean host6_before = FALSE; - gboolean no_stale = TRUE; - char *short_hostname = NULL; - char *custom4 = NULL; - char *custom6 = NULL; + char **lines = NULL, **iter; + GString *new_contents = NULL; - g_return_val_if_fail (lines != NULL, FALSE); - g_return_val_if_fail (hostname != NULL, FALSE); + if (contents_len == 0 || !strstr (contents, ADDED_TAG)) + return NULL; - hostname4_is_fallback = !strcmp (hostname, fallback_hostname4); - hostname6_is_fallback = !strcmp (hostname, fallback_hostname6); + new_contents = g_string_sized_new (contents_len); - /* Find the short hostname, like 'foo' from 'foo.bar.baz'; we want to - * make sure that the entries we add for this host also include the short - * hostname too so that if the resolver does not answer queries for the - * machine's actual hostname/domain, that stuff like 'ping foo' still works. + /* Remove "# Added ..." lines */ + lines = g_strsplit_set (contents, "\n\r", -1); + for (iter = lines; iter && *iter; iter++) { + if (!strstr (*iter, ADDED_TAG)) { + g_string_append (new_contents, *iter); + g_string_append_c (new_contents, '\n'); + } + } + g_strfreev (lines); + + /* Remove last blank line at end of file, if one exists; this is + * an artifact of how g_strsplit_set() works. */ - if (!hostname4_is_fallback || !hostname6_is_fallback) { - char *dot; + if ( (new_contents->len > 2) + && (new_contents->str[new_contents->len - 1] == '\n')) + g_string_truncate (new_contents, new_contents->len - 1); - short_hostname = g_strdup (hostname); - dot = strchr (short_hostname, '.'); - if (dot && *(dot+1)) - *dot = '\0'; - else { - g_free (short_hostname); - short_hostname = NULL; - } - } - - /* We need the following in /etc/hosts: - * - * 1) current hostname mapped to current IPv4 addresses if IPv4 is active - * 2) current hostname mapped to current IPv6 addresses if IPv6 is active - * 3) 'localhost' mapped to 127.0.0.1 - * 4) 'localhost6' mapped to ::1 - * - * If all these things exist we don't need to bother updating the file. - */ - - if (!ip4_addr) - host4_before = TRUE; - if (!ip6_addr) - host6_before = TRUE; - - /* Look for the four cases from above */ - for (line = lines; lines && *line; line++) { - gboolean found_hostname = FALSE; - - if ((*line[0] == '\0') || (*line[0] == '#')) - continue; - - found_hostname = nm_policy_hosts_find_token (*line, hostname); - if (found_hostname) { - /* Found the current hostname on this line */ - if (ip4_addr && ip4_addr_matches (*line, ip4_addr)) { - found_host4 = TRUE; - if (strstr (*line, ADDED_TAG)) { - if (!host4_before) - host4_before = !found_localhost4; - } else { - found_user_host4 = TRUE; - host4_before = TRUE; /* Ignore if user added mapping manually */ - } - } else if (!ip4_addr && strstr (*line, ADDED_TAG)) { - /* If this is a stale NM-added IPv4 entry we need to remove it, - * so make sure we update /etc/hosts. - */ - if (is_ip4_addr (*line)) - no_stale = FALSE; - } - - if (ip6_addr && ip6_addr_matches (*line, ip6_addr)) { - found_host6 = TRUE; - if (strstr (*line, ADDED_TAG)) { - if (!host6_before) - host6_before = !found_localhost6; - } else { - found_user_host6 = TRUE; - host6_before = TRUE; /* Ignore if user added mapping manually */ - } - } else if (!ip6_addr && strstr (*line, ADDED_TAG)) { - /* If this is a stale NM-added IPv6 entry we need to remove it, - * so make sure we update /etc/hosts. - */ - if (is_ip6_addr (*line)) - no_stale = FALSE; - } - } - - if (is_local_mapping (*line, FALSE, "localhost")) { - /* a 127.0.0.1 line containing 'localhost' */ - found_localhost4 = TRUE; - custom4 = get_custom_hostnames (*line, hostname, old_hostname, short_hostname, fallback_hostname4); - if (!ip4_addr) { - /* If there's no IP-specific mapping for the current hostname - * but that hostname is present on in the local mapping line, - * we've found our IPv4 hostname mapping. If the hostname is - * the fallback *IPv6* hostname it's not going to show up in - * the IPv4 local mapping though, so fake it. - */ - if (hostname6_is_fallback || found_hostname) - found_host4 = TRUE; - } - } else if (is_local_mapping (*line, TRUE, "localhost6")) { - /* a ::1 line containing 'localhost6' */ - found_localhost6 = TRUE; - custom6 = get_custom_hostnames (*line, hostname, old_hostname, short_hostname, fallback_hostname6); - if (!ip6_addr) { - /* If there's no IP-specific mapping for the current hostname - * but that hostname is present on in the local mapping line, - * we've found our IPv6 hostname mapping. If the hostname is - * the fallback *IPv4* hostname it's not going to show up in - * the IPv6 local mapping though, so fake it. - */ - if (hostname4_is_fallback || found_hostname) - found_host6 = TRUE; - } - } - - if ( found_localhost4 - && found_host4 - && found_localhost6 - && found_host6 - && host4_before - && host6_before - && no_stale) - goto out; /* No update required */ - } - - contents = g_string_sized_new (existing_len ? existing_len + 100 : 200); - if (!contents) { - g_set_error_literal (error, 0, 0, "not enough memory"); - goto out; - } - - /* Construct the new hosts file; replace any 127.0.0.1/::1 entry that is - * at the beginning of the file or right after initial comments and contains - * the string 'localhost' (for IPv4) or 'localhost6' (for IPv6). If there - * is no 127.0.0.1 or ::1 entry at the beginning or after initial comments - * that contains 'localhost' or 'localhost6', add one there - * and ignore any other 127.0.0.1/::1 entries that contain 'localhost' or - * 'localhost6'. - */ - for (line = lines, initial_comments = TRUE; lines && *line; line++) { - /* This is the first line after the initial comments */ - if (strlen (*line) && initial_comments && (*line[0] != '#')) { - initial_comments = FALSE; - - /* If the user added their own mapping for the hostname, just make - * a simple 'localhost' mapping and assume the user knows what they - * are doing with their manual hostname entry. Otherwise if the - * hostname wasn't found somewhere else, add it to the localhost - * mapping line to make sure it's mapped to something. - */ - - /* Add the address mappings first so they take precedence */ - if (!hostname4_is_fallback && ip4_addr && !found_user_host4) { - g_string_append_printf (contents, "%s\t%s", ip4_addr, hostname); - if (short_hostname) - g_string_append_printf (contents, "\t%s", short_hostname); - g_string_append_printf (contents, "\t%s\n", ADDED_TAG); - } - if (!hostname6_is_fallback && ip6_addr && !found_user_host6) { - g_string_append_printf (contents, "%s\t%s", ip6_addr, hostname); - if (short_hostname) - g_string_append_printf (contents, "\t%s", short_hostname); - g_string_append_printf (contents, "\t%s\n", ADDED_TAG); - } - - /* IPv4 localhost line */ - g_string_append (contents, "127.0.0.1"); - if (!hostname4_is_fallback && !ip4_addr && !found_user_host4) { - g_string_append_printf (contents, "\t%s", hostname); - if (short_hostname) - g_string_append_printf (contents, "\t%s", short_hostname); - } - g_string_append_printf (contents, "\t%s\tlocalhost", fallback_hostname4); - if (custom4) - g_string_append (contents, custom4); - g_string_append_c (contents, '\n'); - - /* IPv6 localhost line */ - g_string_append (contents, "::1"); - if (!hostname6_is_fallback && !hostname4_is_fallback && !ip6_addr && !found_user_host6) { - g_string_append_printf (contents, "\t%s", hostname); - if (short_hostname) - g_string_append_printf (contents, "\t%s", short_hostname); - } - g_string_append_printf (contents, "\t%s\tlocalhost6", fallback_hostname6); - if (custom6) - g_string_append (contents, custom6); - g_string_append_c (contents, '\n'); - - added = TRUE; - } - - /* Don't add the original line if it is a localhost mapping */ - if ( !is_local_mapping (*line, FALSE, "localhost") - && !is_local_mapping (*line, FALSE, fallback_hostname4) - && !is_local_mapping (*line, FALSE, hostname) - && !is_local_mapping (*line, TRUE, "localhost6") - && !is_local_mapping (*line, TRUE, fallback_hostname6) - && !is_local_mapping (*line, TRUE, hostname) - && !strstr (*line, ADDED_TAG)) { - - g_string_append (contents, *line); - /* Only append the new line if this isn't the last line in the file */ - if (*(line+1)) - g_string_append_c (contents, '\n'); - } - } - - /* Hmm, /etc/hosts was empty for some reason */ - if (!added) { - g_string_append (contents, "# Do not remove the following lines, or various programs\n"); - g_string_append (contents, "# that require network functionality will fail.\n"); - - /* Add the address mappings first so they take precedence */ - if (!hostname4_is_fallback && ip4_addr) { - g_string_append_printf (contents, "%s\t%s", ip4_addr, hostname); - if (short_hostname) - g_string_append_printf (contents, "\t%s", short_hostname); - g_string_append_printf (contents, "\t%s\n", ADDED_TAG); - } - if (!hostname6_is_fallback && ip6_addr) { - g_string_append_printf (contents, "%s\t%s", ip6_addr, hostname); - if (short_hostname) - g_string_append_printf (contents, "\t%s", short_hostname); - g_string_append_printf (contents, "\t%s\n", ADDED_TAG); - } - - g_string_append_printf (contents, "127.0.0.1\t%s\tlocalhost\n", fallback_hostname4); - g_string_append_printf (contents, "::1\t%s\tlocalhost6\n", fallback_hostname6); - } - -out: - g_free (custom4); - g_free (custom6); - g_free (short_hostname); - return contents; + return new_contents; } -gboolean -nm_policy_hosts_update_etc_hosts (const char *hostname, - const char *old_hostname, - const char *fallback_hostname4, - const char *fallback_hostname6, - const char *ip4_addr, - const char *ip6_addr, - gboolean *out_changed) +/* remove any leftover "# Added by NetworkManager" lines */ +void +nm_policy_hosts_clean_etc_hosts (void) { char *contents = NULL; - char **lines = NULL; - GError *error = NULL; - GString *new_contents = NULL; gsize contents_len = 0; - gboolean success = FALSE; - - g_return_val_if_fail (hostname != NULL, FALSE); - g_return_val_if_fail (out_changed != NULL, FALSE); + GError *error = NULL; + GString *new; if (!g_file_get_contents (SYSCONFDIR "/hosts", &contents, &contents_len, &error)) { nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s", error ? error->code : 0, (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); - return FALSE; + return; } - /* Get the new /etc/hosts contents */ - lines = g_strsplit_set (contents, "\n\r", 0); - new_contents = nm_policy_get_etc_hosts ((const char **) lines, - contents_len, - hostname, - old_hostname, - fallback_hostname4, - fallback_hostname6, - ip4_addr, - ip6_addr, - &error); - g_strfreev (lines); - g_free (contents); - - if (new_contents) { - nm_log_info (LOGD_DNS, "Updating /etc/hosts with new system hostname"); + new = nm_policy_get_etc_hosts (contents, contents_len); + if (new && new->len) { + nm_log_info (LOGD_DNS, "Cleaning leftovers from /etc/hosts"); g_clear_error (&error); - /* And actually update /etc/hosts */ - if (!g_file_set_contents (SYSCONFDIR "/hosts", new_contents->str, -1, &error)) { - nm_log_warn (LOGD_DNS, "couldn't update " SYSCONFDIR "/hosts: (%d) %s", - error ? error->code : 0, - (error && error->message) ? error->message : "(unknown)"); + if (!g_file_set_contents (SYSCONFDIR "/hosts", new->str, -1, &error)) { + nm_log_dbg (LOGD_DNS, "couldn't update " SYSCONFDIR "/hosts: (%d) %s", + error ? error->code : 0, + (error && error->message) ? error->message : "(unknown)"); g_clear_error (&error); - } else { - success = TRUE; - *out_changed = TRUE; } - - g_string_free (new_contents, TRUE); - } else if (!error) { - /* No change required */ - success = TRUE; - } else { - nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s", - error->code, error->message ? error->message : "(unknown)"); - g_clear_error (&error); } - return success; + if (new) + g_string_free (new, TRUE); } diff --git a/src/nm-policy-hosts.h b/src/nm-policy-hosts.h index ebaaf0fd41..9f4bf9a9a9 100644 --- a/src/nm-policy-hosts.h +++ b/src/nm-policy-hosts.h @@ -23,26 +23,10 @@ #include -gboolean nm_policy_hosts_update_etc_hosts (const char *hostname, - const char *old_hostname, - const char *fallback_hostname4, - const char *fallback_hostname6, - const char *ip4_addr, - const char *ip6_addr, - gboolean *out_changed); +void nm_policy_hosts_clean_etc_hosts (void); /* Only for testcases; don't use outside of nm-policy-hosts.c */ -gboolean nm_policy_hosts_find_token (const char *line, const char *token); - -GString *nm_policy_get_etc_hosts (const char **lines, - gsize existing_len, - const char *hostname, - const char *old_hostname, - const char *fallback_hostname4, - const char *fallback_hostname6, - const char *ip4_addr, - const char *ip6_addr, - GError **error); +GString *nm_policy_get_etc_hosts (const char *contents, gsize contents_len); #endif /* NM_POLICY_HOSTS_H */ diff --git a/src/nm-policy.c b/src/nm-policy.c index b0c366234b..b5c212929b 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -42,7 +42,6 @@ #include "nm-system.h" #include "nm-dns-manager.h" #include "nm-vpn-manager.h" -#include "nm-policy-hosts.h" #include "nm-policy-hostname.h" struct NMPolicy { @@ -235,9 +234,6 @@ _set_hostname (NMPolicy *policy, const char *new_hostname, const char *msg) { - char ip4_addr[INET_ADDRSTRLEN + 1]; - char ip6_addr[INET6_ADDRSTRLEN + 1]; - if (change_hostname) { NMDnsManager *dns_mgr; @@ -249,43 +245,7 @@ _set_hostname (NMPolicy *policy, g_object_unref (dns_mgr); } - /* Get the default IPv4 and IPv6 addresses so we can assign - * the hostname to them in /etc/hosts. - */ - memset (ip4_addr, 0, sizeof (ip4_addr)); - if (policy->default_device4) { - NMIP4Config *config = NULL; - NMIP4Address *addr = NULL; - - config = nm_device_get_ip4_config (policy->default_device4); - if (config) - addr = nm_ip4_config_get_address (config, 0); - - if (addr) { - struct in_addr tmp; - - tmp.s_addr = nm_ip4_address_get_address (addr); - inet_ntop (AF_INET, &tmp, ip4_addr, sizeof (ip4_addr)); - } - } - - memset (ip6_addr, 0, sizeof (ip6_addr)); - if (policy->default_device6) { - NMIP6Config *config = NULL; - NMIP6Address *addr = NULL; - - config = nm_device_get_ip6_config (policy->default_device6); - if (config) - addr = nm_ip6_config_get_address (config, 0); - - if (addr) - inet_ntop (AF_INET6, nm_ip6_address_get_address (addr), ip6_addr, sizeof (ip6_addr)); - } - - if (nm_policy_set_system_hostname (policy->cur_hostname, - strlen (ip4_addr) ? ip4_addr : NULL, - strlen (ip6_addr) ? ip6_addr : NULL, - msg)) + if (nm_policy_set_system_hostname (policy->cur_hostname, msg)) nm_utils_call_dispatcher ("hostname", NULL, NULL, NULL); } diff --git a/src/tests/test-policy-hosts.c b/src/tests/test-policy-hosts.c index 8865c4264e..62862e756f 100644 --- a/src/tests/test-policy-hosts.c +++ b/src/tests/test-policy-hosts.c @@ -23,41 +23,17 @@ #include "nm-policy-hosts.h" -#define FALLBACK_HOSTNAME4 "localhost.localdomain" -#define FALLBACK_HOSTNAME6 "localhost6.localdomain6" - -#define DEBUG 0 +#define DEBUG 1 static void -test_generic (const char *before, - const char *after, - const char *hostname, - const char *ip4_addr, - const char *ip6_addr, - gboolean expect_error) +test_generic (const char *before, const char *after) { - char **lines; GString *newc; - GError *error = NULL; /* Get the new /etc/hosts contents */ - lines = g_strsplit_set (before, "\n\r", 0); - newc = nm_policy_get_etc_hosts ((const char **) lines, - strlen (before), - hostname, - NULL, - FALLBACK_HOSTNAME4, - FALLBACK_HOSTNAME6, - ip4_addr, - ip6_addr, - &error); - g_strfreev (lines); + newc = nm_policy_get_etc_hosts (before, strlen (before)); - if (expect_error) { - g_assert (newc == NULL); - g_assert (error != NULL); - g_clear_error (&error); - } else if (after == NULL) { + if (after == NULL) { /* No change to /etc/hosts required */ #if DEBUG if (newc != NULL) { @@ -68,10 +44,8 @@ test_generic (const char *before, } #endif g_assert (newc == NULL); - g_assert (error == NULL); } else { g_assert (newc != NULL); - g_assert (error == NULL); #if DEBUG g_message ("\n- NEW ---------------------------------\n" @@ -81,7 +55,6 @@ test_generic (const char *before, "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", newc->str, after); #endif - g_assert (strlen (newc->str) == strlen (after)); g_assert (strcmp (newc->str, after) == 0); g_string_free (newc, TRUE); } @@ -99,7 +72,7 @@ static const char *generic_before = \ static void test_hosts_generic (void) { - test_generic (generic_before, NULL, "localhost.localdomain", NULL, NULL, FALSE); + test_generic (generic_before, NULL); } /*******************************************/ @@ -112,308 +85,12 @@ static const char *generic_no_boilerplate_before = \ static void test_hosts_generic_no_boilerplate (void) { - test_generic (generic_no_boilerplate_before, NULL, "localhost.localdomain", NULL, NULL, FALSE); + test_generic (generic_no_boilerplate_before, NULL); } /*******************************************/ -static const char *generic_no_boilerplate_no_lh_before = \ - "127.0.0.1 localhost.localdomain\n" - "::1 localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *generic_no_boilerplate_no_lh_after = \ - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_generic_no_boilerplate_no_lh (void) -{ - test_generic (generic_no_boilerplate_no_lh_before, - generic_no_boilerplate_no_lh_after, - "localhost.localdomain", - NULL, - NULL, - FALSE); -} - -/*******************************************/ - - -static const char *generic_no_boilerplate_no_lh_no_host_before = \ - "127.0.0.1 localhost.localdomain\n" - "::1 localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *generic_no_boilerplate_no_lh_no_host_after = \ - "127.0.0.1 comet localhost.localdomain localhost\n" - "::1 comet localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_generic_no_boilerplate_no_lh_no_host (void) -{ - test_generic (generic_no_boilerplate_no_lh_no_host_before, - generic_no_boilerplate_no_lh_no_host_after, - "comet", - NULL, - NULL, - FALSE); -} - -/*******************************************/ -static const char *named_generic_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 playboy localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *named_generic_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 playboy localhost.localdomain localhost\n" - "::1 playboy localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_named_generic (void) -{ - test_generic (named_generic_before, named_generic_after, "playboy", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *named4_non127_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 tomcat localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "192.168.1.2 tomcat\n"; - -static void -test_hosts_named4_non127 (void) -{ - test_generic (named4_non127_before, NULL, "tomcat", "192.168.1.2", NULL, FALSE); -} - -/*******************************************/ - -static const char *named6_non127_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 tomcat localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "3001:abba::3234 tomcat\n"; - -static void -test_hosts_named6_non127 (void) -{ - test_generic (named6_non127_before, NULL, "tomcat", NULL, "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *named4_non127_more_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 tomcat localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "192.168.1.2 tomcat\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "127.0.0.1 srx.main.ebayrtm.com\n" - "127.0.0.1 cdn5.tribalfusion.com\n"; - -static void -test_hosts_named4_non127_more (void) -{ - test_generic (named4_non127_more_before, NULL, "tomcat", "192.168.1.2", NULL, FALSE); -} - -/*******************************************/ - -static const char *named6_non127_more_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 tomcat localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "3001:abba::3234 tomcat\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "127.0.0.1 srx.main.ebayrtm.com\n" - "127.0.0.1 cdn5.tribalfusion.com\n"; - -static void -test_hosts_named6_non127_more (void) -{ - test_generic (named6_non127_more_before, NULL, "tomcat", NULL, "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *named_no_lh_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain\n" - "::1 localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "192.168.1.2 tomcat\n"; - -static const char *named_no_lh_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 tomcat localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "192.168.1.2 tomcat\n"; - -static void -test_hosts_named_no_localhost (void) -{ - test_generic (named_no_lh_before, named_no_lh_after, "tomcat", "192.168.1.2", NULL, FALSE); -} - -/*******************************************/ - -static const char *no_lh_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 tomcat\n" - "::1 localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *no_lh_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 tomcat localhost.localdomain localhost\n" - "::1 tomcat localhost6.localdomain6 localhost6\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_no_localhost (void) -{ - test_generic (no_lh_before, no_lh_after, "tomcat", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *named_last_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 sparcbook.ausil.us\n" - "::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 sparcbook.ausil.us\n"; - -static void -test_hosts_named_last (void) -{ - test_generic (named_last_before, NULL, "sparcbook.ausil.us", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *no_host4_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "::1 localhost6.localdomain6 localhost6\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "127.0.0.1 srx.main.ebayrtm.com\n" - "127.0.0.1 cdn5.tribalfusion.com\n" - "127.0.0.1 a.tribalfusion.com\n"; - -static const char *no_host4_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost\n" - "::1 comet localhost6.localdomain6 localhost6\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n" - "127.0.0.1 srx.main.ebayrtm.com\n" - "127.0.0.1 cdn5.tribalfusion.com\n" - "127.0.0.1 a.tribalfusion.com\n"; - -static void -test_hosts_no_host4 (void) -{ - test_generic (no_host4_before, no_host4_after, "comet", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *no_host6_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *no_host6_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost\n" - "::1 comet localhost6.localdomain6 localhost6\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_no_host6 (void) -{ - test_generic (no_host6_before, no_host6_after, "comet", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *named46_non127_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.2 comet\n" - "3001:abba::3234 comet\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_named46_non127 (void) -{ - test_generic (named46_non127_before, NULL, "comet", "192.168.1.2", "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *named46_non127_long_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.2 comet.space comet\n" - "3001:abba::3234 comet.space comet\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_named46_non127_long (void) -{ - test_generic (named46_non127_long_before, NULL, "comet.space", "192.168.1.2", "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *named46_non127_other4_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.3 comet\n" - "3001:abba::3234 comet\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *named46_non127_other4_after = \ +static const char *leftover_before = \ "# Do not remove the following line, or various programs\n" "# that require network functionality will fail.\n" "192.168.1.2 comet # Added by NetworkManager\n" @@ -424,417 +101,55 @@ static const char *named46_non127_other4_after = \ "\n" "127.0.0.1 lcmd.us.intellitxt.com\n"; -static void -test_hosts_named46_non127_other4 (void) -{ - test_generic (named46_non127_other4_before, named46_non127_other4_after, "comet", "192.168.1.2", "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *named46_non127_other4_long_before = \ +static const char *leftover_after = \ "# Do not remove the following line, or various programs\n" "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.3 comet.space\n" - "3001:abba::3234 comet.space\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *named46_non127_other4_long_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "192.168.1.2 comet.space comet # Added by NetworkManager\n" "127.0.0.1 localhost.localdomain localhost\n" "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.3 comet.space\n" - "3001:abba::3234 comet.space\n" + "192.168.1.3 comet\n" + "3001:abba::3234 comet\n" "\n" "127.0.0.1 lcmd.us.intellitxt.com\n"; static void -test_hosts_named46_non127_other4_long (void) +test_hosts_leftover (void) { - test_generic (named46_non127_other4_long_before, named46_non127_other4_long_after, "comet.space", "192.168.1.2", "3001:abba::3234", FALSE); + test_generic (leftover_before, leftover_after); } /*******************************************/ -static const char *named46_non127_other6_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.2 comet\n" - "3001:abba::9675 comet\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *named46_non127_other6_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "3001:abba::3234 comet # Added by NetworkManager\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.2 comet\n" - "3001:abba::9675 comet\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_named46_non127_other6 (void) -{ - test_generic (named46_non127_other6_before, named46_non127_other6_after, "comet", "192.168.1.2", "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *named46_non127_other6_long_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.2 comet.space\n" - "3001:abba::9675 comet.space\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *named46_non127_other6_long_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "3001:abba::3234 comet.space comet # Added by NetworkManager\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.2 comet.space\n" - "3001:abba::9675 comet.space\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_named46_non127_other6_long (void) -{ - test_generic (named46_non127_other6_long_before, named46_non127_other6_long_after, "comet.space", "192.168.1.2", "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *unnamed46_non127_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *unnamed46_non127_after = \ +static const char *leftover_double_newline_before = \ "# Do not remove the following line, or various programs\n" "# that require network functionality will fail.\n" "192.168.1.2 comet # Added by NetworkManager\n" - "3001:abba::3234 comet # Added by NetworkManager\n" "127.0.0.1 localhost.localdomain localhost\n" "::1 localhost6.localdomain6 localhost6\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_unnamed46_non127 (void) -{ - test_generic (unnamed46_non127_before, unnamed46_non127_after, "comet", "192.168.1.2", "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *unnamed46_non127_long_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *unnamed46_non127_long_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "192.168.1.2 comet.space comet # Added by NetworkManager\n" - "3001:abba::3234 comet.space comet # Added by NetworkManager\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_unnamed46_non127_long (void) -{ - test_generic (unnamed46_non127_long_before, unnamed46_non127_long_after, "comet.space", "192.168.1.2", "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *named46_non127_wrong_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "192.168.1.3 comet # Added by NetworkManager\n" - "3001:abba::9876 comet # Added by NetworkManager\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static const char *named46_non127_wrong_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "192.168.1.2 comet # Added by NetworkManager\n" - "3001:abba::3234 comet # Added by NetworkManager\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n" - "\n" - "127.0.0.1 lcmd.us.intellitxt.com\n"; - -static void -test_hosts_named46_non127_wrong (void) -{ - test_generic (named46_non127_wrong_before, named46_non127_wrong_after, "comet", "192.168.1.2", "3001:abba::3234", FALSE); -} - -/*******************************************/ - -static const char *long_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost comet\n" - "::1 localhost6.localdomain6 localhost6\n" + "192.168.1.3 comet\n" + "3001:abba::3234 comet\n" "\n" "127.0.0.1 lcmd.us.intellitxt.com\n" - "127.0.0.1 adserver.adtech.de\n" - "127.0.0.1 a.as-us.falkag.net\n" - "127.0.0.1 a.as-eu.falkag.net\n" - "127.0.0.1 ads.doubleclick.com\n" - "\n" - "# random comment\n" - "127.0.0.1 m1.2mdn.net\n" - "127.0.0.1 ds.serving-sys.com\n" - "127.0.0.1 pagead2.googlesyndication.com\n" - "127.0.0.1 ad.doubleclick.com\n" - "127.0.0.1 ad.doubleclick.net\n" - "127.0.0.1 oascentral.movietickets.com\n" - "127.0.0.1 view.atdmt.com\n" - "127.0.0.1 ads.chumcity.com\n"; + "\n"; -static const char *long_after = \ +static const char *leftover_double_newline_after = \ "# Do not remove the following line, or various programs\n" "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost\n" - "::1 comet localhost6.localdomain6 localhost6\n" + "127.0.0.1 localhost.localdomain localhost\n" + "::1 localhost6.localdomain6 localhost6\n" + "192.168.1.3 comet\n" + "3001:abba::3234 comet\n" "\n" "127.0.0.1 lcmd.us.intellitxt.com\n" - "127.0.0.1 adserver.adtech.de\n" - "127.0.0.1 a.as-us.falkag.net\n" - "127.0.0.1 a.as-eu.falkag.net\n" - "127.0.0.1 ads.doubleclick.com\n" - "\n" - "# random comment\n" - "127.0.0.1 m1.2mdn.net\n" - "127.0.0.1 ds.serving-sys.com\n" - "127.0.0.1 pagead2.googlesyndication.com\n" - "127.0.0.1 ad.doubleclick.com\n" - "127.0.0.1 ad.doubleclick.net\n" - "127.0.0.1 oascentral.movietickets.com\n" - "127.0.0.1 view.atdmt.com\n" - "127.0.0.1 ads.chumcity.com\n"; + "\n"; static void -test_hosts_long (void) +test_hosts_leftover_double_newline (void) { - test_generic (long_before, long_after, "comet", NULL, NULL, FALSE); + test_generic (leftover_double_newline_before, leftover_double_newline_after); } /*******************************************/ -static const char *custom4_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost pintglass\n" - "::1 localhost6.localdomain6 localhost6\n"; - -static const char *custom4_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost pintglass\n" - "::1 comet localhost6.localdomain6 localhost6\n"; - -static void -test_hosts_custom4 (void) -{ - test_generic (custom4_before, custom4_after, "comet", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *custom6_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6 pintglass\n"; - -static const char *custom6_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost\n" - "::1 comet localhost6.localdomain6 localhost6 pintglass\n"; - -static void -test_hosts_custom6 (void) -{ - test_generic (custom6_before, custom6_after, "comet", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *custom46_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost shotglass\n" - "::1 localhost6.localdomain6 localhost6 pintglass\n"; - -static const char *custom46_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost shotglass\n" - "::1 comet localhost6.localdomain6 localhost6 pintglass\n"; - -static void -test_hosts_custom46 (void) -{ - test_generic (custom46_before, custom46_after, "comet", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *custom46_mixed_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 localhost.localdomain localhost shotglass\n" - "::1 localhost6.localdomain6 localhost6 pintglass\n"; - -static const char *custom46_mixed_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost shotglass\n" - "::1 comet localhost6.localdomain6 localhost6 pintglass\n"; - -static void -test_hosts_custom46_mixed (void) -{ - test_generic (custom46_mixed_before, custom46_mixed_after, "comet", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *stale4_removed_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "1.2.3.4 comet # Added by NetworkManager\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 comet localhost6.localdomain6 localhost6\n"; - -static const char *stale4_removed_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost\n" - "::1 comet localhost6.localdomain6 localhost6\n"; - -static void -test_hosts_stale4_removed (void) -{ - test_generic (stale4_removed_before, stale4_removed_after, "comet", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *stale6_removed_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "3001:abba::3234 comet # Added by NetworkManager\n" - "127.0.0.1 comet localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n"; - -static const char *stale6_removed_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost\n" - "::1 comet localhost6.localdomain6 localhost6\n"; - -static void -test_hosts_stale6_removed (void) -{ - test_generic (stale6_removed_before, stale6_removed_after, "comet", NULL, NULL, FALSE); -} - -/*******************************************/ - -static const char *stale46_removed_before = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "1.2.3.4 comet # Added by NetworkManager\n" - "3001:abba::3234 comet # Added by NetworkManager\n" - "127.0.0.1 localhost.localdomain localhost\n" - "::1 localhost6.localdomain6 localhost6\n"; - -static const char *stale46_removed_after = \ - "# Do not remove the following line, or various programs\n" - "# that require network functionality will fail.\n" - "127.0.0.1 comet localhost.localdomain localhost\n" - "::1 comet localhost6.localdomain6 localhost6\n"; - -static void -test_hosts_stale46_removed (void) -{ - test_generic (stale46_removed_before, stale46_removed_after, "comet", NULL, NULL, FALSE); -} - -/*******************************************/ - -typedef struct { - const char *line; - const char *token; - gboolean expected; -} Foo; - -static Foo foo[] = { - /* Using \t here to easily differentiate tabs vs. spaces for testing */ - { "127.0.0.1\tfoobar\tblah", "blah", TRUE }, - { "", "blah", FALSE }, - { "1.1.1.1\tbork\tfoo", "blah", FALSE }, - { "127.0.0.1 foobar\tblah", "blah", TRUE }, - { "127.0.0.1 foobar blah", "blah", TRUE }, - { "127.0.0.1 localhost", "localhost.localdomain", FALSE }, - { "192.168.1.1 blah borkbork", "blah", TRUE }, - { "192.168.1.1 foobar\tblah borkbork", "blah", TRUE }, - { "192.168.1.1\tfoobar\tblah\tborkbork", "blah", TRUE }, - { "192.168.1.1 \tfoobar \tblah \tborkbork\t ", "blah", TRUE }, - { "\t\t\t\t \t\t\tasdfadf a\t\t\t\t\t \t\t\t\t\t ", "blah", FALSE }, - { NULL, NULL, FALSE } -}; - -static void -test_find_token (void) -{ - Foo *iter = &foo[0]; - - while (iter->line) { - gboolean found; - - found = nm_policy_hosts_find_token (iter->line, iter->token); - if (found != iter->expected) { - g_warning ("find-token: unexpected token result %d for '%s' <= '%s' (expected %d)", - found, iter->line, iter->token, iter->expected); - } - g_assert (found == iter->expected); - iter++; - } -} - #if GLIB_CHECK_VERSION(2,25,12) typedef GTestFixtureFunc TCFunc; #else @@ -851,38 +166,10 @@ int main (int argc, char **argv) suite = g_test_get_root (); - g_test_suite_add (suite, TESTCASE (test_find_token, NULL)); g_test_suite_add (suite, TESTCASE (test_hosts_generic, NULL)); g_test_suite_add (suite, TESTCASE (test_hosts_generic_no_boilerplate, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_generic_no_boilerplate_no_lh, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_generic_no_boilerplate_no_lh_no_host, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named_generic, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named4_non127, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named6_non127, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named4_non127_more, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named6_non127_more, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named46_non127, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named46_non127_long, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named46_non127_other4, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named46_non127_other4_long, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named46_non127_other6, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named46_non127_other6_long, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named46_non127_wrong, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_unnamed46_non127, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_unnamed46_non127_long, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named_no_localhost, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_no_localhost, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_named_last, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_no_host4, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_no_host6, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_long, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_custom4, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_custom6, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_custom46, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_custom46_mixed, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_stale4_removed, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_stale6_removed, NULL)); - g_test_suite_add (suite, TESTCASE (test_hosts_stale46_removed, NULL)); + g_test_suite_add (suite, TESTCASE (test_hosts_leftover, NULL)); + g_test_suite_add (suite, TESTCASE (test_hosts_leftover_double_newline, NULL)); return g_test_run (); } From 297e3c6463f54956077cfaf08d09fc6f5aafc5dd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 17 Dec 2010 23:00:03 -0600 Subject: [PATCH 053/102] dhclient: split out dhclient config merging and add testcases --- .gitignore | 1 + configure.ac | 1 + po/POTFILES.in | 1 + src/dhcp-manager/Makefile.am | 38 +++- src/dhcp-manager/nm-dhcp-dhclient-utils.c | 214 ++++++++++++++++++++ src/dhcp-manager/nm-dhcp-dhclient-utils.h | 35 ++++ src/dhcp-manager/nm-dhcp-dhclient.c | 97 +-------- src/dhcp-manager/tests/Makefile.am | 28 +++ src/dhcp-manager/tests/test-dhcp-dhclient.c | 203 +++++++++++++++++++ 9 files changed, 521 insertions(+), 97 deletions(-) create mode 100644 src/dhcp-manager/nm-dhcp-dhclient-utils.c create mode 100644 src/dhcp-manager/nm-dhcp-dhclient-utils.h create mode 100644 src/dhcp-manager/tests/Makefile.am create mode 100644 src/dhcp-manager/tests/test-dhcp-dhclient.c diff --git a/.gitignore b/.gitignore index 033eaada1e..201955cec8 100644 --- a/.gitignore +++ b/.gitignore @@ -93,6 +93,7 @@ libnm-util/tests/test-need-secrets libnm-util/tests/test-setting-8021x src/tests/test-dhcp-options src/tests/test-policy-hosts +src/dhcp-manager/tests/test-dhcp-dhclient system-settings/plugins/keyfile/tests/test-keyfile system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh diff --git a/configure.ac b/configure.ac index 0665886927..cf05ab7aa8 100644 --- a/configure.ac +++ b/configure.ac @@ -518,6 +518,7 @@ src/logging/Makefile src/dns-manager/Makefile src/vpn-manager/Makefile src/dhcp-manager/Makefile +src/dhcp-manager/tests/Makefile src/ip6-manager/Makefile src/supplicant-manager/Makefile src/supplicant-manager/tests/Makefile diff --git a/po/POTFILES.in b/po/POTFILES.in index f3421b4a60..d4988c43ca 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -16,6 +16,7 @@ policy/org.freedesktop.NetworkManager.policy.in src/nm-netlink-monitor.c src/main.c src/dhcp-manager/nm-dhcp-dhclient.c +src/dhcp-manager/nm-dhcp-dhclient-utils.c src/dhcp-manager/nm-dhcp-manager.c src/logging/nm-logging.c src/dns-manager/nm-dns-manager.c diff --git a/src/dhcp-manager/Makefile.am b/src/dhcp-manager/Makefile.am index e29c6718a3..14ddde0bd2 100644 --- a/src/dhcp-manager/Makefile.am +++ b/src/dhcp-manager/Makefile.am @@ -1,3 +1,5 @@ +SUBDIRS=. tests + INCLUDES = \ -I${top_srcdir} \ -I${top_srcdir}/include \ @@ -6,15 +8,40 @@ INCLUDES = \ -I${top_srcdir}/libnm-util \ -I${top_srcdir}/src -noinst_LTLIBRARIES = libdhcp-manager.la +noinst_LTLIBRARIES = libdhcp-manager.la libdhcp-dhclient.la + +################## dhclient ################## + +libdhcp_dhclient_la_SOURCES = \ + nm-dhcp-dhclient-utils.h \ + nm-dhcp-dhclient-utils.c \ + nm-dhcp-dhclient.h \ + nm-dhcp-dhclient.c + +libdhcp_dhclient_la_CPPFLAGS = \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + -DG_DISABLE_DEPRECATED \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -DLIBEXECDIR=\"$(libexecdir)\" \ + -DLOCALSTATEDIR=\"$(localstatedir)\" \ + -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ + -DDHCLIENT_V$(DHCLIENT_VERSION) + +libdhcp_dhclient_la_LIBADD = \ + $(top_builddir)/marshallers/libmarshallers.la \ + $(top_builddir)/src/logging/libnm-logging.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) + +################## main lib ################## libdhcp_manager_la_SOURCES = \ nm-dhcp-client.c \ nm-dhcp-client.h \ nm-dhcp-manager.c \ nm-dhcp-manager.h \ - nm-dhcp-dhclient.h \ - nm-dhcp-dhclient.c \ nm-dhcp-dhcpcd.h \ nm-dhcp-dhcpcd.c @@ -22,18 +49,15 @@ libdhcp_manager_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ $(GLIB_CFLAGS) \ -DG_DISABLE_DEPRECATED \ - -DBINDIR=\"$(bindir)\" \ - -DDATADIR=\"$(datadir)\" \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ -DLIBEXECDIR=\"$(libexecdir)\" \ -DLOCALSTATEDIR=\"$(localstatedir)\" \ -DDHCLIENT_PATH=\"$(DHCLIENT_PATH)\" \ - -DDHCLIENT_V$(DHCLIENT_VERSION) \ -DDHCPCD_PATH=\"$(DHCPCD_PATH)\" libdhcp_manager_la_LIBADD = \ $(top_builddir)/marshallers/libmarshallers.la \ $(top_builddir)/src/logging/libnm-logging.la \ + $(builddir)/libdhcp-dhclient.la \ $(DBUS_LIBS) \ $(GLIB_LIBS) diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c new file mode 100644 index 0000000000..cfc766f253 --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -0,0 +1,214 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; 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, 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) 2010 Red Hat, Inc. + */ + +#include + +#include +#include +#include +#include + +#include "nm-dhcp-dhclient-utils.h" + +#define CLIENTID_TAG "send dhcp-client-identifier" +#define CLIENTID_FORMAT CLIENTID_TAG " \"%s\"; # added by NetworkManager" +#define CLIENTID_FORMAT_OCTETS CLIENTID_TAG " %s; # added by NetworkManager" + +#define HOSTNAME_TAG "send host-name" +#define HOSTNAME_FORMAT HOSTNAME_TAG " \"%s\"; # added by NetworkManager" + +#define ALSOREQ_TAG "also request " + +static void +add_also_request (GPtrArray *array, const char *item) +{ + int i; + + for (i = 0; i < array->len; i++) { + if (!strcmp (g_ptr_array_index (array, i), item)) + return; + } + g_ptr_array_add (array, g_strdup (item)); +} + +char * +nm_dhcp_dhclient_create_config (const char *interface, + NMSettingIP4Config *s_ip4, + guint8 *anycast_addr, + const char *hostname, + const char *orig_path, + const char *orig_contents) +{ + GString *new_contents; + GPtrArray *alsoreq; + int i; + + new_contents = g_string_new (_("# Created by NetworkManager\n")); + alsoreq = g_ptr_array_sized_new (5); + + if (orig_contents) { + char **lines, **line; + gboolean in_alsoreq = FALSE; + + g_string_append_printf (new_contents, _("# Merged from %s\n\n"), orig_path); + + lines = g_strsplit_set (orig_contents, "\n\r", 0); + for (line = lines; lines && *line; line++) { + char *p = *line; + + if (!strlen (g_strstrip (p))) + continue; + + /* Override config file "dhcp-client-id" and use one from the + * connection. + */ + if ( s_ip4 + && nm_setting_ip4_config_get_dhcp_client_id (s_ip4) + && !strncmp (p, CLIENTID_TAG, strlen (CLIENTID_TAG))) + continue; + + /* Override config file hostname and use one from the connection */ + if (hostname && !strncmp (p, HOSTNAME_TAG, strlen (HOSTNAME_TAG))) + continue; + + /* Check for "also require" */ + if (!strncmp (p, ALSOREQ_TAG, strlen (ALSOREQ_TAG))) { + in_alsoreq = TRUE; + p += strlen (ALSOREQ_TAG); + } + + if (in_alsoreq) { + char **areq, **aiter; + + /* Grab each 'also require' option and save for later */ + areq = g_strsplit_set (p, "\t ,", -1); + for (aiter = areq; aiter && *aiter; aiter++) { + if (!strlen (g_strstrip (*aiter))) + continue; + + if (*aiter[0] == ';') { + /* all done */ + in_alsoreq = FALSE; + break; + } + + if (!isalnum ((*aiter)[0])) + continue; + + if ((*aiter)[strlen (*aiter) - 1] == ';') { + /* Remove the EOL marker */ + (*aiter)[strlen (*aiter) - 1] = '\0'; + in_alsoreq = FALSE; + } + + add_also_request (alsoreq, *aiter); + } + + if (areq) + g_strfreev (areq); + + continue; + } + + /* Existing configuration line is OK, add it to new configuration */ + g_string_append (new_contents, *line); + g_string_append_c (new_contents, '\n'); + } + + if (lines) + g_strfreev (lines); + } else + g_string_append_c (new_contents, '\n'); + + /* Add NM options from connection */ + if (s_ip4) { + const char *tmp; + gboolean added = FALSE; + + tmp = nm_setting_ip4_config_get_dhcp_client_id (s_ip4); + if (tmp) { + gboolean is_octets = TRUE; + const char *p = tmp; + + while (*p) { + if (!isxdigit (*p) && (*p != ':')) { + is_octets = FALSE; + break; + } + p++; + } + + /* If the client ID is just hex digits and : then don't use quotes, + * because dhclient expects either a quoted ASCII string, or a byte + * array formated as hex octets separated by : + */ + if (is_octets) + g_string_append_printf (new_contents, CLIENTID_FORMAT_OCTETS "\n", tmp); + else + g_string_append_printf (new_contents, CLIENTID_FORMAT "\n", tmp); + added = TRUE; + } + + if (hostname) { + g_string_append_printf (new_contents, HOSTNAME_FORMAT "\n", hostname); + added = TRUE; + } + + if (added) + g_string_append_c (new_contents, '\n'); + } + + /* Define options for classless static routes */ + g_string_append (new_contents, + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"); + g_string_append (new_contents, + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"); + + g_string_append_c (new_contents, '\n'); + + /* Everything we want to request from the DHCP server */ + add_also_request (alsoreq, "rfc3442-classless-static-routes"); + add_also_request (alsoreq, "ms-classless-static-routes"); + add_also_request (alsoreq, "ntp-servers"); + + /* And add it to the dhclient configuration */ + for (i = 0; i < alsoreq->len; i++) { + char *t = g_ptr_array_index (alsoreq, i); + + g_string_append_printf (new_contents, "also request %s;\n", t); + g_free (t); + } + g_ptr_array_free (alsoreq, TRUE); + + g_string_append_c (new_contents, '\n'); + + if (anycast_addr) { + g_string_append_printf (new_contents, "interface \"%s\" {\n" + " initial-interval 1; \n" + " anycast-mac ethernet %02x:%02x:%02x:%02x:%02x:%02x;\n" + "}\n", + interface, + anycast_addr[0], anycast_addr[1], + anycast_addr[2], anycast_addr[3], + anycast_addr[4], anycast_addr[5]); + } + + return g_string_free (new_contents, FALSE); +} + diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.h b/src/dhcp-manager/nm-dhcp-dhclient-utils.h new file mode 100644 index 0000000000..77def55182 --- /dev/null +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.h @@ -0,0 +1,35 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; 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, 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) 2010 Red Hat, Inc. + */ + +#ifndef NM_DHCP_DHCLIENT_UTILS_H +#define NM_DHCP_DHCLIENT_UTILS_H + +#include +#include + +#include + +char *nm_dhcp_dhclient_create_config (const char *interface, + NMSettingIP4Config *s_ip4, + guint8 *anycast_addr, + const char *hostname, + const char *orig_path, + const char *orig_contents); + +#endif /* NM_DHCP_DHCLIENT_UTILS_H */ + diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index d8781524e9..f6f2a540dc 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -39,6 +39,7 @@ #include "nm-dhcp-dhclient.h" #include "nm-utils.h" #include "nm-logging.h" +#include "nm-dhcp-dhclient-utils.h" G_DEFINE_TYPE (NMDHCPDhclient, nm_dhcp_dhclient, NM_TYPE_DHCP_CLIENT) @@ -302,12 +303,6 @@ out: } -#define DHCP_CLIENT_ID_TAG "send dhcp-client-identifier" -#define DHCP_CLIENT_ID_FORMAT DHCP_CLIENT_ID_TAG " \"%s\"; # added by NetworkManager" -#define DHCP_CLIENT_ID_FORMAT_OCTETS DHCP_CLIENT_ID_TAG " %s; # added by NetworkManager" - -#define DHCP_HOSTNAME_TAG "send host-name" -#define DHCP_HOSTNAME_FORMAT DHCP_HOSTNAME_TAG " \"%s\"; # added by NetworkManager" static gboolean merge_dhclient_config (const char *iface, @@ -318,105 +313,27 @@ merge_dhclient_config (const char *iface, const char *orig_path, GError **error) { - GString *new_contents; - char *orig_contents = NULL; + char *orig = NULL, *new; gboolean success = FALSE; g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (conf_file != NULL, FALSE); - new_contents = g_string_new (_("# Created by NetworkManager\n")); - if (g_file_test (orig_path, G_FILE_TEST_EXISTS)) { GError *read_error = NULL; - if (!g_file_get_contents (orig_path, &orig_contents, NULL, &read_error)) { + if (!g_file_get_contents (orig_path, &orig, NULL, &read_error)) { nm_log_warn (LOGD_DHCP, "(%s): error reading dhclient configuration %s: %s", iface, orig_path, read_error->message); g_error_free (read_error); } } - /* Add existing options, if any, but ignore stuff NM will replace. */ - if (orig_contents) { - char **lines = NULL, **line; + new = nm_dhcp_dhclient_create_config (iface, s_ip4, anycast_addr, hostname, orig_path, orig); + g_assert (new); + success = g_file_set_contents (conf_file, new, -1, error); + g_free (new); - g_string_append_printf (new_contents, _("# Merged from %s\n\n"), orig_path); - - lines = g_strsplit_set (orig_contents, "\n\r", 0); - for (line = lines; lines && *line; line++) { - gboolean ignore = FALSE; - - if (!strlen (g_strstrip (*line))) - continue; - - if ( s_ip4 - && nm_setting_ip4_config_get_dhcp_client_id (s_ip4) - && !strncmp (*line, DHCP_CLIENT_ID_TAG, strlen (DHCP_CLIENT_ID_TAG))) - ignore = TRUE; - - if ( s_ip4 - && hostname - && !strncmp (*line, DHCP_HOSTNAME_TAG, strlen (DHCP_HOSTNAME_TAG))) - ignore = TRUE; - - if (!ignore) { - g_string_append (new_contents, *line); - g_string_append_c (new_contents, '\n'); - } - } - - if (lines) - g_strfreev (lines); - g_free (orig_contents); - } else - g_string_append_c (new_contents, '\n'); - - /* Add NM options from connection */ - if (s_ip4) { - const char *tmp; - - tmp = nm_setting_ip4_config_get_dhcp_client_id (s_ip4); - if (tmp) { - gboolean is_octets = TRUE; - const char *p = tmp; - - while (*p) { - if (!isxdigit (*p) && (*p != ':')) { - is_octets = FALSE; - break; - } - p++; - } - - /* If the client ID is just hex digits and : then don't use quotes, - * because dhclient expects either a quoted ASCII string, or a byte - * array formated as hex octets separated by : - */ - if (is_octets) - g_string_append_printf (new_contents, DHCP_CLIENT_ID_FORMAT_OCTETS "\n", tmp); - else - g_string_append_printf (new_contents, DHCP_CLIENT_ID_FORMAT "\n", tmp); - } - - if (hostname) - g_string_append_printf (new_contents, DHCP_HOSTNAME_FORMAT "\n", hostname); - } - - if (anycast_addr) { - g_string_append_printf (new_contents, "interface \"%s\" {\n" - " initial-interval 1; \n" - " anycast-mac ethernet %02x:%02x:%02x:%02x:%02x:%02x;\n" - "}\n", - iface, - anycast_addr[0], anycast_addr[1], - anycast_addr[2], anycast_addr[3], - anycast_addr[4], anycast_addr[5]); - } - - success = g_file_set_contents (conf_file, new_contents->str, -1, error); - - g_string_free (new_contents, TRUE); return success; } diff --git a/src/dhcp-manager/tests/Makefile.am b/src/dhcp-manager/tests/Makefile.am new file mode 100644 index 0000000000..b075fd683a --- /dev/null +++ b/src/dhcp-manager/tests/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES = \ + -I$(top_srcdir)/include \ + -I${top_srcdir}/libnm-util \ + -I$(top_srcdir)/src/dhcp-manager + +noinst_PROGRAMS = test-dhcp-dhclient + +####### policy /etc/hosts test ####### + +test_dhcp_dhclient_SOURCES = \ + test-dhcp-dhclient.c + +test_dhcp_dhclient_CPPFLAGS = \ + $(GLIB_CFLAGS) + +test_dhcp_dhclient_LDADD = \ + -ldl \ + $(top_builddir)/src/dhcp-manager/libdhcp-dhclient.la \ + $(top_builddir)/libnm-util/libnm-util.la \ + $(GLIB_LIBS) + +if WITH_TESTS + +check-local: test-dhcp-dhclient + $(abs_builddir)/test-dhcp-dhclient + +endif + diff --git a/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c new file mode 100644 index 0000000000..1f5166b003 --- /dev/null +++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c @@ -0,0 +1,203 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; 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, 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) 2010 Red Hat, Inc. + * + */ + +#include +#include + +#include "nm-dhcp-dhclient-utils.h" +#include "nm-utils.h" + +#define DEBUG 0 + +static void +test_config (const char *orig, + const char *expected, + const char *hostname, + const char *dhcp_client_id, + const char *iface, + guint8 *anycast_addr) +{ + NMSettingIP4Config *s_ip4; + char *new; + + s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new (); + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID, dhcp_client_id, NULL); + + new = nm_dhcp_dhclient_create_config (iface, + s_ip4, + anycast_addr, + hostname, + "/path/to/dhclient.conf", + orig); + g_assert (new != NULL); + +#if DEBUG + g_message ("\n- NEW ---------------------------------\n" + "%s" + "+ EXPECTED ++++++++++++++++++++++++++++++\n" + "%s" + "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n", + new, expected); +#endif + g_assert (strlen (new) == strlen (expected)); + g_assert (strcmp (new, expected) == 0); + g_free (new); +} + +/*******************************************/ + +static const char *orig_missing_expected = \ + "# Created by NetworkManager\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_orig_missing (void) +{ + test_config (NULL, orig_missing_expected, + NULL, + NULL, + "eth0", + NULL); +} + +/*******************************************/ + +static const char *override_client_id_orig = \ + "send dhcp-client-identifier 00:30:04:20:7A:08;\n"; + +static const char *override_client_id_expected = \ + "# Created by NetworkManager\n" + "# Merged from /path/to/dhclient.conf\n" + "\n" + "send dhcp-client-identifier 11:22:33:44:55:66; # added by NetworkManager\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_override_client_id (void) +{ + test_config (override_client_id_orig, override_client_id_expected, + NULL, + "11:22:33:44:55:66", + "eth0", + NULL); +} + +/*******************************************/ + +static const char *override_hostname_orig = \ + "send host-name \"foobar\";\n"; + +static const char *override_hostname_expected = \ + "# Created by NetworkManager\n" + "# Merged from /path/to/dhclient.conf\n" + "\n" + "send host-name \"blahblah\"; # added by NetworkManager\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_override_hostname (void) +{ + test_config (override_hostname_orig, override_hostname_expected, + "blahblah", + NULL, + "eth0", + NULL); +} + +/*******************************************/ + +static const char *existing_alsoreq_orig = \ + "also request something;\n" + "also request another-thing;\n" + ; + +static const char *existing_alsoreq_expected = \ + "# Created by NetworkManager\n" + "# Merged from /path/to/dhclient.conf\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "\n" + "also request something;\n" + "also request another-thing;\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_existing_alsoreq (void) +{ + test_config (existing_alsoreq_orig, existing_alsoreq_expected, + NULL, + NULL, + "eth0", + NULL); +} + +/*******************************************/ + +#if GLIB_CHECK_VERSION(2,25,12) +typedef GTestFixtureFunc TCFunc; +#else +typedef void (*TCFunc)(void); +#endif + +#define TESTCASE(t, d) g_test_create_case (#t, 0, d, NULL, (TCFunc) t, NULL) + +int main (int argc, char **argv) +{ + GTestSuite *suite; + + g_test_init (&argc, &argv, NULL); + + g_type_init (); + + suite = g_test_get_root (); + + g_test_suite_add (suite, TESTCASE (test_orig_missing, NULL)); + g_test_suite_add (suite, TESTCASE (test_override_client_id, NULL)); + g_test_suite_add (suite, TESTCASE (test_override_hostname, NULL)); + g_test_suite_add (suite, TESTCASE (test_existing_alsoreq, NULL)); + + return g_test_run (); +} + From e079f25a2b9553b1082aa15057b6dd07decd3558 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 17 Dec 2010 23:05:41 -0600 Subject: [PATCH 054/102] dhclient: explicitly request WPAD option (bgo #368423) --- src/dhcp-manager/nm-dhcp-dhclient-utils.c | 3 +++ src/dhcp-manager/tests/test-dhcp-dhclient.c | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/src/dhcp-manager/nm-dhcp-dhclient-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c index cfc766f253..cc5255ab59 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient-utils.c +++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c @@ -179,12 +179,15 @@ nm_dhcp_dhclient_create_config (const char *interface, "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n"); g_string_append (new_contents, "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n"); + /* Web Proxy Auto-Discovery option (bgo #368423) */ + g_string_append (new_contents, "option wpad code 252 = string;\n"); g_string_append_c (new_contents, '\n'); /* Everything we want to request from the DHCP server */ add_also_request (alsoreq, "rfc3442-classless-static-routes"); add_also_request (alsoreq, "ms-classless-static-routes"); + add_also_request (alsoreq, "wpad"); add_also_request (alsoreq, "ntp-servers"); /* And add it to the dhclient configuration */ diff --git a/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c index 1f5166b003..37d37e7f09 100644 --- a/src/dhcp-manager/tests/test-dhcp-dhclient.c +++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c @@ -68,9 +68,11 @@ static const char *orig_missing_expected = \ "\n" "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" "\n" "also request rfc3442-classless-static-routes;\n" "also request ms-classless-static-routes;\n" + "also request wpad;\n" "also request ntp-servers;\n" "\n"; @@ -97,9 +99,11 @@ static const char *override_client_id_expected = \ "\n" "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" "\n" "also request rfc3442-classless-static-routes;\n" "also request ms-classless-static-routes;\n" + "also request wpad;\n" "also request ntp-servers;\n" "\n"; @@ -126,9 +130,11 @@ static const char *override_hostname_expected = \ "\n" "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" "\n" "also request rfc3442-classless-static-routes;\n" "also request ms-classless-static-routes;\n" + "also request wpad;\n" "also request ntp-servers;\n" "\n"; @@ -155,11 +161,13 @@ static const char *existing_alsoreq_expected = \ "\n" "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" "\n" "also request something;\n" "also request another-thing;\n" "also request rfc3442-classless-static-routes;\n" "also request ms-classless-static-routes;\n" + "also request wpad;\n" "also request ntp-servers;\n" "\n"; From 08ba12929d7f478ae9e57bcecb278443f830e923 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 19 Dec 2010 12:10:57 -0600 Subject: [PATCH 055/102] dhclient: add testcase for multiline 'also require' statements --- src/dhcp-manager/tests/test-dhcp-dhclient.c | 38 +++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/dhcp-manager/tests/test-dhcp-dhclient.c b/src/dhcp-manager/tests/test-dhcp-dhclient.c index 37d37e7f09..c1cd6f80c4 100644 --- a/src/dhcp-manager/tests/test-dhcp-dhclient.c +++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c @@ -183,6 +183,43 @@ test_existing_alsoreq (void) /*******************************************/ +static const char *existing_multiline_alsoreq_orig = \ + "also request something another-thing yet-another-thing\n" + " foobar baz blah;\n" + ; + +static const char *existing_multiline_alsoreq_expected = \ + "# Created by NetworkManager\n" + "# Merged from /path/to/dhclient.conf\n" + "\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" + "\n" + "also request something;\n" + "also request another-thing;\n" + "also request yet-another-thing;\n" + "also request foobar;\n" + "also request baz;\n" + "also request blah;\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request wpad;\n" + "also request ntp-servers;\n" + "\n"; + +static void +test_existing_multiline_alsoreq (void) +{ + test_config (existing_multiline_alsoreq_orig, existing_multiline_alsoreq_expected, + NULL, + NULL, + "eth0", + NULL); +} + +/*******************************************/ + #if GLIB_CHECK_VERSION(2,25,12) typedef GTestFixtureFunc TCFunc; #else @@ -205,6 +242,7 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_override_client_id, NULL)); g_test_suite_add (suite, TESTCASE (test_override_hostname, NULL)); g_test_suite_add (suite, TESTCASE (test_existing_alsoreq, NULL)); + g_test_suite_add (suite, TESTCASE (test_existing_multiline_alsoreq, NULL)); return g_test_run (); } From 2bee736df163b5ee28b13c85f7b63ba55be80415 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 1 Jan 2011 18:00:50 -0600 Subject: [PATCH 056/102] modem: handle IP Method changes after modem has been created Some modems don't know their IP method when they are created, but will update it later. Handle the changed signal for that. --- src/modem-manager/nm-modem.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index e07b818bbb..b3f7eaa1cb 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -876,6 +876,12 @@ modem_properties_changed (DBusGProxy *proxy, priv->mm_enabled = g_value_get_boolean (value); g_object_notify (G_OBJECT (self), NM_MODEM_ENABLED); } + + value = g_hash_table_lookup (props, "IpMethod"); + if (value && G_VALUE_HOLDS_UINT (value)) { + priv->ip_method = g_value_get_uint (value); + g_object_notify (G_OBJECT (self), NM_MODEM_IP_METHOD); + } } /*****************************************************************************/ From 81cb867e9fbde39d70154f832c25edaa2d0afc28 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 2 Jan 2011 10:24:23 -0600 Subject: [PATCH 057/102] policy: don't update hostname on exit It's a leftover from when /etc/hosts got fixed up, and since that isn't being done anymore, there's no reason to touch the hostname on exit. It will already have been updated in response to device deactivation (if the hostname was DHCP-provided for example) so it shouldn't need to be touched on exit. This also removes a potential crash on shutdown when systemd or another startup manager kills D-Bus before NetworkManager, which made the dispatcher code angry (which got executed on hostname change). --- src/nm-policy.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index b5c212929b..53557039e5 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -1222,15 +1222,6 @@ nm_policy_destroy (NMPolicy *policy) } g_slist_free (policy->dev_signal_ids); - /* Rewrite /etc/hosts on exit to ensure we don't leave stale IP addresses - * lying around. FIXME: this will take out a valid IP address of an - * ethernet device we're leaving active (ie, a connection we can "assume" - * when NM starts again). - */ - policy->default_device4 = NULL; - policy->default_device6 = NULL; - update_system_hostname (policy, NULL, NULL); - g_free (policy->orig_hostname); g_free (policy->cur_hostname); From 15a9f29a14783fcd1b8e936a8338452737825726 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 2 Jan 2011 10:49:36 -0600 Subject: [PATCH 058/102] core: handle D-Bus disconnect better on exit We're just going to quit here anyway, so we don't need to make sure the property filter is unregistered. Fixes a crash on exit if D-Bus has quit before NM has. --- src/nm-manager.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index afcc6add54..9bd5354152 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -4364,10 +4364,11 @@ dispose (GObject *object) /* Unregister property filter */ bus = nm_dbus_manager_get_connection (priv->dbus_mgr); - g_assert (bus); - dbus_connection = dbus_g_connection_get_connection (bus); - g_assert (dbus_connection); - dbus_connection_remove_filter (dbus_connection, prop_filter, manager); + if (bus) { + dbus_connection = dbus_g_connection_get_connection (bus); + g_assert (dbus_connection); + dbus_connection_remove_filter (dbus_connection, prop_filter, manager); + } g_object_unref (priv->dbus_mgr); if (priv->bluez_mgr) From c28850ed527ee25cc8c59cedb3290b553e4023f6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 2 Jan 2011 17:34:23 -0600 Subject: [PATCH 059/102] wimax: fix up WiMAX radio enable/disable and add polkit permission --- libnm-glib/nm-client.c | 3 +++ libnm-glib/nm-client.h | 3 ++- policy/org.freedesktop.NetworkManager.policy.in | 9 +++++++++ src/nm-manager-auth.h | 1 + src/nm-manager.c | 17 +++++++++++------ 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index dcfdf074b6..9dc06af26f 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -330,6 +330,7 @@ register_for_property_changed (NMClient *client) #define NM_AUTH_PERMISSION_ENABLE_DISABLE_NETWORK "org.freedesktop.NetworkManager.enable-disable-network" #define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" #define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX "org.freedesktop.NetworkManager.enable-disable-wimax" #define NM_AUTH_PERMISSION_USE_USER_CONNECTIONS "org.freedesktop.NetworkManager.use-user-connections" static NMClientPermission @@ -341,6 +342,8 @@ nm_permission_to_client (const char *nm) return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI; else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN)) return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN; + else if (!strcmp (nm, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX)) + return NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX; else if (!strcmp (nm, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS)) return NM_CLIENT_PERMISSION_USE_USER_CONNECTIONS; return NM_CLIENT_PERMISSION_NONE; diff --git a/libnm-glib/nm-client.h b/libnm-glib/nm-client.h index 3c6f737488..4153ebcadd 100644 --- a/libnm-glib/nm-client.h +++ b/libnm-glib/nm-client.h @@ -59,8 +59,9 @@ typedef enum { NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIFI = 2, NM_CLIENT_PERMISSION_ENABLE_DISABLE_WWAN = 3, NM_CLIENT_PERMISSION_USE_USER_CONNECTIONS = 4, + NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX = 5, - NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_USE_USER_CONNECTIONS + NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX } NMClientPermission; typedef enum { diff --git a/policy/org.freedesktop.NetworkManager.policy.in b/policy/org.freedesktop.NetworkManager.policy.in index 3e7db0588e..185265885b 100644 --- a/policy/org.freedesktop.NetworkManager.policy.in +++ b/policy/org.freedesktop.NetworkManager.policy.in @@ -45,6 +45,15 @@ + + <_description>Enable or disable WiMAX mobile broadband devices + <_message>System policy prevents enabling or disabling WiMAX mobile broadband devices + + no + yes + + + <_description>Allow use of user-specific connections <_message>System policy prevents use of user-specific connections diff --git a/src/nm-manager-auth.h b/src/nm-manager-auth.h index 6682f91ca1..35bf270f65 100644 --- a/src/nm-manager-auth.h +++ b/src/nm-manager-auth.h @@ -31,6 +31,7 @@ #define NM_AUTH_PERMISSION_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake" #define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI "org.freedesktop.NetworkManager.enable-disable-wifi" #define NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN "org.freedesktop.NetworkManager.enable-disable-wwan" +#define NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX "org.freedesktop.NetworkManager.enable-disable-wimax" #define NM_AUTH_PERMISSION_USE_USER_CONNECTIONS "org.freedesktop.NetworkManager.use-user-connections" #define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control" diff --git a/src/nm-manager.c b/src/nm-manager.c index 55e4b45ba8..da47f5b1bc 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -2119,8 +2119,8 @@ add_device (NMManager *self, NMDevice *device) */ } else if (NM_IS_WIMAX_DEVICE (device)) { nm_manager_rfkill_update (self, RFKILL_TYPE_WIMAX); - nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), - priv->radio_states[RFKILL_TYPE_WIMAX].enabled); + enabled = radio_enabled_for_type (self, RFKILL_TYPE_WIMAX); + nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled); } type_desc = nm_device_get_type_desc (device); @@ -3782,6 +3782,7 @@ get_permissions_done_cb (NMAuthChain *chain, get_perm_add_result (chain, results, NM_AUTH_PERMISSION_SLEEP_WAKE); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN); + get_perm_add_result (chain, results, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS); get_perm_add_result (chain, results, NM_AUTH_PERMISSION_NETWORK_CONTROL); dbus_g_method_return (context, results); @@ -3809,6 +3810,7 @@ impl_manager_get_permissions (NMManager *self, nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_SLEEP_WAKE, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIFI, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN, FALSE); + nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_USE_USER_CONNECTIONS, FALSE); nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_NETWORK_CONTROL, FALSE); } @@ -4157,6 +4159,9 @@ prop_filter (DBusConnection *connection, } else if (!strcmp (propname, "WwanEnabled")) { glib_propname = NM_MANAGER_WWAN_ENABLED; permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WWAN; + } else if (!strcmp (propname, "WimaxEnabled")) { + glib_propname = NM_MANAGER_WIMAX_ENABLED; + permission = NM_AUTH_PERMISSION_ENABLE_DISABLE_WIMAX; } else return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -4467,9 +4472,9 @@ set_property (GObject *object, guint prop_id, g_value_get_boolean (value)); break; case PROP_WIMAX_ENABLED: - manager_set_radio_enabled (NM_MANAGER (object), - &priv->radio_states[RFKILL_TYPE_WIMAX], - g_value_get_boolean (value)); + manager_radio_user_toggled (NM_MANAGER (object), + &priv->radio_states[RFKILL_TYPE_WIMAX], + g_value_get_boolean (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -4508,7 +4513,7 @@ get_property (GObject *object, guint prop_id, g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WWAN].hw_enabled); break; case PROP_WIMAX_ENABLED: - g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WIMAX].enabled); + g_value_set_boolean (value, radio_enabled_for_type (self, RFKILL_TYPE_WIMAX)); break; case PROP_WIMAX_HARDWARE_ENABLED: g_value_set_boolean (value, priv->radio_states[RFKILL_TYPE_WIMAX].hw_enabled); From 76c7d2f95c57d318d867bcd63633eaaf0727d1dd Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sun, 2 Jan 2011 22:16:22 -0600 Subject: [PATCH 060/102] logging: add WiMAX log domain --- man/NetworkManager.conf.5.in | 10 +++++----- src/logging/nm-logging.c | 4 +++- src/logging/nm-logging.h | 1 + 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/man/NetworkManager.conf.5.in b/man/NetworkManager.conf.5.in index c866f1b337..a45adde8c7 100644 --- a/man/NetworkManager.conf.5.in +++ b/man/NetworkManager.conf.5.in @@ -162,11 +162,11 @@ warning messages. .B domains=\fI,, ...\fP The following log domains are available: [NONE, HW, RKILL, ETHER, WIFI, BT, MB, DHCP4, DHCP6, PPP, WIFI_SCAN, IP4, IP6, AUTOIP4, DNS, VPN, SHARING, SUPPLICANT, -USER_SET, SYS_SET, SUSPEND, CORE, DEVICE, OLPC]. When "NONE" is given by itself, -logging is disabled. MB = Mobile Broadband, USER_SET = user settings operations -and communication, SYS_SET = system settings service operations, OLPC = OLPC -Mesh device operations, CORE = core daemon operations, DEVICE = activation and -general interface operations. +USER_SET, SYS_SET, SUSPEND, CORE, DEVICE, OLPC, WIMAX]. When "NONE" is given by +itself, logging is disabled. MB = Mobile Broadband, USER_SET = user settings +operations and communication, SYS_SET = system settings service operations, OLPC += OLPC Mesh device operations, CORE = core daemon operations, DEVICE = activation +and general interface operations. .SH "SEE ALSO" .BR http://live.gnome.org/NetworkManager/SystemSettings .sp diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c index 5b5622fd70..01bbb36555 100644 --- a/src/logging/nm-logging.c +++ b/src/logging/nm-logging.c @@ -42,7 +42,8 @@ static guint32 log_domains = \ LOGD_HW | LOGD_RFKILL | LOGD_ETHER | LOGD_WIFI | LOGD_BT | LOGD_MB | \ LOGD_DHCP4 | LOGD_DHCP6 | LOGD_PPP | LOGD_IP4 | LOGD_IP6 | LOGD_AUTOIP4 | \ LOGD_DNS | LOGD_VPN | LOGD_SHARING | LOGD_SUPPLICANT | LOGD_USER_SET | \ - LOGD_SYS_SET | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH; + LOGD_SYS_SET | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH | \ + LOGD_WIMAX; typedef struct { guint32 num; @@ -82,6 +83,7 @@ static const LogDesc domain_descs[] = { { LOGD_CORE, "CORE" }, { LOGD_DEVICE, "DEVICE" }, { LOGD_OLPC_MESH, "OLPC" }, + { LOGD_WIMAX, "WIMAX" }, { 0, NULL } }; diff --git a/src/logging/nm-logging.h b/src/logging/nm-logging.h index e4abcf75ca..4bfc8078a0 100644 --- a/src/logging/nm-logging.h +++ b/src/logging/nm-logging.h @@ -51,6 +51,7 @@ enum { LOGD_CORE = 0x00100000, /* Core daemon and policy stuff */ LOGD_DEVICE = 0x00200000, /* Device state and activation */ LOGD_OLPC_MESH = 0x00400000, + LOGD_WIMAX = 0x00800000, }; #define LOGD_DHCP (LOGD_DHCP4 | LOGD_DHCP6) From 7ce5053a9e752d0ce9d843885c09108c9f0e60a2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 3 Jan 2011 23:45:41 -0600 Subject: [PATCH 061/102] libnm-glib: fix WiMAX NSP property retrieval --- libnm-glib/nm-wimax-nsp.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/libnm-glib/nm-wimax-nsp.c b/libnm-glib/nm-wimax-nsp.c index 0c2cbca8f6..0b3b59571a 100644 --- a/libnm-glib/nm-wimax-nsp.c +++ b/libnm-glib/nm-wimax-nsp.c @@ -114,10 +114,11 @@ nm_wimax_nsp_get_signal_quality (NMWimaxNsp *nsp) 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); + if (!priv->signal_quality) { + priv->signal_quality = _nm_object_get_uint_property (NM_OBJECT (nsp), + NM_DBUS_INTERFACE_WIMAX_NSP, + DBUS_PROP_SIGNAL_QUALITY); + } return priv->signal_quality; } @@ -138,10 +139,11 @@ nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp) 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); + if (!priv->network_type) { + priv->network_type = _nm_object_get_byte_property (NM_OBJECT (nsp), + NM_DBUS_INTERFACE_WIMAX_NSP, + DBUS_PROP_NETWORK_TYPE); + } return priv->network_type; } @@ -263,7 +265,7 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) /** * NMWimaxNsp:name: * - * The name of the wimax NSP. + * The name of the WiMAX NSP. **/ g_object_class_install_property (object_class, PROP_NAME, @@ -276,7 +278,7 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) /** * NMWimaxNsp:signal-quality: * - * The signal quality of the wimax NSP. + * The signal quality of the WiMAX NSP. **/ g_object_class_install_property (object_class, PROP_SIGNAL_QUALITY, @@ -289,7 +291,7 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) /** * NMWimaxNsp:network-type: * - * The network type of the wimax NSP. + * The network type of the WiMAX NSP. **/ g_object_class_install_property (object_class, PROP_NETWORK_TYPE, From 9e80c1e85d6ba032729a4e2bf488e522884926c9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 3 Jan 2011 23:55:38 -0600 Subject: [PATCH 062/102] wimax: make WiMAX mostly work Heavily modify Inaky's Intel WiMAX SDK glue (originally from connman) to be more generic and more thread-safe, and suitable for use with NetworkManager instead of rolling our own client code. Rewrite the NMDeviceWimax code to mostly work. Still to be done: actual connection logic, DHCP handling, spawning wimaxd if it's not started yet --- include/NetworkManager.h | 2 +- introspection/Makefile.am | 2 +- introspection/all.xml | 4 +- ...m-wimax-device.xml => nm-device-wimax.xml} | 0 libnm-glib/Makefile.am | 12 +- libnm-glib/libnm-glib.ver | 12 +- .../{nm-wimax-device.c => nm-device-wimax.c} | 163 +-- libnm-glib/nm-device-wimax.h | 68 + libnm-glib/nm-device.c | 4 +- libnm-glib/nm-wimax-device.h | 67 - src/nm-manager.c | 4 +- src/nm-udev-manager.c | 7 +- src/wimax/Makefile.am | 17 +- src/wimax/iwmxsdk.c | 1286 +++++++++++++++++ src/wimax/iwmxsdk.h | 98 ++ src/wimax/nm-device-wimax.c | 1071 ++++++++++++++ src/wimax/nm-device-wimax.h | 68 + src/wimax/nm-wimax-device.c | 1037 ------------- src/wimax/nm-wimax-device.h | 70 - src/wimax/nm-wimax-manager.c | 139 +- src/wimax/nm-wimax-manager.h | 30 +- src/wimax/nm-wimax-util.c | 95 +- src/wimax/nm-wimax-util.h | 13 +- test/nm-tool.c | 30 +- 24 files changed, 2835 insertions(+), 1464 deletions(-) rename introspection/{nm-wimax-device.xml => nm-device-wimax.xml} (100%) rename libnm-glib/{nm-wimax-device.c => nm-device-wimax.c} (72%) create mode 100644 libnm-glib/nm-device-wimax.h delete mode 100644 libnm-glib/nm-wimax-device.h create mode 100644 src/wimax/iwmxsdk.c create mode 100644 src/wimax/iwmxsdk.h create mode 100644 src/wimax/nm-device-wimax.c create mode 100644 src/wimax/nm-device-wimax.h delete mode 100644 src/wimax/nm-wimax-device.c delete mode 100644 src/wimax/nm-wimax-device.h diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 7e68855a13..b2a0098caf 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -38,7 +38,7 @@ #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_DEVICE_WIMAX 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" diff --git a/introspection/Makefile.am b/introspection/Makefile.am index 67abff899e..9c6958894d 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -11,6 +11,7 @@ EXTRA_DIST = \ nm-device-cdma.xml \ nm-device-gsm.xml \ nm-device-serial.xml \ + nm-device-wimax.xml \ nm-device.xml \ nm-ip4-config.xml \ nm-ip6-config.xml \ @@ -25,6 +26,5 @@ EXTRA_DIST = \ nm-active-connection.xml \ nm-dhcp4-config.xml \ nm-dhcp6-config.xml \ - nm-wimax-device.xml \ nm-wimax-nsp.xml diff --git a/introspection/all.xml b/introspection/all.xml index 5e0abc4876..521ab017d5 100644 --- a/introspection/all.xml +++ b/introspection/all.xml @@ -35,6 +35,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + @@ -44,8 +46,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - diff --git a/introspection/nm-wimax-device.xml b/introspection/nm-device-wimax.xml similarity index 100% rename from introspection/nm-wimax-device.xml rename to introspection/nm-device-wimax.xml diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index 02ba666717..a3b5577986 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -10,6 +10,7 @@ BUILT_SOURCES = \ nm-device-ethernet-bindings.h \ nm-device-wifi-bindings.h \ nm-device-bt-bindings.h \ + nm-device-wimax-bindings.h \ nm-exported-connection-glue.h \ nm-exported-connection-bindings.h \ nm-settings-glue.h \ @@ -21,8 +22,7 @@ BUILT_SOURCES = \ nm-ip4-config-bindings.h \ nm-dhcp4-config-bindings.h \ nm-ip6-config-bindings.h \ - nm-dhcp6-config-bindings.h \ - nm-wimax-device-bindings.h + nm-dhcp6-config-bindings.h ##################################################### # Deprecated original libnm_glib bits @@ -86,7 +86,7 @@ libnminclude_HEADERS = \ nm-settings-connection-interface.h \ nm-exported-connection.h \ nm-settings-service.h \ - nm-wimax-device.h \ + nm-device-wimax.h \ nm-wimax-nsp.h libnm_glib_la_SOURCES = \ @@ -123,7 +123,7 @@ libnm_glib_la_SOURCES = \ nm-settings-connection-interface.c \ nm-exported-connection.c \ nm-settings-service.c \ - nm-wimax-device.c \ + nm-device-wimax.c \ nm-wimax-nsp.c libnm_glib_la_LIBADD = \ @@ -205,8 +205,8 @@ nm-ip6-config-bindings.h: $(top_srcdir)/introspection/nm-ip6-config.xml nm-dhcp6-config-bindings.h: $(top_srcdir)/introspection/nm-dhcp6-config.xml $(AM_V_GEN) dbus-binding-tool --prefix=nm_dhcp6_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=$@ $< +nm-device-wimax-bindings.h: $(top_srcdir)/introspection/nm-device-wimax.xml + dbus-binding-tool --prefix=nm_device_wimax --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 9ec54de9dd..e046b162d0 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -167,12 +167,12 @@ 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_device_wimax_get_hw_address; + nm_device_wimax_get_active_nsp; + nm_device_wimax_get_nsp_by_path; + nm_device_wimax_get_nsps; + nm_device_wimax_get_type; + nm_device_wimax_new; nm_wimax_nsp_get_name; nm_wimax_nsp_get_network_type; nm_wimax_nsp_get_signal_quality; diff --git a/libnm-glib/nm-wimax-device.c b/libnm-glib/nm-device-wimax.c similarity index 72% rename from libnm-glib/nm-wimax-device.c rename to libnm-glib/nm-device-wimax.c index 09a9bad64d..4d43dc8c0e 100644 --- a/libnm-glib/nm-wimax-device.c +++ b/libnm-glib/nm-device-wimax.c @@ -17,26 +17,27 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * + * Copyright (C) 2011 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. */ #include -#include "nm-wimax-device.h" +#include "nm-device-wimax.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" +#include "nm-device-wimax-bindings.h" -G_DEFINE_TYPE (NMWimaxDevice, nm_wimax_device, NM_TYPE_DEVICE) +G_DEFINE_TYPE (NMDeviceWimax, nm_device_wimax, NM_TYPE_DEVICE) -#define NM_WIMAX_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_WIMAX_DEVICE, NMWimaxDevicePrivate)) +#define NM_DEVICE_WIMAX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxPrivate)) static gboolean demarshal_active_nsp (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field); -void _nm_wimax_device_set_wireless_enabled (NMWimaxDevice *wimax, gboolean enabled); +void _nm_device_wimax_set_wireless_enabled (NMDeviceWimax *wimax, gboolean enabled); typedef struct { gboolean disposed; @@ -46,7 +47,7 @@ typedef struct { NMWimaxNsp *active_nsp; gboolean null_active_nsp; GPtrArray *nsps; -} NMWimaxDevicePrivate; +} NMDeviceWimaxPrivate; enum { PROP_0, @@ -69,46 +70,46 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; /** - * nm_wimax_device_new: + * nm_device_wimax_new: * @connection: the #DBusGConnection * @path: the DBus object path of the wimax * - * Creates a new #NMWimaxDevice. + * Creates a new #NMDeviceWimax. * * Returns: a new wimax **/ GObject * -nm_wimax_device_new (DBusGConnection *connection, const char *path) +nm_device_wimax_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, + return g_object_new (NM_TYPE_DEVICE_WIMAX, NM_OBJECT_DBUS_CONNECTION, connection, NM_OBJECT_DBUS_PATH, path, NULL); } /** - * nm_wimax_device_get_hw_address: - * @device: a #NMWimaxDevice + * nm_device_wimax_get_hw_address: + * @device: a #NMDeviceWimax * - * Gets the hardware (MAC) address of the #NMWimaxDevice + * Gets the hardware (MAC) address of the #NMDeviceWimax * * 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) +nm_device_wimax_get_hw_address (NMDeviceWimax *wimax) { - NMWimaxDevicePrivate *priv; + NMDeviceWimaxPrivate *priv; - g_return_val_if_fail (NM_IS_WIMAX_DEVICE (wimax), NULL); + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL); - priv = NM_WIMAX_DEVICE_GET_PRIVATE (wimax); + priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); if (!priv->hw_address) { priv->hw_address = _nm_object_get_string_property (NM_OBJECT (wimax), - NM_DBUS_INTERFACE_WIMAX_DEVICE, + NM_DBUS_INTERFACE_DEVICE_WIMAX, DBUS_PROP_HW_ADDRESS); } @@ -116,22 +117,22 @@ nm_wimax_device_get_hw_address (NMWimaxDevice *wimax) } /** - * nm_wimax_device_get_active_nsp: - * @wimax: a #NMWimaxDevice + * nm_device_wimax_get_active_nsp: + * @wimax: a #NMDeviceWimax * * Gets the active #NMWimaxNsp. * * Returns: the access point or %NULL if none is active **/ NMWimaxNsp * -nm_wimax_device_get_active_nsp (NMWimaxDevice *wimax) +nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax) { - NMWimaxDevicePrivate *priv; + NMDeviceWimaxPrivate *priv; NMDeviceState state; char *path; GValue value = { 0, }; - g_return_val_if_fail (NM_IS_WIMAX_DEVICE (wimax), NULL); + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL); state = nm_device_get_state (NM_DEVICE (wimax)); switch (state) { @@ -146,14 +147,14 @@ nm_wimax_device_get_active_nsp (NMWimaxDevice *wimax) break; } - priv = NM_WIMAX_DEVICE_GET_PRIVATE (wimax); + priv = NM_DEVICE_WIMAX_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, + NM_DBUS_INTERFACE_DEVICE_WIMAX, DBUS_PROP_ACTIVE_NSP); if (path) { g_value_init (&value, DBUS_TYPE_G_OBJECT_PATH); @@ -166,26 +167,26 @@ nm_wimax_device_get_active_nsp (NMWimaxDevice *wimax) } /** - * nm_wimax_device_get_nsps: - * @wimax: a #NMWimaxDevice + * nm_device_wimax_get_nsps: + * @wimax: a #NMDeviceWimax * - * Gets all the scanned NSPs of the #NMWimaxDevice. + * Gets all the scanned NSPs of the #NMDeviceWimax. * * 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) +nm_device_wimax_get_nsps (NMDeviceWimax *wimax) { - NMWimaxDevicePrivate *priv; + NMDeviceWimaxPrivate *priv; DBusGConnection *connection; GValue value = { 0, }; GError *error = NULL; GPtrArray *temp; - g_return_val_if_fail (NM_IS_WIMAX_DEVICE (wimax), NULL); + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL); - priv = NM_WIMAX_DEVICE_GET_PRIVATE (wimax); + priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); if (priv->nsps) return handle_ptr_array_return (priv->nsps); @@ -205,8 +206,8 @@ nm_wimax_device_get_nsps (NMWimaxDevice *wimax) } /** - * nm_wimax_device_get_nsp_by_path: - * @wimax: a #NMWimaxDevice + * nm_device_wimax_get_nsp_by_path: + * @wimax: a #NMDeviceWimax * @path: the object path of the NSP * * Gets a #NMWimaxNsp by path. @@ -214,17 +215,17 @@ nm_wimax_device_get_nsps (NMWimaxDevice *wimax) * Returns: the access point or %NULL if none is found. **/ NMWimaxNsp * -nm_wimax_device_get_nsp_by_path (NMWimaxDevice *wimax, +nm_device_wimax_get_nsp_by_path (NMDeviceWimax *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 (NM_IS_DEVICE_WIMAX (wimax), NULL); g_return_val_if_fail (path != NULL, NULL); - nsps = nm_wimax_device_get_nsps (wimax); + nsps = nm_device_wimax_get_nsps (wimax); if (!nsps) return NULL; @@ -242,17 +243,17 @@ nm_wimax_device_get_nsp_by_path (NMWimaxDevice *wimax, static void nsp_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data) { - NMWimaxDevice *self = NM_WIMAX_DEVICE (user_data); - NMWimaxDevicePrivate *priv; + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv; GObject *nsp; g_return_if_fail (self != NULL); - nsp = G_OBJECT (nm_wimax_device_get_nsp_by_path (self, path)); + nsp = G_OBJECT (nm_device_wimax_get_nsp_by_path (self, path)); if (!nsp) { DBusGConnection *connection = nm_object_get_connection (NM_OBJECT (self)); - priv = NM_WIMAX_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); nsp = G_OBJECT (_nm_object_cache_get (path)); if (nsp) { g_ptr_array_add (priv->nsps, g_object_ref (nsp)); @@ -270,20 +271,20 @@ nsp_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data) 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); + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); NMWimaxNsp *nsp; g_return_if_fail (self != NULL); - nsp = nm_wimax_device_get_nsp_by_path (self, path); + nsp = nm_device_wimax_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); + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP); } g_signal_emit (self, signals[NSP_REMOVED], 0, nsp); @@ -293,13 +294,13 @@ nsp_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data) } static void -clean_up_nsps (NMWimaxDevice *self, gboolean notify) +clean_up_nsps (NMDeviceWimax *self, gboolean notify) { - NMWimaxDevicePrivate *priv; + NMDeviceWimaxPrivate *priv; - g_return_if_fail (NM_IS_WIMAX_DEVICE (self)); + g_return_if_fail (NM_IS_DEVICE_WIMAX (self)); - priv = NM_WIMAX_DEVICE_GET_PRIVATE (self); + priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); if (priv->active_nsp) { g_object_unref (priv->active_nsp); @@ -323,7 +324,7 @@ clean_up_nsps (NMWimaxDevice *self, gboolean notify) /**************************************************************/ static void -nm_wimax_device_init (NMWimaxDevice *wimax) +nm_device_wimax_init (NMDeviceWimax *wimax) { } @@ -333,14 +334,14 @@ get_property (GObject *object, GValue *value, GParamSpec *pspec) { - NMWimaxDevice *self = NM_WIMAX_DEVICE (object); + NMDeviceWimax *self = NM_DEVICE_WIMAX (object); switch (prop_id) { case PROP_HW_ADDRESS: - g_value_set_string (value, nm_wimax_device_get_hw_address (self)); + g_value_set_string (value, nm_device_wimax_get_hw_address (self)); break; case PROP_ACTIVE_NSP: - g_value_set_object (value, nm_wimax_device_get_active_nsp (self)); + g_value_set_object (value, nm_device_wimax_get_active_nsp (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -351,8 +352,8 @@ get_property (GObject *object, 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); + NMDeviceWimax *self = NM_DEVICE_WIMAX (device); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); switch (nm_device_get_state (device)) { case NM_DEVICE_STATE_UNKNOWN: @@ -365,7 +366,7 @@ state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) priv->active_nsp = NULL; priv->null_active_nsp = FALSE; } - _nm_object_queue_notify (NM_OBJECT (device), NM_WIMAX_DEVICE_ACTIVE_NSP); + _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIMAX_ACTIVE_NSP); break; default: break; @@ -375,7 +376,7 @@ state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) static gboolean demarshal_active_nsp (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) { - NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (object); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (object); const char *path; NMWimaxNsp *nsp = NULL; DBusGConnection *connection; @@ -408,17 +409,17 @@ demarshal_active_nsp (NMObject *object, GParamSpec *pspec, GValue *value, gpoint if (nsp) priv->active_nsp = nsp; - _nm_object_queue_notify (object, NM_WIMAX_DEVICE_ACTIVE_NSP); + _nm_object_queue_notify (object, NM_DEVICE_WIMAX_ACTIVE_NSP); return TRUE; } static void -register_for_property_changed (NMWimaxDevice *wimax) +register_for_property_changed (NMDeviceWimax *wimax) { - NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (wimax); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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 }, + { NM_DEVICE_WIMAX_HW_ADDRESS, _nm_object_demarshal_generic, &priv->hw_address }, + { NM_DEVICE_WIMAX_ACTIVE_NSP, demarshal_active_nsp, &priv->active_nsp }, { NULL }, }; @@ -433,20 +434,20 @@ constructor (GType type, GObjectConstructParam *construct_params) { GObject *object; - NMWimaxDevicePrivate *priv; + NMDeviceWimaxPrivate *priv; - object = G_OBJECT_CLASS (nm_wimax_device_parent_class)->constructor (type, + object = G_OBJECT_CLASS (nm_device_wimax_parent_class)->constructor (type, n_construct_params, construct_params); if (!object) return NULL; - priv = NM_WIMAX_DEVICE_GET_PRIVATE (object); + priv = NM_DEVICE_WIMAX_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); + NM_DBUS_INTERFACE_DEVICE_WIMAX); dbus_g_proxy_add_signal (priv->proxy, "NspAdded", DBUS_TYPE_G_OBJECT_PATH, @@ -462,7 +463,7 @@ constructor (GType type, G_CALLBACK (nsp_removed_proxy), object, NULL); - register_for_property_changed (NM_WIMAX_DEVICE (object)); + register_for_property_changed (NM_DEVICE_WIMAX (object)); g_signal_connect (object, "notify::" NM_DEVICE_STATE, @@ -475,38 +476,38 @@ constructor (GType type, static void dispose (GObject *object) { - NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (object); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (object); if (priv->disposed) { - G_OBJECT_CLASS (nm_wimax_device_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_device_wimax_parent_class)->dispose (object); return; } priv->disposed = TRUE; - clean_up_nsps (NM_WIMAX_DEVICE (object), FALSE); + clean_up_nsps (NM_DEVICE_WIMAX (object), FALSE); g_object_unref (priv->proxy); - G_OBJECT_CLASS (nm_wimax_device_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_device_wimax_parent_class)->dispose (object); } static void finalize (GObject *object) { - NMWimaxDevicePrivate *priv = NM_WIMAX_DEVICE_GET_PRIVATE (object); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (object); if (priv->hw_address) g_free (priv->hw_address); - G_OBJECT_CLASS (nm_wimax_device_parent_class)->finalize (object); + G_OBJECT_CLASS (nm_device_wimax_parent_class)->finalize (object); } static void -nm_wimax_device_class_init (NMWimaxDeviceClass *wimax_class) +nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) { GObjectClass *object_class = G_OBJECT_CLASS (wimax_class); - g_type_class_add_private (wimax_class, sizeof (NMWimaxDevicePrivate)); + g_type_class_add_private (wimax_class, sizeof (NMDeviceWimaxPrivate)); /* virtual methods */ object_class->constructor = constructor; @@ -517,13 +518,13 @@ nm_wimax_device_class_init (NMWimaxDeviceClass *wimax_class) /* properties */ /** - * NMWimaxDevice:active-nsp: + * NMDeviceWimax: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, + g_param_spec_object (NM_DEVICE_WIMAX_ACTIVE_NSP, "Active NSP", "Active NSP", NM_TYPE_WIMAX_NSP, @@ -532,7 +533,7 @@ nm_wimax_device_class_init (NMWimaxDeviceClass *wimax_class) /* signals */ /** - * NMWimaxDevice::nsp-added: + * NMDeviceWimax::nsp-added: * @self: the wimax device that received the signal * @nsp: the new NSP * @@ -542,14 +543,14 @@ nm_wimax_device_class_init (NMWimaxDeviceClass *wimax_class) g_signal_new ("nsp-added", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMWimaxDeviceClass, nsp_added), + G_STRUCT_OFFSET (NMDeviceWimaxClass, nsp_added), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT); /** - * NMWimaxDevice::nsp-removed: + * NMDeviceWimax::nsp-removed: * @self: the wimax device that received the signal * @nsp: the removed NSP * @@ -559,7 +560,7 @@ nm_wimax_device_class_init (NMWimaxDeviceClass *wimax_class) g_signal_new ("nsp-removed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (NMWimaxDeviceClass, nsp_removed), + G_STRUCT_OFFSET (NMDeviceWimaxClass, nsp_removed), NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, diff --git a/libnm-glib/nm-device-wimax.h b/libnm-glib/nm-device-wimax.h new file mode 100644 index 0000000000..818444531b --- /dev/null +++ b/libnm-glib/nm-device-wimax.h @@ -0,0 +1,68 @@ +/* -*- 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) 2011 Red Hat, Inc. + * Copyright (C) 2009 Novell, Inc. + */ + +#ifndef NM_DEVICE_WIMAX_H +#define NM_DEVICE_WIMAX_H + +#include "nm-device.h" +#include "nm-wimax-nsp.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WIMAX (nm_device_wimax_get_type ()) +#define NM_DEVICE_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimax)) +#define NM_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) +#define NM_IS_DEVICE_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIMAX)) +#define NM_IS_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEVICE_WIMAX)) +#define NM_DEVICE_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) + +#define NM_DEVICE_WIMAX_HW_ADDRESS "hw-address" +#define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" + +typedef struct { + NMDevice parent; +} NMDeviceWimax; + +typedef struct { + NMDeviceClass parent; + + /* Signals */ + void (*nsp_added) (NMDeviceWimax *self, NMWimaxNsp *nsp); + void (*nsp_removed) (NMDeviceWimax *self, NMWimaxNsp *nsp); +} NMDeviceWimaxClass; + +GType nm_device_wimax_get_type (void); + +GObject *nm_device_wimax_new (DBusGConnection *connection, + const char *path); + +const char *nm_device_wimax_get_hw_address (NMDeviceWimax *wimax); +NMWimaxNsp *nm_device_wimax_get_active_nsp (NMDeviceWimax *wimax); +NMWimaxNsp *nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, + const char *path); + +const GPtrArray *nm_device_wimax_get_nsps (NMDeviceWimax *wimax); + +G_END_DECLS + +#endif /* NM_DEVICE_WIMAX_H */ diff --git a/libnm-glib/nm-device.c b/libnm-glib/nm-device.c index 74f9342ef3..b494749ada 100644 --- a/libnm-glib/nm-device.c +++ b/libnm-glib/nm-device.c @@ -32,7 +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-wimax.h" #include "nm-device.h" #include "nm-device-private.h" #include "nm-object-private.h" @@ -726,7 +726,7 @@ nm_device_new (DBusGConnection *connection, const char *path) dtype = NM_TYPE_DEVICE_BT; break; case NM_DEVICE_TYPE_WIMAX: - dtype = NM_TYPE_WIMAX_DEVICE; + dtype = NM_TYPE_DEVICE_WIMAX; break; default: g_warning ("Unknown device type %d", g_value_get_uint (&value)); diff --git a/libnm-glib/nm-wimax-device.h b/libnm-glib/nm-wimax-device.h deleted file mode 100644 index 1e59fd0d52..0000000000 --- a/libnm-glib/nm-wimax-device.h +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- 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/src/nm-manager.c b/src/nm-manager.c index da47f5b1bc..d74922a4f6 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -38,7 +38,7 @@ #include "nm-device-ethernet.h" #include "nm-device-wifi.h" #include "nm-device-olpc-mesh.h" -#include "nm-wimax-device.h" +#include "nm-device-wimax.h" #include "nm-device-cdma.h" #include "nm-device-gsm.h" #include "nm-system.h" @@ -2117,7 +2117,7 @@ add_device (NMManager *self, NMDevice *device) nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), priv->radio_states[RFKILL_TYPE_WWAN].enabled); */ - } else if (NM_IS_WIMAX_DEVICE (device)) { + } else if (NM_IS_DEVICE_WIMAX (device)) { nm_manager_rfkill_update (self, RFKILL_TYPE_WIMAX); enabled = radio_enabled_for_type (self, RFKILL_TYPE_WIMAX); nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled); diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c index 8a590ca137..31b4e69707 100644 --- a/src/nm-udev-manager.c +++ b/src/nm-udev-manager.c @@ -38,7 +38,7 @@ #include "nm-device-wifi.h" #include "nm-device-olpc-mesh.h" #include "nm-device-ethernet.h" -#include "nm-wimax-manager.h" +#include "nm-device-wimax.h" typedef struct { GUdevClient *client; @@ -339,6 +339,9 @@ is_olpc_mesh (GUdevDevice *device) static gboolean is_wimax (const char *driver) { + /* FIXME: check 'DEVTYPE' instead; but since we only support Intel + * WiMAX devices for now this is appropriate. + */ return g_strcmp0 (driver, "i2400m_usb") == 0; } @@ -395,7 +398,7 @@ device_creator (NMUdevManager *manager, else if (is_wireless (udev_device)) device = (GObject *) nm_device_wifi_new (path, ifname, driver); else if (is_wimax (driver)) - device = (GObject *) nm_wimax_manager_create_device (path, ifname, driver); + device = (GObject *) nm_device_wimax_new (path, ifname, driver); else device = (GObject *) nm_device_ethernet_new (path, ifname, driver); diff --git a/src/wimax/Makefile.am b/src/wimax/Makefile.am index 2b915b4b03..83e53cd2ec 100644 --- a/src/wimax/Makefile.am +++ b/src/wimax/Makefile.am @@ -1,5 +1,6 @@ INCLUDES = \ -I${top_srcdir}/src \ + -I${top_srcdir}/src/logging \ -I${top_srcdir}/include \ -I${top_srcdir}/libnm-util \ -I${top_builddir}/marshallers @@ -7,15 +8,15 @@ INCLUDES = \ noinst_LTLIBRARIES = libwimax.la libwimax_la_SOURCES = \ - nm-wimax-device.c \ - nm-wimax-device.h \ - nm-wimax-manager.c \ - nm-wimax-manager.h \ + nm-device-wimax.c \ + nm-device-wimax.h \ nm-wimax-nsp.c \ nm-wimax-nsp.h \ nm-wimax-types.h \ nm-wimax-util.c \ - nm-wimax-util.h + nm-wimax-util.h \ + iwmxsdk.c \ + iwmxsdk.h libwimax_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ @@ -29,11 +30,11 @@ libwimax_la_LIBADD = \ 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=$@ $< +nm-device-wimax-glue.h: $(top_srcdir)/introspection/nm-device-wimax.xml + dbus-binding-tool --prefix=nm_device_wimax --mode=glib-server --output=$@ $< BUILT_SOURCES = \ nm-wimax-nsp-glue.h \ - nm-wimax-device-glue.h + nm-device-wimax-glue.h CLEANFILES = $(BUILT_SOURCES) diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c new file mode 100644 index 0000000000..54ad84e8d6 --- /dev/null +++ b/src/wimax/iwmxsdk.c @@ -0,0 +1,1286 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * + * Copyright (C) 2011 Red Hat, Inc. All rights reserved. + * Copyright (C) 2007-2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "logging/nm-logging.h" +#include "iwmxsdk.h" + +static WIMAX_API_DEVICE_ID g_api; + +static int iwmx_sdk_setup(struct wmxsdk *wmxsdk); +static void iwmx_sdk_remove(struct wmxsdk *wmxsdk); + +/* Misc utilities */ +#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/* Misc values */ +enum { + /* + * WARNING!!!!! + * + * ONLY ONE DEVICE SUPPORTED + * + * - on removal, there is no way to know which device was + * removed (the removed device is removed from the list and + * the callback doesn't have any more information than the + * index in the list that getlistdevice would return -- racy + * as hell). + * + * - on insertion, there is not enough information provided. + */ + IWMX_SDK_DEV_MAX = 1, +}; + +/* Yes, this is dirty; see above on IWMX_SDK_DEV_MAX */ +static struct wmxsdk *g_iwmx_sdk_devs[IWMX_SDK_DEV_MAX]; + +static struct wmxsdk *deviceid_to_wmxsdk(WIMAX_API_DEVICE_ID *device_id) +{ + unsigned cnt; + for (cnt = 0; cnt < IWMX_SDK_DEV_MAX; cnt++) { + struct wmxsdk *wmxsdk = g_iwmx_sdk_devs[cnt]; + if (wmxsdk && + wmxsdk->device_id.deviceIndex == device_id->deviceIndex) + return wmxsdk; + } + return NULL; +} + +struct wmxsdk *iwmx_sdk_get_wmxsdk_for_iface(const char *iface) +{ + unsigned cnt; + + for (cnt = 0; cnt < IWMX_SDK_DEV_MAX; cnt++) { + struct wmxsdk *wmxsdk = g_iwmx_sdk_devs[cnt]; + if (wmxsdk && !strcmp(wmxsdk->ifname, iface)) + return wmxsdk; + } + return NULL; +} + +/* + * 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... + * + */ +static int 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; +} + +/**************************************************************/ + +typedef struct { + WimaxNewWmxsdkFunc callback; + void *user_data; +} NewSdkCallback; + +GStaticMutex new_callbacks_mutex = G_STATIC_MUTEX_INIT; +static GSList *new_callbacks = NULL; + +void iwmx_sdk_new_callback_register(WimaxNewWmxsdkFunc callback, void *user_data) +{ + NewSdkCallback *cb; + + cb = g_malloc0 (sizeof (NewSdkCallback)); + g_assert (cb); + cb->callback = callback; + cb->user_data = user_data; + + g_static_mutex_lock (&new_callbacks_mutex); + new_callbacks = g_slist_append (new_callbacks, cb); + g_static_mutex_unlock (&new_callbacks_mutex); +} + +void iwmx_sdk_new_callback_unregister(WimaxNewWmxsdkFunc callback, void *user_data) +{ + GSList *iter; + NewSdkCallback *found = NULL; + + g_static_mutex_lock (&new_callbacks_mutex); + for (iter = new_callbacks; iter; iter = g_slist_next (iter)) { + NewSdkCallback *cb = iter->data; + + if (cb->callback == callback && cb->user_data == user_data) { + found = cb; + break; + } + } + + if (found) { + new_callbacks = g_slist_remove (new_callbacks, found); + g_free (found); + } + g_static_mutex_unlock (&new_callbacks_mutex); +} + +/****************************************************************/ + +typedef struct { + struct wmxsdk *wmxsdk; + WIMAX_API_DEVICE_STATUS new_status; + WIMAX_API_DEVICE_STATUS old_status; + WIMAX_API_STATUS_REASON reason; +} StateChangeInfo; + +static gboolean +state_change_handler(gpointer user_data) +{ + StateChangeInfo *info = user_data; + + if (info->wmxsdk->state_change_cb) { + info->wmxsdk->state_change_cb(info->wmxsdk, + info->new_status, + info->old_status, + info->reason, + info->wmxsdk->callback_data); + } + wmxsdk_unref(info->wmxsdk); + memset(info, 0, sizeof(*info)); + free(info); + return FALSE; +} + +static void +_schedule_state_change(struct wmxsdk *wmxsdk, + WIMAX_API_DEVICE_STATUS new_status, + WIMAX_API_DEVICE_STATUS old_status, + WIMAX_API_STATUS_REASON reason) +{ + StateChangeInfo *info; + + info = malloc(sizeof (*info)); + if (!info) + return; + + memset(info, 0, sizeof(*info)); + info->wmxsdk = wmxsdk; + info->new_status = new_status; + info->old_status = old_status; + info->reason = reason; + + wmxsdk_ref(wmxsdk); + g_idle_add(state_change_handler, info); +} + +typedef struct { + struct wmxsdk *wmxsdk; + WIMAX_API_NETWORK_CONNECTION_RESP result; +} ConnectResultInfo; + +static gboolean +connect_result_handler(gpointer user_data) +{ + ConnectResultInfo *info = user_data; + + if (info->wmxsdk->connect_result_cb) { + info->wmxsdk->connect_result_cb(info->wmxsdk, + info->result, + info->wmxsdk->callback_data); + } + wmxsdk_unref(info->wmxsdk); + memset(info, 0, sizeof(*info)); + free(info); + return FALSE; +} + +static void +_schedule_connect_result(struct wmxsdk *wmxsdk, + WIMAX_API_NETWORK_CONNECTION_RESP resp) +{ + ConnectResultInfo *info; + + info = malloc(sizeof (*info)); + if (!info) + return; + + memset(info, 0, sizeof(*info)); + info->wmxsdk = wmxsdk; + info->result = resp; + + wmxsdk_ref(wmxsdk); + g_idle_add(connect_result_handler, info); +} + +typedef struct { + struct wmxsdk *wmxsdk; + WIMAX_API_NSP_INFO_EX *nsps; + guint num_nsps; +} ScanResultInfo; + +static gboolean +scan_result_handler(gpointer user_data) +{ + ScanResultInfo *info = user_data; + + if (info->wmxsdk->scan_result_cb) { + info->wmxsdk->scan_result_cb(info->wmxsdk, + info->nsps, + info->num_nsps, + info->wmxsdk->callback_data); + } + wmxsdk_unref(info->wmxsdk); + free(info->nsps); + memset(info, 0, sizeof(*info)); + free(info); + return FALSE; +} + +static void +_schedule_scan_result(struct wmxsdk *wmxsdk, + WIMAX_API_NSP_INFO_EX *nsps, + guint num_nsps) +{ + ScanResultInfo *info; + size_t nsps_size; + int i, tmp; + + info = malloc(sizeof (*info)); + if (!info) + return; + + memset(info, 0, sizeof(*info)); + info->wmxsdk = wmxsdk; + + nsps_size = num_nsps * sizeof (WIMAX_API_NSP_INFO_EX); + info->nsps = malloc(nsps_size); + memcpy(info->nsps, nsps, nsps_size); + info->num_nsps = num_nsps; + + /* CAPI may report link quality as zero -- if it does check if it is a bug + * by computing it based on CINR. If it is different, use the computed one. + */ + for (i = 0; i < num_nsps; i++) { + WIMAX_API_NSP_INFO_EX *nsp = &info->nsps[i]; + + if (nsp->linkQuality == 0) { + tmp = cinr_to_percentage(nsp->CINR - 10); + if (tmp != nsp->linkQuality) + nsp->linkQuality = tmp; + } + } + + wmxsdk_ref(wmxsdk); + g_idle_add(scan_result_handler, info); +} + +static gboolean +removed_handler(gpointer user_data) +{ + struct wmxsdk *wmxsdk = user_data; + + if (wmxsdk->removed_cb) + wmxsdk->removed_cb(wmxsdk, wmxsdk->callback_data); + wmxsdk_unref(wmxsdk); + return FALSE; +} + +static void +_schedule_removed(struct wmxsdk *wmxsdk) +{ + wmxsdk_ref(wmxsdk); + g_idle_add(removed_handler, wmxsdk); +} + +/****************************************************************/ + +/* + * Convert a WiMAX API status to an string. + */ +const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status) +{ + switch (status) { + case WIMAX_API_DEVICE_STATUS_UnInitialized: + return "uninitialized"; + case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW: + return "rf off"; + case WIMAX_API_DEVICE_STATUS_RF_OFF_HW: + return "rf off (hard-block)"; + case WIMAX_API_DEVICE_STATUS_RF_OFF_SW: + return "rf off (soft-block)"; + case WIMAX_API_DEVICE_STATUS_Ready: + return "ready"; + case WIMAX_API_DEVICE_STATUS_Scanning: + return "scanning"; + case WIMAX_API_DEVICE_STATUS_Connecting: + return "connecting"; + case WIMAX_API_DEVICE_STATUS_Data_Connected: + return "connected"; + default: + return "unknown"; + } +} + +const char *iwmx_sdk_reason_to_str(WIMAX_API_STATUS_REASON reason) +{ + switch (reason) { + case WIMAX_API_STATUS_REASON_Normal: + return "normal"; + + /**< Failed to complete NW entry with the selected operator (unspecified reason). */ + case WIMAX_API_STATUS_REASON_Fail_to_connect_to_NW: + return "unspecified failure"; + + /**< Failed to complete ranging */ + case WIMAX_API_STATUS_REASON_Fail_to_connect_Ranging: + return "ranging failed"; + + /**< SBC phase failed */ + case WIMAX_API_STATUS_REASON_Fail_to_connect_SBC: + return "sbc failed"; + + /**< Security error. EAP authentication failed device level */ + case WIMAX_API_STATUS_REASON_Fail_to_connect_EAP_AUTH_Device: + return "EAP device auth failed"; + + /**< Security error. EAP authentication failed user level */ + case WIMAX_API_STATUS_REASON_Fail_to_connect_EAP_AUTH_user: + return "EAP user auth failed"; + + /**< Security error. Handshake failed */ + case WIMAX_API_STATUS_REASON_Fail_to_connect_3_Way_Handshake: + return "3 way handshake failed"; + + /**< Registration failed */ + case WIMAX_API_STATUS_REASON_Fail_to_connect_REG: + return "registration failed"; + + /**< Failed to initialize the data path (failed to perform DSA to one UL and one DL SFs). */ + case WIMAX_API_STATUS_REASON_Fail_to_connect_datapath: + return "datapath failed"; + + default: + return "unknown"; + } +} + + +/* + * Get the device's status from the device + * + * Does NOT cache the result + * Does NOT trigger a state change in NetworkManager + * + * Returns < 0 errno code on error, status code if ok. + */ +static WIMAX_API_DEVICE_STATUS iwmx_sdk_get_device_status(struct wmxsdk *wmxsdk) +{ + WIMAX_API_RET r; + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + + WIMAX_API_DEVICE_STATUS dev_status; + WIMAX_API_CONNECTION_PROGRESS_INFO pi; + + r = GetDeviceStatus(&wmxsdk->device_id, &dev_status, &pi); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot read device state: %d (%s)", r, errstr); + dev_status = -EIO; + } + return dev_status; +} + +/* + * Get the device's status from the device but return a string describing it + * + * Same conditions as iwmx_sdk_get_device_status(). + */ +static const char *iwmx_sdk_get_device_status_str(struct wmxsdk *wmxsdk) +{ + const char *result; + WIMAX_API_DEVICE_STATUS dev_status; + + dev_status = iwmx_sdk_get_device_status(wmxsdk); + if ((int) dev_status < 0) + result = "cannot read device state"; + else + result = iwmx_sdk_dev_status_to_str(dev_status); + return result; +} + +/* + * If the device is connected but we don't know about the network, + * create the knowledge of it. + * + * Asks the WiMAX API to report which NSP we are connected to and we + * create/update a network_el in the device's network list. Then + * return it. + * + * Returns NULL on error. + * + */ +WIMAX_API_CONNECTED_NSP_INFO_EX *iwmx_sdk_get_connected_network(struct wmxsdk *wmxsdk) +{ + WIMAX_API_CONNECTED_NSP_INFO_EX *nsp_info = NULL; + WIMAX_API_RET r; + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + + nsp_info = malloc(sizeof (*nsp_info)); + if (!nsp_info) { + nm_log_err(LOGD_WIMAX, "wmxsdk: cannot allocate NSP info"); + return NULL; + } + + r = GetConnectedNSPEx(&wmxsdk->device_id, nsp_info); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot get connected NSP info: %d (%s)", r, errstr); + free (nsp_info); + nsp_info = NULL; + } else { + /* Migth be 0 sometimes; fix that up */ + if (nsp_info->linkQuality == 0) { + int linkq_expected = cinr_to_percentage(nsp_info->CINR - 10); + if (linkq_expected != nsp_info->linkQuality) + nsp_info->linkQuality = linkq_expected; + } + } + + return nsp_info; +} + +/* + * Callback for a RF State command + * + * Called by the WiMAX API when a command sent to change the RF state + * is completed. This is just a confirmation of what happened with the + * command. + * + * We don't do anything, as when the device changes state, the state + * change callback is called and that will fiddle with the NetworkManager + * internals. + */ +static void __iwmx_sdk_rf_state_cb(WIMAX_API_DEVICE_ID *device_id, + WIMAX_API_RF_STATE rf_state) +{ + nm_log_dbg(LOGD_WIMAX, "rf_state changed to %d", rf_state); +} + +/* + * Turn the radio on or off + * + * First it checks that we are in the right state before doing + * anything; there might be no need to do anything. + * + * Issue a command to the WiMAX API, wait for a callback confirming it + * is done. Sometimes the callback is missed -- in that case, do force + * a state change evaluation. + * + * Frustration note: + * + * Geezoos efing Xist, they make difficult even the most simple + * of the operations + * + * This thing is definitely a pain. If the radio is ON already + * and you switch it on again...well, there is no way to tell + * because you don't get a callback saying it basically + * suceeded. But on the other hand, if the thing was in a + * different state and action needs to be taken, you have to wait + * for a callback to confirm it's done. However, there is also an + * state change callback, which is almost the same, so now you + * have to handle things in two "unrelated" threads of execution. + * + * How the shpx are you expected to tell the difference? Check + * status first? On timeout? Nice gap (eighteen wheeler size) for + * race conditions. + */ +int iwmx_sdk_rf_state_set(struct wmxsdk *wmxsdk, WIMAX_API_RF_STATE rf_state) +{ + int result; + + WIMAX_API_RET r; + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + WIMAX_API_DEVICE_STATUS dev_status; + + g_assert(rf_state == WIMAX_API_RF_ON || rf_state == WIMAX_API_RF_OFF); + + /* Guess what the current radio state is; if it is ON + * already, don't redo it. */ + dev_status = iwmx_sdk_get_device_status(wmxsdk); + if ((int) dev_status < 0) { + result = dev_status; + goto error_get_status; + } + switch (dev_status) { + case WIMAX_API_DEVICE_STATUS_UnInitialized: + result = -EINVAL; + goto error_cant_do; + case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW: + case WIMAX_API_DEVICE_STATUS_RF_OFF_HW: + nm_log_err(LOGD_WIMAX, "wmxsdk: cannot turn on radio: hw switch is off"); + result = -EPERM; + goto error_cant_do; + break; + case WIMAX_API_DEVICE_STATUS_RF_OFF_SW: + if (rf_state == WIMAX_API_RF_OFF) { + result = 0; + nm_log_dbg(LOGD_WIMAX, "radio is already off"); + goto out_done; + } + 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: + if (rf_state == WIMAX_API_RF_ON) { + result = 0; + nm_log_dbg(LOGD_WIMAX, "radio is already on"); + goto out_done; + } + break; + default: + g_assert(1); + } + /* Ok, flip the radio */ + r = CmdControlPowerManagement(&wmxsdk->device_id, rf_state); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot flip radio to %d: %d (%s) [device is in state %s]", + rf_state, r, errstr, iwmx_sdk_get_device_status_str(wmxsdk)); + result = -EIO; + } else + result = -EINPROGRESS; +out_done: +error_cant_do: +error_get_status: + return result; +} + +/* + * Read the cached device status + */ +WIMAX_API_DEVICE_STATUS iwmxsdk_status_get(struct wmxsdk *wmxsdk) +{ + WIMAX_API_DEVICE_STATUS status; + + g_mutex_lock(wmxsdk->status_mutex); + status = wmxsdk->status; + g_mutex_unlock(wmxsdk->status_mutex); + return status; +} + +/* + * Callback for a Connect command + * + * Called by the WiMAX API when a command sent to connect is + * completed. This is just a confirmation of what happened with the + * command. + * + * WE DON'T DO MUCH HERE -- the real meat happens when a state change + * callback is sent, where we detect we move to connected state (or + * from disconnecting to something else); the state change callback is + * called and that will fiddle with the NetworkManager internals. + */ +static void __iwmx_sdk_connect_cb(WIMAX_API_DEVICE_ID *device_id, + WIMAX_API_NETWORK_CONNECTION_RESP resp) +{ + WIMAX_API_DEVICE_STATUS status; + struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id); + + status = iwmxsdk_status_get(wmxsdk); + if (resp == WIMAX_API_CONNECTION_SUCCESS) { + if (status != WIMAX_API_DEVICE_STATUS_Data_Connected) { + nm_log_err(LOGD_WIMAX, "wmxsdk: error: connect worked, but state" + " didn't change (now it is %d [%s])", + status, + iwmx_sdk_dev_status_to_str(status)); + } + } else { + nm_log_err(LOGD_WIMAX, "wmxsdk: failed to connect (status %d: %s)", + status, iwmx_sdk_dev_status_to_str(status)); + } + + _schedule_connect_result(wmxsdk, resp); +} + +/* + * Connect to a network + * + * This function starts the connection process to a given network; + * when the device changes status, the status change callback will + * tell NetworkManager if the network is finally connected or not. + * + * One of the reasons it is done like that is to allow external tools + * to control the device and the plugin just passing the status so + * NetworkManager displays the right info. + */ +int iwmx_sdk_connect(struct wmxsdk *wmxsdk, const char *nsp_name) +{ + int result = 0; + + WIMAX_API_RET r; + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + WIMAX_API_DEVICE_STATUS dev_status; + + g_mutex_lock(wmxsdk->connect_mutex); + /* Guess what the current radio state is; if it is ON + * already, don't redo it. */ + dev_status = iwmxsdk_status_get(wmxsdk); + if ((int) dev_status < 0) { + result = dev_status; + goto error_get_status; + } + switch (dev_status) { + case WIMAX_API_DEVICE_STATUS_UnInitialized: + nm_log_err(LOGD_WIMAX, "wmxsdk: SW BUG? HW is uninitialized"); + result = -EINVAL; + goto error_cant_do; + 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: + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot connect: radio is off"); + result = -EPERM; + goto error_cant_do; + case WIMAX_API_DEVICE_STATUS_Ready: + case WIMAX_API_DEVICE_STATUS_Scanning: + break; + case WIMAX_API_DEVICE_STATUS_Connecting: + nm_log_dbg(LOGD_WIMAX, "Connect already pending, waiting for it"); + result = -EINPROGRESS; + goto error_cant_do; + case WIMAX_API_DEVICE_STATUS_Data_Connected: + nm_log_err(LOGD_WIMAX, "wmxsdk: BUG? need to disconnect?"); + result = -EINVAL; + goto error_cant_do; + default: + g_assert(1); + } + + /* Ok, do the connection, wait for a callback */ + r = CmdConnectToNetwork(&wmxsdk->device_id, (void *) nsp_name, 0, 0); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot connect to network %s: %d (%s) - device is in state '%s'", + nsp_name, r, errstr, + iwmx_sdk_get_device_status_str(wmxsdk)); + result = -EIO; + } + +error_cant_do: +error_get_status: + g_mutex_unlock(wmxsdk->connect_mutex); + return result; +} + +/* + * Callback for a Disconnect command + * + * Called by the WiMAX API when a command sent to connect is + * completed. This is just a confirmation of what happened with the + * command. + * + * When the device changes state, the state change callback is called + * and that will fiddle with the NetworkManager internals. + * + * We just update the result of the command and wake up anybody who is + * waiting for this conditional variable. + */ +static void __iwmx_sdk_disconnect_cb(WIMAX_API_DEVICE_ID *device_id, + WIMAX_API_NETWORK_CONNECTION_RESP resp) +{ + struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id); + WIMAX_API_DEVICE_STATUS status; + + status = iwmxsdk_status_get(wmxsdk); + if (resp == WIMAX_API_CONNECTION_SUCCESS) { + if (status == WIMAX_API_DEVICE_STATUS_Data_Connected) { + nm_log_err(LOGD_WIMAX, "wmxsdk: error: disconnect worked, " + "but state didn't change (now it is %d [%s])", status, + iwmx_sdk_dev_status_to_str(status)); + } + } else + nm_log_err(LOGD_WIMAX, "wmxsdk: failed to disconnect (status %d: %s)", + status, iwmx_sdk_dev_status_to_str(status)); +} + +/* + * Disconnect from a network + * + * This function tells the device to disconnect; the state change + * callback will take care of inform NetworkManager's internals. + */ +int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk) +{ + int result; + + WIMAX_API_RET r; + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + WIMAX_API_DEVICE_STATUS dev_status; + + g_mutex_lock(wmxsdk->connect_mutex); + /* Guess what the current radio state is; if it is ON + * already, don't redo it. */ + dev_status = iwmx_sdk_get_device_status(wmxsdk); + if ((int) dev_status < 0) { + result = dev_status; + goto error_get_status; + } + switch (dev_status) { + case WIMAX_API_DEVICE_STATUS_UnInitialized: + nm_log_err(LOGD_WIMAX, "wmxsdk: SW BUG? HW is uninitialized"); + result = -EINVAL; + goto error_cant_do; + 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: + nm_log_dbg(LOGD_WIMAX, "Cannot disconnect, radio is off; ignoring"); + result = 0; + goto error_cant_do; + case WIMAX_API_DEVICE_STATUS_Ready: + case WIMAX_API_DEVICE_STATUS_Scanning: + nm_log_dbg(LOGD_WIMAX, "Cannot disconnect, already disconnected; ignoring"); + result = 0; + goto error_cant_do; + case WIMAX_API_DEVICE_STATUS_Connecting: + case WIMAX_API_DEVICE_STATUS_Data_Connected: + break; + default: + g_assert(1); + } + /* Ok, flip the radio */ + r = CmdDisconnectFromNetwork(&wmxsdk->device_id); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot disconnect from network: %d (%s)", r, errstr); + result = -EIO; + } else + result = -EINPROGRESS; +error_cant_do: +error_get_status: + g_mutex_unlock(wmxsdk->connect_mutex); + return result; +} + +/* + * Callback for state change messages + * + * Just pass them to the state transition handler + */ +static void __iwmx_sdk_state_change_cb(WIMAX_API_DEVICE_ID *device_id, + WIMAX_API_DEVICE_STATUS status, + WIMAX_API_STATUS_REASON reason, + WIMAX_API_CONNECTION_PROGRESS_INFO pi) +{ + struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id); + WIMAX_API_DEVICE_STATUS old_status; + + nm_log_dbg(LOGD_WIMAX, "wmxsdk: state change to (%d) %s reason (%d) %s", + status, iwmx_sdk_dev_status_to_str (status), + reason, iwmx_sdk_reason_to_str (reason)); + + g_mutex_lock(wmxsdk->status_mutex); + old_status = wmxsdk->status; + wmxsdk->status = status; + g_mutex_unlock(wmxsdk->status_mutex); + + _schedule_state_change(wmxsdk, status, old_status, reason); +} + +/* + * Called by _iwmx_sdk_*scan_cb() when [wide or preferred] scan results + * are available. + * + * From here we update NetworkManager's idea of which networks are available. + */ +static void __iwmx_sdk_scan_common_cb(WIMAX_API_DEVICE_ID *device_id, + WIMAX_API_NSP_INFO_EX *nsp_list, + UINT32 nsp_list_size) +{ + struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id); + + g_static_mutex_lock(&wmxsdk->network_mutex); + _schedule_scan_result(wmxsdk, nsp_list, nsp_list_size); + g_static_mutex_unlock(&wmxsdk->network_mutex); +} + +/* + * Called by the WiMAX API when we get a wide scan result + * + * We treat them same as wide, so we just call that. + */ +static void __iwmx_sdk_wide_scan_cb(WIMAX_API_DEVICE_ID *device_id, + WIMAX_API_NSP_INFO_EX *nsp_list, + UINT32 nsp_list_size) +{ + __iwmx_sdk_scan_common_cb(device_id, nsp_list, nsp_list_size); +} + +/* + * Called by the WiMAX API when we get a normal (non wide) scan result + * + * We treat them same as wide, so we just call that. + */ +static void __iwmx_sdk_scan_cb(WIMAX_API_DEVICE_ID *device_id, + WIMAX_API_NSP_INFO_EX *nsp_list, + UINT32 nsp_list_size, UINT32 searchProgress) +{ + __iwmx_sdk_scan_common_cb(device_id, nsp_list, nsp_list_size); +} + +/* + * Called to ask the device to scan for networks + * + * We don't really scan as the WiMAX SDK daemon scans in the + * background for us. We just get the results and hand them back via + * the scan_result_cb callback. + */ +int iwmx_sdk_get_networks(struct wmxsdk *wmxsdk) +{ + int result; + + UINT32 nsp_list_length = 10; + WIMAX_API_NSP_INFO_EX nsp_list[10]; /* FIXME: up to 32? */ + + WIMAX_API_RET r; + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + + r = GetNetworkListEx(&wmxsdk->device_id, nsp_list, &nsp_list_length); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot get network list: %d (%s)", r, errstr); + result = -EIO; + goto error_scan; + } + + if (nsp_list_length == 0) { + nm_log_dbg(LOGD_WIMAX, "no networks"); + } else + __iwmx_sdk_scan_common_cb(&wmxsdk->device_id, nsp_list, + nsp_list_length); + result = 0; +error_scan: + return result; +} + +/* + * Initialize the WiMAX API, register with it, setup callbacks + * + */ +static int iwmx_sdk_setup(struct wmxsdk *wmxsdk) +{ + int result; + + WIMAX_API_RET r; + + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + + result = -ENFILE; + + /* device_id initialized by iwmx_sdk_dev_add */ + + r = WiMaxDeviceOpen(&wmxsdk->device_id); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot open device: %d (%s)", r, errstr); + goto error_wimaxdeviceopen; + } + + /* + * We scan in auto mode (in the background) + * + * Otherwise is messy -- if we have NetworkManager triggering a scan + * when we call iwmx_nm_scan() -> iwmx_sdk_scan(), most of the + * times that causes a race condition when the UI asks for a + * scan right before displaying the network menu. As there is + * no way to cancel an ongoing scan before connecting, we are + * stuck. So we do auto bg and have iwmx_sdk_scan() just return + * the current network list. + */ + r = SetConnectionMode(&wmxsdk->device_id, + WIMAX_API_CONNECTION_AUTO_SCAN_MANUAL_CONNECT); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot set connectin mode to manual: %d (%s)", r, errstr); + goto error_connection_mode; + } + + r = SubscribeControlPowerManagement(&wmxsdk->device_id, + __iwmx_sdk_rf_state_cb); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to radio change events: %u (%s)", r, errstr); + result = -EIO; + goto error_subscribe_rf_state; + } + + r = SubscribeDeviceStatusChange(&wmxsdk->device_id, + __iwmx_sdk_state_change_cb); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to state chaneg events: %d (%s)", r, errstr); + goto error_subscribe_state_change; + } + + r = SubscribeNetworkSearchWideScanEx(&wmxsdk->device_id, + __iwmx_sdk_wide_scan_cb); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to wide scan events: %d (%s)", r, errstr); + goto error_subscribe_wide_scan; + } + r = SubscribeNetworkSearchEx(&wmxsdk->device_id, __iwmx_sdk_scan_cb); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to scan events: %d (%s)", r, errstr); + goto error_subscribe_scan; + } + + r = SubscribeConnectToNetwork(&wmxsdk->device_id, + __iwmx_sdk_connect_cb); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to connect events: %d (%s)", r, errstr); + goto error_subscribe_connect; + } + + r = SubscribeDisconnectToNetwork(&wmxsdk->device_id, + __iwmx_sdk_disconnect_cb); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to disconnect events: %d (%s)", r, errstr); + goto error_subscribe_disconnect; + } + + wmxsdk->status = iwmx_sdk_get_device_status(wmxsdk); + if ((int) wmxsdk->status < 0) + wmxsdk->status = WIMAX_API_DEVICE_STATUS_UnInitialized; + + return 0; + + UnsubscribeDisconnectToNetwork(&wmxsdk->device_id); +error_subscribe_disconnect: + UnsubscribeConnectToNetwork(&wmxsdk->device_id); +error_subscribe_connect: + UnsubscribeNetworkSearchEx(&wmxsdk->device_id); +error_subscribe_scan: + UnsubscribeNetworkSearchWideScanEx(&wmxsdk->device_id); +error_subscribe_wide_scan: + UnsubscribeDeviceStatusChange(&wmxsdk->device_id); +error_subscribe_state_change: + UnsubscribeControlPowerManagement(&wmxsdk->device_id); +error_subscribe_rf_state: +error_connection_mode: + WiMaxDeviceClose(&wmxsdk->device_id); +error_wimaxdeviceopen: + return result; +} + +/* + * Called when a device is torn down + * + * Cleanup all that is done in iwmx_sdk_setup(). Remove callbacks, + * unregister from the WiMAX API. + */ +static void iwmx_sdk_remove(struct wmxsdk *wmxsdk) +{ + UnsubscribeDisconnectToNetwork(&wmxsdk->device_id); + UnsubscribeConnectToNetwork(&wmxsdk->device_id); + UnsubscribeNetworkSearchEx(&wmxsdk->device_id); + UnsubscribeNetworkSearchWideScanEx(&wmxsdk->device_id); + UnsubscribeDeviceStatusChange(&wmxsdk->device_id); + UnsubscribeControlPowerManagement(&wmxsdk->device_id); + WiMaxDeviceClose(&wmxsdk->device_id); +} + +void iwmx_sdk_set_callbacks(struct wmxsdk *wmxsdk, + WimaxStateChangeFunc state_change_cb, + WimaxConnectResultFunc connect_result_cb, + WimaxScanResultFunc scan_result_cb, + WimaxRemovedFunc removed_cb, + void *user_data) +{ + wmxsdk->state_change_cb = state_change_cb; + wmxsdk->connect_result_cb = connect_result_cb; + wmxsdk->scan_result_cb = scan_result_cb; + wmxsdk->removed_cb = removed_cb; + wmxsdk->callback_data = user_data; +} + +/* Initialize a [zeroed] struct wmxsdk */ +static struct wmxsdk *wmxsdk_new(void) +{ + struct wmxsdk *wmxsdk; + + wmxsdk = malloc(sizeof(*wmxsdk)); + if (wmxsdk) { + memset(wmxsdk, 0, sizeof(*wmxsdk)); + + wmxsdk->refcount = 1; + g_static_mutex_init(&wmxsdk->network_mutex); + + wmxsdk->status = WIMAX_API_DEVICE_STATUS_UnInitialized; + wmxsdk->status_mutex = g_mutex_new(); + g_assert(wmxsdk->status_mutex); + + wmxsdk->connect_mutex = g_mutex_new(); + g_assert(wmxsdk->connect_mutex); + } + return wmxsdk; +} + +struct wmxsdk *wmxsdk_ref(struct wmxsdk *wmxsdk) +{ + g_atomic_int_add(&wmxsdk->refcount, 1); + return wmxsdk; +} + +void wmxsdk_unref(struct wmxsdk *wmxsdk) +{ + if (g_atomic_int_dec_and_test(&wmxsdk->refcount)) { + g_mutex_free(wmxsdk->status_mutex); + g_mutex_free(wmxsdk->connect_mutex); + memset(wmxsdk, 0, sizeof(*wmxsdk)); + free(wmxsdk); + } +} + +static void iwmx_sdk_dev_add(unsigned idx, unsigned api_idx, const char *name) +{ + int ifindex; + struct wmxsdk *wmxsdk; + const char *s; + + if (idx >= IWMX_SDK_DEV_MAX) { + nm_log_err(LOGD_WIMAX, "BUG! idx (%u) >= IWMX_SDK_DEV_MAX (%u)", idx, IWMX_SDK_DEV_MAX); + goto error_bug; + } + if (g_iwmx_sdk_devs[idx] != NULL) { + nm_log_err(LOGD_WIMAX, "BUG! device index %u already enumerated?", idx); + goto error_bug; + } + + wmxsdk = wmxsdk_new(); + if (wmxsdk == NULL) { + nm_log_err(LOGD_WIMAX, "Can't allocate %zu bytes", sizeof(*wmxsdk)); + goto error_bug; + } + + /* + * This depends on a hack in the WiMAX Network Service; it has + * to return, as part of the device name, a string "if:IFNAME" + * where the OS's device name is stored. + */ + s = strstr(name, "if:"); + if (s == NULL + || sscanf(s, "if:%15[^ \f\n\r\t\v]", wmxsdk->ifname) != 1) { + nm_log_err(LOGD_WIMAX, "Cannot extract network interface name off '%s'", + name); + goto error_noifname; + } + nm_log_dbg(LOGD_WIMAX, "network interface name: '%s'", wmxsdk->ifname); + + ifindex = if_nametoindex(wmxsdk->ifname); + if (ifindex <= 0) { + nm_log_err(LOGD_WIMAX, "wxmsdk: %s: cannot find interface index", wmxsdk->ifname); + goto error_noifname; + } + + strncpy(wmxsdk->name, name, sizeof(wmxsdk->name)); + wmxsdk->device_id.privilege = WIMAX_API_PRIVILEGE_READ_WRITE; + wmxsdk->device_id.deviceIndex = api_idx; + + if (iwmx_sdk_setup(wmxsdk) != 0) { + nm_log_err(LOGD_WIMAX, "wxmsdk: %s: cannot set up interface", wmxsdk->ifname); + goto error_setup; + } + + g_iwmx_sdk_devs[idx] = wmxsdk; + return; + +error_setup: +error_noifname: + wmxsdk_unref(wmxsdk); +error_bug: + return; +} + +static void iwmx_sdk_dev_rm(unsigned idx) +{ + struct wmxsdk *wmxsdk; + + if (idx >= IWMX_SDK_DEV_MAX) { + nm_log_err(LOGD_WIMAX, "BUG! idx (%u) >= IWMX_SDK_DEV_MAX (%u)", idx, IWMX_SDK_DEV_MAX); + return; + } + + wmxsdk = g_iwmx_sdk_devs[idx]; + _schedule_removed(wmxsdk); + iwmx_sdk_remove(wmxsdk); + wmxsdk_unref(wmxsdk); + g_iwmx_sdk_devs[idx] = NULL; +} + +static void iwmx_sdk_addremove_cb(WIMAX_API_DEVICE_ID *devid, + BOOL presence) +{ + unsigned int cnt; + WIMAX_API_RET r; + WIMAX_API_HW_DEVICE_ID device_id_list[5]; + UINT32 device_id_list_size = ARRAY_SIZE(device_id_list); + + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + + nm_log_dbg(LOGD_WIMAX, "cb: handle %u index #%u is %d", devid->sdkHandle, + devid->deviceIndex, presence); + + r = GetListDevice(devid, device_id_list, &device_id_list_size); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(devid, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot obtain list of devices: %d (%s)", r, errstr); + return; + } + + if (device_id_list_size == 0) { + nm_log_dbg(LOGD_WIMAX, "No WiMAX devices reported"); + } else + for (cnt = 0; cnt < device_id_list_size; cnt++) { + WIMAX_API_HW_DEVICE_ID *dev = + device_id_list + cnt; + nm_log_dbg(LOGD_WIMAX, "#%u index #%u device %s", cnt, + dev->deviceIndex, dev->deviceName); + } + if (device_id_list_size < devid->deviceIndex) { + nm_log_err(LOGD_WIMAX, "wmxsdk: changed device (%u) not in the list? (%u items)", + devid->deviceIndex, device_id_list_size); + return; + } + + if (presence) { + WIMAX_API_HW_DEVICE_ID *dev = + device_id_list + devid->deviceIndex; + iwmx_sdk_dev_add(devid->deviceIndex, dev->deviceIndex, + dev->deviceName); + } else { + iwmx_sdk_dev_rm(devid->deviceIndex); + } +} + +/* + * Initialize the WiMAX API, register with it, setup callbacks for + * device coming up / dissapearing + */ +int iwmx_sdk_api_init(void) +{ + int result; + unsigned int cnt; + WIMAX_API_RET r; + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + + WIMAX_API_HW_DEVICE_ID device_id_list[5]; + UINT32 device_id_list_size = ARRAY_SIZE(device_id_list); + + memset(&g_api, 0, sizeof(g_api)); + g_api.privilege = WIMAX_API_PRIVILEGE_READ_WRITE; + + result = -EIO; + r = WiMaxAPIOpen(&g_api); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&g_api, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: WiMaxAPIOpen failed with %d (%s)", r, errstr); + goto error_wimaxapiopen; + } + + r = SubscribeDeviceInsertRemove(&g_api, iwmx_sdk_addremove_cb); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&g_api, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: insert/remove subscribe failed with %d (%s)", r, errstr); + goto error_close; + } + + r = GetListDevice(&g_api, device_id_list, &device_id_list_size); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&g_api, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot obtain list of devices: %d (%s)", r, errstr); + goto error_close; + } + if (device_id_list_size < g_api.deviceIndex) { + nm_log_err(LOGD_WIMAX, "wmxsdk: changed device (%u) not in the list? (%u items)", + g_api.deviceIndex, device_id_list_size); + } + + if (device_id_list_size == 0) { + nm_log_dbg(LOGD_WIMAX, "No WiMAX devices reported"); + } else { + for (cnt = 0; cnt < device_id_list_size; cnt++) { + WIMAX_API_HW_DEVICE_ID *dev = device_id_list + cnt; + nm_log_dbg(LOGD_WIMAX, "#%u index #%u device %s", cnt, dev->deviceIndex, dev->deviceName); + iwmx_sdk_dev_add(cnt, dev->deviceIndex, dev->deviceName); + } + } + return 0; + +error_close: + WiMaxAPIClose(&g_api); +error_wimaxapiopen: + return result; +} + +void iwmx_sdk_api_exit(void) +{ + WIMAX_API_RET r; + + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + + r = WiMaxAPIClose(&g_api); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&g_api, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: WiMaxAPIClose failed with %d (%s)", r, errstr); + } + return; +} diff --git a/src/wimax/iwmxsdk.h b/src/wimax/iwmxsdk.h new file mode 100644 index 0000000000..e065b0a83d --- /dev/null +++ b/src/wimax/iwmxsdk.h @@ -0,0 +1,98 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * + * Copyright (C) 2011 Red Hat, Inc. All rights reserved. + * Copyright (C) 2007-2010 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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 St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef IWMXSDK_H +#define IWMXSDK_H + +#include +#include + +struct wmxsdk; + +typedef void (*WimaxNewWmxsdkFunc) (struct wmxsdk *wmxsdk, void *user_data); + +typedef void (*WimaxStateChangeFunc) (struct wmxsdk *wmxsdk, + WIMAX_API_DEVICE_STATUS new_status, + WIMAX_API_DEVICE_STATUS old_status, + WIMAX_API_STATUS_REASON reason, + void *user_data); + +typedef void (*WimaxConnectResultFunc) (struct wmxsdk *wmxsdk, + WIMAX_API_NETWORK_CONNECTION_RESP resp, + void *user_data); + +typedef void (*WimaxScanResultFunc) (struct wmxsdk *wmxsdk, + WIMAX_API_NSP_INFO_EX *nsps, + guint num_nsps, + void *user_data); + +typedef void (*WimaxRemovedFunc) (struct wmxsdk *wmxsdk, void *user_data); + +struct wmxsdk { + gint refcount; + + WIMAX_API_DEVICE_ID device_id; + + WimaxStateChangeFunc state_change_cb; + WimaxConnectResultFunc connect_result_cb; + WimaxScanResultFunc scan_result_cb; + WimaxRemovedFunc removed_cb; + void *callback_data; + + GStaticMutex network_mutex; + + WIMAX_API_DEVICE_STATUS status; + GMutex *status_mutex; + + GMutex *connect_mutex; + + char name[100]; + char ifname[16]; +}; + +struct wmxsdk *iwmx_sdk_get_wmxsdk_for_iface(const char *iface); + +struct wmxsdk *wmxsdk_ref(struct wmxsdk *wmxsdk); +void wmxsdk_unref(struct wmxsdk *wmxsdk); + +/* Register/unregister callbacks when a new wmxsdk is set up */ +void iwmx_sdk_new_callback_register(WimaxNewWmxsdkFunc callback, void *user_data); +void iwmx_sdk_new_callback_unregister(WimaxNewWmxsdkFunc callback, void *user_data); + +void iwmx_sdk_set_callbacks(struct wmxsdk *wmxsdk, + WimaxStateChangeFunc state_change_cb, + WimaxConnectResultFunc connect_result_cb, + WimaxScanResultFunc scan_result_cb, + WimaxRemovedFunc removed_cb, + void *user_data); + +WIMAX_API_DEVICE_STATUS iwmxsdk_status_get(struct wmxsdk *wmxsdk); +int iwmx_sdk_connect(struct wmxsdk *wmxsdk, const char *nsp_name); +int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk); +WIMAX_API_CONNECTED_NSP_INFO_EX *iwmx_sdk_get_connected_network(struct wmxsdk *wmxsdk); +const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status); +const char *iwmx_sdk_reason_to_str(WIMAX_API_STATUS_REASON reason); +int iwmx_sdk_rf_state_set(struct wmxsdk *wmxsdk, WIMAX_API_RF_STATE rf_state); +int iwmx_sdk_get_networks(struct wmxsdk *wmxsdk); +int iwmx_sdk_api_init(void); +void iwmx_sdk_api_exit(void); + +#endif /* IWMXSDK_H */ diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c new file mode 100644 index 0000000000..ed3120315d --- /dev/null +++ b/src/wimax/nm-device-wimax.c @@ -0,0 +1,1071 @@ +/* -*- 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) 2010 Red Hat, Inc. + * Copyright (C) 2009 Novell, Inc. + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "nm-device-wimax.h" +#include "nm-wimax-util.h" +#include "nm-logging.h" +#include "nm-device-interface.h" +#include "nm-device-private.h" +#include "nm-system.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" +#include "nm-rfkill.h" +#include "iwmxsdk.h" + +static gboolean impl_device_get_nsp_list (NMDeviceWimax *device, GPtrArray **list, GError **error); + +#include "nm-device-wimax-glue.h" + +static void device_interface_init (NMDeviceInterface *iface_class); + +G_DEFINE_TYPE_EXTENDED (NMDeviceWimax, nm_device_wimax, NM_TYPE_DEVICE, 0, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init)) + +enum { + PROP_0, + PROP_HW_ADDRESS, + PROP_ACTIVE_NSP, + + LAST_PROP +}; + +enum { + NSP_ADDED, + NSP_REMOVED, + PROPERTIES_CHANGED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +#define NM_DEVICE_WIMAX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_DEVICE_WIMAX, \ + NMDeviceWimaxPrivate)) + +typedef struct { + gboolean disposed; + + struct wmxsdk *sdk; + WIMAX_API_DEVICE_STATUS status; + gboolean connect_failed; + + gboolean enabled; + gboolean wimaxd_enabled; + struct ether_addr hw_addr; + guint activation_timeout_id; + + guint sdk_action_defer_id; + + GSList *nsp_list; + NMWimaxNsp *current_nsp; +} NMDeviceWimaxPrivate; + +/***********************************************************/ + +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; +} + +/***********************************************************/ + +void +nm_device_wimax_get_hw_address (NMDeviceWimax *self, struct ether_addr *addr) +{ + NMDeviceWimaxPrivate *priv; + + g_return_if_fail (NM_IS_DEVICE_WIMAX (self)); + g_return_if_fail (addr != NULL); + + priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + memcpy (addr, &(priv->hw_addr), sizeof (struct ether_addr)); +} + +static gboolean +impl_device_get_nsp_list (NMDeviceWimax *self, GPtrArray **nsps, GError **error) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + GSList *iter; + + *nsps = g_ptr_array_sized_new (g_slist_length (priv->nsp_list)); + for (iter = priv->nsp_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 (NMDeviceWimax *self, NMWimaxNsp *new_nsp) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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_DEVICE_WIMAX_ACTIVE_NSP); + + g_free (old_path); +} + +NMWimaxNsp * +nm_device_wimax_get_active_nsp (NMDeviceWimax *self) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), NULL); + + return NM_DEVICE_WIMAX_GET_PRIVATE (self)->current_nsp; +} + +static gboolean +activation_timed_out (gpointer data) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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 +remove_all_nsps (NMDeviceWimax *self) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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 NMWimaxNsp * +get_nsp_by_name (NMDeviceWimax *self, const char *name) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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 gboolean +update_availability (NMDeviceWimax *self, gboolean old_available) +{ + NMDevice *device = NM_DEVICE (self); + NMDeviceState state; + gboolean new_available, changed = FALSE; + + new_available = nm_device_is_available (device); +nm_log_dbg (LOGD_WIMAX, "old_avail %d, new_avail %d", old_available, new_available); + if (new_available == old_available) + return FALSE; + + state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + if (state == NM_DEVICE_STATE_UNAVAILABLE) { + if (new_available == TRUE) { + nm_device_state_changed (device, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_REASON_NONE); + changed = TRUE; + } + } else if (state >= NM_DEVICE_STATE_DISCONNECTED) { + if (new_available == FALSE) { + nm_device_state_changed (device, + NM_DEVICE_STATE_UNAVAILABLE, + NM_DEVICE_STATE_REASON_NONE); + changed = TRUE; + } + } + + return changed; +} + +/* NMDeviceInterface interface */ + +static void +real_set_enabled (NMDeviceInterface *device, gboolean enabled) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (device); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + gboolean old_available; + int ret; + +nm_log_dbg (LOGD_WIMAX, "setting wimax enabled %d (was %d)", enabled, priv->enabled); + if (priv->enabled == enabled) + return; + + old_available = nm_device_is_available (NM_DEVICE (device)); + priv->enabled = enabled; +nm_log_dbg (LOGD_WIMAX, "wimax enabled changed to %d", priv->enabled); + + /* Set the WiMAX device RF state to the current user-specified enabled state */ + if (priv->sdk) { + ret = iwmx_sdk_rf_state_set (priv->sdk, + enabled ? WIMAX_API_RF_ON : WIMAX_API_RF_OFF); + if (ret != -EINPROGRESS) { + nm_log_warn (LOGD_WIMAX, "failed to %s WiMAX radio", + priv->enabled ? "enable" : "disable"); + } + } + + update_availability (self, old_available); +} + +/* NMDevice methods */ + +static void +real_take_down (NMDevice *device) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (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) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (dev); + + if (!priv->enabled || !priv->wimaxd_enabled) + return FALSE; + + 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 *dev) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (dev); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + struct ifreq req; + int fd; + + fd = socket (PF_INET, SOCK_DGRAM, 0); + if (fd < 0) { + nm_log_warn (LOGD_HW, "couldn't open control socket."); + return; + } + + memset (&req, 0, sizeof (struct ifreq)); + strncpy (req.ifr_name, nm_device_get_iface (dev), IFNAMSIZ); + + errno = 0; + if (ioctl (fd, SIOCGIFHWADDR, &req) < 0) { + nm_log_err (LOGD_HW | LOGD_WIMAX, + "(%s) failed to read hardware address (error %d)", + nm_device_get_iface (dev), errno); + } else { + memcpy (&priv->hw_addr, &req.ifr_hwaddr.sa_data, ETH_ALEN); + g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_HW_ADDRESS); + } + + close (fd); +} + +static gboolean +real_check_connection_compatible (NMDevice *device, + NMConnection *connection, + GError **error) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); + const char *iface = nm_device_get_iface (device); + + if (!priv->enabled) { + nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled", iface); + return FALSE; + } + + if (!priv->wimaxd_enabled) { + nm_log_dbg (LOGD_WIMAX, "(%s): not available because not enabled in wimaxd", iface); + return FALSE; + } + + if (!nm_wimax_util_sdk_is_initialized ()) { + nm_log_dbg (LOGD_WIMAX, "(%s): not available because WiMAX SDK not initialized", iface); + return FALSE; + } + + if (!priv->sdk) { + nm_log_dbg (LOGD_WIMAX, "(%s): not available because not known to WiMAX SDK", iface); + return FALSE; + } + + return iwmxsdk_status_get (priv->sdk) >= WIMAX_API_DEVICE_STATUS_Ready; +} + +static void +clear_activation_timeout (NMDeviceWimax *self) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (priv->activation_timeout_id) { + g_source_remove (priv->activation_timeout_id); + priv->activation_timeout_id = 0; + } + + priv->connect_failed = FALSE; +} + +static NMActStageReturn +real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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_DEVICE_WIMAX (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) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); + NMConnection *connection; + NMSettingWimax *s_wimax; + const char *nsp; + int ret; + + 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); + + nsp = nm_setting_wimax_get_network_name (s_wimax); + g_assert (nsp); + + priv->connect_failed = FALSE; + ret = iwmx_sdk_connect (priv->sdk, nsp); + if (ret != 0) { + nm_log_err (LOGD_WIMAX, "Failed to connect to NSP '%s'", nsp); + *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) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); + WIMAX_API_DEVICE_STATUS status; + int ret; + + clear_activation_timeout (NM_DEVICE_WIMAX (device)); + + set_current_nsp (NM_DEVICE_WIMAX (device), NULL); + + if (priv->sdk) { + /* Read explicit status here just to make sure we have the most + * up-to-date status and to ensure we disconnect if needed. + */ + status = iwmxsdk_status_get (priv->sdk); + if ((int) status < 0) { + nm_log_err (LOGD_WIMAX, "Failed to read WiMAX device status: %d", status); + } else { + if ( status == WIMAX_API_DEVICE_STATUS_Connecting + || status == WIMAX_API_DEVICE_STATUS_Data_Connected) { + ret = iwmx_sdk_disconnect (priv->sdk); + if (ret < 0) { + nm_log_err (LOGD_WIMAX, "Failed to disconnect WiMAX device: %d", ret); + } + } + } + } +} + +/*************************************************************************/ + +static void +wmx_state_change_cb (struct wmxsdk *wmxsdk, + WIMAX_API_DEVICE_STATUS new_status, + WIMAX_API_DEVICE_STATUS old_status, + WIMAX_API_STATUS_REASON reason, + void *user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + NMDeviceState state; + const char *iface; + gboolean old_available = FALSE; + const char *nsp_name = NULL; + + iface = nm_device_get_iface (NM_DEVICE (self)); + state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + old_available = nm_device_is_available (NM_DEVICE (self)); + + priv->status = new_status; + if (priv->current_nsp) + nsp_name = nm_wimax_nsp_get_name (priv->current_nsp); + + nm_log_dbg (LOGD_WIMAX, "(%s): wimax state change %s -> %s (reason %d)", + iface, + iwmx_sdk_dev_status_to_str (old_status), + iwmx_sdk_dev_status_to_str (new_status), + reason); + + switch (new_status) { + case WIMAX_API_DEVICE_STATUS_UnInitialized: + case WIMAX_API_DEVICE_STATUS_RF_OFF_HW_SW: + case WIMAX_API_DEVICE_STATUS_RF_OFF_HW: + case WIMAX_API_DEVICE_STATUS_RF_OFF_SW: + if (priv->wimaxd_enabled) { + priv->wimaxd_enabled = FALSE; + if (update_availability (self, old_available)) + return; + } + 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: + if (priv->wimaxd_enabled == FALSE) { + priv->wimaxd_enabled = TRUE; + if (update_availability (self, old_available)) + return; + } + break; + default: + nm_log_warn (LOGD_WIMAX, "(%s): unhandled WiMAX device state %d", + iface, new_status); + break; + } + + /* Handle activation success and failure */ + if (IS_ACTIVATING_STATE (state)) { + if (new_status == WIMAX_API_DEVICE_STATUS_Data_Connected) { + /* Success */ + clear_activation_timeout (self); + + nm_log_info (LOGD_WIMAX, "(%s): connected to '%s'", + iface, nsp_name); + nm_device_activate_schedule_stage3_ip_config_start (NM_DEVICE (self)); + return; + } + + if (priv->connect_failed || new_status < WIMAX_API_DEVICE_STATUS_Connecting) { + /* Connection attempt failed */ + nm_log_info (LOGD_WIMAX, "(%s): connection to '%s' failed: (%d) %s", + iface, nsp_name, reason, iwmx_sdk_reason_to_str (reason)); + nm_device_state_changed (NM_DEVICE (self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_CONFIG_FAILED); + return; + } + } + + /* Handle disconnection */ + if ( old_status == WIMAX_API_DEVICE_STATUS_Data_Connected + && new_status < WIMAX_API_DEVICE_STATUS_Connecting) { + + nm_log_info (LOGD_WIMAX, "(%s): disconnected from '%s': (%d) %s", + iface, nsp_name, reason, iwmx_sdk_reason_to_str (reason)); + + nm_device_state_changed (NM_DEVICE (self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_CONFIG_FAILED); + } +} + +static void +wmx_connect_result_cb (struct wmxsdk *wmxsdk, + WIMAX_API_NETWORK_CONNECTION_RESP result, + void *user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + NMDeviceState state; + + state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + if (IS_ACTIVATING_STATE (state)) { + priv->connect_failed = (result == WIMAX_API_CONNECTION_SUCCESS); + /* Wait for the state change so we can get the reason code; we + * cache the connect failure so we don't have to wait for the + * activation timeout. + */ + } +} + +static void +remove_outdated_nsps (NMDeviceWimax *self, + WIMAX_API_NSP_INFO_EX *nsp_list, + guint32 list_size) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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); + gboolean found = FALSE; + int i; + + for (i = 0; i < list_size; i++) { + 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 void +wmx_scan_result_cb (struct wmxsdk *wmxsdk, + WIMAX_API_NSP_INFO_EX *nsps, + guint num_nsps, + void *user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + const char *iface = nm_device_get_iface (NM_DEVICE (self)); + int i; + + remove_outdated_nsps (self, nsps, num_nsps); + + /* Add new NSPs and update existing ones */ + for (i = 0; i < num_nsps; i++) { + WIMAX_API_NSP_INFO_EX *sdk_nsp = &nsps[i]; + const char *nsp_name = (const char *) sdk_nsp->NSPName; + NMWimaxNspNetworkType net_type; + NMWimaxNsp *nsp; + gboolean new_nsp; + + nsp = get_nsp_by_name (self, nsp_name); + new_nsp = (nsp == NULL); + if (new_nsp) { + nsp = nm_wimax_nsp_new (nsp_name); + nm_log_dbg (LOGD_WIMAX, "(%s): new WiMAX NSP '%s'", iface, nsp_name); + } + + net_type = nm_wimax_util_convert_network_type (sdk_nsp->networkType); + g_object_set (nsp, + NM_WIMAX_NSP_SIGNAL_QUALITY, sdk_nsp->linkQuality, + NM_WIMAX_NSP_NETWORK_TYPE, net_type, + NULL); + + nm_log_dbg (LOGD_WIMAX, "(%s): WiMAX NSP '%s' quality %d%% type %d", + iface, nsp_name, sdk_nsp->linkQuality, net_type); + + 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 +wmx_removed_cb (struct wmxsdk *wmxsdk, void *user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (priv->sdk) { + /* Clear callbacks just in case we don't hold the last reference */ + iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL); + + wmxsdk_unref (priv->sdk); + priv->sdk = NULL; + + priv->status = WIMAX_API_DEVICE_STATUS_UnInitialized; + nm_device_state_changed (NM_DEVICE (self), + NM_DEVICE_STATE_UNAVAILABLE, + NM_DEVICE_STATE_REASON_NONE); + } +} + +/*************************************************************************/ + +static void +device_state_changed (NMDevice *device, + NMDeviceState new_state, + NMDeviceState old_state, + NMDeviceStateReason reason, + gpointer user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (device); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (new_state < NM_DEVICE_STATE_DISCONNECTED) + remove_all_nsps (self); + + if ( new_state == NM_DEVICE_STATE_DISCONNECTED + && old_state < NM_DEVICE_STATE_DISCONNECTED) { + if (priv->sdk) + iwmx_sdk_get_networks (priv->sdk); + } + + if (new_state == NM_DEVICE_STATE_FAILED || new_state <= NM_DEVICE_STATE_DISCONNECTED) + clear_activation_timeout (self); +} + +/*************************************************************************/ + +static gboolean +sdk_action_defer_cb (gpointer user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + + NM_DEVICE_WIMAX_GET_PRIVATE (self)->sdk_action_defer_id = 0; + update_availability (self, FALSE); + return FALSE; +} + +static void +wmx_new_sdk_cb (struct wmxsdk *sdk, void *user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + /* If we now have the SDK, schedule an idle handler to start the device up */ + if (!priv->sdk) { + priv->sdk = wmxsdk_ref (sdk); + iwmx_sdk_set_callbacks(priv->sdk, + wmx_state_change_cb, + wmx_connect_result_cb, + wmx_scan_result_cb, + wmx_removed_cb, + self); + + if (!priv->sdk_action_defer_id) + priv->sdk_action_defer_id = g_idle_add (sdk_action_defer_cb, self); + } +} + +/*************************************************************************/ + +NMDevice * +nm_device_wimax_new (const char *udi, + const char *iface, + const char *driver) +{ + NMDevice *device; + + g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (driver != NULL, NULL); + + device = (NMDevice *) g_object_new (NM_TYPE_DEVICE_WIMAX, + 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_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WIMAX, + NULL); + if (device) { + struct wmxsdk *sdk; + + nm_wimax_util_sdk_ref (); + g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), NULL); + + /* See if the SDK already knows about this interface */ + sdk = iwmx_sdk_get_wmxsdk_for_iface (iface); + if (sdk) + wmx_new_sdk_cb (sdk, device); + + /* If it doesn't, we want to be notified when it does */ + iwmx_sdk_new_callback_register (wmx_new_sdk_cb, device); + } + + return device; +} + +static void +device_interface_init (NMDeviceInterface *iface_class) +{ + iface_class->set_enabled = real_set_enabled; +} + +static void +nm_device_wimax_init (NMDeviceWimax *self) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + priv->status = WIMAX_API_DEVICE_STATUS_UnInitialized; +} + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + switch (prop_id) { + 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) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (object); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + struct ether_addr hw_addr; + + switch (prop_id) { + case PROP_HW_ADDRESS: + nm_device_wimax_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 +dispose (GObject *object) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (object); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (priv->disposed) + goto done; + + priv->disposed = TRUE; + + clear_activation_timeout (self); + + if (priv->sdk_action_defer_id) + g_source_remove (priv->sdk_action_defer_id); + + if (priv->sdk) { + iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL); + wmxsdk_unref (priv->sdk); + } + + set_current_nsp (self, NULL); + + g_slist_foreach (priv->nsp_list, (GFunc) g_object_unref, NULL); + g_slist_free (priv->nsp_list); + + iwmx_sdk_new_callback_unregister (wmx_new_sdk_cb, self); + nm_wimax_util_sdk_unref (); + +done: + G_OBJECT_CLASS (nm_device_wimax_parent_class)->dispose (object); +} + +static void +nm_device_wimax_class_init (NMDeviceWimaxClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + NMDeviceClass *device_class = NM_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (NMDeviceWimaxPrivate)); + + /* Virtual methods */ + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->dispose = dispose; + + 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_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_WIMAX_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_DEVICE_WIMAX_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 (NMDeviceWimaxClass, 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 (NMDeviceWimaxClass, 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 (NMDeviceWimaxClass, properties_changed)); + + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_device_wimax_object_info); + + dbus_g_error_domain_register (NM_WIMAX_ERROR, NULL, NM_TYPE_WIMAX_ERROR); +} diff --git a/src/wimax/nm-device-wimax.h b/src/wimax/nm-device-wimax.h new file mode 100644 index 0000000000..9dbe149e22 --- /dev/null +++ b/src/wimax/nm-device-wimax.h @@ -0,0 +1,68 @@ +/* -*- 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) 2010 Red Hat, Inc. + * Copyright (C) 2009 Novell, Inc. + */ + +#ifndef NM_DEVICE_WIMAX_H +#define NM_DEVICE_WIMAX_H + +#include +#include +#include "nm-device.h" +#include "nm-wimax-nsp.h" + +G_BEGIN_DECLS + +#define NM_TYPE_DEVICE_WIMAX (nm_device_wimax_get_type ()) +#define NM_DEVICE_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimax)) +#define NM_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) +#define NM_IS_DEVICE_WIMAX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_WIMAX)) +#define NM_IS_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIMAX)) +#define NM_DEVICE_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) + +#define NM_DEVICE_WIMAX_HW_ADDRESS "hw-address" +#define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" + +typedef struct { + NMDevice parent; +} NMDeviceWimax; + +typedef struct { + NMDeviceClass parent; + + /* Signals */ + void (*nsp_added) (NMDeviceWimax *wimax, NMWimaxNsp *nsp); + void (*nsp_removed) (NMDeviceWimax *wimax, NMWimaxNsp *nsp); + void (*properties_changed) (NMDeviceWimax *wimax, GHashTable *properties); +} NMDeviceWimaxClass; + +GType nm_device_wimax_get_type (void); + +NMDevice *nm_device_wimax_new (const char *udi, + const char *iface, + const char *driver); + +void nm_device_wimax_get_hw_address (NMDeviceWimax *self, + struct ether_addr *addr); + +NMWimaxNsp *nm_device_wimax_get_active_nsp (NMDeviceWimax *self); + +G_END_DECLS + +#endif /* NM_DEVICE_WIMAX_H */ diff --git a/src/wimax/nm-wimax-device.c b/src/wimax/nm-wimax-device.c deleted file mode 100644 index a98bee7d40..0000000000 --- a/src/wimax/nm-wimax-device.c +++ /dev/null @@ -1,1037 +0,0 @@ -/* -*- 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 "nm-system.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" - -static void device_interface_init (NMDeviceInterface *iface_class); - -G_DEFINE_TYPE_EXTENDED (NMWimaxDevice, nm_wimax_device, NM_TYPE_DEVICE, 0, - G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, device_interface_init)) - -enum { - PROP_0, - PROP_INDEX, - 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 { - WIMAX_API_DEVICE_ID device_id; - NMWimaxDevice *object; - - gboolean enabled; - struct ether_addr hw_addr; - 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, - 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, - 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)); -} - -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: - 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_device_interface_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); -} - -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 (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: - 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, - 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++) { - 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 (WIMAX_API_DEVICE_ID *device_id, - 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++) { - 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 (WIMAX_API_DEVICE_ID *device_id, - 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 (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 (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; - } -} - -/* NMDeviceInterface interface */ - -static void -real_set_enabled (NMDeviceInterface *device, gboolean enabled) -{ - NMWimaxDevicePrivate *priv = GET_PRIVATE (device); - - if (priv->enabled == enabled) - return; - - priv->enabled = enabled; - schedule_rf_state_update (NM_WIMAX_DEVICE (device)); -} - -/* 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); - 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_WSTRING) 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) { - - 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 -device_interface_init (NMDeviceInterface *iface_class) -{ - iface_class->set_enabled = real_set_enabled; -} - -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; - 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_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 deleted file mode 100644 index f461dad73c..0000000000 --- a/src/wimax/nm-wimax-device.h +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- 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_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, - guchar wimax_device_index); - -void nm_wimax_device_get_hw_address (NMWimaxDevice *self, - struct ether_addr *addr); - -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 index e571f96d9d..c058ae9012 100644 --- a/src/wimax/nm-wimax-manager.c +++ b/src/wimax/nm-wimax-manager.c @@ -15,120 +15,81 @@ * 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. + * Copyright (C) 2009 - 2010 Red Hat, Inc. */ -#include -#include -#include - #include "nm-wimax-manager.h" -#include "nm-wimax-device.h" -#include "nm-wimax-util.h" +#include "nm-logging.h" +#include "iwmxsdk.h" + +G_DEFINE_TYPE (NMWimaxManager, nm_wimax_manager, G_TYPE_OBJECT) + +#define NM_WIMAX_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ + NM_TYPE_WIMAX_MANAGER, \ + NMWimaxManagerPrivate)) typedef struct { - WIMAX_API_DEVICE_ID device_id; - int refs; -} NMWimaxManager; + gboolean disposed; -static NMWimaxManager *global_wimax_manager = NULL; + gboolean sdk_initialized; +} NMWimaxManagerPrivate; -static NMWimaxManager * +/***************************************************/ + +/*************************************************************/ + +NMWimaxManager * nm_wimax_manager_get (void) { - WIMAX_API_RET result; + static NMWimaxManager *singleton = NULL; - if (!global_wimax_manager) { - global_wimax_manager = g_new (NMWimaxManager, 1); - global_wimax_manager->refs = 1; + if (!singleton) + singleton = NM_WIMAX_MANAGER (g_object_new (NM_TYPE_WIMAX_MANAGER, NULL)); + else + g_object_ref (singleton); - 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; + g_assert (singleton); + return singleton; } static void -nm_wimax_manager_unref (NMWimaxManager *manager) +nm_wimax_manager_init (NMWimaxManager *self) { - if (--manager->refs == 0) { - g_debug ("Closing WiMAX API"); - WiMaxAPIClose (&manager->device_id); - g_free (manager); - global_wimax_manager = NULL; + NMWimaxManagerPrivate *priv = NM_WIMAX_MANAGER_GET_PRIVATE (self); + int ret; + + ret = iwmx_sdk_api_init(); + if (ret != 0) { + nm_log_warn (LOGD_WIMAX, "Failed to initialize WiMAX: %d", ret); + return; } + + priv->sdk_initialized = TRUE; } -static gboolean -wimax_device_matches (WIMAX_API_HW_DEVICE_ID *hw_id, - const char *ifname) +static void +dispose (GObject *object) { - const char *device_name; - char *s; - char hw_ifname[16]; + NMWimaxManagerPrivate *priv = NM_WIMAX_MANAGER_GET_PRIVATE (object); - if (!hw_id) - return FALSE; + if (!priv->disposed) { + priv->disposed = TRUE; - device_name = (const char *) hw_id->deviceName; - if (!device_name) - return FALSE; + if (priv->sdk_initialized) + iwmx_sdk_api_exit (); + } - 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; - - return TRUE; + G_OBJECT_CLASS (nm_wimax_manager_parent_class)->dispose (object); } -NMDevice * -nm_wimax_manager_create_device (const char *path, - const char *ifname, - const char *driver) +static void +nm_wimax_manager_class_init (NMWimaxManagerClass *wimax_class) { - NMWimaxManager *manager; - WIMAX_API_HW_DEVICE_ID device_id_list[5]; - NMDevice *device = NULL; - guint32 device_id_list_size = 5; - WIMAX_API_RET result; + GObjectClass *object_class = G_OBJECT_CLASS (wimax_class); - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (ifname != NULL, NULL); - g_return_val_if_fail (driver != NULL, NULL); + g_type_class_add_private (wimax_class, sizeof (NMWimaxManagerPrivate)); - 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)) { - device = nm_wimax_device_new (path, ifname, driver, 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; + /* virtual methods */ + object_class->dispose = dispose; } + diff --git a/src/wimax/nm-wimax-manager.h b/src/wimax/nm-wimax-manager.h index c3b2881ce5..6277370bf7 100644 --- a/src/wimax/nm-wimax-manager.h +++ b/src/wimax/nm-wimax-manager.h @@ -15,16 +15,36 @@ * 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. + * Copyright (C) 2009 - 2010 Red Hat, Inc. */ #ifndef NM_WIMAX_MANAGER_H #define NM_WIMAX_MANAGER_H -#include "nm-device.h" +#include +#include -NMDevice *nm_wimax_manager_create_device (const char *path, - const char *ifname, - const char *driver); +#define NM_TYPE_WIMAX_MANAGER (nm_wimax_manager_get_type ()) +#define NM_WIMAX_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIMAX_MANAGER, NMWimaxManager)) +#define NM_WIMAX_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIMAX_MANAGER, NMWimaxManagerClass)) +#define NM_IS_WIMAX_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIMAX_MANAGER)) +#define NM_IS_WIMAX_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_WIMAX_MANAGER)) +#define NM_WIMAX_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIMAX_MANAGER, NMWimaxManagerClass)) + +#define NM_WIMAX_MANAGER_DEVICE_ADDED "device-added" +#define NM_WIMAX_MANAGER_DEVICE_REMOVED "device-removed" + +typedef struct { + GObject parent; +} NMWimaxManager; + +typedef struct { + GObjectClass parent; +} NMWimaxManagerClass; + +GType nm_wimax_manager_get_type (void); + +NMWimaxManager *nm_wimax_manager_get (void); #endif /* NM_WIMAX_MANAGER_H */ + diff --git a/src/wimax/nm-wimax-util.c b/src/wimax/nm-wimax-util.c index fcb11f1dc8..bca25a1dbf 100644 --- a/src/wimax/nm-wimax-util.c +++ b/src/wimax/nm-wimax-util.c @@ -21,21 +21,41 @@ #include #include "nm-wimax-util.h" #include "nm-utils.h" +#include "iwmxsdk.h" +#include "nm-logging.h" + +static guint sdk_refcount = 0; void -nm_wimax_util_error (WIMAX_API_DEVICE_ID *device_id, - const char *message, - WIMAX_API_RET result) +nm_wimax_util_sdk_ref (void) { - char *warning_msg; - char str[MAX_SIZE_OF_STRING_BUFFER]; - guint32 str_len = MAX_SIZE_OF_STRING_BUFFER; + int ret = 0; - 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); -} + if (sdk_refcount == 0) { + ret = iwmx_sdk_api_init (); + if (ret != 0) { + nm_log_warn (LOGD_WIMAX, "Failed to initialize WiMAX: %d", ret); + return; + } + } + sdk_refcount++; +} + +gboolean +nm_wimax_util_sdk_is_initialized (void) +{ + return sdk_refcount > 0; +} + +void +nm_wimax_util_sdk_unref (void) +{ + g_return_if_fail (sdk_refcount > 0); + + sdk_refcount--; + if (sdk_refcount == 0) + iwmx_sdk_api_exit (); +} NMWimaxNspNetworkType nm_wimax_util_convert_network_type (WIMAX_API_NETWORK_TYPE wimax_network_type) @@ -60,56 +80,3 @@ nm_wimax_util_convert_network_type (WIMAX_API_NETWORK_TYPE wimax_network_type) 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"; - } - - return "Unknown device state"; -} diff --git a/src/wimax/nm-wimax-util.h b/src/wimax/nm-wimax-util.h index 30c5bb68e6..71f5aa29d2 100644 --- a/src/wimax/nm-wimax-util.h +++ b/src/wimax/nm-wimax-util.h @@ -21,17 +21,18 @@ #ifndef NM_WIMAX_UTIL_H #define NM_WIMAX_UTIL_H +#include + #include #include #include "nm-wimax-types.h" -void nm_wimax_util_error (WIMAX_API_DEVICE_ID *device_id, - const char *message, - WIMAX_API_RET result); +void nm_wimax_util_sdk_ref (void); + +gboolean nm_wimax_util_sdk_is_initialized (void); + +void nm_wimax_util_sdk_unref (void); 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 54b7fcbbe9..e161bc7664 100644 --- a/test/nm-tool.c +++ b/test/nm-tool.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include @@ -199,13 +199,13 @@ wimax_network_type_to_str (NMWimaxNspNetworkType type) { switch (type) { case NM_WIMAX_NSP_NETWORK_TYPE_HOME: - return "Home network"; + return "Home"; case NM_WIMAX_NSP_NETWORK_TYPE_PARTNER: - return "Partner network"; + return "Partner"; case NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER: - return "Roaming partner network"; + return "Roaming"; default: - return "Unknown network"; + return "Unknown"; } } @@ -225,11 +225,11 @@ detail_nsp (gpointer data, gpointer user_data) 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)); + data_str = g_strdup_printf ("%d%% (%s)", + nm_wimax_nsp_get_signal_quality (nsp), + wimax_network_type_to_str (nm_wimax_nsp_get_network_type (nsp))); - print_string (label, data); + print_string (label, data_str); g_free (label); g_free (data_str); } @@ -379,7 +379,7 @@ 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)) + else if (NM_IS_DEVICE_WIMAX (device)) print_string ("Type", "WiMAX"); print_string ("Driver", nm_device_get_driver (device) ? nm_device_get_driver (device) : "(unknown)"); @@ -396,8 +396,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))); + else if (NM_IS_DEVICE_WIMAX (device)) + tmp = g_strdup (nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device))); if (tmp) { print_string ("HW Address", tmp); @@ -463,19 +463,19 @@ detail_device (gpointer data, gpointer user_data) print_string (" Carrier", "on"); else print_string (" Carrier", "off"); - } else if (NM_IS_WIMAX_DEVICE (device)) { + } else if (NM_IS_DEVICE_WIMAX (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_nsp = nm_device_wimax_get_active_nsp (NM_DEVICE_WIMAX (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)); + nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (device)); if (nsps && nsps->len) g_ptr_array_foreach ((GPtrArray *) nsps, detail_nsp, (gpointer) active_name); } From a6697a16d34e5d38d61cdb199b52bc8ab000bdc4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 09:12:12 -0600 Subject: [PATCH 063/102] wimax: remove files forgotten in last commit The nm-wimax-manager stuff is no longer needed. --- src/wimax/nm-wimax-manager.c | 95 ------------------------------------ src/wimax/nm-wimax-manager.h | 50 ------------------- 2 files changed, 145 deletions(-) delete mode 100644 src/wimax/nm-wimax-manager.c delete mode 100644 src/wimax/nm-wimax-manager.h diff --git a/src/wimax/nm-wimax-manager.c b/src/wimax/nm-wimax-manager.c deleted file mode 100644 index c058ae9012..0000000000 --- a/src/wimax/nm-wimax-manager.c +++ /dev/null @@ -1,95 +0,0 @@ -/* -*- 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 - 2010 Red Hat, Inc. - */ - -#include "nm-wimax-manager.h" -#include "nm-logging.h" -#include "iwmxsdk.h" - -G_DEFINE_TYPE (NMWimaxManager, nm_wimax_manager, G_TYPE_OBJECT) - -#define NM_WIMAX_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ - NM_TYPE_WIMAX_MANAGER, \ - NMWimaxManagerPrivate)) - -typedef struct { - gboolean disposed; - - gboolean sdk_initialized; -} NMWimaxManagerPrivate; - -/***************************************************/ - -/*************************************************************/ - -NMWimaxManager * -nm_wimax_manager_get (void) -{ - static NMWimaxManager *singleton = NULL; - - if (!singleton) - singleton = NM_WIMAX_MANAGER (g_object_new (NM_TYPE_WIMAX_MANAGER, NULL)); - else - g_object_ref (singleton); - - g_assert (singleton); - return singleton; -} - -static void -nm_wimax_manager_init (NMWimaxManager *self) -{ - NMWimaxManagerPrivate *priv = NM_WIMAX_MANAGER_GET_PRIVATE (self); - int ret; - - ret = iwmx_sdk_api_init(); - if (ret != 0) { - nm_log_warn (LOGD_WIMAX, "Failed to initialize WiMAX: %d", ret); - return; - } - - priv->sdk_initialized = TRUE; -} - -static void -dispose (GObject *object) -{ - NMWimaxManagerPrivate *priv = NM_WIMAX_MANAGER_GET_PRIVATE (object); - - if (!priv->disposed) { - priv->disposed = TRUE; - - if (priv->sdk_initialized) - iwmx_sdk_api_exit (); - } - - G_OBJECT_CLASS (nm_wimax_manager_parent_class)->dispose (object); -} - -static void -nm_wimax_manager_class_init (NMWimaxManagerClass *wimax_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (wimax_class); - - g_type_class_add_private (wimax_class, sizeof (NMWimaxManagerPrivate)); - - /* virtual methods */ - object_class->dispose = dispose; -} - diff --git a/src/wimax/nm-wimax-manager.h b/src/wimax/nm-wimax-manager.h deleted file mode 100644 index 6277370bf7..0000000000 --- a/src/wimax/nm-wimax-manager.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- 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 - 2010 Red Hat, Inc. - */ - -#ifndef NM_WIMAX_MANAGER_H -#define NM_WIMAX_MANAGER_H - -#include -#include - -#define NM_TYPE_WIMAX_MANAGER (nm_wimax_manager_get_type ()) -#define NM_WIMAX_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIMAX_MANAGER, NMWimaxManager)) -#define NM_WIMAX_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIMAX_MANAGER, NMWimaxManagerClass)) -#define NM_IS_WIMAX_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIMAX_MANAGER)) -#define NM_IS_WIMAX_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_WIMAX_MANAGER)) -#define NM_WIMAX_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIMAX_MANAGER, NMWimaxManagerClass)) - -#define NM_WIMAX_MANAGER_DEVICE_ADDED "device-added" -#define NM_WIMAX_MANAGER_DEVICE_REMOVED "device-removed" - -typedef struct { - GObject parent; -} NMWimaxManager; - -typedef struct { - GObjectClass parent; -} NMWimaxManagerClass; - -GType nm_wimax_manager_get_type (void); - -NMWimaxManager *nm_wimax_manager_get (void); - -#endif /* NM_WIMAX_MANAGER_H */ - From a361ccd31db20b1043ab0baa792e4e73871e06e5 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 16:37:33 -0600 Subject: [PATCH 064/102] libnm-glib: add hissing hw-address property for WiMAX devices --- libnm-glib/nm-device-wimax.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libnm-glib/nm-device-wimax.c b/libnm-glib/nm-device-wimax.c index 4d43dc8c0e..bc9d6a088b 100644 --- a/libnm-glib/nm-device-wimax.c +++ b/libnm-glib/nm-device-wimax.c @@ -517,6 +517,19 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) /* properties */ + /** + * NMDeviceWimax:hw-address: + * + * The hardware (MAC) address of the device. + **/ + g_object_class_install_property + (object_class, PROP_HW_ADDRESS, + g_param_spec_string (NM_DEVICE_WIMAX_HW_ADDRESS, + "MAC Address", + "Hardware MAC address", + NULL, + G_PARAM_READABLE)); + /** * NMDeviceWimax:active-nsp: * From 8c2932fc2b6c81e5a58dfe574ee0645ebd083ed3 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 16:45:00 -0600 Subject: [PATCH 065/102] wimax: fix NSP property type confusion Just make them all uints. --- libnm-glib/nm-wimax-nsp.c | 16 ++++++++-------- libnm-glib/nm-wimax-nsp.h | 3 ++- src/wimax/nm-wimax-nsp.c | 14 +++++++------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/libnm-glib/nm-wimax-nsp.c b/libnm-glib/nm-wimax-nsp.c index 0b3b59571a..eebdbaaac9 100644 --- a/libnm-glib/nm-wimax-nsp.c +++ b/libnm-glib/nm-wimax-nsp.c @@ -36,7 +36,7 @@ typedef struct { DBusGProxy *proxy; char *name; - guint8 signal_quality; + guint32 signal_quality; NMWimaxNspNetworkType network_type; } NMWimaxNspPrivate; @@ -106,7 +106,7 @@ nm_wimax_nsp_get_name (NMWimaxNsp *nsp) * * Returns: the signal quality **/ -guint8 +guint32 nm_wimax_nsp_get_signal_quality (NMWimaxNsp *nsp) { NMWimaxNspPrivate *priv; @@ -140,7 +140,7 @@ nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp) priv = NM_WIMAX_NSP_GET_PRIVATE (nsp); if (!priv->network_type) { - priv->network_type = _nm_object_get_byte_property (NM_OBJECT (nsp), + priv->network_type = _nm_object_get_uint_property (NM_OBJECT (nsp), NM_DBUS_INTERFACE_WIMAX_NSP, DBUS_PROP_NETWORK_TYPE); } @@ -282,11 +282,11 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *nsp_class) **/ 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)); + g_param_spec_uint (NM_WIMAX_NSP_SIGNAL_QUALITY, + "Signal Quality", + "Signal Quality", + 0, 100, 0, + G_PARAM_READABLE)); /** * NMWimaxNsp:network-type: diff --git a/libnm-glib/nm-wimax-nsp.h b/libnm-glib/nm-wimax-nsp.h index 654b49c75e..5507b75295 100644 --- a/libnm-glib/nm-wimax-nsp.h +++ b/libnm-glib/nm-wimax-nsp.h @@ -17,6 +17,7 @@ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * + * Copyright (C) 2011 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. */ @@ -69,7 +70,7 @@ 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); +guint32 nm_wimax_nsp_get_signal_quality (NMWimaxNsp *nsp); NMWimaxNspNetworkType nm_wimax_nsp_get_network_type (NMWimaxNsp *nsp); G_END_DECLS diff --git a/src/wimax/nm-wimax-nsp.c b/src/wimax/nm-wimax-nsp.c index e69fc95efb..de17cd88d6 100644 --- a/src/wimax/nm-wimax-nsp.c +++ b/src/wimax/nm-wimax-nsp.c @@ -231,13 +231,13 @@ nm_wimax_nsp_class_init (NMWimaxNspClass *klass) 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)); + g_param_spec_uint (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] = From 752d17cf9d168bc37dbea46a2b846eb3f6d3e7d6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 16:48:25 -0600 Subject: [PATCH 066/102] wimax: more NSP property type fixes Forgot this in the last commit. --- src/wimax/nm-wimax-nsp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wimax/nm-wimax-nsp.c b/src/wimax/nm-wimax-nsp.c index de17cd88d6..d9e905b1fc 100644 --- a/src/wimax/nm-wimax-nsp.c +++ b/src/wimax/nm-wimax-nsp.c @@ -139,7 +139,7 @@ set_property (GObject *object, guint prop_id, { NMWimaxNspPrivate *priv = GET_PRIVATE (object); guint32 quality; - guchar network_type; + guint network_type; switch (prop_id) { case PROP_NAME: @@ -154,7 +154,7 @@ set_property (GObject *object, guint prop_id, } break; case PROP_NETWORK_TYPE: - network_type = g_value_get_uchar (value); + network_type = g_value_get_uint (value); if (network_type != priv->network_type) { priv->network_type = network_type; g_object_notify (object, NM_WIMAX_NSP_NETWORK_TYPE); @@ -180,7 +180,7 @@ get_property (GObject *object, guint prop_id, 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)); + g_value_set_uint (value, nm_wimax_nsp_get_network_type (self)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); From 3e4b54a5d02c1fd96bde77049f745e263ff450a2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 18:23:29 -0600 Subject: [PATCH 067/102] policy: recheck auto-activatable connections when WiMAX NSPs change --- src/nm-policy.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/nm-policy.c b/src/nm-policy.c index 53557039e5..6ecc74ddbd 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -36,6 +36,7 @@ #include "nm-device-wifi.h" #include "nm-device-ethernet.h" #include "nm-device-modem.h" +#include "nm-device-wimax.h" #include "nm-dbus-manager.h" #include "nm-setting-ip4-config.h" #include "nm-setting-connection.h" @@ -932,6 +933,12 @@ wireless_networks_changed (NMDeviceWifi *device, NMAccessPoint *ap, gpointer use schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0); } +static void +nsps_changed (NMDeviceWimax *device, NMWimaxNsp *nsp, gpointer user_data) +{ + schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0); +} + typedef struct { gulong id; NMDevice *device; @@ -982,6 +989,16 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data) G_CALLBACK (wireless_networks_changed), policy); policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); + } else if (NM_IS_DEVICE_WIMAX (device)) { + id = g_signal_connect (device, "nsp-added", + G_CALLBACK (nsps_changed), + policy); + policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); + + id = g_signal_connect (device, "nsp-removed", + G_CALLBACK (nsps_changed), + policy); + policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); } } From d11b7bc611d355ea4152402dc0c8c14f40212b6b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 18:24:10 -0600 Subject: [PATCH 068/102] wimax: do nothing if state isn't actually changing --- src/wimax/nm-device-wimax.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index ed3120315d..14336ea5c2 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -618,6 +618,9 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, gboolean old_available = FALSE; const char *nsp_name = NULL; + if (new_status == old_status) + return; + iface = nm_device_get_iface (NM_DEVICE (self)); state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); old_available = nm_device_is_available (NM_DEVICE (self)); @@ -848,9 +851,10 @@ static gboolean sdk_action_defer_cb (gpointer user_data) { NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + gboolean old_available = nm_device_is_available (NM_DEVICE (self)); NM_DEVICE_WIMAX_GET_PRIVATE (self)->sdk_action_defer_id = 0; - update_availability (self, FALSE); + update_availability (self, old_available); return FALSE; } From a802c7f40d14a49f1960290d1590ea7fd5e4d36c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 18:25:14 -0600 Subject: [PATCH 069/102] wimax: work around wide-char stupidity in Intel WiMAX SDK The SDK internally use wchar_t for NSP names even though the names are actually UTF-8 (since the driver uses UTF-8/ASCII). So work around that by using the full network name buffer in case the NSP name is an odd number of characters and thus widechar comparison functions like wcscmp() would fail when given ASCII. --- src/wimax/iwmxsdk.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c index 54ad84e8d6..85ef709cfe 100644 --- a/src/wimax/iwmxsdk.c +++ b/src/wimax/iwmxsdk.c @@ -661,6 +661,7 @@ int iwmx_sdk_connect(struct wmxsdk *wmxsdk, const char *nsp_name) char errstr[512]; UINT32 errstr_size = sizeof(errstr); WIMAX_API_DEVICE_STATUS dev_status; + char sdk_name[MAX_SIZE_OF_NSP_NAME]; g_mutex_lock(wmxsdk->connect_mutex); /* Guess what the current radio state is; if it is ON @@ -696,8 +697,15 @@ int iwmx_sdk_connect(struct wmxsdk *wmxsdk, const char *nsp_name) g_assert(1); } + /* The SDK treats the network name as wchar_t* while the contents are + * actually just UTF-8... WTF? Hand it a full buffer to work around + * boundary cases where the NSP name contains an odd # of characters. + */ + memset(sdk_name, 0, sizeof (sdk_name)); + memcpy(sdk_name, nsp_name, strlen (nsp_name)); + /* Ok, do the connection, wait for a callback */ - r = CmdConnectToNetwork(&wmxsdk->device_id, (void *) nsp_name, 0, 0); + r = CmdConnectToNetwork(&wmxsdk->device_id, &sdk_name[0], 0, 0); if (r != WIMAX_API_RET_SUCCESS) { GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot connect to network %s: %d (%s) - device is in state '%s'", From 30721f8aa702c102ccb057071fabc0bb2f564125 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 18:26:52 -0600 Subject: [PATCH 070/102] wimax: set initial device status --- src/wimax/iwmxsdk.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c index 85ef709cfe..050f745c83 100644 --- a/src/wimax/iwmxsdk.c +++ b/src/wimax/iwmxsdk.c @@ -918,7 +918,7 @@ error_scan: */ static int iwmx_sdk_setup(struct wmxsdk *wmxsdk) { - int result; + int result, status; WIMAX_API_RET r; @@ -1002,9 +1002,18 @@ static int iwmx_sdk_setup(struct wmxsdk *wmxsdk) goto error_subscribe_disconnect; } - wmxsdk->status = iwmx_sdk_get_device_status(wmxsdk); - if ((int) wmxsdk->status < 0) - wmxsdk->status = WIMAX_API_DEVICE_STATUS_UnInitialized; + status = iwmx_sdk_get_device_status(wmxsdk); + if ((int) status < 0) + status = WIMAX_API_DEVICE_STATUS_UnInitialized; + + g_mutex_lock(wmxsdk->status_mutex); + wmxsdk->status = status; + g_mutex_unlock(wmxsdk->status_mutex); + + _schedule_state_change(wmxsdk, + status, + WIMAX_API_DEVICE_STATUS_UnInitialized, + WIMAX_API_STATUS_REASON_Normal); return 0; From 597c2aeb80dfc08a5659ba461cdf9c3b0a83af52 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 18:50:25 -0600 Subject: [PATCH 071/102] wimax: fix a few SDK return value checks --- src/wimax/nm-device-wimax.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 14336ea5c2..f34a5d63a7 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -302,7 +302,7 @@ nm_log_dbg (LOGD_WIMAX, "wimax enabled changed to %d", priv->enabled); if (priv->sdk) { ret = iwmx_sdk_rf_state_set (priv->sdk, enabled ? WIMAX_API_RF_ON : WIMAX_API_RF_OFF); - if (ret != -EINPROGRESS) { + if (ret < 0 && ret != -EINPROGRESS) { nm_log_warn (LOGD_WIMAX, "failed to %s WiMAX radio", priv->enabled ? "enable" : "disable"); } @@ -560,7 +560,7 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) priv->connect_failed = FALSE; ret = iwmx_sdk_connect (priv->sdk, nsp); - if (ret != 0) { + if (ret < 0 && ret != -EINPROGRESS) { nm_log_err (LOGD_WIMAX, "Failed to connect to NSP '%s'", nsp); *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; @@ -594,7 +594,7 @@ real_deactivate_quickly (NMDevice *device) if ( status == WIMAX_API_DEVICE_STATUS_Connecting || status == WIMAX_API_DEVICE_STATUS_Data_Connected) { ret = iwmx_sdk_disconnect (priv->sdk); - if (ret < 0) { + if (ret < 0 && ret != -EINPROGRESS) { nm_log_err (LOGD_WIMAX, "Failed to disconnect WiMAX device: %d", ret); } } From 568f11ee541ed06012ba6a449e09095bc8f8a9fa Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 18:50:48 -0600 Subject: [PATCH 072/102] wimax: fix disconnect conditions Only fail an activated device if it's actually activated, and only fail an activating device if the timeout triggers or if the connect callback indicates failure, not based on device state. --- src/wimax/nm-device-wimax.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index f34a5d63a7..e92577c608 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -674,7 +674,7 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, return; } - if (priv->connect_failed || new_status < WIMAX_API_DEVICE_STATUS_Connecting) { + if (priv->connect_failed) { /* Connection attempt failed */ nm_log_info (LOGD_WIMAX, "(%s): connection to '%s' failed: (%d) %s", iface, nsp_name, reason, iwmx_sdk_reason_to_str (reason)); @@ -686,15 +686,17 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, } /* Handle disconnection */ - if ( old_status == WIMAX_API_DEVICE_STATUS_Data_Connected - && new_status < WIMAX_API_DEVICE_STATUS_Connecting) { + if (state == NM_DEVICE_STATE_ACTIVATED) { + if ( old_status == WIMAX_API_DEVICE_STATUS_Data_Connected + && new_status < WIMAX_API_DEVICE_STATUS_Connecting) { - nm_log_info (LOGD_WIMAX, "(%s): disconnected from '%s': (%d) %s", - iface, nsp_name, reason, iwmx_sdk_reason_to_str (reason)); + nm_log_info (LOGD_WIMAX, "(%s): disconnected from '%s': (%d) %s", + iface, nsp_name, reason, iwmx_sdk_reason_to_str (reason)); - nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_CONFIG_FAILED); + nm_device_state_changed (NM_DEVICE (self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_CONFIG_FAILED); + } } } From 31a0dfa533cb0073cb0452ac65a98c21edacae6d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 4 Jan 2011 18:51:51 -0600 Subject: [PATCH 073/102] wimax: reduce connect timeout a bit --- src/wimax/nm-device-wimax.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index e92577c608..71525c38e5 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -566,8 +566,8 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) 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); + /* FIXME: Is 40 seconds good estimation? I have no idea */ + priv->activation_timeout_id = g_timeout_add_seconds (40, activation_timed_out, device); return NM_ACT_STAGE_RETURN_POSTPONE; } From d1c7f3d992bb74b28bfac2292b4abb99f76d58e4 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 09:59:08 -0600 Subject: [PATCH 074/102] wimax: handle media status change events Which we need to use for DHCP renew. --- src/wimax/iwmxsdk.c | 82 +++++++++++++++++++++++++++++++++++++ src/wimax/iwmxsdk.h | 9 ++++ src/wimax/nm-device-wimax.c | 37 ++++++++++++++++- 3 files changed, 126 insertions(+), 2 deletions(-) diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c index 050f745c83..ba5bb9c71f 100644 --- a/src/wimax/iwmxsdk.c +++ b/src/wimax/iwmxsdk.c @@ -209,6 +209,45 @@ _schedule_state_change(struct wmxsdk *wmxsdk, g_idle_add(state_change_handler, info); } +typedef struct { + struct wmxsdk *wmxsdk; + WIMAX_API_MEDIA_STATUS media_status; +} MediaStatusInfo; + +static gboolean +media_status_change_handler(gpointer user_data) +{ + MediaStatusInfo *info = user_data; + + if (info->wmxsdk->media_status_cb) { + info->wmxsdk->media_status_cb(info->wmxsdk, + info->media_status, + info->wmxsdk->callback_data); + } + wmxsdk_unref(info->wmxsdk); + memset(info, 0, sizeof(*info)); + free(info); + return FALSE; +} + +static void +_schedule_media_status_change(struct wmxsdk *wmxsdk, + WIMAX_API_MEDIA_STATUS media_status) +{ + MediaStatusInfo *info; + + info = malloc(sizeof (*info)); + if (!info) + return; + + memset(info, 0, sizeof(*info)); + info->wmxsdk = wmxsdk; + info->media_status = media_status; + + wmxsdk_ref(wmxsdk); + g_idle_add(media_status_change_handler, info); +} + typedef struct { struct wmxsdk *wmxsdk; WIMAX_API_NETWORK_CONNECTION_RESP result; @@ -400,6 +439,19 @@ const char *iwmx_sdk_reason_to_str(WIMAX_API_STATUS_REASON reason) } } +const char *iwmx_sdk_media_status_to_str(WIMAX_API_MEDIA_STATUS status) +{ + switch (status) { + case WIMAX_API_MEDIA_STATUS_LINK_UP: + return "link-up"; + case WIMAX_API_MEDIA_STATUS_LINK_DOWN: + return "link-down"; + case WIMAX_API_MEDIA_STATUS_LINK_RENEW: + return "link-renew"; + default: + return "unknown"; + } +} /* * Get the device's status from the device @@ -810,6 +862,24 @@ error_get_status: return result; } +static void __iwmx_sdk_media_status_update_cb (WIMAX_API_DEVICE_ID_P device_id, + WIMAX_API_MEDIA_STATUS mediaStatus) +{ + struct wmxsdk *wmxsdk = deviceid_to_wmxsdk(device_id); + + /* Ignore redundant LINK_UP events */ + if ( mediaStatus == WIMAX_API_MEDIA_STATUS_LINK_UP + && wmxsdk->media_status == WIMAX_API_MEDIA_STATUS_LINK_UP) + return; + + wmxsdk->media_status = mediaStatus; + + nm_log_dbg(LOGD_WIMAX, "wmxsdk: media status change to (%d) %s", + mediaStatus, iwmx_sdk_media_status_to_str (mediaStatus)); + + _schedule_media_status_change(wmxsdk, mediaStatus); +} + /* * Callback for state change messages * @@ -1002,6 +1072,13 @@ static int iwmx_sdk_setup(struct wmxsdk *wmxsdk) goto error_subscribe_disconnect; } + r = SubscribeMediaStatusUpdate(&wmxsdk->device_id, __iwmx_sdk_media_status_update_cb); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot subscribe to media status events: %d (%s)", r, errstr); + goto error_subscribe_media_status; + } + status = iwmx_sdk_get_device_status(wmxsdk); if ((int) status < 0) status = WIMAX_API_DEVICE_STATUS_UnInitialized; @@ -1017,6 +1094,8 @@ static int iwmx_sdk_setup(struct wmxsdk *wmxsdk) return 0; + UnsubscribeMediaStatusUpdate(&wmxsdk->device_id); +error_subscribe_media_status: UnsubscribeDisconnectToNetwork(&wmxsdk->device_id); error_subscribe_disconnect: UnsubscribeConnectToNetwork(&wmxsdk->device_id); @@ -1043,6 +1122,7 @@ error_wimaxdeviceopen: */ static void iwmx_sdk_remove(struct wmxsdk *wmxsdk) { + UnsubscribeMediaStatusUpdate(&wmxsdk->device_id); UnsubscribeDisconnectToNetwork(&wmxsdk->device_id); UnsubscribeConnectToNetwork(&wmxsdk->device_id); UnsubscribeNetworkSearchEx(&wmxsdk->device_id); @@ -1054,12 +1134,14 @@ static void iwmx_sdk_remove(struct wmxsdk *wmxsdk) void iwmx_sdk_set_callbacks(struct wmxsdk *wmxsdk, WimaxStateChangeFunc state_change_cb, + WimaxMediaStatusFunc media_status_cb, WimaxConnectResultFunc connect_result_cb, WimaxScanResultFunc scan_result_cb, WimaxRemovedFunc removed_cb, void *user_data) { wmxsdk->state_change_cb = state_change_cb; + wmxsdk->media_status_cb = media_status_cb; wmxsdk->connect_result_cb = connect_result_cb; wmxsdk->scan_result_cb = scan_result_cb; wmxsdk->removed_cb = removed_cb; diff --git a/src/wimax/iwmxsdk.h b/src/wimax/iwmxsdk.h index e065b0a83d..1cef36fa3d 100644 --- a/src/wimax/iwmxsdk.h +++ b/src/wimax/iwmxsdk.h @@ -24,6 +24,7 @@ #include #include +#include struct wmxsdk; @@ -35,6 +36,10 @@ typedef void (*WimaxStateChangeFunc) (struct wmxsdk *wmxsdk, WIMAX_API_STATUS_REASON reason, void *user_data); +typedef void (*WimaxMediaStatusFunc) (struct wmxsdk *wmxsdk, + WIMAX_API_MEDIA_STATUS media_status, + void *user_data); + typedef void (*WimaxConnectResultFunc) (struct wmxsdk *wmxsdk, WIMAX_API_NETWORK_CONNECTION_RESP resp, void *user_data); @@ -52,6 +57,7 @@ struct wmxsdk { WIMAX_API_DEVICE_ID device_id; WimaxStateChangeFunc state_change_cb; + WimaxMediaStatusFunc media_status_cb; WimaxConnectResultFunc connect_result_cb; WimaxScanResultFunc scan_result_cb; WimaxRemovedFunc removed_cb; @@ -60,6 +66,7 @@ struct wmxsdk { GStaticMutex network_mutex; WIMAX_API_DEVICE_STATUS status; + WIMAX_API_MEDIA_STATUS media_status; GMutex *status_mutex; GMutex *connect_mutex; @@ -79,6 +86,7 @@ void iwmx_sdk_new_callback_unregister(WimaxNewWmxsdkFunc callback, void *user_da void iwmx_sdk_set_callbacks(struct wmxsdk *wmxsdk, WimaxStateChangeFunc state_change_cb, + WimaxMediaStatusFunc media_status_func, WimaxConnectResultFunc connect_result_cb, WimaxScanResultFunc scan_result_cb, WimaxRemovedFunc removed_cb, @@ -90,6 +98,7 @@ int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk); WIMAX_API_CONNECTED_NSP_INFO_EX *iwmx_sdk_get_connected_network(struct wmxsdk *wmxsdk); const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status); const char *iwmx_sdk_reason_to_str(WIMAX_API_STATUS_REASON reason); +const char *iwmx_sdk_media_status_to_str(WIMAX_API_MEDIA_STATUS status); int iwmx_sdk_rf_state_set(struct wmxsdk *wmxsdk, WIMAX_API_RF_STATE rf_state); int iwmx_sdk_get_networks(struct wmxsdk *wmxsdk); int iwmx_sdk_api_init(void); diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 71525c38e5..86df993aab 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -700,6 +700,38 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, } } +static void +wmx_media_status_cb (struct wmxsdk *wmxsdk, + WIMAX_API_MEDIA_STATUS new_status, + void *user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceState state; + const char *iface; + + iface = nm_device_get_iface (NM_DEVICE (self)); + state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); + + nm_log_dbg (LOGD_WIMAX, "(%s): media status change to %d", + iface, iwmx_sdk_media_status_to_str (new_status)); + + /* We only care about media events while activated */ + if (state != NM_DEVICE_STATE_ACTIVATED) + return; + + switch (new_status) { + case WIMAX_API_MEDIA_STATUS_LINK_UP: + break; + case WIMAX_API_MEDIA_STATUS_LINK_DOWN: + break; + case WIMAX_API_MEDIA_STATUS_LINK_RENEW: + break; + default: + nm_log_err (LOGD_WIMAX, "(%s): unhandled media status %d", iface, new_status); + break; + } +} + static void wmx_connect_result_cb (struct wmxsdk *wmxsdk, WIMAX_API_NETWORK_CONNECTION_RESP result, @@ -810,7 +842,7 @@ wmx_removed_cb (struct wmxsdk *wmxsdk, void *user_data) if (priv->sdk) { /* Clear callbacks just in case we don't hold the last reference */ - iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL); + iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL, NULL); wmxsdk_unref (priv->sdk); priv->sdk = NULL; @@ -871,6 +903,7 @@ wmx_new_sdk_cb (struct wmxsdk *sdk, void *user_data) priv->sdk = wmxsdk_ref (sdk); iwmx_sdk_set_callbacks(priv->sdk, wmx_state_change_cb, + wmx_media_status_cb, wmx_connect_result_cb, wmx_scan_result_cb, wmx_removed_cb, @@ -987,7 +1020,7 @@ dispose (GObject *object) g_source_remove (priv->sdk_action_defer_id); if (priv->sdk) { - iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL); + iwmx_sdk_set_callbacks (priv->sdk, NULL, NULL, NULL, NULL, NULL, NULL); wmxsdk_unref (priv->sdk); } From e598b186567b2eb89f28265bf4f13f77f48b9b66 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 14:06:48 -0600 Subject: [PATCH 075/102] wimax: add link timeout --- src/wimax/nm-device-wimax.c | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 86df993aab..bbb14718f2 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -88,6 +88,8 @@ typedef struct { guint sdk_action_defer_id; + guint link_timeout_id; + GSList *nsp_list; NMWimaxNsp *current_nsp; } NMDeviceWimaxPrivate; @@ -510,6 +512,17 @@ clear_activation_timeout (NMDeviceWimax *self) priv->connect_failed = FALSE; } +static void +clear_link_timeout (NMDeviceWimax *self) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (priv->link_timeout_id) { + g_source_remove (priv->link_timeout_id); + priv->link_timeout_id = 0; + } +} + static NMActStageReturn real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { @@ -518,6 +531,8 @@ real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) GSList *iter; const char *path; + clear_link_timeout (NM_DEVICE_WIMAX (device)); + req = nm_device_get_act_request (device); if (!req) goto err; @@ -580,6 +595,7 @@ real_deactivate_quickly (NMDevice *device) int ret; clear_activation_timeout (NM_DEVICE_WIMAX (device)); + clear_link_timeout (NM_DEVICE_WIMAX (device)); set_current_nsp (NM_DEVICE_WIMAX (device), NULL); @@ -700,12 +716,28 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, } } +static gboolean +link_timeout_cb (gpointer user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + priv->link_timeout_id = 0; + + nm_device_state_changed (NM_DEVICE (self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_CARRIER); + + return FALSE; +} + static void wmx_media_status_cb (struct wmxsdk *wmxsdk, WIMAX_API_MEDIA_STATUS new_status, void *user_data) { NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); NMDeviceState state; const char *iface; @@ -719,10 +751,13 @@ wmx_media_status_cb (struct wmxsdk *wmxsdk, if (state != NM_DEVICE_STATE_ACTIVATED) return; + clear_link_timeout (self); + switch (new_status) { case WIMAX_API_MEDIA_STATUS_LINK_UP: break; case WIMAX_API_MEDIA_STATUS_LINK_DOWN: + priv->link_timeout_id = g_timeout_add (15, link_timeout_cb, self); break; case WIMAX_API_MEDIA_STATUS_LINK_RENEW: break; @@ -869,6 +904,7 @@ device_state_changed (NMDevice *device, if (new_state < NM_DEVICE_STATE_DISCONNECTED) remove_all_nsps (self); + /* Request initial NSP list */ if ( new_state == NM_DEVICE_STATE_DISCONNECTED && old_state < NM_DEVICE_STATE_DISCONNECTED) { if (priv->sdk) @@ -877,6 +913,9 @@ device_state_changed (NMDevice *device, if (new_state == NM_DEVICE_STATE_FAILED || new_state <= NM_DEVICE_STATE_DISCONNECTED) clear_activation_timeout (self); + + if (new_state != NM_DEVICE_STATE_ACTIVATED) + clear_link_timeout (self); } /*************************************************************************/ @@ -1015,6 +1054,7 @@ dispose (GObject *object) priv->disposed = TRUE; clear_activation_timeout (self); + clear_link_timeout (self); if (priv->sdk_action_defer_id) g_source_remove (priv->sdk_action_defer_id); From 1ec327130a20fd61f968a456365b72b8489885f0 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 14:07:32 -0600 Subject: [PATCH 076/102] core: factor out DHCPv4 setup --- src/nm-device.c | 91 +++++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 41 deletions(-) diff --git a/src/nm-device.c b/src/nm-device.c index e8f0b206ca..34a9c23a2f 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -1477,16 +1477,63 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data) } } +static NMActStageReturn +dhcp4_start (NMDevice *self, + NMConnection *connection, + NMSettingIP4Config *s_ip4, + NMDeviceStateReason *reason) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMSettingConnection *s_con; + guint8 *anycast = NULL; + + s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); + g_assert (s_con); + + /* Begin a DHCP transaction on the interface */ + + if (priv->dhcp_anycast_address) + anycast = priv->dhcp_anycast_address->data; + + /* Clear old exported DHCP options */ + if (priv->dhcp4_config) + g_object_unref (priv->dhcp4_config); + priv->dhcp4_config = nm_dhcp4_config_new (); + + g_warn_if_fail (priv->dhcp4_client == NULL); + priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager, + nm_device_get_ip_iface (self), + nm_setting_connection_get_uuid (s_con), + s_ip4, + priv->dhcp_timeout, + anycast); + if (!priv->dhcp4_client) { + *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED; + return NM_ACT_STAGE_RETURN_FAILURE; + } + + priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client, + "state-changed", + G_CALLBACK (dhcp_state_changed), + self); + priv->dhcp4_timeout_sigid = g_signal_connect (priv->dhcp4_client, + "timeout", + G_CALLBACK (dhcp_timeout), + self); + + /* DHCP devices will be notified by the DHCP manager when stuff happens */ + return NM_ACT_STAGE_RETURN_POSTPONE; +} + static NMActStageReturn real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMConnection *connection; - NMSettingConnection *s_con; NMSettingIP4Config *s_ip4; NMActRequest *req; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; - const char *ip_iface, *method = NULL, *uuid; + const char *ip_iface, *method = NULL; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -1499,9 +1546,6 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) req = nm_device_get_act_request (self); connection = nm_act_request_get_connection (req); - s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); - g_assert (s_con); - uuid = nm_setting_connection_get_uuid (s_con); s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); @@ -1510,42 +1554,7 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) method = nm_setting_ip4_config_get_method (s_ip4); if (!s_ip4 || !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - guint8 *anycast = NULL; - - /* Begin a DHCP transaction on the interface */ - - if (priv->dhcp_anycast_address) - anycast = priv->dhcp_anycast_address->data; - - /* Clear old exported DHCP options */ - if (priv->dhcp4_config) - g_object_unref (priv->dhcp4_config); - priv->dhcp4_config = nm_dhcp4_config_new (); - - priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager, - ip_iface, - uuid, - s_ip4, - priv->dhcp_timeout, - anycast); - if (priv->dhcp4_client) { - priv->dhcp4_state_sigid = g_signal_connect (priv->dhcp4_client, - "state-changed", - G_CALLBACK (dhcp_state_changed), - self); - priv->dhcp4_timeout_sigid = g_signal_connect (priv->dhcp4_client, - "timeout", - G_CALLBACK (dhcp_timeout), - self); - - /* DHCP devices will be notified by the DHCP manager when - * stuff happens. - */ - ret = NM_ACT_STAGE_RETURN_POSTPONE; - } else { - *reason = NM_DEVICE_STATE_REASON_DHCP_START_FAILED; - ret = NM_ACT_STAGE_RETURN_FAILURE; - } + ret = dhcp4_start (self, connection, s_ip4, reason); } else if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { GError *error = NULL; const char *iface = nm_device_get_iface (self); From bee33b9a26955d86890fddf01a546b79610e4830 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 15:13:04 -0600 Subject: [PATCH 077/102] wimax: notify listeners of new wimax devices If wimaxd gets started after NetworkManager, we need to notify NetworkManager that the daemon has found and set up any wimax interface it finds. Most of the code for this was there but not previously hooked up. --- src/wimax/iwmxsdk.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c index ba5bb9c71f..28e57bb1f3 100644 --- a/src/wimax/iwmxsdk.c +++ b/src/wimax/iwmxsdk.c @@ -160,6 +160,19 @@ void iwmx_sdk_new_callback_unregister(WimaxNewWmxsdkFunc callback, void *user_da g_static_mutex_unlock (&new_callbacks_mutex); } +static void iwmx_sdk_call_new_callbacks(struct wmxsdk *wmxsdk) +{ + GSList *iter; + + g_static_mutex_lock (&new_callbacks_mutex); + for (iter = new_callbacks; iter; iter = g_slist_next (iter)) { + NewSdkCallback *cb = iter->data; + + cb->callback (wmxsdk, cb->user_data); + } + g_static_mutex_unlock (&new_callbacks_mutex); +} + /****************************************************************/ typedef struct { @@ -1237,6 +1250,9 @@ static void iwmx_sdk_dev_add(unsigned idx, unsigned api_idx, const char *name) } g_iwmx_sdk_devs[idx] = wmxsdk; + + /* Notify listeners of new devices */ + iwmx_sdk_call_new_callbacks (wmxsdk); return; error_setup: From a9918eefac5fbff34e91367b8f1927eba58e0e9d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 15:27:48 -0600 Subject: [PATCH 078/102] wimax: protect device add/remove with a mutex Sometimes the add/remove code will get re-entered by the SDK because the SDK is stupid. Lock the code to ensure we don't double-detect the same device. --- src/wimax/iwmxsdk.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c index 28e57bb1f3..ab4b0ec1c4 100644 --- a/src/wimax/iwmxsdk.c +++ b/src/wimax/iwmxsdk.c @@ -39,9 +39,7 @@ #include "iwmxsdk.h" static WIMAX_API_DEVICE_ID g_api; - -static int iwmx_sdk_setup(struct wmxsdk *wmxsdk); -static void iwmx_sdk_remove(struct wmxsdk *wmxsdk); +static GStaticMutex add_remove_mutex = G_STATIC_MUTEX_INIT; /* Misc utilities */ #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) @@ -1285,10 +1283,11 @@ static void iwmx_sdk_addremove_cb(WIMAX_API_DEVICE_ID *devid, WIMAX_API_RET r; WIMAX_API_HW_DEVICE_ID device_id_list[5]; UINT32 device_id_list_size = ARRAY_SIZE(device_id_list); - char errstr[512]; UINT32 errstr_size = sizeof(errstr); + g_static_mutex_lock(&add_remove_mutex); + nm_log_dbg(LOGD_WIMAX, "cb: handle %u index #%u is %d", devid->sdkHandle, devid->deviceIndex, presence); @@ -1296,22 +1295,24 @@ static void iwmx_sdk_addremove_cb(WIMAX_API_DEVICE_ID *devid, if (r != WIMAX_API_RET_SUCCESS) { GetErrorString(devid, r, errstr, &errstr_size); nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot obtain list of devices: %d (%s)", r, errstr); - return; + goto out; } if (device_id_list_size == 0) { nm_log_dbg(LOGD_WIMAX, "No WiMAX devices reported"); - } else + } else { for (cnt = 0; cnt < device_id_list_size; cnt++) { WIMAX_API_HW_DEVICE_ID *dev = device_id_list + cnt; nm_log_dbg(LOGD_WIMAX, "#%u index #%u device %s", cnt, dev->deviceIndex, dev->deviceName); } + } + if (device_id_list_size < devid->deviceIndex) { nm_log_err(LOGD_WIMAX, "wmxsdk: changed device (%u) not in the list? (%u items)", devid->deviceIndex, device_id_list_size); - return; + goto out; } if (presence) { @@ -1322,6 +1323,9 @@ static void iwmx_sdk_addremove_cb(WIMAX_API_DEVICE_ID *devid, } else { iwmx_sdk_dev_rm(devid->deviceIndex); } + +out: + g_static_mutex_unlock(&add_remove_mutex); } /* From 9c99066d6caab46deba26d39df9a01b4dd7476d2 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 15:30:59 -0600 Subject: [PATCH 079/102] wimax: if the device is connected at startup, force it to disconnect Otherwise it doesn't auto-scan and we get no network list. As a later optimization, we could detect this, call iwmx_sdk_get_connected_network() to get the current NSP, match that up with a connection, and "assume" the connection like we do for Ethernet devices. --- src/dhcp-manager/nm-dhcp-client.c | 16 +++--- src/dhcp-manager/nm-dhcp-client.h | 25 +++++---- src/dhcp-manager/nm-dhcp-dhclient.c | 79 ++++++++++++++++++++--------- src/dhcp-manager/nm-dhcp-dhcpcd.c | 6 ++- src/dhcp-manager/nm-dhcp-manager.c | 2 +- src/nm-device.c | 55 ++++++++++++++------ src/nm-device.h | 2 + src/wimax/nm-device-wimax.c | 46 +++++++++++------ 8 files changed, 153 insertions(+), 78 deletions(-) diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 3a8b194081..c4dfec64d7 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -136,10 +136,10 @@ watch_cleanup (NMDHCPClient *self) } } -static void -stop_process (GPid pid, const char *iface) +void +nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs) { - int i = 15; /* 3 seconds */ + int i = (timeout_secs ? timeout_secs : 3) * 5; /* default 3 seconds */ g_return_if_fail (pid > 0); @@ -183,7 +183,7 @@ stop_process (GPid pid, const char *iface) } static void -real_stop (NMDHCPClient *self) +real_stop (NMDHCPClient *self, gboolean release) { NMDHCPClientPrivate *priv; @@ -196,7 +196,7 @@ real_stop (NMDHCPClient *self) /* Clean up the watch handler since we're explicitly killing the daemon */ watch_cleanup (self); - stop_process (priv->pid, priv->iface); + nm_dhcp_client_stop_pid (priv->pid, priv->iface, 0); priv->info_only = FALSE; } @@ -376,7 +376,7 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) exe = proc_contents; if (!strcmp (exe, binary_name)) - stop_process ((GPid) tmp, NULL); + nm_dhcp_client_stop_pid ((GPid) tmp, NULL, 0); } } @@ -387,7 +387,7 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) } void -nm_dhcp_client_stop (NMDHCPClient *self) +nm_dhcp_client_stop (NMDHCPClient *self, gboolean release) { NMDHCPClientPrivate *priv; @@ -398,7 +398,7 @@ nm_dhcp_client_stop (NMDHCPClient *self) /* Kill the DHCP client */ if (!priv->dead) { - NM_DHCP_CLIENT_GET_CLASS (self)->stop (self); + NM_DHCP_CLIENT_GET_CLASS (self)->stop (self, release); priv->dead = TRUE; nm_log_info (LOGD_DHCP, "(%s): canceled DHCP transaction, DHCP client pid %d", diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index f357170b9c..19c7365edc 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -76,18 +76,19 @@ typedef struct { /* Methods */ - GPid (*ip4_start) (NMDHCPClient *self, - NMSettingIP4Config *s_ip4, - guint8 *anycast_addr, - const char *hostname); + GPid (*ip4_start) (NMDHCPClient *self, + NMSettingIP4Config *s_ip4, + guint8 *anycast_addr, + const char *hostname); - GPid (*ip6_start) (NMDHCPClient *self, - NMSettingIP6Config *s_ip6, - guint8 *anycast_addr, - const char *hostname, - gboolean info_only); + GPid (*ip6_start) (NMDHCPClient *self, + NMSettingIP6Config *s_ip6, + guint8 *anycast_addr, + const char *hostname, + gboolean info_only); - void (*stop) (NMDHCPClient *self); + void (*stop) (NMDHCPClient *self, + gboolean release); /* Signals */ void (*state_changed) (NMDHCPClient *self, NMDHCPState state); @@ -116,7 +117,7 @@ gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self, const char *hostname, gboolean info_only); -void nm_dhcp_client_stop (NMDHCPClient *self); +void nm_dhcp_client_stop (NMDHCPClient *self, gboolean release); void nm_dhcp_client_new_options (NMDHCPClient *self, GHashTable *options, @@ -133,5 +134,7 @@ NMIP6Config *nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test) /* Backend helpers */ void nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name); +void nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs); + #endif /* NM_DHCP_CLIENT_H */ diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index f6f2a540dc..75684459f6 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -411,15 +411,15 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED) static GPid dhclient_start (NMDHCPClient *client, - const char *ip_opt, - const char *mode_opt) + const char *mode_opt, + gboolean release) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); GPtrArray *argv = NULL; GPid pid = -1; GError *error = NULL; const char *iface, *uuid; - char *binary_name, *cmd_str; + char *binary_name, *cmd_str, *pid_file = NULL; gboolean ipv6; guint log_domain; @@ -436,28 +436,33 @@ dhclient_start (NMDHCPClient *client, nm_log_warn (log_domain, "(%s): ISC dhcp3 does not support IPv6", iface); return -1; } -#else - g_return_val_if_fail (ip_opt != NULL, -1); #endif - priv->pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid", - ipv6 ? "6" : "", - iface); - if (!priv->pid_file) { - nm_log_warn (log_domain, "(%s): not enough memory for dhcpcd options.", iface); - return -1; - } - if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) { nm_log_warn (log_domain, "%s does not exist.", priv->path); return -1; } + pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid", + ipv6 ? "6" : "", + iface); + if (!pid_file) { + nm_log_warn (log_domain, "(%s): not enough memory for dhcpcd options.", iface); + return -1; + } + /* Kill any existing dhclient from the pidfile */ binary_name = g_path_get_basename (priv->path); - nm_dhcp_client_stop_existing (priv->pid_file, binary_name); + nm_dhcp_client_stop_existing (pid_file, binary_name); g_free (binary_name); + if (release) { + /* release doesn't use the pidfile after killing an old client */ + g_free (pid_file); + pid_file = NULL; + } + + g_free (priv->lease_file); priv->lease_file = get_leasefile_for_iface (iface, uuid, ipv6); if (!priv->lease_file) { nm_log_warn (log_domain, "(%s): not enough memory for dhclient options.", iface); @@ -469,17 +474,26 @@ dhclient_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) "-d"); + if (release) + g_ptr_array_add (argv, (gpointer) "-r"); + #if !defined(DHCLIENT_V3) - g_ptr_array_add (argv, (gpointer) ip_opt); - if (mode_opt) - g_ptr_array_add (argv, (gpointer) mode_opt); + if (ipv6) { + g_ptr_array_add (argv, (gpointer) "-6"); + if (mode_opt) + g_ptr_array_add (argv, (gpointer) mode_opt); + } else { + g_ptr_array_add (argv, (gpointer) "-4"); + } #endif g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH ); - g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ - g_ptr_array_add (argv, (gpointer) priv->pid_file); + if (pid_file) { + g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ + g_ptr_array_add (argv, (gpointer) pid_file); + } g_ptr_array_add (argv, (gpointer) "-lf"); /* Set lease file */ g_ptr_array_add (argv, (gpointer) priv->lease_file); @@ -501,8 +515,10 @@ dhclient_start (NMDHCPClient *client, nm_log_warn (log_domain, "dhclient failed to start: '%s'", error->message); g_error_free (error); pid = -1; - } else + } else { nm_log_info (log_domain, "dhclient started with pid %d", pid); + priv->pid_file = pid_file; + } g_ptr_array_free (argv, TRUE); return pid; @@ -525,7 +541,7 @@ real_ip4_start (NMDHCPClient *client, return -1; } - return dhclient_start (client, "-4", NULL); + return dhclient_start (client, NULL, FALSE); } static GPid @@ -535,21 +551,34 @@ real_ip6_start (NMDHCPClient *client, const char *hostname, gboolean info_only) { - return dhclient_start (client, "-6", info_only ? "-S" : "-N"); + return dhclient_start (client, info_only ? "-S" : "-N", FALSE); } static void -real_stop (NMDHCPClient *client) +real_stop (NMDHCPClient *client, gboolean release) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); /* Chain up to parent */ - NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client); + NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client, release); if (priv->conf_file) remove (priv->conf_file); - if (priv->pid_file) + if (priv->pid_file) { remove (priv->pid_file); + g_free (priv->pid_file); + priv->pid_file = NULL; + } + + if (release) { + GPid rpid; + + rpid = dhclient_start (client, NULL, TRUE); + if (rpid > 0) { + /* Wait a few seconds for the release to happen */ + nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client), 5); + } + } } /***************************************************/ diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index 4fb703c480..237661fe47 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -170,15 +170,17 @@ real_ip6_start (NMDHCPClient *client, } static void -real_stop (NMDHCPClient *client) +real_stop (NMDHCPClient *client, gboolean release) { NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client); /* Chain up to parent */ - NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client); + NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client, release); if (priv->pid_file) remove (priv->pid_file); + + /* FIXME: implement release... */ } /***************************************************/ diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index a1e3e5e24d..d3c064199c 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -429,7 +429,7 @@ client_start (NMDHCPManager *self, /* Kill any old client instance */ client = get_client_for_iface (self, iface, ipv6); if (client) { - nm_dhcp_client_stop (client); + nm_dhcp_client_stop (client, FALSE); remove_client (self, client); } diff --git a/src/nm-device.c b/src/nm-device.c index 34a9c23a2f..b9701a399e 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -184,8 +184,8 @@ static NMActStageReturn dhcp6_start (NMDevice *self, NMDeviceStateReason *reason); static void addrconf6_cleanup (NMDevice *self); -static void dhcp6_cleanup (NMDevice *self, gboolean stop); -static void dhcp4_cleanup (NMDevice *self, gboolean stop); +static void dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release); +static void dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release); static void @@ -1467,7 +1467,7 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data) if (!nm_device_get_act_request (device)) return; - nm_dhcp_client_stop (client); + nm_dhcp_client_stop (client, FALSE); if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { if (nm_dhcp_client_get_ipv6 (client)) @@ -1480,17 +1480,16 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data) static NMActStageReturn dhcp4_start (NMDevice *self, NMConnection *connection, - NMSettingIP4Config *s_ip4, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; guint8 *anycast = NULL; s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); g_assert (s_con); - - /* Begin a DHCP transaction on the interface */ + s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); if (priv->dhcp_anycast_address) anycast = priv->dhcp_anycast_address->data; @@ -1500,6 +1499,7 @@ dhcp4_start (NMDevice *self, g_object_unref (priv->dhcp4_config); priv->dhcp4_config = nm_dhcp4_config_new (); + /* Begin DHCP on the interface */ g_warn_if_fail (priv->dhcp4_client == NULL); priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager, nm_device_get_ip_iface (self), @@ -1525,6 +1525,31 @@ dhcp4_start (NMDevice *self, return NM_ACT_STAGE_RETURN_POSTPONE; } +gboolean +nm_device_dhcp4_renew (NMDevice *self, gboolean release) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMActStageReturn ret; + NMDeviceStateReason reason; + NMActRequest *req; + NMConnection *connection; + + g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE); + + /* Terminate old DHCP instance and release the old lease */ + dhcp4_cleanup (self, TRUE, TRUE); + + req = nm_device_get_act_request (self); + g_assert (req); + connection = nm_act_request_get_connection (req); + g_assert (connection); + + /* Start DHCP again on the interface */ + ret = dhcp4_start (self, connection, &reason); + + return (ret != NM_ACT_STAGE_RETURN_FAILURE); +} + static NMActStageReturn real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) { @@ -1554,7 +1579,7 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) method = nm_setting_ip4_config_get_method (s_ip4); if (!s_ip4 || !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - ret = dhcp4_start (self, connection, s_ip4, reason); + ret = dhcp4_start (self, connection, reason); } else if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { GError *error = NULL; const char *iface = nm_device_get_iface (self); @@ -2675,7 +2700,7 @@ delayed_transitions_clear (NMDevice *self) } static void -dhcp4_cleanup (NMDevice *self, gboolean stop) +dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -2698,7 +2723,7 @@ dhcp4_cleanup (NMDevice *self, gboolean stop) } if (stop) - nm_dhcp_client_stop (priv->dhcp4_client); + nm_dhcp_client_stop (priv->dhcp4_client, release); g_object_unref (priv->dhcp4_client); priv->dhcp4_client = NULL; @@ -2706,7 +2731,7 @@ dhcp4_cleanup (NMDevice *self, gboolean stop) } static void -dhcp6_cleanup (NMDevice *self, gboolean stop) +dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -2730,7 +2755,7 @@ dhcp6_cleanup (NMDevice *self, gboolean stop) } if (stop) - nm_dhcp_client_stop (priv->dhcp6_client); + nm_dhcp_client_stop (priv->dhcp6_client, release); g_object_unref (priv->dhcp6_client); priv->dhcp6_client = NULL; @@ -2779,8 +2804,8 @@ nm_device_deactivate_quickly (NMDevice *self) /* Clear any delayed transitions */ delayed_transitions_clear (self); - dhcp4_cleanup (self, TRUE); - dhcp6_cleanup (self, TRUE); + dhcp4_cleanup (self, TRUE, FALSE); + dhcp6_cleanup (self, TRUE, FALSE); addrconf6_cleanup (self); dnsmasq_cleanup (self); aipd_cleanup (self); @@ -3357,8 +3382,8 @@ dispose (GObject *object) delayed_transitions_clear (self); /* Clean up and stop DHCP */ - dhcp4_cleanup (self, take_down); - dhcp6_cleanup (self, take_down); + dhcp4_cleanup (self, take_down, FALSE); + dhcp6_cleanup (self, take_down, FALSE); addrconf6_cleanup (self); dnsmasq_cleanup (self); diff --git a/src/nm-device.h b/src/nm-device.h index db2b1b7db0..bd400fd6bf 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -185,6 +185,8 @@ void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr); void nm_device_clear_autoconnect_inhibit (NMDevice *device); +gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); + G_END_DECLS #endif /* NM_DEVICE_H */ diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index bbb14718f2..870759e333 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -587,12 +587,33 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_POSTPONE; } +static void +force_disconnect (struct wmxsdk *sdk) +{ + WIMAX_API_DEVICE_STATUS status; + int ret; + + g_return_if_fail (sdk != NULL); + + status = iwmxsdk_status_get (sdk); + if ((int) status < 0) { + nm_log_err (LOGD_WIMAX, "Failed to read WiMAX device status: %d", status); + return; + } + + if ( status == WIMAX_API_DEVICE_STATUS_Connecting + || status == WIMAX_API_DEVICE_STATUS_Data_Connected) { + ret = iwmx_sdk_disconnect (sdk); + if (ret < 0 && ret != -EINPROGRESS) { + nm_log_err (LOGD_WIMAX, "Failed to disconnect WiMAX device: %d", ret); + } + } +} + static void real_deactivate_quickly (NMDevice *device) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); - WIMAX_API_DEVICE_STATUS status; - int ret; clear_activation_timeout (NM_DEVICE_WIMAX (device)); clear_link_timeout (NM_DEVICE_WIMAX (device)); @@ -603,18 +624,7 @@ real_deactivate_quickly (NMDevice *device) /* Read explicit status here just to make sure we have the most * up-to-date status and to ensure we disconnect if needed. */ - status = iwmxsdk_status_get (priv->sdk); - if ((int) status < 0) { - nm_log_err (LOGD_WIMAX, "Failed to read WiMAX device status: %d", status); - } else { - if ( status == WIMAX_API_DEVICE_STATUS_Connecting - || status == WIMAX_API_DEVICE_STATUS_Data_Connected) { - ret = iwmx_sdk_disconnect (priv->sdk); - if (ret < 0 && ret != -EINPROGRESS) { - nm_log_err (LOGD_WIMAX, "Failed to disconnect WiMAX device: %d", ret); - } - } - } + force_disconnect (priv->sdk); } } @@ -662,10 +672,14 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, return; } 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: + /* If for some reason we're initially connected, force a disconnect here */ + if (state < NM_DEVICE_STATE_DISCONNECTED) + force_disconnect (wmxsdk); + /* Fall through */ + case WIMAX_API_DEVICE_STATUS_Ready: + case WIMAX_API_DEVICE_STATUS_Scanning: if (priv->wimaxd_enabled == FALSE) { priv->wimaxd_enabled = TRUE; if (update_availability (self, old_available)) From 71adbcbb20d685aca4c0de67f0c0c13cd9f5fe00 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 15:38:03 -0600 Subject: [PATCH 080/102] Revert "wimax: if the device is connected at startup, force it to disconnect" This reverts commit 9c99066d6caab46deba26d39df9a01b4dd7476d2. Yay for finger-memory of git commit -a... --- src/dhcp-manager/nm-dhcp-client.c | 16 +++--- src/dhcp-manager/nm-dhcp-client.h | 25 ++++----- src/dhcp-manager/nm-dhcp-dhclient.c | 79 +++++++++-------------------- src/dhcp-manager/nm-dhcp-dhcpcd.c | 6 +-- src/dhcp-manager/nm-dhcp-manager.c | 2 +- src/nm-device.c | 55 ++++++-------------- src/nm-device.h | 2 - src/wimax/nm-device-wimax.c | 46 ++++++----------- 8 files changed, 78 insertions(+), 153 deletions(-) diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index c4dfec64d7..3a8b194081 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -136,10 +136,10 @@ watch_cleanup (NMDHCPClient *self) } } -void -nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs) +static void +stop_process (GPid pid, const char *iface) { - int i = (timeout_secs ? timeout_secs : 3) * 5; /* default 3 seconds */ + int i = 15; /* 3 seconds */ g_return_if_fail (pid > 0); @@ -183,7 +183,7 @@ nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs) } static void -real_stop (NMDHCPClient *self, gboolean release) +real_stop (NMDHCPClient *self) { NMDHCPClientPrivate *priv; @@ -196,7 +196,7 @@ real_stop (NMDHCPClient *self, gboolean release) /* Clean up the watch handler since we're explicitly killing the daemon */ watch_cleanup (self); - nm_dhcp_client_stop_pid (priv->pid, priv->iface, 0); + stop_process (priv->pid, priv->iface); priv->info_only = FALSE; } @@ -376,7 +376,7 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) exe = proc_contents; if (!strcmp (exe, binary_name)) - nm_dhcp_client_stop_pid ((GPid) tmp, NULL, 0); + stop_process ((GPid) tmp, NULL); } } @@ -387,7 +387,7 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) } void -nm_dhcp_client_stop (NMDHCPClient *self, gboolean release) +nm_dhcp_client_stop (NMDHCPClient *self) { NMDHCPClientPrivate *priv; @@ -398,7 +398,7 @@ nm_dhcp_client_stop (NMDHCPClient *self, gboolean release) /* Kill the DHCP client */ if (!priv->dead) { - NM_DHCP_CLIENT_GET_CLASS (self)->stop (self, release); + NM_DHCP_CLIENT_GET_CLASS (self)->stop (self); priv->dead = TRUE; nm_log_info (LOGD_DHCP, "(%s): canceled DHCP transaction, DHCP client pid %d", diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index 19c7365edc..f357170b9c 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -76,19 +76,18 @@ typedef struct { /* Methods */ - GPid (*ip4_start) (NMDHCPClient *self, - NMSettingIP4Config *s_ip4, - guint8 *anycast_addr, - const char *hostname); + GPid (*ip4_start) (NMDHCPClient *self, + NMSettingIP4Config *s_ip4, + guint8 *anycast_addr, + const char *hostname); - GPid (*ip6_start) (NMDHCPClient *self, - NMSettingIP6Config *s_ip6, - guint8 *anycast_addr, - const char *hostname, - gboolean info_only); + GPid (*ip6_start) (NMDHCPClient *self, + NMSettingIP6Config *s_ip6, + guint8 *anycast_addr, + const char *hostname, + gboolean info_only); - void (*stop) (NMDHCPClient *self, - gboolean release); + void (*stop) (NMDHCPClient *self); /* Signals */ void (*state_changed) (NMDHCPClient *self, NMDHCPState state); @@ -117,7 +116,7 @@ gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self, const char *hostname, gboolean info_only); -void nm_dhcp_client_stop (NMDHCPClient *self, gboolean release); +void nm_dhcp_client_stop (NMDHCPClient *self); void nm_dhcp_client_new_options (NMDHCPClient *self, GHashTable *options, @@ -134,7 +133,5 @@ NMIP6Config *nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test) /* Backend helpers */ void nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name); -void nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs); - #endif /* NM_DHCP_CLIENT_H */ diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index 75684459f6..f6f2a540dc 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -411,15 +411,15 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED) static GPid dhclient_start (NMDHCPClient *client, - const char *mode_opt, - gboolean release) + const char *ip_opt, + const char *mode_opt) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); GPtrArray *argv = NULL; GPid pid = -1; GError *error = NULL; const char *iface, *uuid; - char *binary_name, *cmd_str, *pid_file = NULL; + char *binary_name, *cmd_str; gboolean ipv6; guint log_domain; @@ -436,33 +436,28 @@ dhclient_start (NMDHCPClient *client, nm_log_warn (log_domain, "(%s): ISC dhcp3 does not support IPv6", iface); return -1; } +#else + g_return_val_if_fail (ip_opt != NULL, -1); #endif + priv->pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid", + ipv6 ? "6" : "", + iface); + if (!priv->pid_file) { + nm_log_warn (log_domain, "(%s): not enough memory for dhcpcd options.", iface); + return -1; + } + if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) { nm_log_warn (log_domain, "%s does not exist.", priv->path); return -1; } - pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid", - ipv6 ? "6" : "", - iface); - if (!pid_file) { - nm_log_warn (log_domain, "(%s): not enough memory for dhcpcd options.", iface); - return -1; - } - /* Kill any existing dhclient from the pidfile */ binary_name = g_path_get_basename (priv->path); - nm_dhcp_client_stop_existing (pid_file, binary_name); + nm_dhcp_client_stop_existing (priv->pid_file, binary_name); g_free (binary_name); - if (release) { - /* release doesn't use the pidfile after killing an old client */ - g_free (pid_file); - pid_file = NULL; - } - - g_free (priv->lease_file); priv->lease_file = get_leasefile_for_iface (iface, uuid, ipv6); if (!priv->lease_file) { nm_log_warn (log_domain, "(%s): not enough memory for dhclient options.", iface); @@ -474,26 +469,17 @@ dhclient_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) "-d"); - if (release) - g_ptr_array_add (argv, (gpointer) "-r"); - #if !defined(DHCLIENT_V3) - if (ipv6) { - g_ptr_array_add (argv, (gpointer) "-6"); - if (mode_opt) - g_ptr_array_add (argv, (gpointer) mode_opt); - } else { - g_ptr_array_add (argv, (gpointer) "-4"); - } + g_ptr_array_add (argv, (gpointer) ip_opt); + if (mode_opt) + g_ptr_array_add (argv, (gpointer) mode_opt); #endif g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH ); - if (pid_file) { - g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ - g_ptr_array_add (argv, (gpointer) pid_file); - } + g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ + g_ptr_array_add (argv, (gpointer) priv->pid_file); g_ptr_array_add (argv, (gpointer) "-lf"); /* Set lease file */ g_ptr_array_add (argv, (gpointer) priv->lease_file); @@ -515,10 +501,8 @@ dhclient_start (NMDHCPClient *client, nm_log_warn (log_domain, "dhclient failed to start: '%s'", error->message); g_error_free (error); pid = -1; - } else { + } else nm_log_info (log_domain, "dhclient started with pid %d", pid); - priv->pid_file = pid_file; - } g_ptr_array_free (argv, TRUE); return pid; @@ -541,7 +525,7 @@ real_ip4_start (NMDHCPClient *client, return -1; } - return dhclient_start (client, NULL, FALSE); + return dhclient_start (client, "-4", NULL); } static GPid @@ -551,34 +535,21 @@ real_ip6_start (NMDHCPClient *client, const char *hostname, gboolean info_only) { - return dhclient_start (client, info_only ? "-S" : "-N", FALSE); + return dhclient_start (client, "-6", info_only ? "-S" : "-N"); } static void -real_stop (NMDHCPClient *client, gboolean release) +real_stop (NMDHCPClient *client) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); /* Chain up to parent */ - NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client, release); + NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client); if (priv->conf_file) remove (priv->conf_file); - if (priv->pid_file) { + if (priv->pid_file) remove (priv->pid_file); - g_free (priv->pid_file); - priv->pid_file = NULL; - } - - if (release) { - GPid rpid; - - rpid = dhclient_start (client, NULL, TRUE); - if (rpid > 0) { - /* Wait a few seconds for the release to happen */ - nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client), 5); - } - } } /***************************************************/ diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index 237661fe47..4fb703c480 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -170,17 +170,15 @@ real_ip6_start (NMDHCPClient *client, } static void -real_stop (NMDHCPClient *client, gboolean release) +real_stop (NMDHCPClient *client) { NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client); /* Chain up to parent */ - NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client, release); + NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client); if (priv->pid_file) remove (priv->pid_file); - - /* FIXME: implement release... */ } /***************************************************/ diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index d3c064199c..a1e3e5e24d 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -429,7 +429,7 @@ client_start (NMDHCPManager *self, /* Kill any old client instance */ client = get_client_for_iface (self, iface, ipv6); if (client) { - nm_dhcp_client_stop (client, FALSE); + nm_dhcp_client_stop (client); remove_client (self, client); } diff --git a/src/nm-device.c b/src/nm-device.c index b9701a399e..34a9c23a2f 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -184,8 +184,8 @@ static NMActStageReturn dhcp6_start (NMDevice *self, NMDeviceStateReason *reason); static void addrconf6_cleanup (NMDevice *self); -static void dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release); -static void dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release); +static void dhcp6_cleanup (NMDevice *self, gboolean stop); +static void dhcp4_cleanup (NMDevice *self, gboolean stop); static void @@ -1467,7 +1467,7 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data) if (!nm_device_get_act_request (device)) return; - nm_dhcp_client_stop (client, FALSE); + nm_dhcp_client_stop (client); if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { if (nm_dhcp_client_get_ipv6 (client)) @@ -1480,16 +1480,17 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data) static NMActStageReturn dhcp4_start (NMDevice *self, NMConnection *connection, + NMSettingIP4Config *s_ip4, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMSettingConnection *s_con; - NMSettingIP4Config *s_ip4; guint8 *anycast = NULL; s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); g_assert (s_con); - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + + /* Begin a DHCP transaction on the interface */ if (priv->dhcp_anycast_address) anycast = priv->dhcp_anycast_address->data; @@ -1499,7 +1500,6 @@ dhcp4_start (NMDevice *self, g_object_unref (priv->dhcp4_config); priv->dhcp4_config = nm_dhcp4_config_new (); - /* Begin DHCP on the interface */ g_warn_if_fail (priv->dhcp4_client == NULL); priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager, nm_device_get_ip_iface (self), @@ -1525,31 +1525,6 @@ dhcp4_start (NMDevice *self, return NM_ACT_STAGE_RETURN_POSTPONE; } -gboolean -nm_device_dhcp4_renew (NMDevice *self, gboolean release) -{ - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMActStageReturn ret; - NMDeviceStateReason reason; - NMActRequest *req; - NMConnection *connection; - - g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE); - - /* Terminate old DHCP instance and release the old lease */ - dhcp4_cleanup (self, TRUE, TRUE); - - req = nm_device_get_act_request (self); - g_assert (req); - connection = nm_act_request_get_connection (req); - g_assert (connection); - - /* Start DHCP again on the interface */ - ret = dhcp4_start (self, connection, &reason); - - return (ret != NM_ACT_STAGE_RETURN_FAILURE); -} - static NMActStageReturn real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) { @@ -1579,7 +1554,7 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) method = nm_setting_ip4_config_get_method (s_ip4); if (!s_ip4 || !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - ret = dhcp4_start (self, connection, reason); + ret = dhcp4_start (self, connection, s_ip4, reason); } else if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { GError *error = NULL; const char *iface = nm_device_get_iface (self); @@ -2700,7 +2675,7 @@ delayed_transitions_clear (NMDevice *self) } static void -dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) +dhcp4_cleanup (NMDevice *self, gboolean stop) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -2723,7 +2698,7 @@ dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) } if (stop) - nm_dhcp_client_stop (priv->dhcp4_client, release); + nm_dhcp_client_stop (priv->dhcp4_client); g_object_unref (priv->dhcp4_client); priv->dhcp4_client = NULL; @@ -2731,7 +2706,7 @@ dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) } static void -dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release) +dhcp6_cleanup (NMDevice *self, gboolean stop) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -2755,7 +2730,7 @@ dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release) } if (stop) - nm_dhcp_client_stop (priv->dhcp6_client, release); + nm_dhcp_client_stop (priv->dhcp6_client); g_object_unref (priv->dhcp6_client); priv->dhcp6_client = NULL; @@ -2804,8 +2779,8 @@ nm_device_deactivate_quickly (NMDevice *self) /* Clear any delayed transitions */ delayed_transitions_clear (self); - dhcp4_cleanup (self, TRUE, FALSE); - dhcp6_cleanup (self, TRUE, FALSE); + dhcp4_cleanup (self, TRUE); + dhcp6_cleanup (self, TRUE); addrconf6_cleanup (self); dnsmasq_cleanup (self); aipd_cleanup (self); @@ -3382,8 +3357,8 @@ dispose (GObject *object) delayed_transitions_clear (self); /* Clean up and stop DHCP */ - dhcp4_cleanup (self, take_down, FALSE); - dhcp6_cleanup (self, take_down, FALSE); + dhcp4_cleanup (self, take_down); + dhcp6_cleanup (self, take_down); addrconf6_cleanup (self); dnsmasq_cleanup (self); diff --git a/src/nm-device.h b/src/nm-device.h index bd400fd6bf..db2b1b7db0 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -185,8 +185,6 @@ void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr); void nm_device_clear_autoconnect_inhibit (NMDevice *device); -gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); - G_END_DECLS #endif /* NM_DEVICE_H */ diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 870759e333..bbb14718f2 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -587,33 +587,12 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_POSTPONE; } -static void -force_disconnect (struct wmxsdk *sdk) -{ - WIMAX_API_DEVICE_STATUS status; - int ret; - - g_return_if_fail (sdk != NULL); - - status = iwmxsdk_status_get (sdk); - if ((int) status < 0) { - nm_log_err (LOGD_WIMAX, "Failed to read WiMAX device status: %d", status); - return; - } - - if ( status == WIMAX_API_DEVICE_STATUS_Connecting - || status == WIMAX_API_DEVICE_STATUS_Data_Connected) { - ret = iwmx_sdk_disconnect (sdk); - if (ret < 0 && ret != -EINPROGRESS) { - nm_log_err (LOGD_WIMAX, "Failed to disconnect WiMAX device: %d", ret); - } - } -} - static void real_deactivate_quickly (NMDevice *device) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); + WIMAX_API_DEVICE_STATUS status; + int ret; clear_activation_timeout (NM_DEVICE_WIMAX (device)); clear_link_timeout (NM_DEVICE_WIMAX (device)); @@ -624,7 +603,18 @@ real_deactivate_quickly (NMDevice *device) /* Read explicit status here just to make sure we have the most * up-to-date status and to ensure we disconnect if needed. */ - force_disconnect (priv->sdk); + status = iwmxsdk_status_get (priv->sdk); + if ((int) status < 0) { + nm_log_err (LOGD_WIMAX, "Failed to read WiMAX device status: %d", status); + } else { + if ( status == WIMAX_API_DEVICE_STATUS_Connecting + || status == WIMAX_API_DEVICE_STATUS_Data_Connected) { + ret = iwmx_sdk_disconnect (priv->sdk); + if (ret < 0 && ret != -EINPROGRESS) { + nm_log_err (LOGD_WIMAX, "Failed to disconnect WiMAX device: %d", ret); + } + } + } } } @@ -672,14 +662,10 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, return; } break; - case WIMAX_API_DEVICE_STATUS_Connecting: - case WIMAX_API_DEVICE_STATUS_Data_Connected: - /* If for some reason we're initially connected, force a disconnect here */ - if (state < NM_DEVICE_STATE_DISCONNECTED) - force_disconnect (wmxsdk); - /* Fall through */ 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: if (priv->wimaxd_enabled == FALSE) { priv->wimaxd_enabled = TRUE; if (update_availability (self, old_available)) From 6ae91e2f6737438ad50d095bd2095d008a89aa38 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 15:39:07 -0600 Subject: [PATCH 081/102] wimax: if the device is connected at startup, force it to disconnect Otherwise it doesn't auto-scan and we get no network list. As a later optimization, we could detect this, call iwmx_sdk_get_connected_network() to get the current NSP, match that up with a connection, and "assume" the connection like we do for Ethernet devices. --- src/wimax/nm-device-wimax.c | 46 ++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index bbb14718f2..870759e333 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -587,12 +587,33 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) return NM_ACT_STAGE_RETURN_POSTPONE; } +static void +force_disconnect (struct wmxsdk *sdk) +{ + WIMAX_API_DEVICE_STATUS status; + int ret; + + g_return_if_fail (sdk != NULL); + + status = iwmxsdk_status_get (sdk); + if ((int) status < 0) { + nm_log_err (LOGD_WIMAX, "Failed to read WiMAX device status: %d", status); + return; + } + + if ( status == WIMAX_API_DEVICE_STATUS_Connecting + || status == WIMAX_API_DEVICE_STATUS_Data_Connected) { + ret = iwmx_sdk_disconnect (sdk); + if (ret < 0 && ret != -EINPROGRESS) { + nm_log_err (LOGD_WIMAX, "Failed to disconnect WiMAX device: %d", ret); + } + } +} + static void real_deactivate_quickly (NMDevice *device) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); - WIMAX_API_DEVICE_STATUS status; - int ret; clear_activation_timeout (NM_DEVICE_WIMAX (device)); clear_link_timeout (NM_DEVICE_WIMAX (device)); @@ -603,18 +624,7 @@ real_deactivate_quickly (NMDevice *device) /* Read explicit status here just to make sure we have the most * up-to-date status and to ensure we disconnect if needed. */ - status = iwmxsdk_status_get (priv->sdk); - if ((int) status < 0) { - nm_log_err (LOGD_WIMAX, "Failed to read WiMAX device status: %d", status); - } else { - if ( status == WIMAX_API_DEVICE_STATUS_Connecting - || status == WIMAX_API_DEVICE_STATUS_Data_Connected) { - ret = iwmx_sdk_disconnect (priv->sdk); - if (ret < 0 && ret != -EINPROGRESS) { - nm_log_err (LOGD_WIMAX, "Failed to disconnect WiMAX device: %d", ret); - } - } - } + force_disconnect (priv->sdk); } } @@ -662,10 +672,14 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, return; } 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: + /* If for some reason we're initially connected, force a disconnect here */ + if (state < NM_DEVICE_STATE_DISCONNECTED) + force_disconnect (wmxsdk); + /* Fall through */ + case WIMAX_API_DEVICE_STATUS_Ready: + case WIMAX_API_DEVICE_STATUS_Scanning: if (priv->wimaxd_enabled == FALSE) { priv->wimaxd_enabled = TRUE; if (update_availability (self, old_available)) From 9917da2c71f75426b7a2891db0d5797ab8b0481f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 16:23:00 -0600 Subject: [PATCH 082/102] dhcp: add DHCP lease release capability --- src/dhcp-manager/nm-dhcp-client.c | 16 +++--- src/dhcp-manager/nm-dhcp-client.h | 25 +++++---- src/dhcp-manager/nm-dhcp-dhclient.c | 79 ++++++++++++++++++++--------- src/dhcp-manager/nm-dhcp-dhcpcd.c | 6 ++- src/dhcp-manager/nm-dhcp-manager.c | 2 +- src/nm-device.c | 55 ++++++++++++++------ src/nm-device.h | 2 + 7 files changed, 123 insertions(+), 62 deletions(-) diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 3a8b194081..c4dfec64d7 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -136,10 +136,10 @@ watch_cleanup (NMDHCPClient *self) } } -static void -stop_process (GPid pid, const char *iface) +void +nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs) { - int i = 15; /* 3 seconds */ + int i = (timeout_secs ? timeout_secs : 3) * 5; /* default 3 seconds */ g_return_if_fail (pid > 0); @@ -183,7 +183,7 @@ stop_process (GPid pid, const char *iface) } static void -real_stop (NMDHCPClient *self) +real_stop (NMDHCPClient *self, gboolean release) { NMDHCPClientPrivate *priv; @@ -196,7 +196,7 @@ real_stop (NMDHCPClient *self) /* Clean up the watch handler since we're explicitly killing the daemon */ watch_cleanup (self); - stop_process (priv->pid, priv->iface); + nm_dhcp_client_stop_pid (priv->pid, priv->iface, 0); priv->info_only = FALSE; } @@ -376,7 +376,7 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) exe = proc_contents; if (!strcmp (exe, binary_name)) - stop_process ((GPid) tmp, NULL); + nm_dhcp_client_stop_pid ((GPid) tmp, NULL, 0); } } @@ -387,7 +387,7 @@ nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name) } void -nm_dhcp_client_stop (NMDHCPClient *self) +nm_dhcp_client_stop (NMDHCPClient *self, gboolean release) { NMDHCPClientPrivate *priv; @@ -398,7 +398,7 @@ nm_dhcp_client_stop (NMDHCPClient *self) /* Kill the DHCP client */ if (!priv->dead) { - NM_DHCP_CLIENT_GET_CLASS (self)->stop (self); + NM_DHCP_CLIENT_GET_CLASS (self)->stop (self, release); priv->dead = TRUE; nm_log_info (LOGD_DHCP, "(%s): canceled DHCP transaction, DHCP client pid %d", diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index f357170b9c..19c7365edc 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -76,18 +76,19 @@ typedef struct { /* Methods */ - GPid (*ip4_start) (NMDHCPClient *self, - NMSettingIP4Config *s_ip4, - guint8 *anycast_addr, - const char *hostname); + GPid (*ip4_start) (NMDHCPClient *self, + NMSettingIP4Config *s_ip4, + guint8 *anycast_addr, + const char *hostname); - GPid (*ip6_start) (NMDHCPClient *self, - NMSettingIP6Config *s_ip6, - guint8 *anycast_addr, - const char *hostname, - gboolean info_only); + GPid (*ip6_start) (NMDHCPClient *self, + NMSettingIP6Config *s_ip6, + guint8 *anycast_addr, + const char *hostname, + gboolean info_only); - void (*stop) (NMDHCPClient *self); + void (*stop) (NMDHCPClient *self, + gboolean release); /* Signals */ void (*state_changed) (NMDHCPClient *self, NMDHCPState state); @@ -116,7 +117,7 @@ gboolean nm_dhcp_client_start_ip6 (NMDHCPClient *self, const char *hostname, gboolean info_only); -void nm_dhcp_client_stop (NMDHCPClient *self); +void nm_dhcp_client_stop (NMDHCPClient *self, gboolean release); void nm_dhcp_client_new_options (NMDHCPClient *self, GHashTable *options, @@ -133,5 +134,7 @@ NMIP6Config *nm_dhcp_client_get_ip6_config (NMDHCPClient *self, gboolean test) /* Backend helpers */ void nm_dhcp_client_stop_existing (const char *pid_file, const char *binary_name); +void nm_dhcp_client_stop_pid (GPid pid, const char *iface, guint timeout_secs); + #endif /* NM_DHCP_CLIENT_H */ diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index f6f2a540dc..75684459f6 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -411,15 +411,15 @@ dhclient_child_setup (gpointer user_data G_GNUC_UNUSED) static GPid dhclient_start (NMDHCPClient *client, - const char *ip_opt, - const char *mode_opt) + const char *mode_opt, + gboolean release) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); GPtrArray *argv = NULL; GPid pid = -1; GError *error = NULL; const char *iface, *uuid; - char *binary_name, *cmd_str; + char *binary_name, *cmd_str, *pid_file = NULL; gboolean ipv6; guint log_domain; @@ -436,28 +436,33 @@ dhclient_start (NMDHCPClient *client, nm_log_warn (log_domain, "(%s): ISC dhcp3 does not support IPv6", iface); return -1; } -#else - g_return_val_if_fail (ip_opt != NULL, -1); #endif - priv->pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid", - ipv6 ? "6" : "", - iface); - if (!priv->pid_file) { - nm_log_warn (log_domain, "(%s): not enough memory for dhcpcd options.", iface); - return -1; - } - if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) { nm_log_warn (log_domain, "%s does not exist.", priv->path); return -1; } + pid_file = g_strdup_printf (LOCALSTATEDIR "/run/dhclient%s-%s.pid", + ipv6 ? "6" : "", + iface); + if (!pid_file) { + nm_log_warn (log_domain, "(%s): not enough memory for dhcpcd options.", iface); + return -1; + } + /* Kill any existing dhclient from the pidfile */ binary_name = g_path_get_basename (priv->path); - nm_dhcp_client_stop_existing (priv->pid_file, binary_name); + nm_dhcp_client_stop_existing (pid_file, binary_name); g_free (binary_name); + if (release) { + /* release doesn't use the pidfile after killing an old client */ + g_free (pid_file); + pid_file = NULL; + } + + g_free (priv->lease_file); priv->lease_file = get_leasefile_for_iface (iface, uuid, ipv6); if (!priv->lease_file) { nm_log_warn (log_domain, "(%s): not enough memory for dhclient options.", iface); @@ -469,17 +474,26 @@ dhclient_start (NMDHCPClient *client, g_ptr_array_add (argv, (gpointer) "-d"); + if (release) + g_ptr_array_add (argv, (gpointer) "-r"); + #if !defined(DHCLIENT_V3) - g_ptr_array_add (argv, (gpointer) ip_opt); - if (mode_opt) - g_ptr_array_add (argv, (gpointer) mode_opt); + if (ipv6) { + g_ptr_array_add (argv, (gpointer) "-6"); + if (mode_opt) + g_ptr_array_add (argv, (gpointer) mode_opt); + } else { + g_ptr_array_add (argv, (gpointer) "-4"); + } #endif g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ g_ptr_array_add (argv, (gpointer) ACTION_SCRIPT_PATH ); - g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ - g_ptr_array_add (argv, (gpointer) priv->pid_file); + if (pid_file) { + g_ptr_array_add (argv, (gpointer) "-pf"); /* Set pid file */ + g_ptr_array_add (argv, (gpointer) pid_file); + } g_ptr_array_add (argv, (gpointer) "-lf"); /* Set lease file */ g_ptr_array_add (argv, (gpointer) priv->lease_file); @@ -501,8 +515,10 @@ dhclient_start (NMDHCPClient *client, nm_log_warn (log_domain, "dhclient failed to start: '%s'", error->message); g_error_free (error); pid = -1; - } else + } else { nm_log_info (log_domain, "dhclient started with pid %d", pid); + priv->pid_file = pid_file; + } g_ptr_array_free (argv, TRUE); return pid; @@ -525,7 +541,7 @@ real_ip4_start (NMDHCPClient *client, return -1; } - return dhclient_start (client, "-4", NULL); + return dhclient_start (client, NULL, FALSE); } static GPid @@ -535,21 +551,34 @@ real_ip6_start (NMDHCPClient *client, const char *hostname, gboolean info_only) { - return dhclient_start (client, "-6", info_only ? "-S" : "-N"); + return dhclient_start (client, info_only ? "-S" : "-N", FALSE); } static void -real_stop (NMDHCPClient *client) +real_stop (NMDHCPClient *client, gboolean release) { NMDHCPDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (client); /* Chain up to parent */ - NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client); + NM_DHCP_CLIENT_CLASS (nm_dhcp_dhclient_parent_class)->stop (client, release); if (priv->conf_file) remove (priv->conf_file); - if (priv->pid_file) + if (priv->pid_file) { remove (priv->pid_file); + g_free (priv->pid_file); + priv->pid_file = NULL; + } + + if (release) { + GPid rpid; + + rpid = dhclient_start (client, NULL, TRUE); + if (rpid > 0) { + /* Wait a few seconds for the release to happen */ + nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client), 5); + } + } } /***************************************************/ diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index 4fb703c480..237661fe47 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -170,15 +170,17 @@ real_ip6_start (NMDHCPClient *client, } static void -real_stop (NMDHCPClient *client) +real_stop (NMDHCPClient *client, gboolean release) { NMDHCPDhcpcdPrivate *priv = NM_DHCP_DHCPCD_GET_PRIVATE (client); /* Chain up to parent */ - NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client); + NM_DHCP_CLIENT_CLASS (nm_dhcp_dhcpcd_parent_class)->stop (client, release); if (priv->pid_file) remove (priv->pid_file); + + /* FIXME: implement release... */ } /***************************************************/ diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index a1e3e5e24d..d3c064199c 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -429,7 +429,7 @@ client_start (NMDHCPManager *self, /* Kill any old client instance */ client = get_client_for_iface (self, iface, ipv6); if (client) { - nm_dhcp_client_stop (client); + nm_dhcp_client_stop (client, FALSE); remove_client (self, client); } diff --git a/src/nm-device.c b/src/nm-device.c index 34a9c23a2f..b9701a399e 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -184,8 +184,8 @@ static NMActStageReturn dhcp6_start (NMDevice *self, NMDeviceStateReason *reason); static void addrconf6_cleanup (NMDevice *self); -static void dhcp6_cleanup (NMDevice *self, gboolean stop); -static void dhcp4_cleanup (NMDevice *self, gboolean stop); +static void dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release); +static void dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release); static void @@ -1467,7 +1467,7 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data) if (!nm_device_get_act_request (device)) return; - nm_dhcp_client_stop (client); + nm_dhcp_client_stop (client, FALSE); if (nm_device_get_state (device) == NM_DEVICE_STATE_IP_CONFIG) { if (nm_dhcp_client_get_ipv6 (client)) @@ -1480,17 +1480,16 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data) static NMActStageReturn dhcp4_start (NMDevice *self, NMConnection *connection, - NMSettingIP4Config *s_ip4, NMDeviceStateReason *reason) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMSettingConnection *s_con; + NMSettingIP4Config *s_ip4; guint8 *anycast = NULL; s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); g_assert (s_con); - - /* Begin a DHCP transaction on the interface */ + s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); if (priv->dhcp_anycast_address) anycast = priv->dhcp_anycast_address->data; @@ -1500,6 +1499,7 @@ dhcp4_start (NMDevice *self, g_object_unref (priv->dhcp4_config); priv->dhcp4_config = nm_dhcp4_config_new (); + /* Begin DHCP on the interface */ g_warn_if_fail (priv->dhcp4_client == NULL); priv->dhcp4_client = nm_dhcp_manager_start_ip4 (priv->dhcp_manager, nm_device_get_ip_iface (self), @@ -1525,6 +1525,31 @@ dhcp4_start (NMDevice *self, return NM_ACT_STAGE_RETURN_POSTPONE; } +gboolean +nm_device_dhcp4_renew (NMDevice *self, gboolean release) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMActStageReturn ret; + NMDeviceStateReason reason; + NMActRequest *req; + NMConnection *connection; + + g_return_val_if_fail (priv->dhcp4_client != NULL, FALSE); + + /* Terminate old DHCP instance and release the old lease */ + dhcp4_cleanup (self, TRUE, TRUE); + + req = nm_device_get_act_request (self); + g_assert (req); + connection = nm_act_request_get_connection (req); + g_assert (connection); + + /* Start DHCP again on the interface */ + ret = dhcp4_start (self, connection, &reason); + + return (ret != NM_ACT_STAGE_RETURN_FAILURE); +} + static NMActStageReturn real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) { @@ -1554,7 +1579,7 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) method = nm_setting_ip4_config_get_method (s_ip4); if (!s_ip4 || !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) { - ret = dhcp4_start (self, connection, s_ip4, reason); + ret = dhcp4_start (self, connection, reason); } else if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) { GError *error = NULL; const char *iface = nm_device_get_iface (self); @@ -2675,7 +2700,7 @@ delayed_transitions_clear (NMDevice *self) } static void -dhcp4_cleanup (NMDevice *self, gboolean stop) +dhcp4_cleanup (NMDevice *self, gboolean stop, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -2698,7 +2723,7 @@ dhcp4_cleanup (NMDevice *self, gboolean stop) } if (stop) - nm_dhcp_client_stop (priv->dhcp4_client); + nm_dhcp_client_stop (priv->dhcp4_client, release); g_object_unref (priv->dhcp4_client); priv->dhcp4_client = NULL; @@ -2706,7 +2731,7 @@ dhcp4_cleanup (NMDevice *self, gboolean stop) } static void -dhcp6_cleanup (NMDevice *self, gboolean stop) +dhcp6_cleanup (NMDevice *self, gboolean stop, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -2730,7 +2755,7 @@ dhcp6_cleanup (NMDevice *self, gboolean stop) } if (stop) - nm_dhcp_client_stop (priv->dhcp6_client); + nm_dhcp_client_stop (priv->dhcp6_client, release); g_object_unref (priv->dhcp6_client); priv->dhcp6_client = NULL; @@ -2779,8 +2804,8 @@ nm_device_deactivate_quickly (NMDevice *self) /* Clear any delayed transitions */ delayed_transitions_clear (self); - dhcp4_cleanup (self, TRUE); - dhcp6_cleanup (self, TRUE); + dhcp4_cleanup (self, TRUE, FALSE); + dhcp6_cleanup (self, TRUE, FALSE); addrconf6_cleanup (self); dnsmasq_cleanup (self); aipd_cleanup (self); @@ -3357,8 +3382,8 @@ dispose (GObject *object) delayed_transitions_clear (self); /* Clean up and stop DHCP */ - dhcp4_cleanup (self, take_down); - dhcp6_cleanup (self, take_down); + dhcp4_cleanup (self, take_down, FALSE); + dhcp6_cleanup (self, take_down, FALSE); addrconf6_cleanup (self); dnsmasq_cleanup (self); diff --git a/src/nm-device.h b/src/nm-device.h index db2b1b7db0..bd400fd6bf 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -185,6 +185,8 @@ void nm_device_set_dhcp_anycast_address (NMDevice *device, guint8 *addr); void nm_device_clear_autoconnect_inhibit (NMDevice *device); +gboolean nm_device_dhcp4_renew (NMDevice *device, gboolean release); + G_END_DECLS #endif /* NM_DEVICE_H */ From 5cbe6da10eb591b55dfe5f5f2d1b79f4507a6c87 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 16:23:22 -0600 Subject: [PATCH 083/102] wimax: release and renew DHCP lease when requested by wimaxd --- src/wimax/nm-device-wimax.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 870759e333..3fe1768cac 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -738,9 +738,10 @@ link_timeout_cb (gpointer user_data) priv->link_timeout_id = 0; + nm_log_dbg (LOGD_WIMAX, "(%s): link timed out", nm_device_get_iface (NM_DEVICE (self))); nm_device_state_changed (NM_DEVICE (self), - NM_DEVICE_STATE_FAILED, - NM_DEVICE_STATE_REASON_CARRIER); + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_CARRIER); return FALSE; } @@ -771,9 +772,16 @@ wmx_media_status_cb (struct wmxsdk *wmxsdk, case WIMAX_API_MEDIA_STATUS_LINK_UP: break; case WIMAX_API_MEDIA_STATUS_LINK_DOWN: + nm_log_dbg (LOGD_WIMAX, "(%s): starting link timeout", iface); priv->link_timeout_id = g_timeout_add (15, link_timeout_cb, self); break; case WIMAX_API_MEDIA_STATUS_LINK_RENEW: + nm_log_dbg (LOGD_WIMAX, "(%s): renewing DHCP lease", iface); + if (!nm_device_dhcp4_renew (NM_DEVICE (self), TRUE)) { + nm_device_state_changed (NM_DEVICE (self), + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_REASON_DHCP_FAILED); + } break; default: nm_log_err (LOGD_WIMAX, "(%s): unhandled media status %d", iface, new_status); From 89095e9fa75e974473b0c485a5e68ea0ddefe55d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 16:30:58 -0600 Subject: [PATCH 084/102] wimax: fix debug log format string --- src/wimax/nm-device-wimax.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 3fe1768cac..fbfcb46660 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -759,7 +759,7 @@ wmx_media_status_cb (struct wmxsdk *wmxsdk, iface = nm_device_get_iface (NM_DEVICE (self)); state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); - nm_log_dbg (LOGD_WIMAX, "(%s): media status change to %d", + nm_log_dbg (LOGD_WIMAX, "(%s): media status change to %s", iface, iwmx_sdk_media_status_to_str (new_status)); /* We only care about media events while activated */ From f87e2251d7dcc434cdccf841918cd6b82cbd5ac7 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 16:34:51 -0600 Subject: [PATCH 085/102] wimax: turn off wimaxd's fast reconnect logic It eventually gets confusing for everyone. NM is the policy, so handle reconnect there. --- src/wimax/iwmxsdk.c | 21 +++++++++++++++++++++ src/wimax/iwmxsdk.h | 1 + src/wimax/nm-device-wimax.c | 1 + 3 files changed, 23 insertions(+) diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c index ab4b0ec1c4..d36967b126 100644 --- a/src/wimax/iwmxsdk.c +++ b/src/wimax/iwmxsdk.c @@ -873,6 +873,27 @@ error_get_status: return result; } +/* + * Turn fast reconnect capability on/off + * + * This function tells wimaxd to turn fast reconnect on or off. + */ +int iwmx_sdk_set_fast_reconnect_enabled(struct wmxsdk *wmxsdk, int enabled) +{ + WIMAX_API_RET r; + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + + r = SetFastReconnectCapabilityStatus(&wmxsdk->device_id, !!enabled); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot set fast reconnect to %d: %d (%s)", + enabled, r, errstr); + return -EIO; + } + return 0; +} + static void __iwmx_sdk_media_status_update_cb (WIMAX_API_DEVICE_ID_P device_id, WIMAX_API_MEDIA_STATUS mediaStatus) { diff --git a/src/wimax/iwmxsdk.h b/src/wimax/iwmxsdk.h index 1cef36fa3d..13e4ff7dc4 100644 --- a/src/wimax/iwmxsdk.h +++ b/src/wimax/iwmxsdk.h @@ -95,6 +95,7 @@ void iwmx_sdk_set_callbacks(struct wmxsdk *wmxsdk, WIMAX_API_DEVICE_STATUS iwmxsdk_status_get(struct wmxsdk *wmxsdk); int iwmx_sdk_connect(struct wmxsdk *wmxsdk, const char *nsp_name); int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk); +int iwmx_sdk_set_fast_reconnect_enabled(struct wmxsdk *wmxsdk, int enabled); WIMAX_API_CONNECTED_NSP_INFO_EX *iwmx_sdk_get_connected_network(struct wmxsdk *wmxsdk); const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status); const char *iwmx_sdk_reason_to_str(WIMAX_API_STATUS_REASON reason); diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index fbfcb46660..ef105a725b 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -969,6 +969,7 @@ wmx_new_sdk_cb (struct wmxsdk *sdk, void *user_data) wmx_scan_result_cb, wmx_removed_cb, self); + iwmx_sdk_set_fast_reconnect_enabled (priv->sdk, 0); if (!priv->sdk_action_defer_id) priv->sdk_action_defer_id = g_idle_add (sdk_action_defer_cb, self); From 13794bfeb67063a2476189264e2a3ed431d69323 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 16:57:56 -0600 Subject: [PATCH 086/102] wimax: poll connected network signal strength --- src/wimax/nm-device-wimax.c | 65 +++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index ef105a725b..3a8ed421d8 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010 - 2011 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. */ @@ -89,6 +89,7 @@ typedef struct { guint sdk_action_defer_id; guint link_timeout_id; + guint poll_id; GSList *nsp_list; NMWimaxNsp *current_nsp; @@ -523,6 +524,17 @@ clear_link_timeout (NMDeviceWimax *self) } } +static void +clear_connected_poll (NMDeviceWimax *self) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (priv->poll_id) { + g_source_remove (priv->poll_id); + priv->poll_id = 0; + } +} + static NMActStageReturn real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { @@ -613,12 +625,14 @@ force_disconnect (struct wmxsdk *sdk) static void real_deactivate_quickly (NMDevice *device) { - NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); + NMDeviceWimax *self = NM_DEVICE_WIMAX (device); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); - clear_activation_timeout (NM_DEVICE_WIMAX (device)); - clear_link_timeout (NM_DEVICE_WIMAX (device)); + clear_activation_timeout (self); + clear_link_timeout (self); + clear_connected_poll (self); - set_current_nsp (NM_DEVICE_WIMAX (device), NULL); + set_current_nsp (self, NULL); if (priv->sdk) { /* Read explicit status here just to make sure we have the most @@ -913,6 +927,38 @@ wmx_removed_cb (struct wmxsdk *wmxsdk, void *user_data) /*************************************************************************/ +static gboolean +connected_poll_cb (gpointer user_data) +{ + NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + WIMAX_API_CONNECTED_NSP_INFO_EX *sdk_nsp; + + g_return_val_if_fail (priv->sdk != NULL, FALSE); + sdk_nsp = iwmx_sdk_get_connected_network (priv->sdk); + if (sdk_nsp) { + const char *nsp_name = (const char *) sdk_nsp->NSPName; + NMWimaxNspNetworkType net_type; + NMWimaxNsp *nsp; + + nsp = get_nsp_by_name (self, nsp_name); + if (nsp) { + net_type = nm_wimax_util_convert_network_type (sdk_nsp->networkType); + g_object_set (nsp, + NM_WIMAX_NSP_SIGNAL_QUALITY, sdk_nsp->linkQuality, + NM_WIMAX_NSP_NETWORK_TYPE, net_type, + NULL); + + nm_log_dbg (LOGD_WIMAX, "(%s): WiMAX NSP '%s' quality %d%% type %d", + nm_device_get_iface (NM_DEVICE (self)), + nsp_name, sdk_nsp->linkQuality, net_type); + } + free (sdk_nsp); + } + + return TRUE; /* reschedule */ +} + static void device_state_changed (NMDevice *device, NMDeviceState new_state, @@ -936,8 +982,14 @@ device_state_changed (NMDevice *device, if (new_state == NM_DEVICE_STATE_FAILED || new_state <= NM_DEVICE_STATE_DISCONNECTED) clear_activation_timeout (self); - if (new_state != NM_DEVICE_STATE_ACTIVATED) + if (new_state == NM_DEVICE_STATE_ACTIVATED) { + /* poll link quality and BSID */ + clear_connected_poll (self); + priv->poll_id = g_timeout_add_seconds (10, connected_poll_cb, self); + } else { clear_link_timeout (self); + clear_connected_poll (self); + } } /*************************************************************************/ @@ -1078,6 +1130,7 @@ dispose (GObject *object) clear_activation_timeout (self); clear_link_timeout (self); + clear_connected_poll (self); if (priv->sdk_action_defer_id) g_source_remove (priv->sdk_action_defer_id); From 6ab1f4f420b488f934b1184c9076372dc2d010fa Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 17:39:14 -0600 Subject: [PATCH 087/102] wimax: only update NSP properties if they've changed --- src/wimax/nm-device-wimax.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 3a8ed421d8..cf6b08f195 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -878,6 +878,7 @@ wmx_scan_result_cb (struct wmxsdk *wmxsdk, WIMAX_API_NSP_INFO_EX *sdk_nsp = &nsps[i]; const char *nsp_name = (const char *) sdk_nsp->NSPName; NMWimaxNspNetworkType net_type; + guint signalq; NMWimaxNsp *nsp; gboolean new_nsp; @@ -889,10 +890,12 @@ wmx_scan_result_cb (struct wmxsdk *wmxsdk, } net_type = nm_wimax_util_convert_network_type (sdk_nsp->networkType); - g_object_set (nsp, - NM_WIMAX_NSP_SIGNAL_QUALITY, sdk_nsp->linkQuality, - NM_WIMAX_NSP_NETWORK_TYPE, net_type, - NULL); + if (net_type != nm_wimax_nsp_get_network_type (nsp)) + g_object_set (nsp, NM_WIMAX_NSP_NETWORK_TYPE, net_type, NULL); + + signalq = sdk_nsp->linkQuality; + if (signalq != nm_wimax_nsp_get_signal_quality (nsp)) + g_object_set (nsp, NM_WIMAX_NSP_SIGNAL_QUALITY, signalq, NULL); nm_log_dbg (LOGD_WIMAX, "(%s): WiMAX NSP '%s' quality %d%% type %d", iface, nsp_name, sdk_nsp->linkQuality, net_type); @@ -938,16 +941,20 @@ connected_poll_cb (gpointer user_data) sdk_nsp = iwmx_sdk_get_connected_network (priv->sdk); if (sdk_nsp) { const char *nsp_name = (const char *) sdk_nsp->NSPName; - NMWimaxNspNetworkType net_type; NMWimaxNsp *nsp; nsp = get_nsp_by_name (self, nsp_name); if (nsp) { + NMWimaxNspNetworkType net_type; + guint signalq; + net_type = nm_wimax_util_convert_network_type (sdk_nsp->networkType); - g_object_set (nsp, - NM_WIMAX_NSP_SIGNAL_QUALITY, sdk_nsp->linkQuality, - NM_WIMAX_NSP_NETWORK_TYPE, net_type, - NULL); + if (net_type != nm_wimax_nsp_get_network_type (nsp)) + g_object_set (nsp, NM_WIMAX_NSP_NETWORK_TYPE, net_type, NULL); + + signalq = sdk_nsp->linkQuality; + if (signalq != nm_wimax_nsp_get_signal_quality (nsp)) + g_object_set (nsp, NM_WIMAX_NSP_SIGNAL_QUALITY, signalq, NULL); nm_log_dbg (LOGD_WIMAX, "(%s): WiMAX NSP '%s' quality %d%% type %d", nm_device_get_iface (NM_DEVICE (self)), From 6971dcd34e86027851f6b391520b65273b2ac786 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 17:54:05 -0600 Subject: [PATCH 088/102] wimax: logging cleanup --- src/wimax/nm-device-wimax.c | 43 +++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index cf6b08f195..1c34836c96 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -259,7 +259,6 @@ update_availability (NMDeviceWimax *self, gboolean old_available) gboolean new_available, changed = FALSE; new_available = nm_device_is_available (device); -nm_log_dbg (LOGD_WIMAX, "old_avail %d, new_avail %d", old_available, new_available); if (new_available == old_available) return FALSE; @@ -292,22 +291,28 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled) NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); gboolean old_available; int ret; + const char *iface; -nm_log_dbg (LOGD_WIMAX, "setting wimax enabled %d (was %d)", enabled, priv->enabled); + iface = nm_device_get_iface (NM_DEVICE (self)); + + nm_log_dbg (LOGD_WIMAX, "(%s): setting radio enabled %d -> %d", + iface, priv->enabled, enabled); if (priv->enabled == enabled) return; old_available = nm_device_is_available (NM_DEVICE (device)); priv->enabled = enabled; -nm_log_dbg (LOGD_WIMAX, "wimax enabled changed to %d", priv->enabled); + + nm_log_dbg (LOGD_WIMAX, "(%s): radio now %s", + iface, priv->enabled ? "enabled" : "disabled"); /* Set the WiMAX device RF state to the current user-specified enabled state */ if (priv->sdk) { ret = iwmx_sdk_rf_state_set (priv->sdk, enabled ? WIMAX_API_RF_ON : WIMAX_API_RF_OFF); if (ret < 0 && ret != -EINPROGRESS) { - nm_log_warn (LOGD_WIMAX, "failed to %s WiMAX radio", - priv->enabled ? "enable" : "disable"); + nm_log_warn (LOGD_WIMAX, "(%s): failed to %s radio", + iface, priv->enabled ? "enable" : "disable"); } } @@ -355,10 +360,13 @@ real_update_hw_address (NMDevice *dev) NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); struct ifreq req; int fd; + const char *iface; + + iface = nm_device_get_iface (dev); fd = socket (PF_INET, SOCK_DGRAM, 0); if (fd < 0) { - nm_log_warn (LOGD_HW, "couldn't open control socket."); + nm_log_warn (LOGD_HW, "(%s): couldn't open control socket.", iface); return; } @@ -368,8 +376,8 @@ real_update_hw_address (NMDevice *dev) errno = 0; if (ioctl (fd, SIOCGIFHWADDR, &req) < 0) { nm_log_err (LOGD_HW | LOGD_WIMAX, - "(%s) failed to read hardware address (error %d)", - nm_device_get_iface (dev), errno); + "(%s): failed to read hardware address (error %d)", + iface, errno); } else { memcpy (&priv->hw_addr, &req.ifr_hwaddr.sa_data, ETH_ALEN); g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_HW_ADDRESS); @@ -588,7 +596,8 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) priv->connect_failed = FALSE; ret = iwmx_sdk_connect (priv->sdk, nsp); if (ret < 0 && ret != -EINPROGRESS) { - nm_log_err (LOGD_WIMAX, "Failed to connect to NSP '%s'", nsp); + nm_log_err (LOGD_WIMAX, "(%s): failed to connect to NSP '%s'", + nm_device_get_iface (device), nsp); *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED; return NM_ACT_STAGE_RETURN_FAILURE; } @@ -600,24 +609,30 @@ real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) } static void -force_disconnect (struct wmxsdk *sdk) +force_disconnect (NMDeviceWimax *self, struct wmxsdk *sdk) { WIMAX_API_DEVICE_STATUS status; int ret; + const char *iface; g_return_if_fail (sdk != NULL); + iface = nm_device_get_iface (NM_DEVICE (self)); + status = iwmxsdk_status_get (sdk); if ((int) status < 0) { - nm_log_err (LOGD_WIMAX, "Failed to read WiMAX device status: %d", status); + nm_log_err (LOGD_WIMAX, "(%s): failed to read WiMAX device status: %d", + iface, status); return; } if ( status == WIMAX_API_DEVICE_STATUS_Connecting || status == WIMAX_API_DEVICE_STATUS_Data_Connected) { + nm_log_dbg (LOGD_WIMAX, "(%s): requesting disconnect", iface); ret = iwmx_sdk_disconnect (sdk); if (ret < 0 && ret != -EINPROGRESS) { - nm_log_err (LOGD_WIMAX, "Failed to disconnect WiMAX device: %d", ret); + nm_log_err (LOGD_WIMAX, "(%s): failed to disconnect WiMAX device: %d", + iface, ret); } } } @@ -638,7 +653,7 @@ real_deactivate_quickly (NMDevice *device) /* Read explicit status here just to make sure we have the most * up-to-date status and to ensure we disconnect if needed. */ - force_disconnect (priv->sdk); + force_disconnect (self, priv->sdk); } } @@ -690,7 +705,7 @@ wmx_state_change_cb (struct wmxsdk *wmxsdk, case WIMAX_API_DEVICE_STATUS_Data_Connected: /* If for some reason we're initially connected, force a disconnect here */ if (state < NM_DEVICE_STATE_DISCONNECTED) - force_disconnect (wmxsdk); + force_disconnect (self, wmxsdk); /* Fall through */ case WIMAX_API_DEVICE_STATUS_Ready: case WIMAX_API_DEVICE_STATUS_Scanning: From 430151d6c2371bf0f0377356e149df2c7a25fd20 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 5 Jan 2011 18:23:08 -0600 Subject: [PATCH 089/102] build: make WiMAX support optional --- configure.ac | 17 ++++++++++++++- src/Makefile.am | 43 ++++++++++++++++++++++--------------- src/nm-manager.c | 6 +++++- src/nm-policy.c | 6 ++++++ src/nm-udev-manager.c | 11 +++++++--- src/wimax/Makefile.am | 4 ++-- src/wimax/nm-device-wimax.h | 1 - test/nm-tool.c | 10 +++++++++ 8 files changed, 73 insertions(+), 25 deletions(-) diff --git a/configure.ac b/configure.ac index ecdc05b0cd..77475dd4a0 100644 --- a/configure.ac +++ b/configure.ac @@ -268,7 +268,16 @@ PKG_CHECK_MODULES(UUID, uuid) AC_SUBST(UUID_CFLAGS) AC_SUBST(UUID_LIBS) -PKG_CHECK_MODULES(WIMAX, libiWmxSdk-0) +AC_ARG_ENABLE(wimax, AC_HELP_STRING([--enable-wimax], [enable WiMAX support]), + [enable_wimax=${enableval}], [enable_wimax=yes]) +if (test "${enable_wimax}" = "yes"); then + PKG_CHECK_MODULES(IWMX_SDK, libiWmxSdk-0, dummy=yes, + AC_MSG_ERROR(Intel WiMAX SDK is required)) + AC_SUBST(IWMX_SDK_CFLAGS) + AC_SUBST(IWMX_SDK_LIBS) + AC_DEFINE(WITH_WIMAX, 1, [Define if you have WiMAX support]) +fi +AM_CONDITIONAL(WITH_WIMAX, test "${enable_wimax}" = "yes") PKG_CHECK_MODULES(POLKIT, polkit-gobject-1) AC_SUBST(POLKIT_CFLAGS) @@ -621,6 +630,12 @@ else echo systemd support: no fi +if test "${enable_wimax}" = "yes"; then + echo WiMAX support: yes +else + echo WiMAX support: no +fi + echo echo Building documentation: ${with_docs} echo Building tests: ${with_tests} diff --git a/src/Makefile.am b/src/Makefile.am index 47d9c6acda..0bc6a54b0e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -10,29 +10,36 @@ SUBDIRS= \ dnsmasq-manager \ modem-manager \ bluez-manager \ - wimax \ - system-settings \ - . \ - tests + system-settings -INCLUDES = -I${top_srcdir} \ - -I${top_srcdir}/include \ - -I${top_builddir}/marshallers \ +if WITH_WIMAX +SUBDIRS += wimax +endif + +SUBDIRS += . tests + +INCLUDES = -I${top_srcdir} \ + -I${top_srcdir}/include \ + -I${top_builddir}/marshallers \ -I${top_srcdir}/src/logging \ -I${top_srcdir}/src/dns-manager \ - -I${top_srcdir}/src/vpn-manager \ - -I${top_srcdir}/src/dhcp-manager \ - -I${top_srcdir}/src/ip6-manager \ - -I${top_srcdir}/src/supplicant-manager \ - -I${top_srcdir}/src/dnsmasq-manager \ - -I${top_srcdir}/src/modem-manager \ + -I${top_srcdir}/src/vpn-manager \ + -I${top_srcdir}/src/dhcp-manager \ + -I${top_srcdir}/src/ip6-manager \ + -I${top_srcdir}/src/supplicant-manager \ + -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 \ -I${top_srcdir}/callouts +if WITH_WIMAX +INCLUDES += -I$(top_srcdir)/src/wimax +endif + +INCLUDES += -I${top_srcdir}/libnm-glib + ########################################### # Test libraries ########################################### @@ -215,7 +222,6 @@ NetworkManager_CPPFLAGS = \ $(GUDEV_CFLAGS) \ $(LIBNL_CFLAGS) \ $(GMODULE_CFLAGS) \ - $(WIMAX_CFLAGS) \ $(POLKIT_CFLAGS) \ -DG_DISABLE_DEPRECATED \ -DBINDIR=\"$(bindir)\" \ @@ -240,7 +246,6 @@ 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 \ @@ -253,6 +258,10 @@ NetworkManager_LDADD = \ $(LIBM) \ $(LIBDL) +if WITH_WIMAX +NetworkManager_LDADD += ./wimax/libwimax.la +endif + NetworkManager_LDFLAGS = -rdynamic libexec_PROGRAMS = nm-crash-logger diff --git a/src/nm-manager.c b/src/nm-manager.c index d74922a4f6..e47ec37f41 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -16,7 +16,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2007 - 2009 Novell, Inc. - * Copyright (C) 2007 - 2010 Red Hat, Inc. + * Copyright (C) 2007 - 2011 Red Hat, Inc. */ #include @@ -38,7 +38,9 @@ #include "nm-device-ethernet.h" #include "nm-device-wifi.h" #include "nm-device-olpc-mesh.h" +#if WITH_WIMAX #include "nm-device-wimax.h" +#endif #include "nm-device-cdma.h" #include "nm-device-gsm.h" #include "nm-system.h" @@ -2117,10 +2119,12 @@ add_device (NMManager *self, NMDevice *device) nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), priv->radio_states[RFKILL_TYPE_WWAN].enabled); */ +#if WITH_WIMAX } else if (NM_IS_DEVICE_WIMAX (device)) { nm_manager_rfkill_update (self, RFKILL_TYPE_WIMAX); enabled = radio_enabled_for_type (self, RFKILL_TYPE_WIMAX); nm_device_interface_set_enabled (NM_DEVICE_INTERFACE (device), enabled); +#endif } type_desc = nm_device_get_type_desc (device); diff --git a/src/nm-policy.c b/src/nm-policy.c index 6ecc74ddbd..8650dfed40 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -36,7 +36,9 @@ #include "nm-device-wifi.h" #include "nm-device-ethernet.h" #include "nm-device-modem.h" +#if WITH_WIMAX #include "nm-device-wimax.h" +#endif #include "nm-dbus-manager.h" #include "nm-setting-ip4-config.h" #include "nm-setting-connection.h" @@ -933,11 +935,13 @@ wireless_networks_changed (NMDeviceWifi *device, NMAccessPoint *ap, gpointer use schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0); } +#if WITH_WIMAX static void nsps_changed (NMDeviceWimax *device, NMWimaxNsp *nsp, gpointer user_data) { schedule_activate_check ((NMPolicy *) user_data, NM_DEVICE (device), 0); } +#endif typedef struct { gulong id; @@ -989,6 +993,7 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data) G_CALLBACK (wireless_networks_changed), policy); policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); +#if WITH_WIMAX } else if (NM_IS_DEVICE_WIMAX (device)) { id = g_signal_connect (device, "nsp-added", G_CALLBACK (nsps_changed), @@ -999,6 +1004,7 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data) G_CALLBACK (nsps_changed), policy); policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device); +#endif } } diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c index 31b4e69707..5e3da0b8d6 100644 --- a/src/nm-udev-manager.c +++ b/src/nm-udev-manager.c @@ -15,9 +15,10 @@ * 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 - 2010 Red Hat, Inc. + * Copyright (C) 2009 - 2011 Red Hat, Inc. */ +#include #include #include #include @@ -38,7 +39,9 @@ #include "nm-device-wifi.h" #include "nm-device-olpc-mesh.h" #include "nm-device-ethernet.h" +#if WITH_WIMAX #include "nm-device-wimax.h" +#endif typedef struct { GUdevClient *client; @@ -397,9 +400,11 @@ device_creator (NMUdevManager *manager, device = (GObject *) nm_device_olpc_mesh_new (path, ifname, driver); else if (is_wireless (udev_device)) device = (GObject *) nm_device_wifi_new (path, ifname, driver); - else if (is_wimax (driver)) + else if (is_wimax (driver)) { +#if WITH_WIMAX device = (GObject *) nm_device_wimax_new (path, ifname, driver); - else +#endif + } else device = (GObject *) nm_device_ethernet_new (path, ifname, driver); out: diff --git a/src/wimax/Makefile.am b/src/wimax/Makefile.am index 83e53cd2ec..91f1dc4e07 100644 --- a/src/wimax/Makefile.am +++ b/src/wimax/Makefile.am @@ -20,11 +20,11 @@ libwimax_la_SOURCES = \ libwimax_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ - $(WIMAX_CFLAGS) + $(IWMX_SDK_CFLAGS) libwimax_la_LIBADD = \ $(DBUS_LIBS) \ - $(WIMAX_LIBS) \ + $(IWMX_SDK_LIBS) \ $(top_builddir)/marshallers/libmarshallers.la nm-wimax-nsp-glue.h: $(top_srcdir)/introspection/nm-wimax-nsp.xml diff --git a/src/wimax/nm-device-wimax.h b/src/wimax/nm-device-wimax.h index 9dbe149e22..8132ade616 100644 --- a/src/wimax/nm-device-wimax.h +++ b/src/wimax/nm-device-wimax.h @@ -23,7 +23,6 @@ #define NM_DEVICE_WIMAX_H #include -#include #include "nm-device.h" #include "nm-wimax-nsp.h" diff --git a/test/nm-tool.c b/test/nm-tool.c index e161bc7664..85ce9ff628 100644 --- a/test/nm-tool.c +++ b/test/nm-tool.c @@ -38,7 +38,9 @@ #include #include #include +#if WITH_WIMAX #include +#endif #include #include #include @@ -194,6 +196,7 @@ detail_access_point (gpointer data, gpointer user_data) g_free (tmp); } +#if WITH_WIMAX static const char * wimax_network_type_to_str (NMWimaxNspNetworkType type) { @@ -233,6 +236,7 @@ detail_nsp (gpointer data, gpointer user_data) g_free (label); g_free (data_str); } +#endif static gchar * ip4_address_as_string (guint32 ip) @@ -379,8 +383,10 @@ detail_device (gpointer data, gpointer user_data) print_string ("Type", "Mobile Broadband (CDMA)"); else if (NM_IS_DEVICE_BT (device)) print_string ("Type", "Bluetooth"); +#if WITH_WIMAX else if (NM_IS_DEVICE_WIMAX (device)) print_string ("Type", "WiMAX"); +#endif print_string ("Driver", nm_device_get_driver (device) ? nm_device_get_driver (device) : "(unknown)"); @@ -396,8 +402,10 @@ 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))); +#if WITH_WIMAX else if (NM_IS_DEVICE_WIMAX (device)) tmp = g_strdup (nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device))); +#endif if (tmp) { print_string ("HW Address", tmp); @@ -463,6 +471,7 @@ detail_device (gpointer data, gpointer user_data) print_string (" Carrier", "on"); else print_string (" Carrier", "off"); +#if WITH_WIMAX } else if (NM_IS_DEVICE_WIMAX (device)) { NMWimaxNsp *active_nsp = NULL; const char *active_name = NULL; @@ -478,6 +487,7 @@ detail_device (gpointer data, gpointer user_data) nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (device)); if (nsps && nsps->len) g_ptr_array_foreach ((GPtrArray *) nsps, detail_nsp, (gpointer) active_name); +#endif } /* IP Setup info */ From 263c05118be032127f3056b7c7d2a4fbef36fc0d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 6 Jan 2011 14:22:17 -0600 Subject: [PATCH 090/102] build: ensure WiMAX bits are linked before system settings System settings still links to libnm-glib, which also contains an NMDeviceWimax class. We don't care about the libnm-glib class, so link the wimax bits first to ensure they are the ones used. This issue will go away when user settings is removed in the near future. --- src/Makefile.am | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 0bc6a54b0e..55a225caf9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -234,6 +234,12 @@ NetworkManager_CPPFLAGS = \ -DNMLOCALEDIR=\"$(datadir)/locale\" \ -DARP_DEBUG + +WIMAX_LIBS= +if WITH_WIMAX +WIMAX_LIBS = ./wimax/libwimax.la +endif + NetworkManager_LDADD = \ $(top_builddir)/marshallers/libmarshallers.la \ ./logging/libnm-logging.la \ @@ -246,6 +252,7 @@ NetworkManager_LDADD = \ ./ppp-manager/libppp-manager.la \ ./modem-manager/libmodem-manager.la \ ./bluez-manager/libbluez-manager.la \ + $(WIMAX_LIBS) \ ./system-settings/libsystem-settings.la \ ./backends/libnmbackend.la \ $(top_builddir)/libnm-util/libnm-util.la \ @@ -258,10 +265,6 @@ NetworkManager_LDADD = \ $(LIBM) \ $(LIBDL) -if WITH_WIMAX -NetworkManager_LDADD += ./wimax/libwimax.la -endif - NetworkManager_LDFLAGS = -rdynamic libexec_PROGRAMS = nm-crash-logger From 9d24269e303d1626f460a70559f8c2fe7d55c02a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 6 Jan 2011 15:18:19 -0600 Subject: [PATCH 091/102] wimax: add Center Frequency, RSSI, CINR, TX Power, and BSID properties Useful diagnostic/support info when device is connected. --- introspection/nm-device-wimax.xml | 40 ++++ libnm-glib/libnm-glib.ver | 5 + libnm-glib/nm-device-wimax.c | 302 ++++++++++++++++++++++++++++-- libnm-glib/nm-device-wimax.h | 15 +- src/wimax/iwmxsdk.c | 36 ++++ src/wimax/iwmxsdk.h | 1 + src/wimax/nm-device-wimax.c | 196 +++++++++++++++++++ src/wimax/nm-device-wimax.h | 21 ++- test/nm-tool.c | 51 ++++- 9 files changed, 645 insertions(+), 22 deletions(-) diff --git a/introspection/nm-device-wimax.xml b/introspection/nm-device-wimax.xml index 69c1102b48..6e414087fa 100644 --- a/introspection/nm-device-wimax.xml +++ b/introspection/nm-device-wimax.xml @@ -20,6 +20,46 @@ + + + Center frequency (in KHz) of the radio channel the device is using to + communicate with the network when connected. Has no meaning when the + device is not connected. + + + + + + RSSI of the current radio link in dBm. This value indicates how strong + the raw received RF signal from the base station is, but does not + indicate the overall quality of the radio link. Has no meaning when the + device is not connected. + + + + + + CINR (Carrier to Interference + Noise Ratio) of the current radio link + in dB. CINR is a more accurate measure of radio link quality. Has no + meaning when the device is not connected. + + + + + + Average power of the last burst transmitted by the device, in units of + 0.5 dBm. i.e. a TxPower of -11 represents an actual device TX power of + -5.5 dBm. Has no meaning when the device is not connected. + + + + + + The ID of the serving base station as received from the network. Has + no meaning when the device is not connected. + + + Object path of the NSP currently used by the WiMax device. diff --git a/libnm-glib/libnm-glib.ver b/libnm-glib/libnm-glib.ver index e046b162d0..16c24e2621 100644 --- a/libnm-glib/libnm-glib.ver +++ b/libnm-glib/libnm-glib.ver @@ -167,10 +167,15 @@ global: nm_vpn_connection_get_type; nm_vpn_connection_get_vpn_state; nm_vpn_connection_new; + nm_device_wimax_get_bsid; + nm_device_wimax_get_center_frequency; + nm_device_wimax_get_cinr; nm_device_wimax_get_hw_address; nm_device_wimax_get_active_nsp; nm_device_wimax_get_nsp_by_path; nm_device_wimax_get_nsps; + nm_device_wimax_get_rssi; + nm_device_wimax_get_tx_power; nm_device_wimax_get_type; nm_device_wimax_new; nm_wimax_nsp_get_name; diff --git a/libnm-glib/nm-device-wimax.c b/libnm-glib/nm-device-wimax.c index bc9d6a088b..bdab0eb743 100644 --- a/libnm-glib/nm-device-wimax.c +++ b/libnm-glib/nm-device-wimax.c @@ -47,18 +47,34 @@ typedef struct { NMWimaxNsp *active_nsp; gboolean null_active_nsp; GPtrArray *nsps; + + guint center_freq; + gint rssi; + gint cinr; + gint tx_power; + char *bsid; } NMDeviceWimaxPrivate; enum { PROP_0, PROP_HW_ADDRESS, PROP_ACTIVE_NSP, + PROP_CENTER_FREQ, + PROP_RSSI, + PROP_CINR, + PROP_TX_POWER, + PROP_BSID, LAST_PROP }; -#define DBUS_PROP_HW_ADDRESS "HwAddress" -#define DBUS_PROP_ACTIVE_NSP "ActiveNsp" +#define DBUS_PROP_HW_ADDRESS "HwAddress" +#define DBUS_PROP_ACTIVE_NSP "ActiveNsp" +#define DBUS_PROP_CENTER_FREQUENCY "CenterFrequency" +#define DBUS_PROP_RSSI "Rssi" +#define DBUS_PROP_CINR "Cinr" +#define DBUS_PROP_TX_POWER "TxPower" +#define DBUS_PROP_BSID "Bsid" enum { NSP_ADDED, @@ -321,6 +337,135 @@ clean_up_nsps (NMDeviceWimax *self, gboolean notify) } } +/** + * nm_device_wimax_get_center_frequency: + * @device: a #NMDeviceWimax + * + * Gets the center frequency (in KHz) of the radio channel the device is using + * to communicate with the network when connected. Has no meaning when the + * device is not connected. + * + * Returns: the center frequency in KHz, or 0 + **/ +guint +nm_device_wimax_get_center_frequency (NMDeviceWimax *wimax) +{ + NMDeviceWimaxPrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), 0); + + priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + if (!priv->center_freq) { + priv->center_freq = _nm_object_get_uint_property (NM_OBJECT (wimax), + NM_DBUS_INTERFACE_DEVICE_WIMAX, + DBUS_PROP_CENTER_FREQUENCY); + } + return priv->center_freq; +} + +/** + * nm_device_wimax_get_rssi: + * @device: a #NMDeviceWimax + * + * Gets the RSSI of the current radio link in dBm. This value indicates how + * strong the raw received RF signal from the base station is, but does not + * indicate the overall quality of the radio link. Has no meaning when the + * device is not connected. + * + * Returns: the RSSI in dBm, or 0 + **/ +gint +nm_device_wimax_get_rssi (NMDeviceWimax *wimax) +{ + NMDeviceWimaxPrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), 0); + + priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + if (!priv->rssi) { + priv->rssi = _nm_object_get_int_property (NM_OBJECT (wimax), + NM_DBUS_INTERFACE_DEVICE_WIMAX, + DBUS_PROP_RSSI); + } + return priv->rssi; +} + +/** + * nm_device_wimax_get_cinr: + * @device: a #NMDeviceWimax + * + * Gets the CINR (Carrier to Interference + Noise Ratio) of the current radio + * link in dB. CINR is a more accurate measure of radio link quality. Has no + * meaning when the device is not connected. + * + * Returns: the CINR in dB, or 0 + **/ +gint +nm_device_wimax_get_cinr (NMDeviceWimax *wimax) +{ + NMDeviceWimaxPrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), 0); + + priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + if (!priv->cinr) { + priv->cinr = _nm_object_get_int_property (NM_OBJECT (wimax), + NM_DBUS_INTERFACE_DEVICE_WIMAX, + DBUS_PROP_CINR); + } + return priv->cinr; +} + +/** + * nm_device_wimax_get_tx_power: + * @device: a #NMDeviceWimax + * + * Average power of the last burst transmitted by the device, in units of + * 0.5 dBm. i.e. a TxPower of -11 represents an actual device TX power of + * -5.5 dBm. Has no meaning when the device is not connected. + * + * Returns: the TX power in dBm, or 0 + **/ +gint +nm_device_wimax_get_tx_power (NMDeviceWimax *wimax) +{ + NMDeviceWimaxPrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), 0); + + priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + if (!priv->tx_power) { + priv->tx_power = _nm_object_get_int_property (NM_OBJECT (wimax), + NM_DBUS_INTERFACE_DEVICE_WIMAX, + DBUS_PROP_TX_POWER); + } + return priv->tx_power; +} + +/** + * nm_device_wimax_get_bsid: + * @device: a #NMDeviceWimax + * + * Gets the ID of the serving Base Station when the device is connected. + * + * Returns: the ID of the serving Base Station, or NULL + **/ +const char * +nm_device_wimax_get_bsid (NMDeviceWimax *wimax) +{ + NMDeviceWimaxPrivate *priv; + + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL); + + priv = NM_DEVICE_WIMAX_GET_PRIVATE (wimax); + if (!priv->bsid) { + priv->bsid = _nm_object_get_string_property (NM_OBJECT (wimax), + NM_DBUS_INTERFACE_DEVICE_WIMAX, + DBUS_PROP_BSID); + } + return priv->bsid; +} + /**************************************************************/ static void @@ -343,19 +488,68 @@ get_property (GObject *object, case PROP_ACTIVE_NSP: g_value_set_object (value, nm_device_wimax_get_active_nsp (self)); break; + case PROP_CENTER_FREQ: + g_value_set_uint (value, nm_device_wimax_get_center_frequency (self)); + break; + case PROP_RSSI: + g_value_set_int (value, nm_device_wimax_get_rssi (self)); + break; + case PROP_CINR: + g_value_set_int (value, nm_device_wimax_get_cinr (self)); + break; + case PROP_TX_POWER: + g_value_set_int (value, nm_device_wimax_get_tx_power (self)); + break; + case PROP_BSID: + g_value_set_string (value, nm_device_wimax_get_bsid (self)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } +static void +clear_link_status (NMDeviceWimax *self) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + + if (priv->center_freq) { + priv->center_freq = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_CENTER_FREQUENCY); + } + + if (priv->rssi) { + priv->rssi = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_RSSI); + } + + if (priv->cinr) { + priv->cinr = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_CINR); + } + + if (priv->tx_power) { + priv->tx_power = 0; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_TX_POWER); + } + + if (priv->bsid) { + g_free (priv->bsid); + priv->bsid = NULL; + _nm_object_queue_notify (NM_OBJECT (self), NM_DEVICE_WIMAX_BSID); + } +} + static void state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) { NMDeviceWimax *self = NM_DEVICE_WIMAX (device); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + NMDeviceState state; - switch (nm_device_get_state (device)) { + state = nm_device_get_state (device); + switch (state) { case NM_DEVICE_STATE_UNKNOWN: case NM_DEVICE_STATE_UNMANAGED: case NM_DEVICE_STATE_UNAVAILABLE: @@ -367,6 +561,13 @@ state_changed_cb (NMDevice *device, GParamSpec *pspec, gpointer user_data) priv->null_active_nsp = FALSE; } _nm_object_queue_notify (NM_OBJECT (device), NM_DEVICE_WIMAX_ACTIVE_NSP); + clear_link_status (self); + break; + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_CONFIG: + case NM_DEVICE_STATE_NEED_AUTH: + case NM_DEVICE_STATE_IP_CONFIG: + clear_link_status (self); break; default: break; @@ -420,6 +621,11 @@ register_for_property_changed (NMDeviceWimax *wimax) const NMPropertiesChangedInfo property_changed_info[] = { { NM_DEVICE_WIMAX_HW_ADDRESS, _nm_object_demarshal_generic, &priv->hw_address }, { NM_DEVICE_WIMAX_ACTIVE_NSP, demarshal_active_nsp, &priv->active_nsp }, + { NM_DEVICE_WIMAX_CENTER_FREQUENCY, _nm_object_demarshal_generic, &priv->center_freq }, + { NM_DEVICE_WIMAX_RSSI, _nm_object_demarshal_generic, &priv->rssi }, + { NM_DEVICE_WIMAX_CINR, _nm_object_demarshal_generic, &priv->cinr }, + { NM_DEVICE_WIMAX_TX_POWER, _nm_object_demarshal_generic, &priv->tx_power }, + { NM_DEVICE_WIMAX_BSID, _nm_object_demarshal_generic, &priv->bsid }, { NULL }, }; @@ -485,23 +691,15 @@ dispose (GObject *object) priv->disposed = TRUE; + g_free (priv->hw_address); + g_free (priv->bsid); + clean_up_nsps (NM_DEVICE_WIMAX (object), FALSE); g_object_unref (priv->proxy); G_OBJECT_CLASS (nm_device_wimax_parent_class)->dispose (object); } -static void -finalize (GObject *object) -{ - NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (object); - - if (priv->hw_address) - g_free (priv->hw_address); - - G_OBJECT_CLASS (nm_device_wimax_parent_class)->finalize (object); -} - static void nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) { @@ -513,7 +711,6 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) object_class->constructor = constructor; object_class->get_property = get_property; object_class->dispose = dispose; - object_class->finalize = finalize; /* properties */ @@ -543,6 +740,81 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class) NM_TYPE_WIMAX_NSP, G_PARAM_READABLE)); + /** + * NMDeviceWimax:center-frequency: + * + * The center frequency (in KHz) of the radio channel the device is using to + * communicate with the network when connected. Has no meaning when the + * device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_CENTER_FREQ, + g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY, + "Center frequency", + "Center frequency", + 0, G_MAXUINT, 0, + G_PARAM_READABLE)); + + /** + * NMDeviceWimax:rssi: + * + * RSSI of the current radio link in dBm. This value indicates how strong + * the raw received RF signal from the base station is, but does not + * indicate the overall quality of the radio link. Has no meaning when the + * device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_RSSI, + g_param_spec_int (NM_DEVICE_WIMAX_RSSI, + "RSSI", + "RSSI", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE)); + + /** + * NMDeviceWimax:cinr: + * + * CINR (Carrier to Interference + Noise Ratio) of the current radio link + * in dB. CINR is a more accurate measure of radio link quality. Has no + * meaning when the device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_CINR, + g_param_spec_int (NM_DEVICE_WIMAX_CINR, + "CINR", + "CINR", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE)); + + /** + * NMDeviceWimax:tx-power: + * + * Average power of the last burst transmitted by the device, in units of + * 0.5 dBm. i.e. a TxPower of -11 represents an actual device TX power of + * -5.5 dBm. Has no meaning when the device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_TX_POWER, + g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER, + "TX Power", + "TX Power", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE)); + + /** + * NMDeviceWimax:bsid: + * + * The ID of the serving base station as received from the network. Has + * no meaning when the device is not connected. + **/ + g_object_class_install_property + (object_class, PROP_BSID, + g_param_spec_string (NM_DEVICE_WIMAX_BSID, + "BSID", + "BSID", + NULL, + G_PARAM_READABLE)); + /* signals */ /** diff --git a/libnm-glib/nm-device-wimax.h b/libnm-glib/nm-device-wimax.h index 818444531b..5e19bbaf95 100644 --- a/libnm-glib/nm-device-wimax.h +++ b/libnm-glib/nm-device-wimax.h @@ -36,8 +36,13 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEVICE_WIMAX)) #define NM_DEVICE_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) -#define NM_DEVICE_WIMAX_HW_ADDRESS "hw-address" -#define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" +#define NM_DEVICE_WIMAX_HW_ADDRESS "hw-address" +#define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" +#define NM_DEVICE_WIMAX_CENTER_FREQUENCY "center-frequency" +#define NM_DEVICE_WIMAX_RSSI "rssi" +#define NM_DEVICE_WIMAX_CINR "cinr" +#define NM_DEVICE_WIMAX_TX_POWER "tx-power" +#define NM_DEVICE_WIMAX_BSID "bsid" typedef struct { NMDevice parent; @@ -63,6 +68,12 @@ NMWimaxNsp *nm_device_wimax_get_nsp_by_path (NMDeviceWimax *wimax, const GPtrArray *nm_device_wimax_get_nsps (NMDeviceWimax *wimax); +guint nm_device_wimax_get_center_frequency (NMDeviceWimax *self); +gint nm_device_wimax_get_rssi (NMDeviceWimax *self); +gint nm_device_wimax_get_cinr (NMDeviceWimax *self); +gint nm_device_wimax_get_tx_power (NMDeviceWimax *self); +const char * nm_device_wimax_get_bsid (NMDeviceWimax *self); + G_END_DECLS #endif /* NM_DEVICE_WIMAX_H */ diff --git a/src/wimax/iwmxsdk.c b/src/wimax/iwmxsdk.c index d36967b126..0c0bc1377e 100644 --- a/src/wimax/iwmxsdk.c +++ b/src/wimax/iwmxsdk.c @@ -550,6 +550,42 @@ WIMAX_API_CONNECTED_NSP_INFO_EX *iwmx_sdk_get_connected_network(struct wmxsdk *w return nsp_info; } +/* + * Asks the WiMAX API to report current link statistics. + * + * Returns NULL on error. + * + */ +WIMAX_API_LINK_STATUS_INFO_EX *iwmx_sdk_get_link_status_info(struct wmxsdk *wmxsdk) +{ + WIMAX_API_LINK_STATUS_INFO_EX *stats = NULL; + WIMAX_API_RET r; + char errstr[512]; + UINT32 errstr_size = sizeof(errstr); + + /* Only report if connected */ + if (iwmxsdk_status_get(wmxsdk) < WIMAX_API_DEVICE_STATUS_Connecting) { + nm_log_err(LOGD_WIMAX, "wmxsdk: cannot get link status info unless connected"); + return NULL; + } + + stats = malloc(sizeof (*stats)); + if (!stats) { + nm_log_err(LOGD_WIMAX, "wmxsdk: cannot allocate links status info"); + return NULL; + } + + r = GetLinkStatusEx(&wmxsdk->device_id, stats); + if (r != WIMAX_API_RET_SUCCESS) { + GetErrorString(&wmxsdk->device_id, r, errstr, &errstr_size); + nm_log_err(LOGD_WIMAX, "wmxsdk: Cannot get link status info: %d (%s)", r, errstr); + free (stats); + stats = NULL; + } + + return stats; +} + /* * Callback for a RF State command * diff --git a/src/wimax/iwmxsdk.h b/src/wimax/iwmxsdk.h index 13e4ff7dc4..bd55679ab2 100644 --- a/src/wimax/iwmxsdk.h +++ b/src/wimax/iwmxsdk.h @@ -97,6 +97,7 @@ int iwmx_sdk_connect(struct wmxsdk *wmxsdk, const char *nsp_name); int iwmx_sdk_disconnect(struct wmxsdk *wmxsdk); int iwmx_sdk_set_fast_reconnect_enabled(struct wmxsdk *wmxsdk, int enabled); WIMAX_API_CONNECTED_NSP_INFO_EX *iwmx_sdk_get_connected_network(struct wmxsdk *wmxsdk); +WIMAX_API_LINK_STATUS_INFO_EX *iwmx_sdk_get_link_status_info(struct wmxsdk *wmxsdk); const char *iwmx_sdk_dev_status_to_str(WIMAX_API_DEVICE_STATUS status); const char *iwmx_sdk_reason_to_str(WIMAX_API_STATUS_REASON reason); const char *iwmx_sdk_media_status_to_str(WIMAX_API_MEDIA_STATUS status); diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 1c34836c96..fba108f5be 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -56,6 +56,11 @@ enum { PROP_0, PROP_HW_ADDRESS, PROP_ACTIVE_NSP, + PROP_CENTER_FREQ, + PROP_RSSI, + PROP_CINR, + PROP_TX_POWER, + PROP_BSID, LAST_PROP }; @@ -93,6 +98,13 @@ typedef struct { GSList *nsp_list; NMWimaxNsp *current_nsp; + + /* interesting stuff when connected */ + guint center_freq; + gint rssi; + gint cinr; + gint tx_power; + char *bsid; } NMDeviceWimaxPrivate; /***********************************************************/ @@ -153,6 +165,46 @@ nm_device_wimax_get_hw_address (NMDeviceWimax *self, struct ether_addr *addr) memcpy (addr, &(priv->hw_addr), sizeof (struct ether_addr)); } +guint32 +nm_device_wimax_get_center_frequency (NMDeviceWimax *self) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0); + + return NM_DEVICE_WIMAX_GET_PRIVATE (self)->center_freq; +} + +gint +nm_device_wimax_get_rssi (NMDeviceWimax *self) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0); + + return NM_DEVICE_WIMAX_GET_PRIVATE (self)->rssi; +} + +gint +nm_device_wimax_get_cinr (NMDeviceWimax *self) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0); + + return NM_DEVICE_WIMAX_GET_PRIVATE (self)->cinr; +} + +gint +nm_device_wimax_get_tx_power (NMDeviceWimax *self) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), 0); + + return NM_DEVICE_WIMAX_GET_PRIVATE (self)->tx_power; +} + +const char * +nm_device_wimax_get_bsid (NMDeviceWimax *self) +{ + g_return_val_if_fail (NM_IS_DEVICE_WIMAX (self), NULL); + + return NM_DEVICE_WIMAX_GET_PRIVATE (self)->bsid; +} + static gboolean impl_device_get_nsp_list (NMDeviceWimax *self, GPtrArray **nsps, GError **error) { @@ -945,14 +997,92 @@ wmx_removed_cb (struct wmxsdk *wmxsdk, void *user_data) /*************************************************************************/ +static inline gint +sdk_rssi_to_dbm (guint raw_rssi) +{ + /* Values range from 0x00 to 0x53, where -123dBm is encoded as 0x00 and + * -40dBm encoded as 0x53 in 1dB increments. + */ + return raw_rssi - 123; +} + +static inline gint +sdk_cinr_to_db (guint raw_cinr) +{ + /* Values range from 0x00 to 0x3F, where -10dB is encoded as 0x00 and + * 53dB encoded as 0x3F in 1dB increments. + */ + return raw_cinr - 10; +} + +static inline gint +sdk_tx_pow_to_dbm (guint raw_tx_pow) +{ + /* Values range from 0x00 to 0xFF, where -84dBm is encoded as 0x00 and + * 43.5dBm is encoded as 0xFF in 0.5dB increments. Normalize so that + * 0 dBm == 0. + */ + return (int) (((double) raw_tx_pow / 2.0) - 84) * 2; +} + +static void +set_link_status (NMDeviceWimax *self, WIMAX_API_LINK_STATUS_INFO_EX *link_status) +{ + NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); + guint center_freq = 0; + gint conv_rssi = 0, conv_cinr = 0, conv_tx_pow = 0; + char *new_bsid = NULL; + + if (link_status) { + center_freq = link_status->centerFrequency; + conv_rssi = sdk_rssi_to_dbm (link_status->RSSI); + conv_cinr = sdk_cinr_to_db (link_status->CINR); + conv_tx_pow = sdk_tx_pow_to_dbm (link_status->txPWR); + new_bsid = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", + link_status->bsId[0], link_status->bsId[1], + link_status->bsId[2], link_status->bsId[3], + link_status->bsId[4], link_status->bsId[5]); + } + + if (priv->center_freq != center_freq) { + priv->center_freq = center_freq; + g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_CENTER_FREQUENCY); + } + + if (priv->rssi != conv_rssi) { + priv->rssi = conv_rssi; + g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_RSSI); + } + + if (priv->cinr != conv_cinr) { + priv->cinr = conv_cinr; + g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_CINR); + } + + if (priv->tx_power != conv_tx_pow) { + priv->tx_power = conv_tx_pow; + g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_TX_POWER); + } + + if (g_strcmp0 (priv->bsid, new_bsid) != 0) { + g_free (priv->bsid); + priv->bsid = new_bsid; + g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_BSID); + } else + g_free (new_bsid); +} + static gboolean connected_poll_cb (gpointer user_data) { NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); WIMAX_API_CONNECTED_NSP_INFO_EX *sdk_nsp; + WIMAX_API_LINK_STATUS_INFO_EX *link_status; g_return_val_if_fail (priv->sdk != NULL, FALSE); + + /* Get details of the connected NSP */ sdk_nsp = iwmx_sdk_get_connected_network (priv->sdk); if (sdk_nsp) { const char *nsp_name = (const char *) sdk_nsp->NSPName; @@ -978,6 +1108,13 @@ connected_poll_cb (gpointer user_data) free (sdk_nsp); } + /* Get details of the current radio link */ + link_status = iwmx_sdk_get_link_status_info (priv->sdk); + if (link_status) { + set_link_status (self, link_status); + free (link_status); + } + return TRUE; /* reschedule */ } @@ -1008,9 +1145,11 @@ device_state_changed (NMDevice *device, /* poll link quality and BSID */ clear_connected_poll (self); priv->poll_id = g_timeout_add_seconds (10, connected_poll_cb, self); + connected_poll_cb (self); } else { clear_link_timeout (self); clear_connected_poll (self); + set_link_status (self, NULL); } } @@ -1133,6 +1272,21 @@ get_property (GObject *object, guint prop_id, else g_value_set_boxed (value, "/"); break; + case PROP_CENTER_FREQ: + g_value_set_uint (value, priv->center_freq); + break; + case PROP_RSSI: + g_value_set_int (value, priv->rssi); + break; + case PROP_CINR: + g_value_set_int (value, priv->cinr); + break; + case PROP_TX_POWER: + g_value_set_int (value, priv->tx_power); + break; + case PROP_BSID: + g_value_set_string (value, priv->bsid); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1162,6 +1316,8 @@ dispose (GObject *object) wmxsdk_unref (priv->sdk); } + g_free (priv->bsid); + set_current_nsp (self, NULL); g_slist_foreach (priv->nsp_list, (GFunc) g_object_unref, NULL); @@ -1216,6 +1372,46 @@ nm_device_wimax_class_init (NMDeviceWimaxClass *klass) DBUS_TYPE_G_OBJECT_PATH, G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_CENTER_FREQ, + g_param_spec_uint (NM_DEVICE_WIMAX_CENTER_FREQUENCY, + "Center frequency", + "Center frequency", + 0, G_MAXUINT, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_RSSI, + g_param_spec_int (NM_DEVICE_WIMAX_RSSI, + "RSSI", + "RSSI", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_CINR, + g_param_spec_int (NM_DEVICE_WIMAX_CINR, + "CINR", + "CINR", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_TX_POWER, + g_param_spec_int (NM_DEVICE_WIMAX_TX_POWER, + "TX Power", + "TX Power", + G_MININT, G_MAXINT, 0, + G_PARAM_READABLE)); + + g_object_class_install_property + (object_class, PROP_BSID, + g_param_spec_string (NM_DEVICE_WIMAX_BSID, + "BSID", + "BSID", + NULL, + G_PARAM_READABLE)); + /* Signals */ signals[NSP_ADDED] = g_signal_new ("nsp-added", diff --git a/src/wimax/nm-device-wimax.h b/src/wimax/nm-device-wimax.h index 8132ade616..d70380acc8 100644 --- a/src/wimax/nm-device-wimax.h +++ b/src/wimax/nm-device-wimax.h @@ -15,7 +15,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2010 Red Hat, Inc. + * Copyright (C) 2010 - 2011 Red Hat, Inc. * Copyright (C) 2009 Novell, Inc. */ @@ -35,8 +35,13 @@ G_BEGIN_DECLS #define NM_IS_DEVICE_WIMAX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_WIMAX)) #define NM_DEVICE_WIMAX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_WIMAX, NMDeviceWimaxClass)) -#define NM_DEVICE_WIMAX_HW_ADDRESS "hw-address" -#define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" +#define NM_DEVICE_WIMAX_HW_ADDRESS "hw-address" +#define NM_DEVICE_WIMAX_ACTIVE_NSP "active-nsp" +#define NM_DEVICE_WIMAX_CENTER_FREQUENCY "center-frequency" +#define NM_DEVICE_WIMAX_RSSI "rssi" +#define NM_DEVICE_WIMAX_CINR "cinr" +#define NM_DEVICE_WIMAX_TX_POWER "tx-power" +#define NM_DEVICE_WIMAX_BSID "bsid" typedef struct { NMDevice parent; @@ -62,6 +67,16 @@ void nm_device_wimax_get_hw_address (NMDeviceWimax *self, NMWimaxNsp *nm_device_wimax_get_active_nsp (NMDeviceWimax *self); +guint nm_device_wimax_get_center_frequency (NMDeviceWimax *self); + +gint nm_device_wimax_get_rssi (NMDeviceWimax *self); + +gint nm_device_wimax_get_cinr (NMDeviceWimax *self); + +gint nm_device_wimax_get_tx_power (NMDeviceWimax *self); + +const char *nm_device_wimax_get_bsid (NMDeviceWimax *self); + G_END_DECLS #endif /* NM_DEVICE_WIMAX_H */ diff --git a/test/nm-tool.c b/test/nm-tool.c index 85ce9ff628..121d9d1762 100644 --- a/test/nm-tool.c +++ b/test/nm-tool.c @@ -1,3 +1,4 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* nm-tool - information tool for NetworkManager * * Dan Williams @@ -16,10 +17,11 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * (C) Copyright 2005 - 2010 Red Hat, Inc. + * (C) Copyright 2005 - 2011 Red Hat, Inc. * (C) Copyright 2007 Novell, Inc. */ +#include #include #include #include @@ -473,13 +475,58 @@ detail_device (gpointer data, gpointer user_data) print_string (" Carrier", "off"); #if WITH_WIMAX } else if (NM_IS_DEVICE_WIMAX (device)) { + NMDeviceWimax *wimax = NM_DEVICE_WIMAX (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_device_wimax_get_active_nsp (NM_DEVICE_WIMAX (device)); + guint tmp_uint; + gint tmp_int; + const char *tmp_str; + + active_nsp = nm_device_wimax_get_active_nsp (wimax); active_name = active_nsp ? nm_wimax_nsp_get_name (active_nsp) : NULL; + + printf ("\n Link Status\n"); + + tmp_uint = nm_device_wimax_get_center_frequency (wimax); + if (tmp_uint) + tmp = g_strdup_printf ("%'.1f MHz", (double) tmp_uint / 1000.0); + else + tmp = g_strdup ("(unknown)"); + print_string (" Center Freq.", tmp); + g_free (tmp); + + tmp_int = nm_device_wimax_get_rssi (wimax); + if (tmp_int) + tmp = g_strdup_printf ("%d dBm", tmp_int); + else + tmp = g_strdup ("(unknown)"); + print_string (" RSSI", tmp); + g_free (tmp); + + tmp_int = nm_device_wimax_get_cinr (wimax); + if (tmp_int) + tmp = g_strdup_printf ("%d dB", tmp_int); + else + tmp = g_strdup ("(unknown)"); + print_string (" CINR", tmp); + g_free (tmp); + + tmp_int = nm_device_wimax_get_tx_power (wimax); + if (tmp_int) + tmp = g_strdup_printf ("%'.2f dBm", (float) tmp_int / 2.0); + else + tmp = g_strdup ("(unknown)"); + print_string (" TX Power", tmp); + g_free (tmp); + + tmp_str = nm_device_wimax_get_bsid (wimax); + if (tmp_str) + print_string (" BSID", tmp_str); + else + print_string (" BSID", "(unknown)"); } printf ("\n WiMAX NSPs %s\n", active_nsp ? "(* current NSP)" : ""); From 93486fc42e4509a95f6627b924005433d66d5791 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 6 Jan 2011 17:01:55 -0600 Subject: [PATCH 092/102] cli: add support for WiMAX devices and connections --- cli/src/connections.c | 108 ++++++++++- cli/src/devices.c | 383 ++++++++++++++++++++++++++++++++++++-- cli/src/network-manager.c | 52 +++++- cli/src/settings.c | 46 +++++ cli/src/settings.h | 2 + 5 files changed, 563 insertions(+), 28 deletions(-) diff --git a/cli/src/connections.c b/cli/src/connections.c index e0b94ceb8c..075cab487c 100644 --- a/cli/src/connections.c +++ b/cli/src/connections.c @@ -38,8 +38,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -108,6 +110,7 @@ static NmcOutputField nmc_fields_settings_names[] = { SETTING_FIELD (NM_SETTING_BLUETOOTH_SETTING_NAME, 0), /* 12 */ SETTING_FIELD (NM_SETTING_OLPC_MESH_SETTING_NAME, 0), /* 13 */ SETTING_FIELD (NM_SETTING_VPN_SETTING_NAME, 0), /* 14 */ + SETTING_FIELD (NM_SETTING_WIMAX_SETTING_NAME, 0), /* 15 */ {NULL, NULL, 0, NULL, 0} }; #define NMC_FIELDS_SETTINGS_NAMES_ALL NM_SETTING_CONNECTION_SETTING_NAME","\ @@ -124,7 +127,8 @@ static NmcOutputField nmc_fields_settings_names[] = { NM_SETTING_CDMA_SETTING_NAME","\ NM_SETTING_BLUETOOTH_SETTING_NAME","\ NM_SETTING_OLPC_MESH_SETTING_NAME","\ - NM_SETTING_VPN_SETTING_NAME + NM_SETTING_VPN_SETTING_NAME","\ + NM_SETTING_WIMAX_SETTING_NAME typedef struct { @@ -143,7 +147,7 @@ static void quit (void); static void show_connection (NMConnection *data, gpointer user_data); static NMConnection *find_connection (GSList *list, const char *filter_type, const char *filter_val); static gboolean find_device_for_connection (NmCli *nmc, NMConnection *connection, const char *iface, const char *ap, - NMDevice **device, const char **spec_object, GError **error); + const char *nsp, NMDevice **device, const char **spec_object, GError **error); static const char *active_connection_state_to_string (NMActiveConnectionState state); static void active_connection_state_cb (NMActiveConnection *active, GParamSpec *pspec, gpointer user_data); static void activate_connection_cb (gpointer user_data, const char *path, GError *error); @@ -161,7 +165,7 @@ usage (void) " COMMAND := { list | status | up | down }\n\n" " list [id | uuid | system | user]\n" " status\n" - " up id | uuid [iface ] [ap ] [--nowait] [--timeout ]\n" + " up id | uuid [iface ] [ap ] [nsp ] [--nowait] [--timeout ]\n" " down id | uuid \n")); } @@ -354,6 +358,15 @@ nmc_connection_detail (NMConnection *connection, NmCli *nmc) continue; } } + + if (!strcasecmp (nmc_fields_settings_names[section_idx].name, nmc_fields_settings_names[15].name)) { + setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX); + if (setting) { + setting_wimax_details (setting, nmc); + was_output = TRUE; + continue; + } + } } if (print_settings_array) @@ -885,6 +898,51 @@ check_olpc_mesh_compatible (NMDeviceOlpcMesh *device, NMConnection *connection, } #endif +static gboolean +check_wimax_compatible (NMDeviceWimax *device, NMConnection *connection, GError **error) +{ + NMSettingConnection *s_con; + NMSettingWimax *s_wimax; + const GByteArray *mac; + const char *device_mac_str; + struct ether_addr *device_mac = NULL; + + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIMAX_SETTING_NAME)) { + g_set_error (error, 0, 0, + "The connection was not a WiMAX connection."); + return FALSE; + } + + s_wimax = NM_SETTING_WIMAX (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX)); + if (!s_wimax) { + g_set_error (error, 0, 0, + "The connection was not a valid WiMAX connection."); + return FALSE; + } + + device_mac_str = nm_device_wimax_get_hw_address (device); + if (device_mac_str) + device_mac = ether_aton (device_mac_str); + if (!device_mac) { + g_set_error (error, 0, 0, "Invalid device MAC address."); + return FALSE; + } + + mac = nm_setting_wimax_get_mac_address (s_wimax); + if (mac && memcmp (mac->data, device_mac->ether_addr_octet, ETH_ALEN)) { + g_set_error (error, 0, 0, + "The connection's MAC address did not match this device."); + return FALSE; + } + + return TRUE; +} + static gboolean nm_device_is_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { @@ -899,6 +957,8 @@ nm_device_is_connection_compatible (NMDevice *device, NMConnection *connection, return check_bt_compatible (NM_DEVICE_BT (device), connection, error); // else if (NM_IS_DEVICE_OLPC_MESH (device)) // return check_olpc_mesh_compatible (NM_DEVICE_OLPC_MESH (device), connection, error); + else if (NM_IS_DEVICE_WIMAX (device)) + return check_wimax_compatible (NM_DEVICE_WIMAX (device), connection, error); g_set_error (error, 0, 0, "unhandled device type '%s'", G_OBJECT_TYPE_NAME (device)); return FALSE; @@ -989,13 +1049,20 @@ get_default_active_connection (NmCli *nmc, NMDevice **device) * IN: connection: connection to activate * iface: device interface name to use (optional) * ap: access point to use (optional; valid just for 802-11-wireless) + * nsp: Network Service Provider to use (option; valid only for wimax) * OUT: device: found device * spec_object: specific_object path of NMAccessPoint * RETURNS: TRUE when a device is found, FALSE otherwise. */ static gboolean -find_device_for_connection (NmCli *nmc, NMConnection *connection, const char *iface, const char *ap, - NMDevice **device, const char **spec_object, GError **error) +find_device_for_connection (NmCli *nmc, + NMConnection *connection, + const char *iface, + const char *ap, + const char *nsp, + NMDevice **device, + const char **spec_object, + GError **error) { NMSettingConnection *s_con; const char *con_type; @@ -1082,6 +1149,25 @@ find_device_for_connection (NmCli *nmc, NMConnection *connection, const char *if } g_free (hwaddr_up); } + + if ( found_device + && nsp + && !strcmp (con_type, NM_SETTING_WIMAX_SETTING_NAME) + && NM_IS_DEVICE_WIMAX (dev)) { + const GPtrArray *nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (dev)); + found_device = NULL; /* Mark as not found; set to the device again later, only if NSP matches */ + + for (j = 0; nsps && (j < nsps->len); j++) { + NMWimaxNsp *candidate_nsp = g_ptr_array_index (nsps, j); + const char *candidate_name = nm_wimax_nsp_get_name (candidate_nsp); + + if (!strcmp (nsp, candidate_name)) { + found_device = dev; + *spec_object = nm_object_get_path (NM_OBJECT (candidate_nsp)); + break; + } + } + } } if (found_device) { @@ -1324,6 +1410,7 @@ do_connection_up (NmCli *nmc, int argc, char **argv) const char *con_type; const char *iface = NULL; const char *ap = NULL; + const char *nsp = NULL; gboolean id_specified = FALSE; gboolean wait = TRUE; GError *error = NULL; @@ -1371,6 +1458,15 @@ do_connection_up (NmCli *nmc, int argc, char **argv) ap = *argv; } + else if (strcmp (*argv, "nsp") == 0) { + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + + nsp = *argv; + } else if (strcmp (*argv, "--nowait") == 0) { wait = FALSE; } else if (strcmp (*argv, "--timeout") == 0) { @@ -1412,7 +1508,7 @@ do_connection_up (NmCli *nmc, int argc, char **argv) g_assert (s_con); con_type = nm_setting_connection_get_connection_type (s_con); - device_found = find_device_for_connection (nmc, connection, iface, ap, &device, &spec_object, &error); + device_found = find_device_for_connection (nmc, connection, iface, ap, nsp, &device, &spec_object, &error); if (!device_found) { if (error) diff --git a/cli/src/devices.c b/cli/src/devices.c index 12da386c4d..5e67c4ef5d 100644 --- a/cli/src/devices.c +++ b/cli/src/devices.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -39,6 +38,7 @@ #include #include //#include +#include #include #include #include @@ -51,6 +51,7 @@ #include #include #include +#include #include "utils.h" #include "devices.h" @@ -75,14 +76,16 @@ static NmcOutputField nmc_fields_dev_list_sections[] = { {"WIFI-PROPERTIES", N_("WIFI-PROPERTIES"), 0, NULL, 0}, /* 2 */ {"AP", N_("AP"), 0, NULL, 0}, /* 3 */ {"WIRED-PROPERTIES", N_("WIRED-PROPERTIES"), 0, NULL, 0}, /* 4 */ - {"IP4-SETTINGS", N_("IP4-SETTINGS"), 0, NULL, 0}, /* 5 */ - {"IP4-DNS", N_("IP4-DNS"), 0, NULL, 0}, /* 6 */ - {"IP6-SETTINGS", N_("IP6-SETTINGS"), 0, NULL, 0}, /* 7 */ - {"IP6-DNS", N_("IP6-DNS"), 0, NULL, 0}, /* 8 */ + {"WIMAX-PROPERTIES", N_("WIMAX-PROPERTIES"), 0, NULL, 0}, /* 5 */ + {"NSP", N_("NSP"), 0, NULL, 0}, /* 6 */ + {"IP4-SETTINGS", N_("IP4-SETTINGS"), 0, NULL, 0}, /* 7 */ + {"IP4-DNS", N_("IP4-DNS"), 0, NULL, 0}, /* 8 */ + {"IP6-SETTINGS", N_("IP6-SETTINGS"), 0, NULL, 0}, /* 9 */ + {"IP6-DNS", N_("IP6-DNS"), 0, NULL, 0}, /* 10 */ {NULL, NULL, 0, NULL, 0} }; -#define NMC_FIELDS_DEV_LIST_SECTIONS_ALL "GENERAL,CAPABILITIES,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4-SETTINGS,IP4-DNS,IP6-SETTINGS,IP6-DNS" -#define NMC_FIELDS_DEV_LIST_SECTIONS_COMMON "GENERAL,CAPABILITIES,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,IP4-SETTINGS,IP4-DNS,IP6-SETTINGS,IP6-DNS" +#define NMC_FIELDS_DEV_LIST_SECTIONS_ALL "GENERAL,CAPABILITIES,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4-SETTINGS,IP4-DNS,IP6-SETTINGS,IP6-DNS" +#define NMC_FIELDS_DEV_LIST_SECTIONS_COMMON "GENERAL,CAPABILITIES,WIFI-PROPERTIES,AP,WIRED-PROPERTIES,WIMAX-PROPERTIES,NSP,IP4-SETTINGS,IP4-DNS,IP6-SETTINGS,IP6-DNS" /* Available fields for 'dev list' - GENERAL part */ static NmcOutputField nmc_fields_dev_list_general[] = { @@ -130,6 +133,19 @@ static NmcOutputField nmc_fields_dev_list_wifi_prop[] = { #define NMC_FIELDS_DEV_LIST_WIFI_PROP_ALL "NAME,WEP,WPA,WPA2,TKIP,CCMP" #define NMC_FIELDS_DEV_LIST_WIFI_PROP_COMMON "NAME,WEP,WPA,WPA2,TKIP,CCMP" +/* Available fields for 'dev list' - wimax properties part */ +static NmcOutputField nmc_fields_dev_list_wimax_prop[] = { + {"NAME", N_("NAME"), 18, NULL, 0}, /* 0 */ + {"CTR-FREQ", N_("CTR-FREQ"), 7, NULL, 0}, /* 1 */ + {"RSSI", N_("RSSI"), 5, NULL, 0}, /* 2 */ + {"CINR", N_("CINR"), 5, NULL, 0}, /* 3 */ + {"TX-POW", N_("TX-POW"), 5, NULL, 0}, /* 4 */ + {"BSID", N_("BSID"), 18, NULL, 0}, /* 5 */ + {NULL, NULL, 0, NULL, 0} +}; +#define NMC_FIELDS_DEV_LIST_WIMAX_PROP_ALL "NAME,CTR-FREQ,RSSI,CINR,TX-POW,BSID" +#define NMC_FIELDS_DEV_LIST_WIMAX_PROP_COMMON "NAME,CTR-FREQ,RSSI,CINR,TX-POW,BSID" + /* Available fields for 'dev list' - IPv4 settings part */ static NmcOutputField nmc_fields_dev_list_ip4_settings[] = { {"NAME", N_("NAME"), 15, NULL, 0}, /* 0 */ @@ -191,6 +207,21 @@ static NmcOutputField nmc_fields_dev_wifi_list[] = { #define NMC_FIELDS_DEV_WIFI_LIST_COMMON "SSID,BSSID,MODE,FREQ,RATE,SIGNAL,SECURITY,ACTIVE" #define NMC_FIELDS_DEV_WIFI_LIST_FOR_DEV_LIST "NAME,"NMC_FIELDS_DEV_WIFI_LIST_COMMON +/* Available fields for 'dev wimax list' */ +static NmcOutputField nmc_fields_dev_wimax_list[] = { + {"NAME", N_("NAME"), 15, NULL, 0}, /* 0 */ + {"NSP", N_("NSP"), 33, NULL, 0}, /* 1 */ + {"SIGNAL", N_("SIGNAL"), 8, NULL, 0}, /* 2 */ + {"TYPE", N_("TYPE"), 16, NULL, 0}, /* 3 */ + {"DEVICE", N_("DEVICE"), 10, NULL, 0}, /* 4 */ + {"ACTIVE", N_("ACTIVE"), 8, NULL, 0}, /* 5 */ + {"DBUS-PATH", N_("DBUS-PATH"), 46, NULL, 0}, /* 6 */ + {NULL, NULL, 0, NULL, 0} +}; +#define NMC_FIELDS_DEV_WIMAX_LIST_ALL "NSP,SIGNAL,TYPE,DEVICE,ACTIVE,DBUS-PATH" +#define NMC_FIELDS_DEV_WIMAX_LIST_COMMON "NSP,SIGNAL,TYPE,DEVICE,ACTIVE" +#define NMC_FIELDS_DEV_WIMAX_LIST_FOR_DEV_LIST "NAME,"NMC_FIELDS_DEV_WIMAX_LIST_COMMON + /* static function prototypes */ static void usage (void); @@ -199,6 +230,7 @@ static NMCResultCode do_devices_status (NmCli *nmc, int argc, char **argv); static NMCResultCode do_devices_list (NmCli *nmc, int argc, char **argv); static NMCResultCode do_device_disconnect (NmCli *nmc, int argc, char **argv); static NMCResultCode do_device_wifi (NmCli *nmc, int argc, char **argv); +static NMCResultCode do_device_wimax (NmCli *nmc, int argc, char **argv); extern GMainLoop *loop; /* glib main loop variable */ @@ -208,11 +240,12 @@ usage (void) { fprintf (stderr, _("Usage: nmcli dev { COMMAND | help }\n\n" - " COMMAND := { status | list | disconnect | wifi }\n\n" + " COMMAND := { status | list | disconnect | wifi | wimax }\n\n" " status\n" " list [iface ]\n" " disconnect iface [--nowait] [--timeout ]\n" - " wifi [list [iface ] [hwaddr ]]\n\n")); + " wifi [list [iface ] [hwaddr ]]\n" + " wimax [list [iface ] [nsp ]]\n\n")); } /* quit main loop */ @@ -265,6 +298,8 @@ get_device_type (NMDevice * device) return NM_SETTING_BLUETOOTH_SETTING_NAME; // else if (NM_IS_DEVICE_OLPC_MESH (device)) // return NM_SETTING_OLPC_MESH_SETTING_NAME; + else if (NM_IS_DEVICE_WIMAX (device)) + return NM_SETTING_WIMAX_SETTING_NAME; else return _("Unknown"); } @@ -447,6 +482,52 @@ detail_access_point (gpointer data, gpointer user_data) g_string_free (security_str, TRUE); } +static void +detail_wimax_nsp (NMWimaxNsp *nsp, NmCli *nmc, NMDevice *dev, int idx) +{ + NMDeviceWimax *wimax = NM_DEVICE_WIMAX (dev); + char *nsp_name, *quality_str; + const char *ntype; + gboolean active = FALSE; + + switch (nm_wimax_nsp_get_network_type (nsp)) { + case NM_WIMAX_NSP_NETWORK_TYPE_HOME: + ntype = _("Home"); + break; + case NM_WIMAX_NSP_NETWORK_TYPE_PARTNER: + ntype = _("Partner"); + break; + case NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER: + ntype = _("Roaming"); + break; + default: + ntype = _("Unknown"); + break; + } + + if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) { + if (nsp == nm_device_wimax_get_active_nsp (wimax)) + active = TRUE; + } + + quality_str = g_strdup_printf ("%u", nm_wimax_nsp_get_signal_quality (nsp)); + nsp_name = g_strdup_printf ("NSP%d", idx); /* NSP */ + + nmc->allowed_fields[0].value = nsp_name; + nmc->allowed_fields[1].value = nm_wimax_nsp_get_name (nsp); + nmc->allowed_fields[2].value = quality_str; + nmc->allowed_fields[3].value = ntype; + nmc->allowed_fields[4].value = nm_device_get_iface (dev); + nmc->allowed_fields[5].value = active ? _("yes") : _("no"); + nmc->allowed_fields[6].value = nm_object_get_path (NM_OBJECT (nsp)); + + nmc->print_fields.flags &= ~NMC_PF_FLAG_MAIN_HEADER_ADD & ~NMC_PF_FLAG_MAIN_HEADER_ONLY & ~NMC_PF_FLAG_FIELD_NAMES; /* Clear header flags */ + print_fields (nmc->print_fields, nmc->allowed_fields); + + g_free (nsp_name); + g_free (quality_str); +} + struct cb_info { NMClient *client; const GPtrArray *active; @@ -523,6 +604,8 @@ show_device_info (gpointer data, gpointer user_data) hwaddr = nm_device_ethernet_get_hw_address (NM_DEVICE_ETHERNET (device)); else if (NM_IS_DEVICE_WIFI (device)) hwaddr = nm_device_wifi_get_hw_address (NM_DEVICE_WIFI (device)); + else if (NM_IS_DEVICE_WIMAX (device)) + hwaddr = nm_device_wimax_get_hw_address (NM_DEVICE_WIMAX (device)); nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[0].name; /* "GENERAL"*/ nmc->allowed_fields[1].value = nm_device_get_iface (device); @@ -633,6 +716,74 @@ show_device_info (gpointer data, gpointer user_data) print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */ was_output = TRUE; } + } else if (NM_IS_DEVICE_WIMAX (device)) { + /* WIMAX-PROPERTIES */ + if (!strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[5].name)) { + char *cfreq = NULL, *rssi = NULL, *cinr = NULL, *txpow = NULL; + guint tmp_uint; + gint tmp_int; + const char *bsid; + + nmc->allowed_fields = nmc_fields_dev_list_wimax_prop; + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES; + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_WIMAX_PROP_ALL, nmc->allowed_fields, NULL); + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ + + nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[5].name; /* "WIMAX-PROPERTIES" */ + + /* Center frequency */ + tmp_uint = nm_device_wimax_get_center_frequency (NM_DEVICE_WIMAX (device)); + if (tmp_uint) + cfreq = g_strdup_printf ("%'.1f MHz", (double) tmp_uint / 1000.0); + nmc->allowed_fields[1].value = cfreq ? cfreq : ""; + + /* RSSI */ + tmp_int = nm_device_wimax_get_rssi (NM_DEVICE_WIMAX (device)); + if (tmp_int) + rssi = g_strdup_printf ("%d dBm", tmp_int); + nmc->allowed_fields[2].value = rssi ? rssi : ""; + + /* CINR */ + tmp_int = nm_device_wimax_get_cinr (NM_DEVICE_WIMAX (device)); + if (tmp_int) + cinr = g_strdup_printf ("%d dB", tmp_int); + nmc->allowed_fields[3].value = cinr ? cinr : ""; + + /* TX Power */ + tmp_int = nm_device_wimax_get_tx_power (NM_DEVICE_WIMAX (device)); + if (tmp_int) + txpow = g_strdup_printf ("%'.2f dBm", (float) tmp_int / 2.0); + nmc->allowed_fields[4].value = txpow ? txpow : ""; + + /* BSID */ + bsid = nm_device_wimax_get_bsid (NM_DEVICE_WIMAX (device)); + nmc->allowed_fields[5].value = bsid ? bsid : ""; + + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX; + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */ + was_output = TRUE; + } + + /* section NSP */ + if (!strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[6].name)) { + const GPtrArray *nsps; + int g, idx = 1; + + nmc->allowed_fields = nmc_fields_dev_wimax_list; + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES; + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_WIMAX_LIST_FOR_DEV_LIST, nmc->allowed_fields, NULL); + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ + + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX; + + nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (device)); + for (g = 0; nsps && g < nsps->len; g++) { + NMWimaxNsp *nsp = g_ptr_array_index (nsps, g); + + detail_wimax_nsp (nsp, nmc, device, idx++); + } + was_output = TRUE; + } } /* IP Setup info */ @@ -642,7 +793,7 @@ show_device_info (gpointer data, gpointer user_data) GSList *iter; /* IP4-SETTINGS */ - if (cfg4 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[5].name)) { + if (cfg4 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[7].name)) { nmc->allowed_fields = nmc_fields_dev_list_ip4_settings; nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES; nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_IP4_SETTINGS_ALL, nmc->allowed_fields, NULL); @@ -662,7 +813,7 @@ show_device_info (gpointer data, gpointer user_data) gateway_str = ip4_address_as_string (nm_ip4_address_get_gateway (addr)); - nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[5].name; /* "IP4-SETTINGS" */ + nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[7].name; /* "IP4-SETTINGS" */ nmc->allowed_fields[1].value = addr_str; nmc->allowed_fields[2].value = prefix_str; nmc->allowed_fields[3].value = gateway_str; @@ -676,7 +827,7 @@ show_device_info (gpointer data, gpointer user_data) was_output = TRUE; } /* IP4-DNS */ - if (cfg4 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[6].name)) { + if (cfg4 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[8].name)) { array = nm_ip4_config_get_nameservers (cfg4); if (array) { int i; @@ -687,7 +838,7 @@ show_device_info (gpointer data, gpointer user_data) print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ for (i = 0; i < array->len; i++) { - char *dns_name = g_strdup_printf ("%s%d", nmc_fields_dev_list_sections[6].name, i+1); + char *dns_name = g_strdup_printf ("%s%d", nmc_fields_dev_list_sections[8].name, i+1); tmp = ip4_address_as_string (g_array_index (array, guint32, i)); nmc->allowed_fields[0].value = dns_name; /* "IP4-DNS" */ nmc->allowed_fields[1].value = tmp; @@ -702,7 +853,7 @@ show_device_info (gpointer data, gpointer user_data) } /* IP6-SETTINGS */ - if (cfg6 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[7].name)) { + if (cfg6 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[9].name)) { nmc->allowed_fields = nmc_fields_dev_list_ip6_settings; nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES; nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_DEV_LIST_IP6_SETTINGS_ALL, nmc->allowed_fields, NULL); @@ -718,7 +869,7 @@ show_device_info (gpointer data, gpointer user_data) prefix_str = g_strdup_printf ("%d", prefix); gateway_str = ip6_address_as_string (nm_ip6_address_get_gateway (addr)); - nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[7].name; /* "IP6-SETTINGS" */ + nmc->allowed_fields[0].value = nmc_fields_dev_list_sections[9].name; /* "IP6-SETTINGS" */ nmc->allowed_fields[1].value = addr_str; nmc->allowed_fields[2].value = prefix_str; nmc->allowed_fields[3].value = gateway_str; @@ -732,7 +883,7 @@ show_device_info (gpointer data, gpointer user_data) was_output = TRUE; } /* IP6-DNS */ - if (cfg6 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[8].name)) { + if (cfg6 && !strcasecmp (nmc_fields_dev_list_sections[section_idx].name, nmc_fields_dev_list_sections[10].name)) { int i = 1; nmc->allowed_fields = nmc_fields_dev_list_ip6_dns; nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES; @@ -740,7 +891,7 @@ show_device_info (gpointer data, gpointer user_data) print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ for (iter = (GSList *) nm_ip6_config_get_nameservers (cfg6); iter; iter = g_slist_next (iter)) { - char *dns_name = g_strdup_printf ("%s%d", nmc_fields_dev_list_sections[8].name, i++); + char *dns_name = g_strdup_printf ("%s%d", nmc_fields_dev_list_sections[10].name, i++); tmp = ip6_address_as_string (iter->data); nmc->allowed_fields[0].value = dns_name; /* "IP6-DNS" */ @@ -1246,6 +1397,199 @@ do_device_wifi (NmCli *nmc, int argc, char **argv) return nmc->return_value; } +static void +show_nsp_info (NMDevice *device, NmCli *nmc) +{ + const GPtrArray *nsps; + int i, idx = 1; + + nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (device)); + for (i = 0; nsps && i < nsps->len; i++) { + NMWimaxNsp *nsp = g_ptr_array_index (nsps, i); + + detail_wimax_nsp (nsp, nmc, device, idx++); + } +} + +static NMCResultCode +do_device_wimax_list (NmCli *nmc, int argc, char **argv) +{ + GError *error = NULL; + NMDevice *device = NULL; + NMWimaxNsp *nsp = NULL; + const char *iface = NULL; + const char *nsp_user = NULL; + const GPtrArray *devices; + const GPtrArray *nsps; + int i, j; + char *fields_str; + char *fields_all = NMC_FIELDS_DEV_WIMAX_LIST_ALL; + char *fields_common = NMC_FIELDS_DEV_WIMAX_LIST_COMMON; + guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0; + guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0; + guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0; + + while (argc > 0) { + if (strcmp (*argv, "iface") == 0) { + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + iface = *argv; + } else if (strcmp (*argv, "nsp") == 0) { + if (next_arg (&argc, &argv) != 0) { + g_string_printf (nmc->return_text, _("Error: %s argument is missing."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + nsp_user = *argv; + } else { + fprintf (stderr, _("Unknown parameter: %s\n"), *argv); + } + + argc--; + argv++; + } + + /* create NMClient */ + if (!nmc->get_client (nmc)) + goto error; + + devices = nm_client_get_devices (nmc->client); + + if (!nmc->required_fields || strcasecmp (nmc->required_fields, "common") == 0) + fields_str = fields_common; + else if (!nmc->required_fields || strcasecmp (nmc->required_fields, "all") == 0) + fields_str = fields_all; + else + fields_str = nmc->required_fields; + + nmc->allowed_fields = nmc_fields_dev_wimax_list; + nmc->print_fields.indices = parse_output_fields (fields_str, nmc->allowed_fields, &error); + + if (error) { + if (error->code == 0) + g_string_printf (nmc->return_text, _("Error: 'dev wimax': %s"), error->message); + else + g_string_printf (nmc->return_text, _("Error: 'dev wimax': %s; allowed fields: %s"), error->message, NMC_FIELDS_DEV_WIMAX_LIST_ALL); + g_error_free (error); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto error; + } + + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES; + nmc->print_fields.header_name = _("WiMAX NSP list"); + + if (iface) { + /* Device specified - list only NSPs of this interface */ + for (i = 0; devices && (i < devices->len); i++) { + NMDevice *candidate = g_ptr_array_index (devices, i); + const char *dev_iface = nm_device_get_iface (candidate); + + if (!strcmp (dev_iface, iface)) { + device = candidate; + break; + } + } + + if (!device) { + g_string_printf (nmc->return_text, _("Error: Device '%s' not found."), iface); + nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + goto error; + } + + if (NM_IS_DEVICE_WIMAX (device)) { + if (nsp_user) { + /* Specific NSP requested - list only that */ + nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (device)); + for (j = 0, nsp = NULL; nsps && (j < nsps->len); j++) { + NMWimaxNsp *candidate_nsp = g_ptr_array_index (nsps, j); + const char *candidate_name = nm_wimax_nsp_get_name (candidate_nsp); + char *nsp_up; + + nsp_up = g_ascii_strup (nsp_user, -1); + if (!strcmp (nsp_up, candidate_name)) + nsp = candidate_nsp; + g_free (nsp_up); + } + if (!nsp) { + g_string_printf (nmc->return_text, _("Error: NSP with name '%s' not found."), nsp_user); + nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + goto error; + } + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ + detail_wimax_nsp (nsp, nmc, device, 1); + } else { + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ + show_nsp_info (device, nmc); + } + } else { + g_string_printf (nmc->return_text, _("Error: Device '%s' is not a WiMAX device."), iface); + nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + goto error; + } + } else { + /* List NSPs for all devices */ + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ + if (nsp_user) { + /* Specific NSP requested - list only that */ + for (i = 0; devices && (i < devices->len); i++) { + NMDevice *dev = g_ptr_array_index (devices, i); + int idx = 1; + + if (!NM_IS_DEVICE_WIMAX (dev)) + continue; + + nsps = nm_device_wimax_get_nsps (NM_DEVICE_WIMAX (dev)); + for (j = 0, nsp = NULL; nsps && (j < nsps->len); j++) { + NMWimaxNsp *candidate_nsp = g_ptr_array_index (nsps, j); + const char *candidate_name = nm_wimax_nsp_get_name (candidate_nsp); + char *nsp_up; + + nsp_up = g_ascii_strup (nsp_user, -1); + if (!strcmp (nsp_up, candidate_name)) { + nsp = candidate_nsp; + detail_wimax_nsp (nsp, nmc, dev, idx); + } + g_free (nsp_up); + } + } + if (!nsp) { + g_string_printf (nmc->return_text, _("Error: Access point with hwaddr '%s' not found."), nsp_user); + nmc->return_value = NMC_RESULT_ERROR_UNKNOWN; + goto error; + } + } else { + for (i = 0; devices && (i < devices->len); i++) { + NMDevice *dev = g_ptr_array_index (devices, i); + if (NM_IS_DEVICE_WIMAX (dev)) + show_nsp_info (dev, nmc); + } + } + } + +error: + return nmc->return_value; +} + +static NMCResultCode +do_device_wimax (NmCli *nmc, int argc, char **argv) +{ + if (argc == 0) + nmc->return_value = do_device_wimax_list (nmc, argc-1, argv+1); + else if (argc > 0) { + if (matches (*argv, "list") == 0) { + nmc->return_value = do_device_wimax_list (nmc, argc-1, argv+1); + } + else { + g_string_printf (nmc->return_text, _("Error: 'dev wimax' command '%s' is not valid."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + } + } + + return nmc->return_value; +} NMCResultCode do_devices (NmCli *nmc, int argc, char **argv) @@ -1281,6 +1625,11 @@ do_devices (NmCli *nmc, int argc, char **argv) goto opt_error; nmc->return_value = do_device_wifi (nmc, argc-1, argv+1); } + else if (matches (*argv, "wimax") == 0) { + if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error)) + goto opt_error; + nmc->return_value = do_device_wimax (nmc, argc-1, argv+1); + } else if (strcmp (*argv, "help") == 0) { usage (); } diff --git a/cli/src/network-manager.c b/cli/src/network-manager.c index 23a2ef11e7..cd7201cc13 100644 --- a/cli/src/network-manager.c +++ b/cli/src/network-manager.c @@ -39,13 +39,16 @@ static NmcOutputField nmc_fields_nm_status[] = { {"WIFI", N_("WIFI"), 10, NULL, 0}, /* 4 */ {"WWAN-HARDWARE", N_("WWAN-HARDWARE"), 15, NULL, 0}, /* 5 */ {"WWAN", N_("WWAN"), 10, NULL, 0}, /* 6 */ - {NULL, NULL, 0, NULL, 0} + {"WIMAX-HARDWARE", N_("WIMAX-HARDWARE"), 15, NULL, 0}, /* 7 */ + {"WIMAX", N_("WIMAX"), 10, NULL, 0}, /* 8 */ + {NULL, NULL, 0, NULL, 0} }; -#define NMC_FIELDS_NM_STATUS_ALL "RUNNING,STATE,NET-ENABLED,WIFI-HARDWARE,WIFI,WWAN-HARDWARE,WWAN" +#define NMC_FIELDS_NM_STATUS_ALL "RUNNING,STATE,NET-ENABLED,WIFI-HARDWARE,WIFI,WWAN-HARDWARE,WWAN,WIMAX-HARDWARE,WIMAX" #define NMC_FIELDS_NM_STATUS_COMMON "RUNNING,STATE,WIFI-HARDWARE,WIFI,WWAN-HARDWARE,WWAN" #define NMC_FIELDS_NM_NET_ENABLED "NET-ENABLED" #define NMC_FIELDS_NM_WIFI "WIFI" #define NMC_FIELDS_NM_WWAN "WWAN" +#define NMC_FIELDS_NM_WIMAX "WIMAX" extern GMainLoop *loop; @@ -62,12 +65,13 @@ usage (void) { fprintf (stderr, _("Usage: nmcli nm { COMMAND | help }\n\n" - " COMMAND := { status | enable | sleep | wifi | wwan }\n\n" + " COMMAND := { status | enable | sleep | wifi | wwan | wimax }\n\n" " status\n" " enable [true|false]\n" " sleep [true|false]\n" " wifi [on|off]\n" - " wwan [on|off]\n\n")); + " wwan [on|off]\n" + " wimax [on|off]\n\n")); } /* quit main loop */ @@ -103,6 +107,7 @@ show_nm_status (NmCli *nmc) NMState state; const char *wireless_hw_enabled_str, *wireless_enabled_str; const char *wwan_hw_enabled_str, *wwan_enabled_str; + const char *wimax_hw_enabled_str, *wimax_enabled_str; GError *error = NULL; const char *fields_str; const char *fields_all = NMC_FIELDS_NM_STATUS_ALL; @@ -145,8 +150,10 @@ show_nm_status (NmCli *nmc) wireless_enabled_str = nm_client_wireless_get_enabled (nmc->client) ? _("enabled") : _("disabled"); wwan_hw_enabled_str = nm_client_wwan_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled"); wwan_enabled_str = nm_client_wwan_get_enabled (nmc->client) ? _("enabled") : _("disabled"); + wimax_hw_enabled_str = nm_client_wimax_hardware_get_enabled (nmc->client) ? _("enabled") : _("disabled"); + wimax_enabled_str = nm_client_wimax_get_enabled (nmc->client) ? _("enabled") : _("disabled"); } else { - wireless_hw_enabled_str = wireless_enabled_str = wwan_hw_enabled_str = wwan_enabled_str = _("unknown"); + wireless_hw_enabled_str = wireless_enabled_str = wwan_hw_enabled_str = wwan_enabled_str = wimax_hw_enabled_str = wimax_enabled_str = _("unknown"); } nmc->allowed_fields[0].value = nm_running ? _("running") : _("not running"); @@ -156,6 +163,8 @@ show_nm_status (NmCli *nmc) nmc->allowed_fields[4].value = wireless_enabled_str; nmc->allowed_fields[5].value = wwan_hw_enabled_str; nmc->allowed_fields[6].value = wwan_enabled_str; + nmc->allowed_fields[7].value = wimax_hw_enabled_str; + nmc->allowed_fields[8].value = wimax_enabled_str; nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag; print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */ @@ -208,6 +217,7 @@ do_network_manager (NmCli *nmc, int argc, char **argv) gboolean enable_net; gboolean enable_wifi; gboolean enable_wwan; + gboolean enable_wimax; guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0; guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0; guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0; @@ -341,6 +351,38 @@ do_network_manager (NmCli *nmc, int argc, char **argv) nm_client_wwan_set_enabled (nmc->client, enable_wwan); } } + else if (matches (*argv, "wimax") == 0) { + if (next_arg (&argc, &argv) != 0) { + if (!nmc_terse_option_check (nmc->print_output, nmc->required_fields, &error)) + goto opt_error; + /* no argument, show current WiMAX state */ + if (nmc->required_fields && strcasecmp (nmc->required_fields, "WIMAX")) { + g_string_printf (nmc->return_text, _("Error: '--fields' value '%s' is not valid here; allowed fields: %s"), + nmc->required_fields, NMC_FIELDS_NM_WIMAX); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto end; + } + nmc->allowed_fields = nmc_fields_nm_status; + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_NM_WIMAX, nmc->allowed_fields, NULL); + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_MAIN_HEADER_ADD | NMC_PF_FLAG_FIELD_NAMES; + nmc->print_fields.header_name = _("WiMAX enabled"); + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ + nmc->allowed_fields[8].value = nm_client_wimax_get_enabled (nmc->client) ? _("enabled") : _("disabled"); + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag; + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print header */ + } else { + if (!strcmp (*argv, "on")) + enable_wimax = TRUE; + else if (!strcmp (*argv, "off")) + enable_wimax = FALSE; + else { + g_string_printf (nmc->return_text, _("Error: invalid 'wimax' parameter: '%s'."), *argv); + nmc->return_value = NMC_RESULT_ERROR_USER_INPUT; + goto end; + } + nm_client_wimax_set_enabled (nmc->client, enable_wimax); + } + } else if (strcmp (*argv, "help") == 0) { usage (); } diff --git a/cli/src/settings.c b/cli/src/settings.c index 8b62876479..35711d9238 100644 --- a/cli/src/settings.c +++ b/cli/src/settings.c @@ -402,6 +402,18 @@ static NmcOutputField nmc_fields_setting_vpn[] = { NM_SETTING_VPN_SECRETS #define NMC_FIELDS_SETTING_VPN_COMMON NMC_FIELDS_SETTING_VPN_ALL +/* Available fields for NM_SETTING_WIMAX_SETTING_NAME */ +static NmcOutputField nmc_fields_setting_wimax[] = { + SETTING_FIELD ("name", 6), /* 0 */ + SETTING_FIELD (NM_SETTING_WIMAX_MAC_ADDRESS, 19), /* 1 */ + SETTING_FIELD (NM_SETTING_WIMAX_NETWORK_NAME, 40), /* 2 */ + {NULL, NULL, 0, NULL, 0} +}; +#define NMC_FIELDS_SETTING_WIMAX_ALL "name"","\ + NM_SETTING_WIMAX_MAC_ADDRESS","\ + NM_SETTING_WIMAX_NETWORK_NAME +#define NMC_FIELDS_SETTING_WIMAX_COMMON NMC_FIELDS_SETTING_WIMAX_ALL + static char * wep_key_type_to_string (NMWepKeyType type) @@ -1381,3 +1393,37 @@ setting_vpn_details (NMSetting *setting, NmCli *nmc) return TRUE; } +gboolean +setting_wimax_details (NMSetting *setting, NmCli *nmc) +{ + NMSettingWimax *s_wimax; + const GByteArray *mac; + char *device_mac_str = NULL; + guint32 mode_flag = (nmc->print_output == NMC_PRINT_PRETTY) ? NMC_PF_FLAG_PRETTY : (nmc->print_output == NMC_PRINT_TERSE) ? NMC_PF_FLAG_TERSE : 0; + guint32 multiline_flag = nmc->multiline_output ? NMC_PF_FLAG_MULTILINE : 0; + guint32 escape_flag = nmc->escape_values ? NMC_PF_FLAG_ESCAPE : 0; + + g_return_val_if_fail (NM_IS_SETTING_WIMAX (setting), FALSE); + s_wimax = (NMSettingWimax *) setting; + + nmc->allowed_fields = nmc_fields_setting_wimax; + nmc->print_fields.indices = parse_output_fields (NMC_FIELDS_SETTING_WIMAX_ALL, nmc->allowed_fields, NULL); + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_FIELD_NAMES; + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print field names */ + + mac = nm_setting_wimax_get_mac_address (s_wimax); + if (mac) + device_mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->data[0], mac->data[1], mac->data[2], mac->data[3], mac->data[4], mac->data[5]); + + nmc->allowed_fields[0].value = NM_SETTING_WIMAX_SETTING_NAME; + nmc->allowed_fields[1].value = device_mac_str; + nmc->allowed_fields[2].value = nm_setting_wimax_get_network_name (s_wimax); + + nmc->print_fields.flags = multiline_flag | mode_flag | escape_flag | NMC_PF_FLAG_SECTION_PREFIX; + print_fields (nmc->print_fields, nmc->allowed_fields); /* Print values */ + + g_free (device_mac_str); + + return TRUE; +} + diff --git a/cli/src/settings.h b/cli/src/settings.h index aec71551da..4901bf2725 100644 --- a/cli/src/settings.h +++ b/cli/src/settings.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "nmcli.h" #include "utils.h" @@ -55,5 +56,6 @@ gboolean setting_cdma_details (NMSetting *setting, NmCli *nmc); gboolean setting_bluetooth_details (NMSetting *setting, NmCli *nmc); gboolean setting_olpc_mesh_details (NMSetting *setting, NmCli *nmc); gboolean setting_vpn_details (NMSetting *setting, NmCli *nmc); +gboolean setting_wimax_details (NMSetting *setting, NmCli *nmc); #endif /* NMC_SETTINGS_H */ From fa0fde8cbda57725b45f7ff9020e3ed531b18a2d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 6 Jan 2011 17:13:38 -0600 Subject: [PATCH 093/102] release: bump version to 0.8.991 for WiMAX support --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 77475dd4a0..8a4b498c8d 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ(2.52) -AC_INIT(NetworkManager, 0.8.990, dcbw@redhat.com, NetworkManager) +AC_INIT(NetworkManager, 0.8.991, dcbw@redhat.com, NetworkManager) AM_INIT_AUTOMAKE([1.9 subdir-objects tar-ustar no-dist-gzip dist-bzip2]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([no])]) AM_MAINTAINER_MODE From f08d892bdaf743bba5f098244f951477aeda2285 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 6 Jan 2011 17:17:10 -0600 Subject: [PATCH 094/102] trivial: fix autoconf warning --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 55a225caf9..ec0fda557e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -237,7 +237,7 @@ NetworkManager_CPPFLAGS = \ WIMAX_LIBS= if WITH_WIMAX -WIMAX_LIBS = ./wimax/libwimax.la +WIMAX_LIBS += ./wimax/libwimax.la endif NetworkManager_LDADD = \ From 5f1a102b11f393e7b2fffa9b8f2c187096870553 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 6 Jan 2011 17:17:18 -0600 Subject: [PATCH 095/102] build: require Intel WiMAX SDK v1.5.1 or greater for WiMAX support --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 8a4b498c8d..32591ced91 100644 --- a/configure.ac +++ b/configure.ac @@ -271,7 +271,7 @@ AC_SUBST(UUID_LIBS) AC_ARG_ENABLE(wimax, AC_HELP_STRING([--enable-wimax], [enable WiMAX support]), [enable_wimax=${enableval}], [enable_wimax=yes]) if (test "${enable_wimax}" = "yes"); then - PKG_CHECK_MODULES(IWMX_SDK, libiWmxSdk-0, dummy=yes, + PKG_CHECK_MODULES(IWMX_SDK, libiWmxSdk-0 >= 1.5.1, dummy=yes, AC_MSG_ERROR(Intel WiMAX SDK is required)) AC_SUBST(IWMX_SDK_CFLAGS) AC_SUBST(IWMX_SDK_LIBS) From e33c09a94223ef9c16a21a856a295de5df80d482 Mon Sep 17 00:00:00 2001 From: Anders Jenbo Date: Mon, 10 Jan 2011 15:12:55 +0100 Subject: [PATCH 096/102] po: updated Danish translation (bgo #638494) --- po/da.po | 2441 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 1791 insertions(+), 650 deletions(-) diff --git a/po/da.po b/po/da.po index cbdb211547..bbcde42d27 100644 --- a/po/da.po +++ b/po/da.po @@ -8,710 +8,1851 @@ msgid "" msgstr "" "Project-Id-Version: NetworkManager\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-02-13 20:50+0100\n" -"PO-Revision-Date: 2007-02-13 20:50+0100\n" -"Last-Translator: Lasse Bang Mikkelsen \n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager&component=general\n" +"POT-Creation-Date: 2010-12-11 15:25+0000\n" +"PO-Revision-Date: 2010-12-12 18:49+0100\n" +"Last-Translator: Anders Jenbo \n" "Language-Team: Danish \n" +"Language: da\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Launchpad-Export-Date: 2010-12-12 00:44+0000\n" +"X-Generator: Launchpad (build Unknown)\n" -#: ../gnome/vpn-properties/nm-vpn-properties.c:417 -msgid "Cannot add VPN connection" -msgstr "Kan ikke tilføje VPN-forbindelse" +#: ../cli/src/connections.c:60 +#: ../cli/src/connections.c:76 +#: ../cli/src/devices.c:89 +#: ../cli/src/devices.c:102 +#: ../cli/src/devices.c:112 +#: ../cli/src/devices.c:122 +#: ../cli/src/devices.c:135 +#: ../cli/src/devices.c:146 +#: ../cli/src/devices.c:157 +#: ../cli/src/devices.c:166 +#: ../cli/src/devices.c:175 +msgid "NAME" +msgstr "NAVN" -#: ../gnome/vpn-properties/nm-vpn-properties.c:419 -msgid "" -"No suitable VPN software was found on your system. Contact your system " -"administrator." -msgstr "" -"Ingen passende VPN-programmel blev fundet på dit system. Kontakt din system-" -"administrator." +#. 0 +#: ../cli/src/connections.c:61 +#: ../cli/src/connections.c:77 +msgid "UUID" +msgstr "UUID" -#: ../gnome/vpn-properties/nm-vpn-properties.c:461 -msgid "Cannot import VPN connection" -msgstr "Kan ikke importere VPN-forbindelse" +#. 1 +#: ../cli/src/connections.c:62 +msgid "DEVICES" +msgstr "ENHEDER" -#: ../gnome/vpn-properties/nm-vpn-properties.c:463 +#. 2 +#: ../cli/src/connections.c:63 +#: ../cli/src/connections.c:79 +msgid "SCOPE" +msgstr "ANVENDELSESOMRÅDE" + +#. 3 +#: ../cli/src/connections.c:64 +msgid "DEFAULT" +msgstr "STANDARD" + +#. 4 +#: ../cli/src/connections.c:65 +msgid "DBUS-SERVICE" +msgstr "DBUS-TJENESTE" + +#. 5 +#: ../cli/src/connections.c:66 +msgid "SPEC-OBJECT" +msgstr "SPEC-OBJEKT" + +#. 6 +#: ../cli/src/connections.c:67 +msgid "VPN" +msgstr "VPN" + +#. 7 +#. 2 +#: ../cli/src/connections.c:68 +#: ../cli/src/connections.c:84 +#: ../cli/src/devices.c:64 +msgid "DBUS-PATH" +msgstr "DBUS-STI" + +#. 1 +#. 0 +#. 1 +#: ../cli/src/connections.c:78 +#: ../cli/src/devices.c:62 +#: ../cli/src/devices.c:91 +msgid "TYPE" +msgstr "TYPE" + +#. 3 +#: ../cli/src/connections.c:80 +msgid "TIMESTAMP" +msgstr "TIDSSTEMPEL" + +#. 4 +#: ../cli/src/connections.c:81 +msgid "TIMESTAMP-REAL" +msgstr "TIDSSTEMPEL-ÆGTE" + +#. 5 +#: ../cli/src/connections.c:82 +msgid "AUTOCONNECT" +msgstr "FORBIND AUTOMATISK" + +#. 6 +#: ../cli/src/connections.c:83 +msgid "READONLY" +msgstr "SKRIVEBESKYTTET" + +#: ../cli/src/connections.c:160 #, c-format msgid "" -"Cannot find suitable software for VPN connection type '%s' to import the " -"file '%s'. Contact your system administrator." +"Usage: nmcli con { COMMAND | help }\n" +" COMMAND := { list | status | up | down }\n" +"\n" +" list [id | uuid | system | user]\n" +" status\n" +" up id | uuid [iface ] [ap ] [--nowait] [--timeout ]\n" +" down id | uuid \n" msgstr "" -"Kan ikke finde passende programmel til VPN-forbindelsestypen '%s', til " -"import af filen '%s'. Kontakt din system-administrator." +"Brug: nmcli con { KOMMANDO | help }\n" +" KOMMANDO := { list | status | up | down }\n" +"\n" +" list [id | uuid | system | user]\n" +" status\n" +" up id | uuid [iface ] [ap ] [--nowait] [--timeout ]\n" +" down id | uuid \n" -#: ../gnome/vpn-properties/nm-vpn-properties.c:580 +#: ../cli/src/connections.c:200 +#: ../cli/src/connections.c:541 #, c-format -msgid "Error retrieving VPN connection '%s'" -msgstr "Fejl ved hentning af VPN-forbindelsen '%s'" +msgid "Error: 'con list': %s" +msgstr "Fejl: 'con list': %s" -#: ../gnome/vpn-properties/nm-vpn-properties.c:583 +#: ../cli/src/connections.c:202 +#: ../cli/src/connections.c:543 #, c-format -msgid "" -"Could not find the UI files for VPN connection type '%s'. Contact your " -"system administrator." -msgstr "" -"Kunne ikke finde brugergrænseflade-filerne til VPN-forbindelsestypen '%s'. " -"Kontakt din system-administrator." +msgid "Error: 'con list': %s; allowed fields: %s" +msgstr "Fejl: 'con list': %s; tilladte felter: %s" -#: ../gnome/vpn-properties/nm-vpn-properties.c:727 +#: ../cli/src/connections.c:210 +msgid "Connection details" +msgstr "Forbindelsesdetaljer" + +#: ../cli/src/connections.c:385 +#: ../cli/src/connections.c:606 +msgid "system" +msgstr "system" + +#: ../cli/src/connections.c:385 +#: ../cli/src/connections.c:606 +msgid "user" +msgstr "bruger" + +#: ../cli/src/connections.c:387 +msgid "never" +msgstr "aldrig" + +#. "CAPABILITIES" +#. Print header +#. "WIFI-PROPERTIES" +#: ../cli/src/connections.c:388 +#: ../cli/src/connections.c:389 +#: ../cli/src/connections.c:607 +#: ../cli/src/connections.c:610 +#: ../cli/src/devices.c:433 +#: ../cli/src/devices.c:558 +#: ../cli/src/devices.c:584 +#: ../cli/src/devices.c:585 +#: ../cli/src/devices.c:586 +#: ../cli/src/devices.c:587 +#: ../cli/src/devices.c:588 +#: ../cli/src/settings.c:508 +#: ../cli/src/settings.c:551 +#: ../cli/src/settings.c:652 +#: ../cli/src/settings.c:926 +#: ../cli/src/settings.c:927 +#: ../cli/src/settings.c:929 +#: ../cli/src/settings.c:931 +#: ../cli/src/settings.c:1056 +#: ../cli/src/settings.c:1057 +#: ../cli/src/settings.c:1058 +#: ../cli/src/settings.c:1137 +#: ../cli/src/settings.c:1138 +#: ../cli/src/settings.c:1139 +#: ../cli/src/settings.c:1140 +#: ../cli/src/settings.c:1141 +#: ../cli/src/settings.c:1142 +#: ../cli/src/settings.c:1143 +#: ../cli/src/settings.c:1144 +#: ../cli/src/settings.c:1145 +#: ../cli/src/settings.c:1146 +#: ../cli/src/settings.c:1147 +#: ../cli/src/settings.c:1148 +#: ../cli/src/settings.c:1149 +#: ../cli/src/settings.c:1224 +msgid "yes" +msgstr "ja" + +#: ../cli/src/connections.c:388 +#: ../cli/src/connections.c:389 +#: ../cli/src/connections.c:607 +#: ../cli/src/connections.c:610 +#: ../cli/src/devices.c:433 +#: ../cli/src/devices.c:558 +#: ../cli/src/devices.c:584 +#: ../cli/src/devices.c:585 +#: ../cli/src/devices.c:586 +#: ../cli/src/devices.c:587 +#: ../cli/src/devices.c:588 +#: ../cli/src/settings.c:508 +#: ../cli/src/settings.c:510 +#: ../cli/src/settings.c:551 +#: ../cli/src/settings.c:652 +#: ../cli/src/settings.c:926 +#: ../cli/src/settings.c:927 +#: ../cli/src/settings.c:929 +#: ../cli/src/settings.c:931 +#: ../cli/src/settings.c:1056 +#: ../cli/src/settings.c:1057 +#: ../cli/src/settings.c:1058 +#: ../cli/src/settings.c:1137 +#: ../cli/src/settings.c:1138 +#: ../cli/src/settings.c:1139 +#: ../cli/src/settings.c:1140 +#: ../cli/src/settings.c:1141 +#: ../cli/src/settings.c:1142 +#: ../cli/src/settings.c:1143 +#: ../cli/src/settings.c:1144 +#: ../cli/src/settings.c:1145 +#: ../cli/src/settings.c:1146 +#: ../cli/src/settings.c:1147 +#: ../cli/src/settings.c:1148 +#: ../cli/src/settings.c:1149 +#: ../cli/src/settings.c:1224 +msgid "no" +msgstr "nej" + +#: ../cli/src/connections.c:462 +#: ../cli/src/connections.c:505 +msgid "System connections" +msgstr "System forbindelser" + +#: ../cli/src/connections.c:467 +#: ../cli/src/connections.c:518 +msgid "User connections" +msgstr "Bruger forbindelser" + +#: ../cli/src/connections.c:479 +#: ../cli/src/connections.c:1342 +#: ../cli/src/connections.c:1358 +#: ../cli/src/connections.c:1367 +#: ../cli/src/connections.c:1378 +#: ../cli/src/connections.c:1463 +#: ../cli/src/devices.c:964 +#: ../cli/src/devices.c:974 +#: ../cli/src/devices.c:1076 +#: ../cli/src/devices.c:1083 #, c-format -msgid "Delete VPN connection \"%s\"?" -msgstr "Slet VPN-forbindelsen \"%s\"?" +msgid "Error: %s argument is missing." +msgstr "Fejl: %s parameter mangler." -#: ../gnome/vpn-properties/nm-vpn-properties.c:730 +#: ../cli/src/connections.c:492 #, c-format -msgid "" -"All information about the VPN connection \"%s\" will be lost and you may " -"need your system administrator to provide information to create a new " -"connection." -msgstr "" -"Al information omkring VPN-forbindelsen \"%s\" vil gå tabt og du får " -"muligvis brug for din system-administrator, som kan give dig de nødvendige " -"informationer til oprettelse af en ny forbindelse." +msgid "Error: %s - no such connection." +msgstr "Fejl: %s - ingen sådan forbindelse." -#: ../gnome/vpn-properties/nm-vpn-properties.c:924 -msgid "Unable to load" -msgstr "Kan ikke indlæse" +#: ../cli/src/connections.c:524 +#: ../cli/src/connections.c:1391 +#: ../cli/src/connections.c:1481 +#: ../cli/src/devices.c:787 +#: ../cli/src/devices.c:854 +#: ../cli/src/devices.c:988 +#: ../cli/src/devices.c:1089 +#, c-format +msgid "Unknown parameter: %s\n" +msgstr "Ukendt parameter: %s\n" -#: ../gnome/vpn-properties/nm-vpn-properties.c:926 -msgid "Cannot find some needed resources (the glade file)!" -msgstr "Kan ikke finde nogle krævede ressourcer (glade-filen)!" +#: ../cli/src/connections.c:533 +#, c-format +msgid "Error: no valid parameter specified." +msgstr "Fejl: ingen korrekte parameter angivet." -#. druid_window = GTK_DIALOG (gtk_dialog_new_with_buttons (_("Create VPN Connection"), -#. NULL, -#. GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, -#. GTK_STOCK_CANCEL, -#. GTK_RESPONSE_REJECT, -#. GTK_STOCK_APPLY, -#. GTK_RESPONSE_ACCEPT, -#. NULL)); -#: ../gnome/vpn-properties/nm-vpn-properties.c:1081 -msgid "Create VPN Connection" -msgstr "Opret VPN-forbindelse" +#: ../cli/src/connections.c:548 +#: ../cli/src/connections.c:1584 +#: ../cli/src/devices.c:1295 +#: ../cli/src/network-manager.c:359 +#, c-format +msgid "Error: %s." +msgstr "Fejl: %s." -#. gtk_container_add (GTK_CONTAINER (druid_window->vbox), GTK_WIDGET(gtk_label_new("Some label"))); -#. gtk_box_pack_start (GTK_BOX (druid_window->vbox), GTK_WIDGET(druid), TRUE,TRUE,0); -#. gtk_box_pack_start (GTK_BOX (druid_window->vbox), GTK_WIDGET(gtk_label_new("Some label")), TRUE,TRUE,0); -#. toplevel = gtk_widget_get_toplevel (GTK_WIDGET (druid)); -#. gtk_signal_connect (GTK_OBJECT (toplevel), "delete_event", GTK_SIGNAL_FUNC (vpn_window_close), NULL); -#. make the druid window modal wrt. our main window -#. gtk_window_set_modal (druid_window, TRUE); -#. gtk_window_set_transient_for (GTK_WINDOW(druid_window), GTK_WINDOW (dialog)); -#. Edit dialog -#: ../gnome/vpn-properties/nm-vpn-properties.c:1099 -msgid "Edit VPN Connection" -msgstr "Redigér VPN-forbindelse" +#: ../cli/src/connections.c:655 +#, c-format +msgid "Error: 'con status': %s" +msgstr "Fejl: 'con status': %s" -#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:1 -msgid "Add a new VPN connection" -msgstr "Tilføj ny VPN-forbindelse" +#: ../cli/src/connections.c:657 +#, c-format +msgid "Error: 'con status': %s; allowed fields: %s" +msgstr "Fejl: 'con status': %s; tilladte fejlter: %s" -#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:2 -msgid "Delete the selected VPN connection" -msgstr "Slet den valgte VPN-forbindelse" +#: ../cli/src/connections.c:664 +msgid "Active connections" +msgstr "Aktive forbindelser" -#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:3 -msgid "E_xport" -msgstr "E_ksportér" +#: ../cli/src/connections.c:1034 +#, c-format +msgid "no active connection on device '%s'" +msgstr "ingen aktiv forbindelse på enhed '%s'" -#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:4 -msgid "Edit the selected VPN connection" -msgstr "Redigér den valgte VPN-forbindelse" +#: ../cli/src/connections.c:1042 +#, c-format +msgid "no active connection or device" +msgstr "ingen aktiv forbindelse eller enhed" -#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:5 -msgid "Export the VPN settings to a file" -msgstr "Eksportér VPN-opsætningen til en fil" +#: ../cli/src/connections.c:1092 +#, c-format +msgid "device '%s' not compatible with connection '%s'" +msgstr "enhed \"%s\" er ikke kompatibel med forbindelse \"%s\"" -#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:6 -msgid "Export the selected VPN connection to a file" -msgstr "Eksportér den valgte VPN-forbindelse til en fil" +#: ../cli/src/connections.c:1094 +#, c-format +msgid "no device found for connection '%s'" +msgstr "ingen enhed fundet til forbindelsen '%s'" -#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:7 -msgid "Manage Virtual Private Network Connections" -msgstr "Håndtér virtuelle private netværks-forbindelser (VPN)" +#: ../cli/src/connections.c:1105 +msgid "activating" +msgstr "aktiverer" -#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:8 -msgid "VPN Connections" -msgstr "VPN-forbindelser" +#: ../cli/src/connections.c:1107 +msgid "activated" +msgstr "aktiveret" -#: ../src/nm-ap-security-wep.c:52 -msgid "40-bit WEP" -msgstr "40-bit WEP" +#: ../cli/src/connections.c:1110 +#: ../cli/src/connections.c:1133 +#: ../cli/src/connections.c:1166 +#: ../cli/src/devices.c:247 +#: ../cli/src/devices.c:559 +#: ../cli/src/network-manager.c:94 +#: ../cli/src/network-manager.c:149 +#: ../cli/src/settings.c:473 +msgid "unknown" +msgstr "ukendt" -#: ../src/nm-ap-security-wep.c:54 -msgid "104-bit WEP" -msgstr "104-bit WEP" +#: ../cli/src/connections.c:1119 +msgid "VPN connecting (prepare)" +msgstr "VPN-forbinder (forbered)" -#: ../src/nm-ap-security-wpa-psk.c:51 -msgid "WPA TKIP" -msgstr "WPA TKIP" +#: ../cli/src/connections.c:1121 +msgid "VPN connecting (need authentication)" +msgstr "VPN-forbinder (kræver godkendelse)" -#: ../src/nm-ap-security-wpa-psk.c:53 -msgid "WPA CCMP" -msgstr "WPA CCMP" +#: ../cli/src/connections.c:1123 +msgid "VPN connecting" +msgstr "VPN-forbinder" -#: ../src/nm-ap-security-wpa-psk.c:55 -msgid "WPA Automatic" -msgstr "WPA automatisk" +#: ../cli/src/connections.c:1125 +msgid "VPN connecting (getting IP configuration)" +msgstr "VPN-forbinder (indhenter IP-konfiguration)" -#: ../src/nm-ap-security-wpa-psk.c:60 -msgid "WPA2 TKIP" -msgstr "WPA2 TKIP" +#: ../cli/src/connections.c:1127 +msgid "VPN connected" +msgstr "VPN-forbundet" -#: ../src/nm-ap-security-wpa-psk.c:62 -msgid "WPA2 CCMP" -msgstr "WPA2 CCMP" +#: ../cli/src/connections.c:1129 +msgid "VPN connection failed" +msgstr "VPN-forbindelse fejlede" -#: ../src/nm-ap-security-wpa-psk.c:64 -msgid "WPA2 Automatic" -msgstr "WPA2 automatisk" +#: ../cli/src/connections.c:1131 +msgid "VPN disconnected" +msgstr "VPN afbrudt" -#: ../src/nm-ap-security.c:334 +#: ../cli/src/connections.c:1142 +msgid "unknown reason" +msgstr "ukendt årsag" + +#: ../cli/src/connections.c:1144 msgid "none" msgstr "ingen" -#: ../src/nm-netlink-monitor.c:174 +#: ../cli/src/connections.c:1146 +msgid "the user was disconnected" +msgstr "brugeren blev frakoblet" + +#: ../cli/src/connections.c:1148 +msgid "the base network connection was interrupted" +msgstr "basenetværketsforbindelsen blev afbrudt" + +#: ../cli/src/connections.c:1150 +msgid "the VPN service stopped unexpectedly" +msgstr "VPN servicen stoppede uventet" + +#: ../cli/src/connections.c:1152 +msgid "the VPN service returned invalid configuration" +msgstr "VPN-tjenesten retunerede en ikke gyldig konfiguration" + +#: ../cli/src/connections.c:1154 +msgid "the connection attempt timed out" +msgstr "forbindelsesforsøget udløb" + +#: ../cli/src/connections.c:1156 +msgid "the VPN service did not start in time" +msgstr "VPN-tjenesten startede ikke i tide" + +#: ../cli/src/connections.c:1158 +msgid "the VPN service failed to start" +msgstr "VPN-tjenesten kunne ikke starte" + +#: ../cli/src/connections.c:1160 +msgid "no valid VPN secrets" +msgstr "ingen korrekte VPN-hemmeligheder" + +#: ../cli/src/connections.c:1162 +msgid "invalid VPN secrets" +msgstr "ukorrekte VPN-hemmeligheder" + +#: ../cli/src/connections.c:1164 +msgid "the connection was removed" +msgstr "forbindelsen blev fjernet" + +#: ../cli/src/connections.c:1178 +#, c-format +msgid "state: %s\n" +msgstr "tilstand: %s\n" + +#: ../cli/src/connections.c:1181 +#: ../cli/src/connections.c:1207 +#, c-format +msgid "Connection activated\n" +msgstr "Forbindelse aktiveret\n" + +#: ../cli/src/connections.c:1184 +#, c-format +msgid "Error: Connection activation failed." +msgstr "Fejl: Forbindelsesaktivering fejlede." + +#: ../cli/src/connections.c:1203 +#, c-format +msgid "state: %s (%d)\n" +msgstr "tilstand: %s (%d)\n" + +#: ../cli/src/connections.c:1213 +#, c-format +msgid "Error: Connection activation failed: %s." +msgstr "Fejl: Forbindelsesaktivering fejlede: %s." + +#: ../cli/src/connections.c:1230 +#: ../cli/src/devices.c:911 +#, c-format +msgid "Error: Timeout %d sec expired." +msgstr "Fejl: Ventetid på %d sek udløb." + +#: ../cli/src/connections.c:1273 +#, c-format +msgid "Error: Connection activation failed: %s" +msgstr "Fejl: Forbindelsesaktivering fejlede: %s" + +#: ../cli/src/connections.c:1287 +#, c-format +msgid "Error: Obtaining active connection for '%s' failed." +msgstr "Fejl: Indhentelse af aktiv forbindelse for '%s' mislykkedes." + +#: ../cli/src/connections.c:1296 +#, c-format +msgid "Active connection state: %s\n" +msgstr "Aktiv forbindelsestilstand: %s\n" + +#: ../cli/src/connections.c:1297 +#, c-format +msgid "Active connection path: %s\n" +msgstr "Aktiv forbindelsessti: %s\n" + +#: ../cli/src/connections.c:1351 +#: ../cli/src/connections.c:1472 +#, c-format +msgid "Error: Unknown connection: %s." +msgstr "Fejl: Ukendt forbindelse: %s." + +#: ../cli/src/connections.c:1386 +#: ../cli/src/devices.c:982 +#, c-format +msgid "Error: timeout value '%s' is not valid." +msgstr "Fejl: Værdi for tidsudløb \"%s\" er ikke korrekt." + +#: ../cli/src/connections.c:1399 +#: ../cli/src/connections.c:1489 +#, c-format +msgid "Error: id or uuid has to be specified." +msgstr "Fejl: Id eller uuid skal angives." + +#: ../cli/src/connections.c:1419 +#, c-format +msgid "Error: No suitable device found: %s." +msgstr "Fejl: Ingen passende enhed fundet: %s." + +#: ../cli/src/connections.c:1421 +#, c-format +msgid "Error: No suitable device found." +msgstr "Fejl: Ingen passende enhed fundet." + +#: ../cli/src/connections.c:1516 +#, c-format +msgid "Warning: Connection not active\n" +msgstr "Advarsel: Forbindelse ikke aktiv\n" + +#: ../cli/src/connections.c:1573 +#, c-format +msgid "Error: 'con' command '%s' is not valid." +msgstr "Fejl: 'con'-kommandoen '%s' er ikke gyldig." + +#: ../cli/src/connections.c:1609 +#, c-format +msgid "Error: could not connect to D-Bus." +msgstr "Fejl: Kunne ikke forbinde til D-Bus." + +#: ../cli/src/connections.c:1616 +#, c-format +msgid "Error: Could not get system settings." +msgstr "Fejl: Kunne ikke indhente systemopsætning." + +#: ../cli/src/connections.c:1624 +#, c-format +msgid "Error: Could not get user settings." +msgstr "Fejl: Kunne ikke indhente brugeropsætning." + +#: ../cli/src/connections.c:1634 +#, c-format +msgid "Error: Can't obtain connections: settings services are not running." +msgstr "Fejl: Kan ikke indhente forbindelser: Opsætningstjenester kører ikke." + +#. 0 +#. 9 +#: ../cli/src/devices.c:61 +#: ../cli/src/devices.c:90 +#: ../cli/src/devices.c:185 +msgid "DEVICE" +msgstr "ENHED" + +#. 1 +#. 4 +#. 0 +#: ../cli/src/devices.c:63 +#: ../cli/src/devices.c:94 +#: ../cli/src/network-manager.c:36 +msgid "STATE" +msgstr "TILSTAND" + +#: ../cli/src/devices.c:73 +msgid "GENERAL" +msgstr "GENERELT" + +#. 0 +#: ../cli/src/devices.c:74 +msgid "CAPABILITIES" +msgstr "FUNKTIONALITETER" + +#. 1 +#: ../cli/src/devices.c:75 +msgid "WIFI-PROPERTIES" +msgstr "WIFI-EGENSKABER" + +#. 2 +#: ../cli/src/devices.c:76 +msgid "AP" +msgstr "AP" + +#. 3 +#: ../cli/src/devices.c:77 +msgid "WIRED-PROPERTIES" +msgstr "TRÅDET-EGENSKABER" + +#. 4 +#: ../cli/src/devices.c:78 +msgid "IP4-SETTINGS" +msgstr "IP4-INSTILLINGER" + +#. 5 +#: ../cli/src/devices.c:79 +msgid "IP4-DNS" +msgstr "IP4-DNS" + +#. 6 +#: ../cli/src/devices.c:80 +msgid "IP6-SETTINGS" +msgstr "IP6-INDSTILLINGER" + +#. 7 +#: ../cli/src/devices.c:81 +msgid "IP6-DNS" +msgstr "IP6-DNS" + +#. 2 +#: ../cli/src/devices.c:92 +msgid "DRIVER" +msgstr "DRIVER" + +#. 3 +#: ../cli/src/devices.c:93 +msgid "HWADDR" +msgstr "HWADDR" + +#. 0 +#: ../cli/src/devices.c:103 +msgid "CARRIER-DETECT" +msgstr "UDBYDER-OPFANG" + +#. 1 +#: ../cli/src/devices.c:104 +msgid "SPEED" +msgstr "HASTIGHED" + +#. 0 +#: ../cli/src/devices.c:113 +msgid "CARRIER" +msgstr "UDBYDER" + +#. 0 +#: ../cli/src/devices.c:123 +msgid "WEP" +msgstr "WEP" + +#. 1 +#: ../cli/src/devices.c:124 +msgid "WPA" +msgstr "WPA" + +#. 2 +#: ../cli/src/devices.c:125 +msgid "WPA2" +msgstr "WPA2" + +#. 3 +#: ../cli/src/devices.c:126 +msgid "TKIP" +msgstr "TKIP" + +#. 4 +#: ../cli/src/devices.c:127 +msgid "CCMP" +msgstr "CCMP" + +#. 0 +#: ../cli/src/devices.c:136 +#: ../cli/src/devices.c:147 +msgid "ADDRESS" +msgstr "ADRESSE" + +#. 1 +#: ../cli/src/devices.c:137 +#: ../cli/src/devices.c:148 +msgid "PREFIX" +msgstr "PRÆFIKS" + +#. 2 +#: ../cli/src/devices.c:138 +#: ../cli/src/devices.c:149 +msgid "GATEWAY" +msgstr "ADGANGSPUNKT" + +#. 0 +#: ../cli/src/devices.c:158 +#: ../cli/src/devices.c:167 +msgid "DNS" +msgstr "DNS" + +#. 0 +#: ../cli/src/devices.c:176 +msgid "SSID" +msgstr "SSID" + +#. 1 +#: ../cli/src/devices.c:177 +msgid "BSSID" +msgstr "BSSID" + +#. 2 +#: ../cli/src/devices.c:178 +msgid "MODE" +msgstr "TILSTAND" + +#. 3 +#: ../cli/src/devices.c:179 +msgid "FREQ" +msgstr "FREK" + +#. 4 +#: ../cli/src/devices.c:180 +msgid "RATE" +msgstr "RATE" + +#. 5 +#: ../cli/src/devices.c:181 +msgid "SIGNAL" +msgstr "SIGNAL" + +#. 6 +#: ../cli/src/devices.c:182 +msgid "SECURITY" +msgstr "SIKKERHED" + +#. 7 +#: ../cli/src/devices.c:183 +msgid "WPA-FLAGS" +msgstr "WPA-FLAG" + +#. 8 +#: ../cli/src/devices.c:184 +msgid "RSN-FLAGS" +msgstr "RSN-FLAG" + +#. 10 +#: ../cli/src/devices.c:186 +msgid "ACTIVE" +msgstr "AKTIV" + +#: ../cli/src/devices.c:209 #, c-format msgid "" -"unable to create netlink socket for monitoring wired ethernet devices - %s" +"Usage: nmcli dev { COMMAND | help }\n" +"\n" +" COMMAND := { status | list | disconnect | wifi }\n" +"\n" +" status\n" +" list [iface ]\n" +" disconnect iface [--nowait] [--timeout ]\n" +" wifi [list [iface ] [hwaddr ]]\n" +"\n" msgstr "" -"kan ikke oprette netlink sokkel til overvågning af kablede ethernet enheder " -"- %s" +"Brug: nmcli dev { KOMMANDO | help }\n" +"\n" +" KOMMANDO := { status | list | disconnect | wifi }\n" +"\n" +" status\n" +" list [iface ]\n" +" disconnect iface [--nowait] [--timeout ]\n" +" wifi [list [iface ] [hwaddr ]]\n" +"\n" -#: ../src/nm-netlink-monitor.c:192 +#: ../cli/src/devices.c:229 +msgid "unmanaged" +msgstr "uhåndteret" + +#: ../cli/src/devices.c:231 +msgid "unavailable" +msgstr "utilgængelig" + +#: ../cli/src/devices.c:233 +#: ../cli/src/network-manager.c:91 +msgid "disconnected" +msgstr "frakoblet" + +#: ../cli/src/devices.c:235 +msgid "connecting (prepare)" +msgstr "forbinder (forbereder)" + +#: ../cli/src/devices.c:237 +msgid "connecting (configuring)" +msgstr "forbinder (konfigurerer)" + +#: ../cli/src/devices.c:239 +msgid "connecting (need authentication)" +msgstr "forbinder (venter på godkendelse)" + +#: ../cli/src/devices.c:241 +msgid "connecting (getting IP configuration)" +msgstr "forbinder (henter IP-konfiguration)" + +#: ../cli/src/devices.c:243 +#: ../cli/src/network-manager.c:89 +msgid "connected" +msgstr "tilsluttet" + +#: ../cli/src/devices.c:245 +msgid "connection failed" +msgstr "forbindelse fejlet" + +#: ../cli/src/devices.c:268 +#: ../cli/src/devices.c:425 +msgid "Unknown" +msgstr "Ukendt" + +#: ../cli/src/devices.c:300 +msgid "(none)" +msgstr "(ingen)" + +#: ../cli/src/devices.c:325 +#, c-format +msgid "%s: error converting IP4 address 0x%X" +msgstr "%s: Fejl under konvertering af IP4-adresse 0x%X" + +#: ../cli/src/devices.c:394 +#, c-format +msgid "%u MHz" +msgstr "%u MHz" + +#: ../cli/src/devices.c:395 +#, c-format +msgid "%u MB/s" +msgstr "%u MB/s" + +#: ../cli/src/devices.c:404 +msgid "Encrypted: " +msgstr "Krypteret: " + +#: ../cli/src/devices.c:409 +msgid "WEP " +msgstr "WEP " + +#: ../cli/src/devices.c:411 +msgid "WPA " +msgstr "WPA " + +#: ../cli/src/devices.c:413 +msgid "WPA2 " +msgstr "WPA2 " + +#: ../cli/src/devices.c:416 +msgid "Enterprise " +msgstr "Erhverv " + +#: ../cli/src/devices.c:425 +msgid "Ad-Hoc" +msgstr "Ad-Hoc" + +#: ../cli/src/devices.c:425 +msgid "Infrastructure" +msgstr "Infrastruktur" + +#: ../cli/src/devices.c:487 +#, c-format +msgid "Error: 'dev list': %s" +msgstr "Fejl: 'dev list': %s" + +#: ../cli/src/devices.c:489 +#, c-format +msgid "Error: 'dev list': %s; allowed fields: %s" +msgstr "Fejl: 'dev list'': %s; tilladte felter: %s" + +#: ../cli/src/devices.c:498 +msgid "Device details" +msgstr "Enhedsdetaljer" + +#: ../cli/src/devices.c:528 +#: ../cli/src/devices.c:927 +msgid "(unknown)" +msgstr "(ukendt)" + +#: ../cli/src/devices.c:529 +msgid "unknown)" +msgstr "ukendt)" + +#: ../cli/src/devices.c:555 +#, c-format +msgid "%u Mb/s" +msgstr "%u Mb/s" + +#. Print header +#. "WIRED-PROPERTIES" +#: ../cli/src/devices.c:628 +msgid "on" +msgstr "tændt" + +#: ../cli/src/devices.c:628 +msgid "off" +msgstr "slukket" + +#: ../cli/src/devices.c:810 +#, c-format +msgid "Error: 'dev status': %s" +msgstr "Fejl: 'dev status': %s" + +#: ../cli/src/devices.c:812 +#, c-format +msgid "Error: 'dev status': %s; allowed fields: %s" +msgstr "Fejl: 'dev status': %s; tilladte felter: %s" + +#: ../cli/src/devices.c:819 +msgid "Status of devices" +msgstr "Status på enheder" + +#: ../cli/src/devices.c:847 +#, c-format +msgid "Error: '%s' argument is missing." +msgstr "Fejl: '%s'-parameter mangler." + +#: ../cli/src/devices.c:876 +#: ../cli/src/devices.c:1015 +#: ../cli/src/devices.c:1138 +#, c-format +msgid "Error: Device '%s' not found." +msgstr "Fejl: Enhed \"%s\" ikke fundet." + +#: ../cli/src/devices.c:899 +#, c-format +msgid "Success: Device '%s' successfully disconnected." +msgstr "Succes: Enhed '%s' frakoblet." + +#: ../cli/src/devices.c:924 +#, c-format +msgid "Error: Device '%s' (%s) disconnecting failed: %s" +msgstr "Fejl: Frakobling af enhed \"%s\" (%s) mislykkedes: %s" + +#: ../cli/src/devices.c:932 +#, c-format +msgid "Device state: %d (%s)\n" +msgstr "Enhedstilstand: %d (%s)\n" + +#: ../cli/src/devices.c:996 +#, c-format +msgid "Error: iface has to be specified." +msgstr "Fejl: iface skal være angivet." + +#: ../cli/src/devices.c:1114 +#, c-format +msgid "Error: 'dev wifi': %s" +msgstr "Fejl: 'dev wifi': %s" + +#: ../cli/src/devices.c:1116 +#, c-format +msgid "Error: 'dev wifi': %s; allowed fields: %s" +msgstr "Fejl: 'dev wifi': %s; tilladte felter: %s" + +#: ../cli/src/devices.c:1123 +msgid "WiFi scan list" +msgstr "WiFi-skanningsliste" + +#: ../cli/src/devices.c:1158 +#: ../cli/src/devices.c:1212 +#, c-format +msgid "Error: Access point with hwaddr '%s' not found." +msgstr "Fejl: Adgangspunkt med hwadr '%s' blev ikke fundet." + +#: ../cli/src/devices.c:1175 +#, c-format +msgid "Error: Device '%s' is not a WiFi device." +msgstr "Fejl: Enhed '%s' er ikke en WiFi-enhed." + +#: ../cli/src/devices.c:1239 +#, c-format +msgid "Error: 'dev wifi' command '%s' is not valid." +msgstr "Fejl: 'dev wifi'-kommandoen '%s' er ikke gyldig." + +#: ../cli/src/devices.c:1286 +#, c-format +msgid "Error: 'dev' command '%s' is not valid." +msgstr "Fejl: 'dev'-kommanoden '%s' er ikke gyldig." + +#: ../cli/src/network-manager.c:35 +msgid "RUNNING" +msgstr "KØRER" + +#. 1 +#: ../cli/src/network-manager.c:37 +msgid "NET-ENABLED" +msgstr "NET-AKTIVERET" + +#. 2 +#: ../cli/src/network-manager.c:38 +msgid "WIFI-HARDWARE" +msgstr "WIFI-HARDWARE" + +#. 3 +#: ../cli/src/network-manager.c:39 +msgid "WIFI" +msgstr "WIFI" + +#. 4 +#: ../cli/src/network-manager.c:40 +msgid "WWAN-HARDWARE" +msgstr "WWAN-HARDWARE" + +#. 5 +#: ../cli/src/network-manager.c:41 +msgid "WWAN" +msgstr "WWAN" + +#: ../cli/src/network-manager.c:64 #, c-format msgid "" -"unable to bind to netlink socket for monitoring wired ethernet devices - %s" +"Usage: nmcli nm { COMMAND | help }\n" +"\n" +" COMMAND := { status | enable | sleep | wifi | wwan }\n" +"\n" +" status\n" +" enable [true|false]\n" +" sleep [true|false]\n" +" wifi [on|off]\n" +" wwan [on|off]\n" +"\n" msgstr "" -"kan ikke tilslutte netlink sokkel til overvågning af kablede ethernet " -"enheder - %s" +"Brug: nmcli nm { KOMMANDO | help }\n" +"\n" +" KOMMANDO := { status | enable | sleep | wifi | wwan }\n" +"\n" +" status\n" +" enable [true|false]\n" +" sleep [true|false]\n" +" wifi [on|off]\n" +" wwan [on|off]\n" +"\n" -#: ../src/nm-netlink-monitor.c:427 -msgid "operation took too long" -msgstr "handlingen overskred tidsgrænsen" +#: ../cli/src/network-manager.c:85 +msgid "asleep" +msgstr "sover" -#: ../src/nm-netlink-monitor.c:524 -msgid "received data from wrong type of sender" -msgstr "modtog data fra forkert type afsender" +#: ../cli/src/network-manager.c:87 +msgid "connecting" +msgstr "forbinder" -#: ../src/nm-netlink-monitor.c:537 -msgid "received data from unexpected sender" -msgstr "modtog data fra uventet afsender" +#: ../cli/src/network-manager.c:128 +#, c-format +msgid "Error: 'nm status': %s" +msgstr "Fejl: 'nm status': %s" -#: ../src/nm-netlink-monitor.c:666 -msgid "too much data was sent over socket and some of it was lost" -msgstr "for meget data var sendt over sokkelen og noget gik tabt" +#: ../cli/src/network-manager.c:130 +#, c-format +msgid "Error: 'nm status': %s; allowed fields: %s" +msgstr "Fejl: 'nm status': %s; tilladte felter: %s" -#: ../src/nm-netlink-monitor.c:774 +#: ../cli/src/network-manager.c:137 +msgid "NetworkManager status" +msgstr "Status for NetworkManager" + +#. Print header +#: ../cli/src/network-manager.c:144 +#: ../cli/src/network-manager.c:145 +#: ../cli/src/network-manager.c:146 +#: ../cli/src/network-manager.c:147 +#: ../cli/src/network-manager.c:154 +#: ../cli/src/network-manager.c:247 +#: ../cli/src/network-manager.c:296 +#: ../cli/src/network-manager.c:328 +msgid "enabled" +msgstr "aktiveret" + +#: ../cli/src/network-manager.c:144 +#: ../cli/src/network-manager.c:145 +#: ../cli/src/network-manager.c:146 +#: ../cli/src/network-manager.c:147 +#: ../cli/src/network-manager.c:154 +#: ../cli/src/network-manager.c:247 +#: ../cli/src/network-manager.c:296 +#: ../cli/src/network-manager.c:328 +msgid "disabled" +msgstr "deaktiveret" + +#: ../cli/src/network-manager.c:152 +msgid "running" +msgstr "kører" + +#: ../cli/src/network-manager.c:152 +msgid "not running" +msgstr "kører ikke" + +#: ../cli/src/network-manager.c:175 +#, c-format +msgid "Error: Couldn't connect to system bus: %s" +msgstr "Fejl: Kunne ikke forbinde til systembus: %s" + +#: ../cli/src/network-manager.c:186 +#, c-format +msgid "Error: Couldn't create D-Bus object proxy." +msgstr "Fejl: Kunne ikke oprette proxy-objekt for D-Bus." + +#: ../cli/src/network-manager.c:192 +#, c-format +msgid "Error in sleep: %s" +msgstr "Fejl ved søvn: %s" + +#: ../cli/src/network-manager.c:237 +#: ../cli/src/network-manager.c:286 +#: ../cli/src/network-manager.c:318 +#, c-format +msgid "Error: '--fields' value '%s' is not valid here; allowed fields: %s" +msgstr "Fejl: '--fields'-værdi '%s' er ikke gyldig her; tilladte felter: %s" + +#: ../cli/src/network-manager.c:245 +msgid "Networking enabled" +msgstr "Netværk aktiveret" + +#: ../cli/src/network-manager.c:256 +#, c-format +msgid "Error: invalid 'enable' parameter: '%s'; use 'true' or 'false'." +msgstr "Fejl: Ugyldig 'enable'-parameter: '%s'; brug 'true' eller 'false'." + +#: ../cli/src/network-manager.c:265 +#, c-format +msgid "Error: Sleeping status is not exported by NetworkManager." +msgstr "Fejl: NetworkManager eksporterer ikke søvnstatus." + +#: ../cli/src/network-manager.c:273 +#, c-format +msgid "Error: invalid 'sleep' parameter: '%s'; use 'true' or 'false'." +msgstr "Fejl: Ugyldig 'sleep'-parameter: '%s'; brug 'true' eller 'false'." + +#: ../cli/src/network-manager.c:294 +msgid "WiFi enabled" +msgstr "WiFi aktiveret" + +#: ../cli/src/network-manager.c:305 +#, c-format +msgid "Error: invalid 'wifi' parameter: '%s'." +msgstr "Fejl: Ugyldig 'wifi'-parameter: '%s'." + +#: ../cli/src/network-manager.c:326 +msgid "WWAN enabled" +msgstr "WWAN aktiveret" + +#: ../cli/src/network-manager.c:337 +#, c-format +msgid "Error: invalid 'wwan' parameter: '%s'." +msgstr "Fejl: Ugyldig 'wwan'-parameter: '%s'." + +#: ../cli/src/network-manager.c:348 +#, c-format +msgid "Error: 'nm' command '%s' is not valid." +msgstr "Fejl: 'nm'-kommando '%s' er ikke gyldig." + +#: ../cli/src/nmcli.c:69 +#, c-format +msgid "" +"Usage: %s [OPTIONS] OBJECT { COMMAND | help }\n" +"\n" +"OPTIONS\n" +" -t[erse] terse output\n" +" -p[retty] pretty output\n" +" -m[ode] tabular|multiline output mode\n" +" -f[ields] |all|common specify fields to output\n" +" -e[scape] yes|no escape columns separators in values\n" +" -v[ersion] show program version\n" +" -h[elp] print this help\n" +"\n" +"OBJECT\n" +" nm NetworkManager status\n" +" con NetworkManager connections\n" +" dev devices managed by NetworkManager\n" +"\n" +msgstr "" +"Brug: %s [TILVALG] OBJEKT { KOMMANDO | help }\n" +"\n" +"TILVALG\n" +" -t[erse] kort udskrift\n" +" -p[retty] pæn udskrift\n" +" -m[ode] tabular|multiline udskriftstilstand\n" +" -f[ields] |all|common angiv felter til udskrift\n" +" -e[scape] yes|no undvig kolonneadskillere i værdier\n" +" -v[ersion] vis programversion\n" +" -h[elp] vis denne hjælpetekst\n" +"\n" +"OBJEKT\n" +" nm status for NetworkManager \n" +" con forbindelser for NetworkManager\n" +" dev enheder håndteret af NetworkManager\n" +"\n" + +#: ../cli/src/nmcli.c:113 +#, c-format +msgid "Error: Object '%s' is unknown, try 'nmcli help'." +msgstr "Fejl: Objekt '%s' er ukendt, prøv 'nmcli help'." + +#: ../cli/src/nmcli.c:143 +#, c-format +msgid "Error: Option '--terse' is specified the second time." +msgstr "Fejl: Tilvalg '--terse' er angivet anden gang." + +#: ../cli/src/nmcli.c:148 +#, c-format +msgid "Error: Option '--terse' is mutually exclusive with '--pretty'." +msgstr "Fejl: Tilvalg '--terse' kan ikke bruges sammen med '--pretty'." + +#: ../cli/src/nmcli.c:156 +#, c-format +msgid "Error: Option '--pretty' is specified the second time." +msgstr "Fejl: Tilvalg '--pretty' er angivet anden gang." + +#: ../cli/src/nmcli.c:161 +#, c-format +msgid "Error: Option '--pretty' is mutually exclusive with '--terse'." +msgstr "Fejl: Tilvalg '--pretty' kan ikke bruges sammen med '--terse'." + +#: ../cli/src/nmcli.c:171 +#: ../cli/src/nmcli.c:187 +#, c-format +msgid "Error: missing argument for '%s' option." +msgstr "Fejl: Mangler argument for tilvalget '%s'." + +#: ../cli/src/nmcli.c:180 +#: ../cli/src/nmcli.c:196 +#, c-format +msgid "Error: '%s' is not valid argument for '%s' option." +msgstr "Fejl: '%s' er ikke et gyldigt argument for tilvalget '%s'." + +#: ../cli/src/nmcli.c:203 +#, c-format +msgid "Error: fields for '%s' options are missing." +msgstr "Fejl: Felter for tilvalgene '%s' mangler." + +#: ../cli/src/nmcli.c:209 +#, c-format +msgid "nmcli tool, version %s\n" +msgstr "nmcli-værktøj, version %s\n" + +#: ../cli/src/nmcli.c:215 +#, c-format +msgid "Error: Option '%s' is unknown, try 'nmcli -help'." +msgstr "Fejl: Tilvalg '%s' er ukendt, prøv 'nmcli -help'." + +#: ../cli/src/nmcli.c:234 +#, c-format +msgid "Caught signal %d, shutting down..." +msgstr "Fik signal %d, afslutter..." + +#: ../cli/src/nmcli.c:259 +#, c-format +msgid "Error: Could not connect to NetworkManager." +msgstr "Fejl: Kunne ikke oprette forbinde til NetworkManager." + +#: ../cli/src/nmcli.c:275 +msgid "Success" +msgstr "Succes" + +#: ../cli/src/settings.c:411 +#, c-format +msgid "%d (hex-ascii-key)" +msgstr "%d (hex-ascii-nøgle)" + +#: ../cli/src/settings.c:413 +#, c-format +msgid "%d (104/128-bit passphrase)" +msgstr "%d (104/128-bit adgangsfrase)" + +#: ../cli/src/settings.c:416 +#, c-format +msgid "%d (unknown)" +msgstr "%d (ukendt)" + +#: ../cli/src/settings.c:442 +msgid "0 (unknown)" +msgstr "0 (ukendt)" + +#: ../cli/src/settings.c:448 +msgid "any, " +msgstr "enhver, " + +#: ../cli/src/settings.c:450 +msgid "900 MHz, " +msgstr "900 MHz, " + +#: ../cli/src/settings.c:452 +msgid "1800 MHz, " +msgstr "1800 MHz, " + +#: ../cli/src/settings.c:454 +msgid "1900 MHz, " +msgstr "1900 MHz, " + +#: ../cli/src/settings.c:456 +msgid "850 MHz, " +msgstr "850 MHz, " + +#: ../cli/src/settings.c:458 +msgid "WCDMA 3GPP UMTS 2100 MHz, " +msgstr "WCDMA 3GPP UMTS 2100 MHz, " + +#: ../cli/src/settings.c:460 +msgid "WCDMA 3GPP UMTS 1800 MHz, " +msgstr "WCDMA 3GPP UMTS 1800 MHz, " + +#: ../cli/src/settings.c:462 +msgid "WCDMA 3GPP UMTS 1700/2100 MHz, " +msgstr "WCDMA 3GPP UMTS 1700/2100 MHz, " + +#: ../cli/src/settings.c:464 +msgid "WCDMA 3GPP UMTS 800 MHz, " +msgstr "WCDMA 3GPP UMTS 800 MHz, " + +#: ../cli/src/settings.c:466 +msgid "WCDMA 3GPP UMTS 850 MHz, " +msgstr "WCDMA 3GPP UMTS 850 MHz, " + +#: ../cli/src/settings.c:468 +msgid "WCDMA 3GPP UMTS 900 MHz, " +msgstr "WCDMA 3GPP UMTS 900 MHz, " + +#: ../cli/src/settings.c:470 +msgid "WCDMA 3GPP UMTS 1700 MHz, " +msgstr "WCDMA 3GPP UMTS 1700 MHz, " + +#: ../cli/src/settings.c:554 +#: ../cli/src/settings.c:721 +msgid "auto" +msgstr "automatisk" + +#: ../cli/src/settings.c:716 +#: ../cli/src/settings.c:719 +#: ../cli/src/settings.c:720 +#: ../cli/src/utils.c:172 +msgid "not set" +msgstr "ikke sat" + +#: ../cli/src/utils.c:124 +#, c-format +msgid "field '%s' has to be alone" +msgstr "feltet '%s' skal stå alene" + +#: ../cli/src/utils.c:127 +#, c-format +msgid "invalid field '%s'" +msgstr "ugyldigt felt '%s'" + +#: ../cli/src/utils.c:146 +#, c-format +msgid "Option '--terse' requires specifying '--fields'" +msgstr "Tilvalg '--terse' kræver angivelse af '--fields'" + +#: ../cli/src/utils.c:150 +#, c-format +msgid "Option '--terse' requires specific '--fields' option values , not '%s'" +msgstr "Tilvalg '--terse' kræver specifikke tilvalgsværdier for '--fields', ikke '%s'" + +#: ../libnm-util/crypto.c:121 +#, c-format +msgid "PEM key file had no end tag '%s'." +msgstr "PEM-nøglefil havde intet slutmærke \"%s\"." + +#: ../libnm-util/crypto.c:131 +#, c-format +msgid "Doesn't look like a PEM private key file." +msgstr "Ligner ikke en privat PEM-nøglefil." + +#: ../libnm-util/crypto.c:139 +#, c-format +msgid "Not enough memory to store PEM file data." +msgstr "Ikke nok hukommelse til at lagre PEM-fildata." + +#: ../libnm-util/crypto.c:155 +#, c-format +msgid "Malformed PEM file: Proc-Type was not first tag." +msgstr "Fejlskrevet PEM-fil: Proc-Type var ikke første mærke." + +#: ../libnm-util/crypto.c:163 +#, c-format +msgid "Malformed PEM file: unknown Proc-Type tag '%s'." +msgstr "Fejlskrevet PEM-fil: Ukendt mærke \"%s\" for Proc-type." + +#: ../libnm-util/crypto.c:173 +#, c-format +msgid "Malformed PEM file: DEK-Info was not the second tag." +msgstr "Fejlskrevet PEM-fil: DEK-info var ikke andet mærke." + +#: ../libnm-util/crypto.c:184 +#, c-format +msgid "Malformed PEM file: no IV found in DEK-Info tag." +msgstr "Fejlskrevet PEM-fil: intet IV fundet i mærket DEK-Info." + +#: ../libnm-util/crypto.c:191 +#, c-format +msgid "Malformed PEM file: invalid format of IV in DEK-Info tag." +msgstr "Fejlskrevet PEM-fil: ugyldigt format af IV i mærket DEK-Info." + +#: ../libnm-util/crypto.c:204 +#, c-format +msgid "Malformed PEM file: unknown private key cipher '%s'." +msgstr "Fejlskrevet PEM-fil: ukendt privat nøgleciffer \"%s\"." + +#: ../libnm-util/crypto.c:223 +#, c-format +msgid "Could not decode private key." +msgstr "Kunne ikke afkode privat nøgle." + +#: ../libnm-util/crypto.c:268 +#, c-format +msgid "PEM certificate '%s' had no end tag '%s'." +msgstr "PEM-certifikatet \"%s\" har intet slutmærke \"%s\"." + +#: ../libnm-util/crypto.c:278 +#, c-format +msgid "Failed to decode certificate." +msgstr "Fejl ved afkodning af certifikat." + +#: ../libnm-util/crypto.c:287 +#, c-format +msgid "Not enough memory to store certificate data." +msgstr "Ikke nok hukommelse til at gemme certifikatdata." + +#: ../libnm-util/crypto.c:295 +#, c-format +msgid "Not enough memory to store file data." +msgstr "Ikke nok hukommelse til at gemme fildata." + +#: ../libnm-util/crypto.c:325 +#, c-format +msgid "IV must be an even number of bytes in length." +msgstr "IV skal have en længde på et lige antal byte." + +#: ../libnm-util/crypto.c:334 +#, c-format +msgid "Not enough memory to store the IV." +msgstr "Ikke nok hukommelse til at gemme IV'en." + +#: ../libnm-util/crypto.c:345 +#, c-format +msgid "IV contains non-hexadecimal digits." +msgstr "IV indeholder ikke-hexadecimale cifre." + +#: ../libnm-util/crypto.c:383 +#: ../libnm-util/crypto_gnutls.c:148 +#: ../libnm-util/crypto_gnutls.c:266 +#: ../libnm-util/crypto_nss.c:171 +#: ../libnm-util/crypto_nss.c:336 +#, c-format +msgid "Private key cipher '%s' was unknown." +msgstr "Privat nøgleciffer \"%s\" var ukendt." + +#: ../libnm-util/crypto.c:392 +#, c-format +msgid "Not enough memory to decrypt private key." +msgstr "Ikke nok hukommelse til at dekryptere privat nøgle." + +#: ../libnm-util/crypto.c:512 +#, c-format +msgid "Unable to determine private key type." +msgstr "Kunne ikke afgøre typen af privat nøgle." + +#: ../libnm-util/crypto.c:531 +#, c-format +msgid "Not enough memory to store decrypted private key." +msgstr "Ikke nok hukommelse til at gemme dekrypteret privat nøgle." + +#: ../libnm-util/crypto_gnutls.c:49 +msgid "Failed to initialize the crypto engine." +msgstr "Kunne ikke initialisere kryptomotor." + +#: ../libnm-util/crypto_gnutls.c:93 +#, c-format +msgid "Failed to initialize the MD5 engine: %s / %s." +msgstr "Kunne ikke initialisere MD5-motor: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:156 +#, c-format +msgid "Invalid IV length (must be at least %zd)." +msgstr "Ugyldig IV-længde (skal være mindst %zd)." + +#: ../libnm-util/crypto_gnutls.c:165 +#: ../libnm-util/crypto_nss.c:188 +#, c-format +msgid "Not enough memory for decrypted key buffer." +msgstr "Ikke nok hukommelse til afkodet nøglebuffer." + +#: ../libnm-util/crypto_gnutls.c:173 +#, c-format +msgid "Failed to initialize the decryption cipher context: %s / %s." +msgstr "Kunne ikke initialisere cifferkontekst til dekryptering: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:182 +#, c-format +msgid "Failed to set symmetric key for decryption: %s / %s." +msgstr "Kunne ikke sætte symmetrisk nøgle til dekryptering: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:191 +#, c-format +msgid "Failed to set IV for decryption: %s / %s." +msgstr "Kunne ikke sætte IV til dekryptering: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:200 +#, c-format +msgid "Failed to decrypt the private key: %s / %s." +msgstr "Kunne ikke dekryptere den private nøgle: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:210 +#: ../libnm-util/crypto_nss.c:267 +#, c-format +msgid "Failed to decrypt the private key: unexpected padding length." +msgstr "Kunne ikke dekryptere den private nøgle: uventet længde af fylddata." + +#: ../libnm-util/crypto_gnutls.c:221 +#: ../libnm-util/crypto_nss.c:278 +#, c-format +msgid "Failed to decrypt the private key." +msgstr "Kunne ikke dekryptere den private nøgle." + +#: ../libnm-util/crypto_gnutls.c:286 +#: ../libnm-util/crypto_nss.c:356 +#, c-format +msgid "Could not allocate memory for encrypting." +msgstr "Kunne ikke allokere hukommelse til kryptering." + +#: ../libnm-util/crypto_gnutls.c:294 +#, c-format +msgid "Failed to initialize the encryption cipher context: %s / %s." +msgstr "Kunne ikke initialisere krypteringscifferkontekst: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:303 +#, c-format +msgid "Failed to set symmetric key for encryption: %s / %s." +msgstr "Kunne ikke sætte symmetrisk nøgle til kryptering: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:313 +#, c-format +msgid "Failed to set IV for encryption: %s / %s." +msgstr "Kunne ikke sætte IV til kryptering: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:322 +#, c-format +msgid "Failed to encrypt the data: %s / %s." +msgstr "Kunne ikke kryptere data: %s / %s." + +#: ../libnm-util/crypto_gnutls.c:362 +#, c-format +msgid "Error initializing certificate data: %s" +msgstr "Fejl under initialisering af certifikatdata: %s" + +#: ../libnm-util/crypto_gnutls.c:384 +#, c-format +msgid "Couldn't decode certificate: %s" +msgstr "Kunne ikke afkode certifikat: %s" + +#: ../libnm-util/crypto_gnutls.c:408 +#, c-format +msgid "Couldn't initialize PKCS#12 decoder: %s" +msgstr "Kunne ikke initialisere PKCS#12-afkoder: %s" + +#: ../libnm-util/crypto_gnutls.c:421 +#, c-format +msgid "Couldn't decode PKCS#12 file: %s" +msgstr "Kunne ikke afkode PKCS#12-fil: %s" + +#: ../libnm-util/crypto_gnutls.c:433 +#, c-format +msgid "Couldn't verify PKCS#12 file: %s" +msgstr "Kunne ikke bekræfte PKCS#12-fil: %s" + +#: ../libnm-util/crypto_nss.c:56 +#, c-format +msgid "Failed to initialize the crypto engine: %d." +msgstr "Kunne ikke initialisere kryptomotor: %d." + +#: ../libnm-util/crypto_nss.c:111 +#, c-format +msgid "Failed to initialize the MD5 context: %d." +msgstr "Kunne ikke initialisere MD5-kontekst: %d." + +#: ../libnm-util/crypto_nss.c:179 +#, c-format +msgid "Invalid IV length (must be at least %d)." +msgstr "Ugyldig IV-længde (skal være mindst %d)." + +#: ../libnm-util/crypto_nss.c:196 +#, c-format +msgid "Failed to initialize the decryption cipher slot." +msgstr "Kunne ikke initialisere cifferplads til dekryptering." + +#: ../libnm-util/crypto_nss.c:206 +#, c-format +msgid "Failed to set symmetric key for decryption." +msgstr "Kunne ikke sætte symmetrisk nøgle til kryptering." + +#: ../libnm-util/crypto_nss.c:216 +#, c-format +msgid "Failed to set IV for decryption." +msgstr "Kunne ikke sætte IV til dekryptering." + +#: ../libnm-util/crypto_nss.c:224 +#, c-format +msgid "Failed to initialize the decryption context." +msgstr "Kunne ikke initialisere dekrypteringskonteksten." + +#: ../libnm-util/crypto_nss.c:237 +#, c-format +msgid "Failed to decrypt the private key: %d." +msgstr "Kunne ikke dekryptere den private nøgle: %d." + +#: ../libnm-util/crypto_nss.c:245 +#, c-format +msgid "Failed to decrypt the private key: decrypted data too large." +msgstr "Kunne ikke dekryptere den private nøgle: for stor mængde dekrypteret data." + +#: ../libnm-util/crypto_nss.c:256 +#, c-format +msgid "Failed to finalize decryption of the private key: %d." +msgstr "Kunne ikke afslutte dekryptering af den private nøgle: %d." + +#: ../libnm-util/crypto_nss.c:364 +#, c-format +msgid "Failed to initialize the encryption cipher slot." +msgstr "Kunne ikke initialisere cifferplads til kryptering." + +#: ../libnm-util/crypto_nss.c:372 +#, c-format +msgid "Failed to set symmetric key for encryption." +msgstr "Kunne ikke sætte symmetrisk nøgle til kryptering." + +#: ../libnm-util/crypto_nss.c:380 +#, c-format +msgid "Failed to set IV for encryption." +msgstr "Kunne ikke sætte IV til kryptering." + +#: ../libnm-util/crypto_nss.c:388 +#, c-format +msgid "Failed to initialize the encryption context." +msgstr "Kunne ikke initialisere krypteringskontekst." + +#: ../libnm-util/crypto_nss.c:396 +#, c-format +msgid "Failed to encrypt: %d." +msgstr "Kunne ikke kryptere: %d." + +#: ../libnm-util/crypto_nss.c:404 +#, c-format +msgid "Unexpected amount of data after encrypting." +msgstr "Uventet mængde af data efter kryptering." + +#: ../libnm-util/crypto_nss.c:447 +#, c-format +msgid "Couldn't decode certificate: %d" +msgstr "Kunne ikke afkode certifikat: %d" + +#: ../libnm-util/crypto_nss.c:482 +#, c-format +msgid "Couldn't convert password to UCS2: %d" +msgstr "Kunne ikke konvertere adgangskode til UCS2: %d" + +#: ../libnm-util/crypto_nss.c:510 +#, c-format +msgid "Couldn't initialize PKCS#12 decoder: %d" +msgstr "Kunne ikke initialisere PKCS#12-afkoder: %d" + +#: ../libnm-util/crypto_nss.c:519 +#, c-format +msgid "Couldn't decode PKCS#12 file: %d" +msgstr "Kunne ikke afkode PKCS#12-fil: %d" + +#: ../libnm-util/crypto_nss.c:528 +#, c-format +msgid "Couldn't verify PKCS#12 file: %d" +msgstr "Kunne ikke verificere PKCS#12-fil: %d" + +#: ../libnm-util/crypto_nss.c:557 +msgid "Could not generate random data." +msgstr "Kunne ikke generere tilfældige data." + +#: ../libnm-util/nm-utils.c:1975 +#, c-format +msgid "Not enough memory to make encryption key." +msgstr "Ikke nok hukommelse til at oprette krypteringsnøgle." + +#: ../libnm-util/nm-utils.c:2085 +msgid "Could not allocate memory for PEM file creation." +msgstr "Kunne ikke allokere hukommelse til PEM-filoprettelse." + +#: ../libnm-util/nm-utils.c:2097 +#, c-format +msgid "Could not allocate memory for writing IV to PEM file." +msgstr "Kunne ikke allokere hukommelse til at skrive IV til PEM-fil." + +#: ../libnm-util/nm-utils.c:2109 +#, c-format +msgid "Could not allocate memory for writing encrypted key to PEM file." +msgstr "Kunne ikke allokere hukommelse til at skrive krypteret nøgle til PEM-fil." + +#: ../libnm-util/nm-utils.c:2128 +#, c-format +msgid "Could not allocate memory for PEM file data." +msgstr "Kunne ikke allokere hukommelse til PEM-fildata." + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:1 +msgid "Connection sharing via a protected WiFi network" +msgstr "Deling af forbindelse via et beskyttet WiFi-netværk" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:2 +msgid "Connection sharing via an open WiFi network" +msgstr "Deling af forbindelse via et åbent WiFi-netværk" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:3 +msgid "Modify persistent system hostname" +msgstr "Ændr fast systemværtsnavn" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:4 +msgid "Modify system connections" +msgstr "Ændr systemforbindelser" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:5 +msgid "System policy prevents modification of system settings" +msgstr "Systempolitikken forhindrer modifikation af systemindstillinger" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:6 +msgid "System policy prevents modification of the persistent system hostname" +msgstr "Systempolitikken forhindrer ændring af det faste systemværtsnavn" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:7 +msgid "System policy prevents sharing connections via a protected WiFi network" +msgstr "Systempolitikken forhindrer deling af forbindelser via et beskyttet WiFi-netværk" + +#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:8 +msgid "System policy prevents sharing connections via an open WiFi network" +msgstr "Systempolitikken forhindrer deling af forbindelser via et åbent WiFi-netværk" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:1 +msgid "Allow control of network connections" +msgstr "Tillad kontrol af netværksforbindelser" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:2 +msgid "Allow use of user-specific connections" +msgstr "Tillad brug af brugerspecifikke forbindelser" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:3 +msgid "Enable or disable WiFi devices" +msgstr "Aktiver eller deaktiver WiFi-enheder" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:4 +msgid "Enable or disable mobile broadband devices" +msgstr "Aktiver eller deaktiver mobile bredbåndsenheder" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:5 +msgid "Enable or disable system networking" +msgstr "Aktiver eller deaktiver systemnetværk" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:6 +msgid "Put NetworkManager to sleep or wake it up (should only be used by system power management)" +msgstr "Sæt NetworkManager i hvile eller væk den (bør kun bruges af systemstrømstyringen)" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:7 +msgid "System policy prevents control of network connections" +msgstr "Systempolitik forhindrer kontrol af netværksforbindelser" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:8 +msgid "System policy prevents enabling or disabling WiFi devices" +msgstr "Systempolitik forhindrer aktivering eller deaktivering af WiFi-enheder" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:9 +msgid "System policy prevents enabling or disabling mobile broadband devices" +msgstr "Systempolitik forhindrer aktivering eller deaktivering af mobile bredbåndsenheder" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:10 +msgid "System policy prevents enabling or disabling system networking" +msgstr "Systempolitik forhindrer aktivering eller deaktivering af systemnetværk" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:11 +msgid "System policy prevents putting NetworkManager to sleep or waking it up" +msgstr "Systempolitik forhindrer at sætte NetworkManager i hvile eller at vække den" + +#: ../policy/org.freedesktop.NetworkManager.policy.in.h:12 +msgid "System policy prevents use of user-specific connections" +msgstr "Systempolitik forhindrer brug af brugerspecifikke forbindelser" + +#: ../src/nm-netlink-monitor.c:100 +#: ../src/nm-netlink-monitor.c:231 +#: ../src/nm-netlink-monitor.c:653 +#, c-format +msgid "error processing netlink message: %s" +msgstr "fejl under behandling af netlink-besked: %s" + +#: ../src/nm-netlink-monitor.c:214 msgid "error occurred while waiting for data on socket" -msgstr "der opstod en fejl mens der blev ventet på data på sokkelen" +msgstr "der opstod en fejl mens der blev ventet på data på soklen" + +#: ../src/nm-netlink-monitor.c:254 +#, c-format +msgid "unable to connect to netlink for monitoring link status: %s" +msgstr "kan ikke forbinde til netlink for at overvåge forbindelsesstatus: %s" + +#: ../src/nm-netlink-monitor.c:265 +#, c-format +msgid "unable to enable netlink handle credential passing: %s" +msgstr "kan ikke aktivere videregivelse af akkreditiver for netlink-håndtag: %s" + +#: ../src/nm-netlink-monitor.c:291 +#: ../src/nm-netlink-monitor.c:353 +#, c-format +msgid "unable to allocate netlink handle for monitoring link status: %s" +msgstr "kan ikke allokere netlink-håndtag til overvågning af forbindelsesstatus: %s" + +#: ../src/nm-netlink-monitor.c:376 +#, c-format +msgid "unable to allocate netlink link cache for monitoring link status: %s" +msgstr "kan ikke allokere netlink-forbindelsesmellemlager til overvågning af forbindelsesstatus: %s" + +#: ../src/nm-netlink-monitor.c:502 +#, c-format +msgid "unable to join netlink group: %s" +msgstr "kan ikke gå ind i netlink-gruppen: %s" + +#: ../src/nm-netlink-monitor.c:629 +#: ../src/nm-netlink-monitor.c:642 +#, c-format +msgid "error updating link cache: %s" +msgstr "fejl ved opdatering af forbindelsesmellemlager: %s" + +#: ../src/main.c:506 +#, c-format +msgid "Invalid option. Please use --help to see a list of valid options.\n" +msgstr "Ugyldigt tilvalg. Brug venligst --help for at se en liste af gyldige tilvalg.\n" + +#: ../src/main.c:577 +#, c-format +msgid "%s. Please use --help to see a list of valid options.\n" +msgstr "%s. Brug venligst --help for at få en liste af gyldige tilvalg.\n" + +#: ../src/dhcp-manager/nm-dhcp-dhclient.c:328 +msgid "# Created by NetworkManager\n" +msgstr "# Oprettet af NetworkManager\n" + +#: ../src/dhcp-manager/nm-dhcp-dhclient.c:344 +#, c-format +msgid "" +"# Merged from %s\n" +"\n" +msgstr "" +"# Sammenflettet fra %s\n" +"\n" + +#: ../src/dhcp-manager/nm-dhcp-manager.c:284 +msgid "no usable DHCP client could be found." +msgstr "kunne ikke finde en brugbar DHCP-klient." + +#: ../src/dhcp-manager/nm-dhcp-manager.c:293 +msgid "'dhclient' could be found." +msgstr "'dhclient' blev fundet." + +#: ../src/dhcp-manager/nm-dhcp-manager.c:303 +msgid "'dhcpcd' could be found." +msgstr "'dhcpcd' blev fundet." + +#: ../src/dhcp-manager/nm-dhcp-manager.c:311 +#, c-format +msgid "unsupported DHCP client '%s'" +msgstr "ikke-understøttet DHCP-klient '%s'" + +#: ../src/logging/nm-logging.c:146 +#, c-format +msgid "Unknown log level '%s'" +msgstr "Ukendt logningsniveau '%s'" + +#: ../src/logging/nm-logging.c:171 +#, c-format +msgid "Unknown log domain '%s'" +msgstr "Ukendt logningsdomæne '%s'" + +#: ../src/dns-manager/nm-dns-manager.c:367 +msgid "NOTE: the libc resolver may not support more than 3 nameservers." +msgstr "BEMÆRK: libc-opløseren understøtter måske ikke mere end tre navneservere." + +#: ../src/dns-manager/nm-dns-manager.c:369 +msgid "The nameservers listed below may not be recognized." +msgstr "Navneserverne vist nedenfor vil måske ikke blive genkendt." + +#: ../src/system-settings/nm-default-wired-connection.c:157 +#, c-format +msgid "Auto %s" +msgstr "Auto %s" + +#: ../system-settings/plugins/ifcfg-rh/reader.c:3408 +#: ../system-settings/plugins/ifnet/connection_parser.c:49 +msgid "System" +msgstr "System" -#: ../src/nm-ap-security-wpa-eap.c:93 ../src/nm-ap-security-wpa-eap.c:117 -msgid "WPA2 Enterprise" -msgstr "WPA2 i virksomhed" - -#: ../src/nm-ap-security-wpa-eap.c:95 ../src/nm-ap-security-wpa-eap.c:122 -msgid "WPA Enterprise" -msgstr "WPA i virksomhed" - -#: ../src/nm-ap-security-leap.c:66 ../src/nm-ap-security-leap.c:82 -msgid "LEAP" -msgstr "LEAP" - -#~ msgid "Passphrase for wireless network %s" -#~ msgstr "Adgangskode til trådløst netværk %s" - -#~ msgid "Connection to the wireless network '%s' failed." -#~ msgstr "Tilslutning til det trådløse netværk '%s' mislykkedes." - -#~ msgid "Connection to the wired network failed." -#~ msgstr "Tilslutning til det kablede netværk mislykkedes." - -#~ msgid "Error displaying connection information: " -#~ msgstr "Fejl ved visning af forbindelses-information: " - -#~ msgid "Could not find some required resources (the glade file)!" -#~ msgstr "Kunne ikke finde nogle krævede ressourcer (glade-filen)!" - -#~ msgid "No active connections!" -#~ msgstr "Ingen aktive forbindelser!" - -#~ msgid "Wired Ethernet (%s)" -#~ msgstr "Kablet Ethernet (%s)" - -#~ msgid "Wireless Ethernet (%s)" -#~ msgstr "Trådløst Ethernet (%s)" - -#~ msgid "NetworkManager Applet" -#~ msgstr "NetworkManager-panelprogram" - -#~ msgid "Copyright © 2004-2005 Red Hat, Inc." -#~ msgstr "Copyright © 2004-2005 Red Hat, Inc." - -#~ msgid "" -#~ "Notification area applet for managing your network devices and " -#~ "connections." -#~ msgstr "" -#~ "Statusfelt-panelprogram til håndtering af dine netværks-enheder og -" -#~ "forbindelser." - -#~ msgid "translator-credits" -#~ msgstr "" -#~ "David Nielsen\n" -#~ "Martin Willemoes Hansen\n" -#~ "Lasse Bang Mikkelsen\n" -#~ "\n" -#~ "Dansk-gruppen \n" -#~ "Mere info: http://www.dansk-gruppen.dk" - -#~ msgid "VPN Error" -#~ msgstr "VPN fejl" - -#~ msgid "VPN Login Failure" -#~ msgstr "VPN logind-fejl" - -#~ msgid "Could not start the VPN connection '%s' due to a login failure." -#~ msgstr "" -#~ "Kunne ikke etablere VPN-forbindelsen '%s' pågrund af en logind-fejl." - -#~ msgid "VPN Start Failure" -#~ msgstr "VPN etablerings-fejl" - -#~ msgid "" -#~ "Could not start the VPN connection '%s' due to a failure launching the " -#~ "VPN program." -#~ msgstr "" -#~ "Kunne ikke etablere VPN-forbindelsen '%s' pågrund af fejl ved start af " -#~ "VPN-program." - -#~ msgid "VPN Connect Failure" -#~ msgstr "VPN tilslutnings-fejl" - -#~ msgid "Could not start the VPN connection '%s' due to a connection error." -#~ msgstr "" -#~ "Kunne ikke etablere VPN-forbindelsen '%s' pågrund af en forbindelses-fejl." - -#~ msgid "VPN Configuration Error" -#~ msgstr "VPN konfigurations-fejl" - -#~ msgid "The VPN connection '%s' was not correctly configured." -#~ msgstr "VPN-forbindelsen '%s' er ikke konfigureret korrekt." - -#~ msgid "" -#~ "Could not start the VPN connection '%s' because the VPN server did not " -#~ "return an adequate network configuration." -#~ msgstr "" -#~ "Kunne ikke etablere VPN-forbindelsen '%s' fordi VPN-serveren ikke " -#~ "returnerede en passende netværks-konfiguration." - -#~ msgid "The VPN service said: \"%s\"" -#~ msgstr "VPN-tjenesten sagde: \"%s\"" - -#~ msgid "VPN connection '%s' said:" -#~ msgstr "VPN-forbindelsen '%s' sagde:" - -#~ msgid "VPN Login Message" -#~ msgstr "VPN logind-meddelelse" - -#~ msgid "" -#~ "The NetworkManager Applet could not find some required resources (the " -#~ "glade file was not found)." -#~ msgstr "" -#~ "NetworkManager panelprogrammet kunne ikke finde nogle krævede ressourcer " -#~ "(glade-filen blev ikke fundet)." - -#~ msgid "The network device \"%s (%s)\" does not support wireless scanning." -#~ msgstr "Netværks-enheden \"%s (%s)\" understøtter ikke trådløs scanning." - -#~ msgid "The network device \"%s (%s)\" does not support link detection." -#~ msgstr "Netværks-enheden \"%s (%s)\" understøtter ikke link-detektering." - -#~ msgid "Preparing device %s for the wired network..." -#~ msgstr "Klargører enheden %s til det kablede netværk..." - -#~ msgid "Preparing device %s for the wireless network '%s'..." -#~ msgstr "Klargører enheden %s til det trådløse netværk '%s'..." - -#~ msgid "Configuring device %s for the wired network..." -#~ msgstr "Konfigurerer enheden %s til det kablede netværk..." - -#~ msgid "Attempting to join the wireless network '%s'..." -#~ msgstr "Forsøger at tilslutte til det trådløse netværk '%s'..." - -#~ msgid "Waiting for Network Key for the wireless network '%s'..." -#~ msgstr "Venter på netværksnøglen til det trådløse netværk '%s'..." - -#~ msgid "Requesting a network address from the wired network..." -#~ msgstr "Forespørger en netværks-adresse fra det kablede netværk..." - -#~ msgid "Requesting a network address from the wireless network '%s'..." -#~ msgstr "Forespørger en netværks-adresse fra det trådløse netværk '%s'..." - -#~ msgid "Finishing connection to the wired network..." -#~ msgstr "Færdiggører tilslutning til det kablede netværk..." - -#~ msgid "Finishing connection to the wireless network '%s'..." -#~ msgstr "Færdiggører tilslutning til det trådløse netværk '%s'..." - -#~ msgid "NetworkManager is not running" -#~ msgstr "NetworkManager kører ikke" - -#~ msgid "Networking disabled" -#~ msgstr "Netværks-understøttelse deaktiveret" - -#~ msgid "No network connection" -#~ msgstr "Ingen netværks-forbindelse" - -#~ msgid "Wired network connection" -#~ msgstr "Kablet netværks-forbindelse" - -#~ msgid "Connected to an Ad-Hoc wireless network" -#~ msgstr "Tilsluttet til et trådløst ad hoc netværk" - -#~ msgid "Wireless network connection to '%s' (%d%%)" -#~ msgstr "Trådløs netværks-forbindelse til '%s' (%d%%)" - -#~ msgid "VPN connection to '%s'" -#~ msgstr "VPN-forbindelse til '%s'" - -#~ msgid "VPN connecting to '%s'" -#~ msgstr "VPN tilslutter til '%s'" - -#~ msgid "_Connect to Other Wireless Network..." -#~ msgstr "_Tilslut til andet trådløst netværk..." - -#~ msgid "Create _New Wireless Network..." -#~ msgstr "Opret _nyt trådløst netværk..." - -#~ msgid "_VPN Connections" -#~ msgstr "_VPN-forbindelser" - -#~ msgid "_Configure VPN..." -#~ msgstr "_Konfigurér VPN..." - -#~ msgid "_Disconnect VPN..." -#~ msgstr "_Afbryd VPN..." - -#~ msgid "_Dial Up Connections" -#~ msgstr "_Opkalds-forbindelser" - -#~ msgid "Connect to %s..." -#~ msgstr "Tilslut til %s..." - -#~ msgid "Disconnect from %s..." -#~ msgstr "Afbryd fra %s..." - -#~ msgid "No network devices have been found" -#~ msgstr "Ingen netværks-enheder blev fundet" - -#~ msgid "NetworkManager is not running..." -#~ msgstr "NetworkManager kører ikke..." - -#~ msgid "Enable _Networking" -#~ msgstr "Aktivér _netværks-understøttelse" - -#~ msgid "Enable _Wireless" -#~ msgstr "Aktivér _trådløst netværk" - -#~ msgid "Connection _Information" -#~ msgstr "Forbindelses-_information" - -#~ msgid "_Help" -#~ msgstr "_Hjælp" - -#~ msgid "_About" -#~ msgstr "_Om" - -#~ msgid "" -#~ "The NetworkManager applet could not find some required resources. It " -#~ "cannot continue.\n" -#~ msgstr "" -#~ "NetworkManager panelprogrammet kunne ikke finde nogle krævede ressourcer " -#~ "- kan ikke fortsætte.\n" - -#~ msgid "Open System" -#~ msgstr "Åbent system" - -#~ msgid "Shared Key" -#~ msgstr "Delt nøgle" - -#~ msgid "TKIP (Default)" -#~ msgstr "TKIP (forvalgt)" - -#~ msgid "AES-CCMP" -#~ msgstr "AES-CCMP" - -#~ msgid "None" -#~ msgstr "Ingen" - -#~ msgid "WEP 40/128-bit ASCII" -#~ msgstr "WEP 40/128-bit ASCII" - -#~ msgid "WEP 40/128-bit hex" -#~ msgstr "WEP 40/128-bit hex" - -#~ msgid "WEP Passphrase" -#~ msgstr "WEP-adgangskode:" - -#~ msgid "Orientation" -#~ msgstr "Retning" - -#~ msgid "The orientation of the tray." -#~ msgstr "Retningen på statusikonet." - -#~ msgid "Wired Network (%s)" -#~ msgstr "Kablet netværk (%s)" - -#~ msgid "_Wired Network" -#~ msgstr "_Kablet netværk" - -#~ msgid "Wireless Network (%s)" -#~ msgid_plural "Wireless Networks (%s)" -#~ msgstr[0] "Trådløst netværk (%s)" -#~ msgstr[1] "Trådløse netværk (%s)" - -#~ msgid "Wireless Network" -#~ msgid_plural "Wireless Networks" -#~ msgstr[0] "Trådløst netværk" -#~ msgstr[1] "Trådløse netværk" - -#~ msgid " (invalid Unicode)" -#~ msgstr " (ugyldig Unicode)" - -#~ msgid "" -#~ "By default, the wireless network's name is set to your computer's name, %" -#~ "s, with no encryption enabled" -#~ msgstr "" -#~ "Som standard navngives det trådløse netværk til din maskines navn, %s, " -#~ "uden nogen kryptering slået til" - -#~ msgid "Create new wireless network" -#~ msgstr "Opret nyt trådløst netværk" - -#~ msgid "" -#~ "Enter the name and security settings of the wireless network you wish to " -#~ "create." -#~ msgstr "" -#~ "Indtast navn- og sikkerhedsopsætning på det trådløse netværk du ønsker at " -#~ "oprette." - -#~ msgid "Create New Wireless Network" -#~ msgstr "Opret nyt trådløst netværk" - -#~ msgid "Existing wireless network" -#~ msgstr "Eksisterende trådløst netværk" - -#~ msgid "Enter the name of the wireless network to which you wish to connect." -#~ msgstr "Indtast navnet på det trådløse netværk du ønsker at tilslutte dig." - -#~ msgid "Connect to Other Wireless Network" -#~ msgstr "Tilslut til andet trådløst netværk" - -#~ msgid "Cannot start VPN connection '%s'" -#~ msgstr "Kan ikke etablere VPN-forbindelsen '%s'" - -#~ msgid "" -#~ "Could not find the authentication dialog for VPN connection type '%s'. " -#~ "Contact your system administrator." -#~ msgstr "" -#~ "Kunne ikke finde godkendelses-vinduet til VPN-forbindelsestypen '%s'. " -#~ "Kontakt din system-administrator." - -#~ msgid "" -#~ "There was a problem launching the authentication dialog for VPN " -#~ "connection type '%s'. Contact your system administrator." -#~ msgstr "" -#~ "Der opstod en fejl ved start af godkendelses-vinduet til VPN-" -#~ "forbindelsestypen '%s'. Kontakt din system-administrator." - -#~ msgid " " -#~ msgstr " " - -#~ msgid "" -#~ "Active Connection Information" -#~ msgstr "" -#~ "Information om aktiv forbindelse" - -#~ msgid "" -#~ "Passphrase Required by Wireless " -#~ "Network\n" -#~ "\n" -#~ "A passphrase or encryption key is required to access the wireless network " -#~ "'%s'." -#~ msgstr "" -#~ "Adgangskode påkrævet af trådløst " -#~ "netværk\n" -#~ "\n" -#~ "En adgangskode eller krypteringsnøgle er påkrævet, for at opnå adgang til " -#~ "det trådløse netværk '%s'." - -#~ msgid "" -#~ "Reduced Network Functionality\n" -#~ "\n" -#~ "%s It will not be completely functional." -#~ msgstr "" -#~ "Reduceret netværks-funktionalitet\n" -#~ "\n" -#~ "%s Den vil ikke være fuldstændig funktionsdygtig." - -#~ msgid "" -#~ "Wireless Network Login " -#~ "Confirmation\n" -#~ "\n" -#~ "You have chosen to log in to the wireless network '%s'. If you are sure " -#~ "that this wireless network is secure, click the checkbox below and " -#~ "NetworkManager will not require confirmation on subsequent log ins." -#~ msgstr "" -#~ "Bekræftelse af logind på trådløst " -#~ "netværk\n" -#~ "\n" -#~ "Du har valgt at logge på det trådløse netværk '%s'. Hvis du er sikker på " -#~ "at dette trådløse netværk er sikkert, afkryds nedenstående " -#~ "afkrydsningsfelt og NetworkManager vil ikke spørge i fremtiden." - -#~ msgid "Authentication:" -#~ msgstr "Godkendelse:" - -#~ msgid "Broadcast Address:" -#~ msgstr "Rundsendings-adresse:" - -#~ msgid "C_onnect" -#~ msgstr "T_ilslut" - -#~ msgid "Connection Information" -#~ msgstr "Forbindelses-information" - -#~ msgid "Default Route:" -#~ msgstr "Standard rute:" - -#~ msgid "Destination Address:" -#~ msgstr "Destinations-adresse:" - -#~ msgid "Hardware Address:" -#~ msgstr "Hardware-adresse:" - -#~ msgid "IP Address:" -#~ msgstr "IP-adresse:" - -#~ msgid "Interface:" -#~ msgstr "Enhed:" - -#~ msgid "Key:" -#~ msgstr "Nøgle:" - -#~ msgid "" -#~ "None\n" -#~ "WEP Passphrase\n" -#~ "WEP 40/128-bit hex\n" -#~ "WEP 40/128-bit ASCII\n" -#~ msgstr "" -#~ "Ingen\n" -#~ "WEP-adgangskode\n" -#~ "WEP 40/128-bit hex\n" -#~ "WEP 40/128-bit ASCII\n" - -#~ msgid "" -#~ "Open System\n" -#~ "Shared Key" -#~ msgstr "" -#~ "Åbent system\n" -#~ "Delt nøgle" - -#~ msgid "Other Wireless Network..." -#~ msgstr "Andet trådløst netværk..." - -#~ msgid "Passphrase:" -#~ msgstr "Adgangskode:" - -#~ msgid "Password:" -#~ msgstr "Adgangskode:" - -#~ msgid "Primary DNS:" -#~ msgstr "Primær DNS:" - -#~ msgid "Secondary DNS:" -#~ msgstr "Sekundær DNS:" - -#~ msgid "Subnet Mask:" -#~ msgstr "Undernet-maske:" - -#~ msgid "Type:" -#~ msgstr "Type:" - -#~ msgid "User Name:" -#~ msgstr "Brugernavn:" - -#~ msgid "Wireless Network Key Required" -#~ msgstr "Nøgle til trådløst netværk påkrævet" - -#~ msgid "Wireless _adapter:" -#~ msgstr "Trådløs _adapter:" - -#~ msgid "_Always Trust this Wireless Network" -#~ msgstr "_Stol altid på dette trådløse netværk" - -#~ msgid "_Don't remind me again" -#~ msgstr "_Påmind mig ikke igen" - -#~ msgid "_Login to Network" -#~ msgstr "_Log på netværk" - -#~ msgid "_Network Name:" -#~ msgstr "_Netværksnavn:" - -#~ msgid "_Wireless Security:" -#~ msgstr "Trådløs sikkerhed:" - -#~ msgid "leap_subwindow" -#~ msgstr "leap_subwindow" - -#~ msgid "wep_key_subwindow" -#~ msgstr "wep_key_subwindow" - -#~ msgid "wep_passphrase_subwindow" -#~ msgstr "wep_passphrase_subwindow" - -#~ msgid "wpa_psk_subwindow" -#~ msgstr "wpa_psk_subwindow" - -#~ msgid "WPA2 Personal" -#~ msgstr "Personlig WPA2" - -#~ msgid "WPA Personal" -#~ msgstr "Personlig WPA" - -#~ msgid "Choose which type of VPN connection you wish to create." -#~ msgstr "Vælg hvilken type VPN-forbindelse du ønsker at oprette." - -#~ msgid "Connect to:" -#~ msgstr "Tilslut til:" - -#~ msgid "Create VPN Connection - 1 of 2" -#~ msgstr "Opret VPN-forbindelse - 1 af 2" - -#~ msgid "Create VPN Connection - 2 of 2" -#~ msgstr "Opret VPN-forbindelse - 2 af 2" - -#~ msgid "Finish Creating VPN Connection" -#~ msgstr "Færdiggør oprettelse af VPN-forbindelse" - -#~ msgid "" -#~ "This assistant will guide you through the creation of a connection to a " -#~ "Virtual Private Network (VPN).\n" -#~ "\n" -#~ "It will require some information, such as IP addresses and secrets. " -#~ "Please see your system administrator to obtain this information." -#~ msgstr "" -#~ "Denne vil guide dig gennem oprettelsen af en forbindelse til et virtuelt " -#~ "privat netværk (VPN).\n" -#~ "\n" -#~ "Denne guide vil kræve nogle informationer, såsom IP-adresser og " -#~ "adgangskode. Henvend dig venligst til din system-administrator for at få " -#~ "disse informationer." From d350513d4bcadb9fdd62f91af546161a89a42a09 Mon Sep 17 00:00:00 2001 From: Daniel Nylander Date: Mon, 10 Jan 2011 15:29:48 +0100 Subject: [PATCH 097/102] po: updated Swedish translation (bgo #638260) --- po/sv.po | 412 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 207 insertions(+), 205 deletions(-) diff --git a/po/sv.po b/po/sv.po index dc9869ed1f..56b73dc1e7 100644 --- a/po/sv.po +++ b/po/sv.po @@ -9,8 +9,8 @@ msgid "" msgstr "" "Project-Id-Version: NetworkManager\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=NetworkManager&component=general\n" -"POT-Creation-Date: 2010-08-10 03:25+0000\n" -"PO-Revision-Date: 2010-08-12 01:57+0100\n" +"POT-Creation-Date: 2010-09-20 15:25+0000\n" +"PO-Revision-Date: 2010-12-29 12:23+0100\n" "Last-Translator: Daniel Nylander \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" @@ -98,7 +98,12 @@ msgstr "AUTOCONNECT" msgid "READONLY" msgstr "SKRIVSKYDDAD" -#: ../cli/src/connections.c:158 +#. 7 +#: ../cli/src/connections.c:83 +msgid "DBUS-PATH" +msgstr "DBUS-SÖKVÄG" + +#: ../cli/src/connections.c:159 #, c-format msgid "" "Usage: nmcli con { COMMAND | help }\n" @@ -117,45 +122,43 @@ msgstr "" " up id | uuid [iface ] [ap ] [--nowait] [--timeout ]\n" " down id | uuid \n" -#: ../cli/src/connections.c:198 -#: ../cli/src/connections.c:537 +#: ../cli/src/connections.c:199 +#: ../cli/src/connections.c:540 #, c-format msgid "Error: 'con list': %s" msgstr "Fel: \"con list\": %s" -#: ../cli/src/connections.c:200 -#: ../cli/src/connections.c:539 +#: ../cli/src/connections.c:201 +#: ../cli/src/connections.c:542 #, c-format msgid "Error: 'con list': %s; allowed fields: %s" msgstr "Fel: \"con list\": %s; tillåtna fält: %s" -#: ../cli/src/connections.c:208 -#| msgid "Connections" +#: ../cli/src/connections.c:209 msgid "Connection details" msgstr "Anslutningsdetaljer" -#: ../cli/src/connections.c:382 -#: ../cli/src/connections.c:602 -#| msgid "System" +#: ../cli/src/connections.c:384 +#: ../cli/src/connections.c:605 msgid "system" msgstr "system" -#: ../cli/src/connections.c:382 -#: ../cli/src/connections.c:602 +#: ../cli/src/connections.c:384 +#: ../cli/src/connections.c:605 msgid "user" msgstr "användare" -#: ../cli/src/connections.c:384 +#: ../cli/src/connections.c:386 msgid "never" msgstr "aldrig" #. "CAPABILITIES" #. Print header #. "WIFI-PROPERTIES" -#: ../cli/src/connections.c:385 -#: ../cli/src/connections.c:386 -#: ../cli/src/connections.c:603 +#: ../cli/src/connections.c:387 +#: ../cli/src/connections.c:388 #: ../cli/src/connections.c:606 +#: ../cli/src/connections.c:609 #: ../cli/src/devices.c:432 #: ../cli/src/devices.c:557 #: ../cli/src/devices.c:583 @@ -190,10 +193,10 @@ msgstr "aldrig" msgid "yes" msgstr "ja" -#: ../cli/src/connections.c:385 -#: ../cli/src/connections.c:386 -#: ../cli/src/connections.c:603 +#: ../cli/src/connections.c:387 +#: ../cli/src/connections.c:388 #: ../cli/src/connections.c:606 +#: ../cli/src/connections.c:609 #: ../cli/src/devices.c:432 #: ../cli/src/devices.c:557 #: ../cli/src/devices.c:583 @@ -229,23 +232,22 @@ msgstr "ja" msgid "no" msgstr "nej" -#: ../cli/src/connections.c:458 -#: ../cli/src/connections.c:501 -#| msgid "System connections:\n" +#: ../cli/src/connections.c:461 +#: ../cli/src/connections.c:504 msgid "System connections" msgstr "systemanslutningar" -#: ../cli/src/connections.c:463 -#: ../cli/src/connections.c:514 +#: ../cli/src/connections.c:466 +#: ../cli/src/connections.c:517 msgid "User connections" msgstr "Användaranslutningar" -#: ../cli/src/connections.c:475 -#: ../cli/src/connections.c:1335 -#: ../cli/src/connections.c:1351 -#: ../cli/src/connections.c:1360 -#: ../cli/src/connections.c:1371 -#: ../cli/src/connections.c:1456 +#: ../cli/src/connections.c:478 +#: ../cli/src/connections.c:1338 +#: ../cli/src/connections.c:1354 +#: ../cli/src/connections.c:1363 +#: ../cli/src/connections.c:1374 +#: ../cli/src/connections.c:1459 #: ../cli/src/devices.c:962 #: ../cli/src/devices.c:972 #: ../cli/src/devices.c:1074 @@ -254,14 +256,14 @@ msgstr "Användaranslutningar" msgid "Error: %s argument is missing." msgstr "Fel: %s-argument saknas." -#: ../cli/src/connections.c:488 +#: ../cli/src/connections.c:491 #, c-format msgid "Error: %s - no such connection." msgstr "Fel: %s - ingen sådan anslutning." -#: ../cli/src/connections.c:520 -#: ../cli/src/connections.c:1384 -#: ../cli/src/connections.c:1474 +#: ../cli/src/connections.c:523 +#: ../cli/src/connections.c:1387 +#: ../cli/src/connections.c:1477 #: ../cli/src/devices.c:785 #: ../cli/src/devices.c:852 #: ../cli/src/devices.c:986 @@ -270,255 +272,254 @@ msgstr "Fel: %s - ingen sådan anslutning." msgid "Unknown parameter: %s\n" msgstr "Okänd parameter: %s\n" -#: ../cli/src/connections.c:529 +#: ../cli/src/connections.c:532 #, c-format msgid "Error: no valid parameter specified." msgstr "Fel: ingen giltig parameter angiven." -#: ../cli/src/connections.c:544 -#: ../cli/src/connections.c:1577 +#: ../cli/src/connections.c:547 +#: ../cli/src/connections.c:1580 #: ../cli/src/devices.c:1293 -#: ../cli/src/network-manager.c:274 +#: ../cli/src/network-manager.c:359 #, c-format msgid "Error: %s." msgstr "Fel: %s." -#: ../cli/src/connections.c:650 +#: ../cli/src/connections.c:653 #, c-format msgid "Error: 'con status': %s" msgstr "Fel: \"con status\": %s" -#: ../cli/src/connections.c:652 +#: ../cli/src/connections.c:655 #, c-format msgid "Error: 'con status': %s; allowed fields: %s" msgstr "Fel: \"con status\": %s; tillåtna fält: %s" -#: ../cli/src/connections.c:659 +#: ../cli/src/connections.c:662 msgid "Active connections" msgstr "Aktiva anslutningar" -#: ../cli/src/connections.c:1027 +#: ../cli/src/connections.c:1030 #, c-format msgid "no active connection on device '%s'" msgstr "ingen aktiv anslutning på enheten \"%s\"" -#: ../cli/src/connections.c:1035 +#: ../cli/src/connections.c:1038 #, c-format msgid "no active connection or device" msgstr "ingen aktiv anslutning eller enhet" -#: ../cli/src/connections.c:1085 +#: ../cli/src/connections.c:1088 #, c-format msgid "device '%s' not compatible with connection '%s'" msgstr "enheten \"%s\" är inte kompatibel med anslutningen \"%s\"" -#: ../cli/src/connections.c:1087 +#: ../cli/src/connections.c:1090 #, c-format -#| msgid "no active connection on device '%s'" msgid "no device found for connection '%s'" msgstr "ingen enhet hittades för anslutningen \"%s\"" -#: ../cli/src/connections.c:1098 +#: ../cli/src/connections.c:1101 msgid "activating" msgstr "aktiverar" -#: ../cli/src/connections.c:1100 +#: ../cli/src/connections.c:1103 msgid "activated" msgstr "aktiverad" -#: ../cli/src/connections.c:1103 -#: ../cli/src/connections.c:1126 -#: ../cli/src/connections.c:1159 +#: ../cli/src/connections.c:1106 +#: ../cli/src/connections.c:1129 +#: ../cli/src/connections.c:1162 #: ../cli/src/devices.c:246 #: ../cli/src/devices.c:558 -#: ../cli/src/network-manager.c:92 -#: ../cli/src/network-manager.c:145 +#: ../cli/src/network-manager.c:94 +#: ../cli/src/network-manager.c:149 #: ../cli/src/settings.c:473 msgid "unknown" msgstr "okänt" -#: ../cli/src/connections.c:1112 +#: ../cli/src/connections.c:1115 msgid "VPN connecting (prepare)" msgstr "VPN ansluter (förbereder)" -#: ../cli/src/connections.c:1114 +#: ../cli/src/connections.c:1117 msgid "VPN connecting (need authentication)" msgstr "VPN ansluter (behöver autentisering)" -#: ../cli/src/connections.c:1116 +#: ../cli/src/connections.c:1119 msgid "VPN connecting" msgstr "VPN ansluter" -#: ../cli/src/connections.c:1118 +#: ../cli/src/connections.c:1121 msgid "VPN connecting (getting IP configuration)" msgstr "VPN ansluter (hämtar IP-konfiguration)" -#: ../cli/src/connections.c:1120 +#: ../cli/src/connections.c:1123 msgid "VPN connected" msgstr "VPN ansluten" -#: ../cli/src/connections.c:1122 +#: ../cli/src/connections.c:1125 msgid "VPN connection failed" msgstr "VPN-anslutning misslyckades" -#: ../cli/src/connections.c:1124 +#: ../cli/src/connections.c:1127 msgid "VPN disconnected" msgstr "VPN frånkopplad" -#: ../cli/src/connections.c:1135 +#: ../cli/src/connections.c:1138 msgid "unknown reason" msgstr "okänd anledning" -#: ../cli/src/connections.c:1137 +#: ../cli/src/connections.c:1140 msgid "none" msgstr "ingen" -#: ../cli/src/connections.c:1139 +#: ../cli/src/connections.c:1142 msgid "the user was disconnected" msgstr "användaren kopplades från" -#: ../cli/src/connections.c:1141 +#: ../cli/src/connections.c:1144 msgid "the base network connection was interrupted" msgstr "basnätverksanslutningen avbröts" -#: ../cli/src/connections.c:1143 +#: ../cli/src/connections.c:1146 msgid "the VPN service stopped unexpectedly" msgstr "VPN-tjänsten stoppades oväntat" -#: ../cli/src/connections.c:1145 +#: ../cli/src/connections.c:1148 msgid "the VPN service returned invalid configuration" msgstr "VPN-tjänsten returnerade en ogiltig konfiguration" -#: ../cli/src/connections.c:1147 +#: ../cli/src/connections.c:1150 msgid "the connection attempt timed out" msgstr "anslutningsförsöket översteg tidsgränsen" -#: ../cli/src/connections.c:1149 +#: ../cli/src/connections.c:1152 msgid "the VPN service did not start in time" msgstr "VPN-tjänsten startade inte i tid" -#: ../cli/src/connections.c:1151 +#: ../cli/src/connections.c:1154 msgid "the VPN service failed to start" msgstr "VPN-tjänsten misslyckades med att starta" -#: ../cli/src/connections.c:1153 +#: ../cli/src/connections.c:1156 msgid "no valid VPN secrets" msgstr "inga giltiga VPN-hemligheter" -#: ../cli/src/connections.c:1155 +#: ../cli/src/connections.c:1158 msgid "invalid VPN secrets" msgstr "ogiltiga VPN-hemligheter" -#: ../cli/src/connections.c:1157 +#: ../cli/src/connections.c:1160 msgid "the connection was removed" msgstr "anslutningen togs bort" -#: ../cli/src/connections.c:1171 +#: ../cli/src/connections.c:1174 #, c-format msgid "state: %s\n" msgstr "tillstånd: %s\n" -#: ../cli/src/connections.c:1174 -#: ../cli/src/connections.c:1200 +#: ../cli/src/connections.c:1177 +#: ../cli/src/connections.c:1203 #, c-format msgid "Connection activated\n" msgstr "Anslutning aktiverad\n" -#: ../cli/src/connections.c:1177 +#: ../cli/src/connections.c:1180 #, c-format msgid "Error: Connection activation failed." msgstr "Fel: Aktivering av anslutning misslyckades." -#: ../cli/src/connections.c:1196 +#: ../cli/src/connections.c:1199 #, c-format msgid "state: %s (%d)\n" msgstr "tillstånd: %s (%d)\n" -#: ../cli/src/connections.c:1206 +#: ../cli/src/connections.c:1209 #, c-format msgid "Error: Connection activation failed: %s." msgstr "Fel: Aktivering av anslutning misslyckades: %s." -#: ../cli/src/connections.c:1223 +#: ../cli/src/connections.c:1226 #: ../cli/src/devices.c:909 #, c-format msgid "Error: Timeout %d sec expired." msgstr "Fel: Tidsgränsen %d sekunder gick ut." -#: ../cli/src/connections.c:1266 +#: ../cli/src/connections.c:1269 #, c-format msgid "Error: Connection activation failed: %s" msgstr "Fel: Aktivering av anslutning misslyckades: %s" -#: ../cli/src/connections.c:1280 +#: ../cli/src/connections.c:1283 #, c-format msgid "Error: Obtaining active connection for '%s' failed." msgstr "Fel: Hämtning av aktiv anslutning för \"%s\" misslyckades." -#: ../cli/src/connections.c:1289 +#: ../cli/src/connections.c:1292 #, c-format msgid "Active connection state: %s\n" msgstr "Tillstånd för aktiv anslutning: %s\n" -#: ../cli/src/connections.c:1290 +#: ../cli/src/connections.c:1293 #, c-format msgid "Active connection path: %s\n" msgstr "Sökväg för aktiv anslutning: %s\n" -#: ../cli/src/connections.c:1344 -#: ../cli/src/connections.c:1465 +#: ../cli/src/connections.c:1347 +#: ../cli/src/connections.c:1468 #, c-format msgid "Error: Unknown connection: %s." msgstr "Fel: Okänd anslutning: %s." -#: ../cli/src/connections.c:1379 +#: ../cli/src/connections.c:1382 #: ../cli/src/devices.c:980 #, c-format msgid "Error: timeout value '%s' is not valid." msgstr "Fel: värdet \"%s\" för tidsgränsen är inte giltigt." -#: ../cli/src/connections.c:1392 -#: ../cli/src/connections.c:1482 +#: ../cli/src/connections.c:1395 +#: ../cli/src/connections.c:1485 #, c-format msgid "Error: id or uuid has to be specified." msgstr "Fel: id eller uuid måste anges." -#: ../cli/src/connections.c:1412 +#: ../cli/src/connections.c:1415 #, c-format msgid "Error: No suitable device found: %s." msgstr "Fel: Ingen lämplig enhet hittades: %s." -#: ../cli/src/connections.c:1414 +#: ../cli/src/connections.c:1417 #, c-format msgid "Error: No suitable device found." msgstr "Fel: Ingen lämplig enhet hittades." -#: ../cli/src/connections.c:1509 +#: ../cli/src/connections.c:1512 #, c-format msgid "Warning: Connection not active\n" msgstr "Varning: Anslutningen är inte aktiv\n" -#: ../cli/src/connections.c:1566 +#: ../cli/src/connections.c:1569 #, c-format msgid "Error: 'con' command '%s' is not valid." msgstr "Fel: \"con\"-kommandot \"%s\" är inte giltigt." -#: ../cli/src/connections.c:1602 +#: ../cli/src/connections.c:1605 #, c-format msgid "Error: could not connect to D-Bus." msgstr "Fel: kunde inte ansluta till D-Bus." -#: ../cli/src/connections.c:1609 +#: ../cli/src/connections.c:1612 #, c-format msgid "Error: Could not get system settings." msgstr "Fel: Kunde inte få systeminställningar." -#: ../cli/src/connections.c:1617 +#: ../cli/src/connections.c:1620 #, c-format msgid "Error: Could not get user settings." msgstr "Fel: Kunde inte få användarinställningar." -#: ../cli/src/connections.c:1627 +#: ../cli/src/connections.c:1630 #, c-format msgid "Error: Can't obtain connections: settings services are not running." msgstr "Fel: Kan inte få anslutningar: inställningstjänster är inte igång." @@ -556,7 +557,6 @@ msgstr "WIFI-EGENSKAPER" #. 2 #: ../cli/src/devices.c:75 -#| msgid "PEAP" msgid "AP" msgstr "AP" @@ -572,7 +572,6 @@ msgstr "IP4-INSTÄLLNINGAR" #. 5 #: ../cli/src/devices.c:78 -#| msgid "DNS" msgid "IP4-DNS" msgstr "IP4-DNS" @@ -583,7 +582,6 @@ msgstr "IP6-INSTÄLLNINGAR" #. 7 #: ../cli/src/devices.c:80 -#| msgid "DNS" msgid "IP6-DNS" msgstr "IP6-DNS" @@ -614,19 +612,16 @@ msgstr "BÄRARE" #. 0 #: ../cli/src/devices.c:122 -#| msgid " WEP" msgid "WEP" msgstr "WEP" #. 1 #: ../cli/src/devices.c:123 -#| msgid " WPA" msgid "WPA" msgstr "WPA" #. 2 #: ../cli/src/devices.c:124 -#| msgid " WPA2" msgid "WPA2" msgstr "WPA2" @@ -637,7 +632,6 @@ msgstr "TKIP" #. 4 #: ../cli/src/devices.c:126 -#| msgid "AES-CCMP" msgid "CCMP" msgstr "CCMP" @@ -667,13 +661,11 @@ msgstr "DNS" #. 0 #: ../cli/src/devices.c:175 -#| msgid "SSID:" msgid "SSID" msgstr "SSID" #. 1 #: ../cli/src/devices.c:176 -#| msgid "BSSID:" msgid "BSSID" msgstr "BSSID" @@ -719,16 +711,6 @@ msgstr "AKTIV" #: ../cli/src/devices.c:208 #, c-format -#| msgid "" -#| "Usage: nmcli dev { COMMAND | help }\n" -#| "\n" -#| " COMMAND := { status | list | disconnect | wifi }\n" -#| "\n" -#| " status\n" -#| " list [iface ]\n" -#| " disconnect iface [--nowait] [--timeout ]\n" -#| " wifi [list [iface ] | apinfo iface hwaddr ]\n" -#| "\n" msgid "" "Usage: nmcli dev { COMMAND | help }\n" "\n" @@ -759,7 +741,7 @@ msgid "unavailable" msgstr "otillgänglig" #: ../cli/src/devices.c:232 -#: ../cli/src/network-manager.c:89 +#: ../cli/src/network-manager.c:91 msgid "disconnected" msgstr "frånkopplad" @@ -780,7 +762,7 @@ msgid "connecting (getting IP configuration)" msgstr "ansluter (hämtar IP-konfiguration)" #: ../cli/src/devices.c:242 -#: ../cli/src/network-manager.c:87 +#: ../cli/src/network-manager.c:89 msgid "connected" msgstr "ansluten" @@ -813,27 +795,22 @@ msgid "%u MB/s" msgstr "%u MB/s" #: ../cli/src/devices.c:403 -#| msgid ", Encrypted: " msgid "Encrypted: " msgstr "Krypterad: " #: ../cli/src/devices.c:408 -#| msgid " WEP" msgid "WEP " msgstr "WEP " #: ../cli/src/devices.c:410 -#| msgid " WPA" msgid "WPA " msgstr "WPA " #: ../cli/src/devices.c:412 -#| msgid " WPA2" msgid "WPA2 " msgstr "WPA2 " #: ../cli/src/devices.c:415 -#| msgid " Enterprise" msgid "Enterprise " msgstr "Företag" @@ -852,12 +829,10 @@ msgstr "Fel: \"dev list\": %s" #: ../cli/src/devices.c:488 #, c-format -#| msgid "Error: Device '%s' (%s) disconnecting failed: %s" msgid "Error: 'dev list': %s; allowed fields: %s" msgstr "Fel: \"dev list\": %s; tillåtna fält: %s" #: ../cli/src/devices.c:497 -#| msgid "Devices" msgid "Device details" msgstr "Enhetsdetaljer" @@ -867,7 +842,6 @@ msgid "(unknown)" msgstr "(okänt)" #: ../cli/src/devices.c:528 -#| msgid "(unknown)" msgid "unknown)" msgstr "okänt)" @@ -934,7 +908,6 @@ msgstr "Fel: gränssnitt (iface) måste anges." #: ../cli/src/devices.c:1112 #, c-format -#| msgid "Error: 'dev wifi' command '%s' is not valid." msgid "Error: 'dev wifi': %s" msgstr "Fel: \"dev wifi\": %s" @@ -974,147 +947,191 @@ msgstr "KÖR" #. 1 #: ../cli/src/network-manager.c:37 -msgid "WIFI-HARDWARE" -msgstr "WIFI-MASKINVARA" +msgid "NET-ENABLED" +msgstr "NÄT-AKTIVERAT" #. 2 #: ../cli/src/network-manager.c:38 -msgid "WIFI" -msgstr "WIFI" +msgid "WIFI-HARDWARE" +msgstr "WIFI-MASKINVARA" #. 3 #: ../cli/src/network-manager.c:39 -msgid "WWAN-HARDWARE" -msgstr "WWAN-MASKINVARA" +msgid "WIFI" +msgstr "WIFI" #. 4 #: ../cli/src/network-manager.c:40 -#| msgid "NM WWAN:" +msgid "WWAN-HARDWARE" +msgstr "WWAN-MASKINVARA" + +#. 5 +#: ../cli/src/network-manager.c:41 msgid "WWAN" msgstr "WWAN" -#: ../cli/src/network-manager.c:62 +#: ../cli/src/network-manager.c:64 #, c-format +#| msgid "" +#| "Usage: nmcli nm { COMMAND | help }\n" +#| "\n" +#| " COMMAND := { status | sleep | wakeup | wifi | wwan }\n" +#| "\n" +#| " status\n" +#| " sleep\n" +#| " wakeup\n" +#| " wifi [on|off]\n" +#| " wwan [on|off]\n" +#| "\n" msgid "" "Usage: nmcli nm { COMMAND | help }\n" "\n" -" COMMAND := { status | sleep | wakeup | wifi | wwan }\n" +" COMMAND := { status | enable | sleep | wifi | wwan }\n" "\n" " status\n" -" sleep\n" -" wakeup\n" +" enable [true|false]\n" +" sleep [true|false]\n" " wifi [on|off]\n" " wwan [on|off]\n" "\n" msgstr "" "Användning: nmcli nm { KOMMANDO | help }\n" "\n" -" KOMMANDO := { status | sleep | wakeup | wifi | wwan }\n" +" KOMMANDO := { status | enable | sleep | wifi | wwan }\n" "\n" " status\n" -" sleep\n" -" wakeup\n" +" enable [true|false]\n" +" sleep [true|false]\n" " wifi [on|off]\n" " wwan [on|off]\n" "\n" -#: ../cli/src/network-manager.c:83 +#: ../cli/src/network-manager.c:85 msgid "asleep" msgstr "sover" -#: ../cli/src/network-manager.c:85 +#: ../cli/src/network-manager.c:87 msgid "connecting" msgstr "ansluter" -#: ../cli/src/network-manager.c:125 +#: ../cli/src/network-manager.c:128 #, c-format msgid "Error: 'nm status': %s" msgstr "Fel: \"nm status\": %s" -#: ../cli/src/network-manager.c:127 +#: ../cli/src/network-manager.c:130 #, c-format msgid "Error: 'nm status': %s; allowed fields: %s" msgstr "Fel: \"nm status\": %s; tillåtna fält: %s" -#: ../cli/src/network-manager.c:134 +#: ../cli/src/network-manager.c:137 msgid "NetworkManager status" msgstr "Status för Nätverkshanterare" #. Print header -#: ../cli/src/network-manager.c:140 -#: ../cli/src/network-manager.c:141 -#: ../cli/src/network-manager.c:142 -#: ../cli/src/network-manager.c:143 -#: ../cli/src/network-manager.c:211 -#: ../cli/src/network-manager.c:243 +#: ../cli/src/network-manager.c:144 +#: ../cli/src/network-manager.c:145 +#: ../cli/src/network-manager.c:146 +#: ../cli/src/network-manager.c:147 +#: ../cli/src/network-manager.c:154 +#: ../cli/src/network-manager.c:247 +#: ../cli/src/network-manager.c:296 +#: ../cli/src/network-manager.c:328 msgid "enabled" msgstr "aktiverad" -#: ../cli/src/network-manager.c:140 -#: ../cli/src/network-manager.c:141 -#: ../cli/src/network-manager.c:142 -#: ../cli/src/network-manager.c:143 -#: ../cli/src/network-manager.c:211 -#: ../cli/src/network-manager.c:243 +#: ../cli/src/network-manager.c:144 +#: ../cli/src/network-manager.c:145 +#: ../cli/src/network-manager.c:146 +#: ../cli/src/network-manager.c:147 +#: ../cli/src/network-manager.c:154 +#: ../cli/src/network-manager.c:247 +#: ../cli/src/network-manager.c:296 +#: ../cli/src/network-manager.c:328 msgid "disabled" msgstr "inaktiverad" -#: ../cli/src/network-manager.c:148 +#: ../cli/src/network-manager.c:152 msgid "running" msgstr "kör" -#: ../cli/src/network-manager.c:148 +#: ../cli/src/network-manager.c:152 msgid "not running" msgstr "kör inte" -#: ../cli/src/network-manager.c:201 -#: ../cli/src/network-manager.c:233 +#: ../cli/src/network-manager.c:175 +#, c-format +#| msgid "Error: could not connect to D-Bus." +msgid "Error: Couldn't connect to system bus: %s" +msgstr "Fel: kunde inte ansluta till systembussen: %s" + +#: ../cli/src/network-manager.c:186 +#, c-format +#| msgid "Error: could not connect to D-Bus." +msgid "Error: Couldn't create D-Bus object proxy." +msgstr "Fel: Kunde inte skapa proxy för D-Bus-objekt." + +#: ../cli/src/network-manager.c:192 +#, c-format +#| msgid "Error: 'con list': %s" +msgid "Error in sleep: %s" +msgstr "Fel i sömn: %s" + +#: ../cli/src/network-manager.c:237 +#: ../cli/src/network-manager.c:286 +#: ../cli/src/network-manager.c:318 #, c-format -#| msgid "Error: timeout value '%s' is not valid." msgid "Error: '--fields' value '%s' is not valid here; allowed fields: %s" msgstr "Fel: värdet \"%s\" för \"--fields\" är inte giltigt här; tillåtna fält: %s" -#: ../cli/src/network-manager.c:209 -#| msgid "enabled" +#: ../cli/src/network-manager.c:245 +#| msgid "WiFi enabled" +msgid "Networking enabled" +msgstr "Nätverk aktiverat" + +#: ../cli/src/network-manager.c:256 +#, c-format +#| msgid "Error: invalid 'wwan' parameter: '%s'." +msgid "Error: invalid 'enable' parameter: '%s'; use 'true' or 'false'." +msgstr "Fel: ogiltig \"enable\"-parameter: \"%s\"; använd \"true\" eller \"false\"." + +#: ../cli/src/network-manager.c:265 +#, c-format +#| msgid "Error: Could not connect to NetworkManager." +msgid "Error: Sleeping status is not exported by NetworkManager." +msgstr "Fel: Sömnstatus exporteras inte av Nätverkshanterare." + +#: ../cli/src/network-manager.c:273 +#, c-format +#| msgid "Error: invalid 'wifi' parameter: '%s'." +msgid "Error: invalid 'sleep' parameter: '%s'; use 'true' or 'false'." +msgstr "Fel: ogiltig \"sleep\"-parameter: \"%s\"; använd \"true\" eller \"false\"." + +#: ../cli/src/network-manager.c:294 msgid "WiFi enabled" msgstr "WiFi aktiverat" -#: ../cli/src/network-manager.c:220 +#: ../cli/src/network-manager.c:305 #, c-format msgid "Error: invalid 'wifi' parameter: '%s'." msgstr "Fel: ogiltig \"wifi\"-parameter: \"%s\"." -#: ../cli/src/network-manager.c:241 -#| msgid "enabled" +#: ../cli/src/network-manager.c:326 msgid "WWAN enabled" msgstr "WWAN aktiverat" -#: ../cli/src/network-manager.c:252 +#: ../cli/src/network-manager.c:337 #, c-format msgid "Error: invalid 'wwan' parameter: '%s'." msgstr "Fel: ogiltig \"wwan\"-parameter: \"%s\"." -#: ../cli/src/network-manager.c:263 +#: ../cli/src/network-manager.c:348 #, c-format msgid "Error: 'nm' command '%s' is not valid." msgstr "Fel: \"nm\"-kommandot \"%s\" är inte giltigt." #: ../cli/src/nmcli.c:69 #, c-format -#| msgid "" -#| "Usage: %s [OPTIONS] OBJECT { COMMAND | help }\n" -#| "\n" -#| "OPTIONS\n" -#| " -t[erse] terse output\n" -#| " -p[retty] pretty output\n" -#| " -v[ersion] show program version\n" -#| " -h[elp] print this help\n" -#| "\n" -#| "OBJECT\n" -#| " nm NetworkManager status\n" -#| " con NetworkManager connections\n" -#| " dev devices managed by NetworkManager\n" -#| "\n" msgid "" "Usage: %s [OPTIONS] OBJECT { COMMAND | help }\n" "\n" @@ -1152,7 +1169,6 @@ msgstr "" #: ../cli/src/nmcli.c:113 #, c-format -#| msgid "Object '%s' is unknown, try 'nmcli help'." msgid "Error: Object '%s' is unknown, try 'nmcli help'." msgstr "Fel: Objektet \"%s\" är okänt, prova \"nmcli help\"." @@ -1179,20 +1195,17 @@ msgstr "Fel: Flaggan \"--pretty\" är ömsesidigt uteslutande med \"--terse\"." #: ../cli/src/nmcli.c:171 #: ../cli/src/nmcli.c:187 #, c-format -#| msgid "Error: %s argument is missing." msgid "Error: missing argument for '%s' option." msgstr "Fel: argument för flaggan \"%s\" saknas." #: ../cli/src/nmcli.c:180 #: ../cli/src/nmcli.c:196 #, c-format -#| msgid "Error: '%s' argument is missing." msgid "Error: '%s' is not valid argument for '%s' option." msgstr "Fel: \"%s\" är inte ett giltigt argument för flaggan \"%s\"." #: ../cli/src/nmcli.c:203 #, c-format -#| msgid "Error: '%s' argument is missing." msgid "Error: fields for '%s' options are missing." msgstr "Fel: fält för \"%s\"-flaggor saknas." @@ -1203,7 +1216,6 @@ msgstr "nmcli-verktyg, version %s\n" #: ../cli/src/nmcli.c:215 #, c-format -#| msgid "Option '%s' is unknown, try 'nmcli -help'." msgid "Error: Option '%s' is unknown, try 'nmcli -help'." msgstr "Fel: Flaggan \"%s\" är okänd, prova \"nmcli -help\"." @@ -1228,18 +1240,15 @@ msgstr "%d (hex-ascii-nyckel)" #: ../cli/src/settings.c:413 #, c-format -#| msgid "WEP 128-bit Passphrase" msgid "%d (104/128-bit passphrase)" msgstr "%d (104/128-bitars lösenfras)" #: ../cli/src/settings.c:416 #, c-format -#| msgid "(unknown)" msgid "%d (unknown)" msgstr "%d (okänt)" #: ../cli/src/settings.c:442 -#| msgid "(unknown)" msgid "0 (unknown)" msgstr "0 (okänt)" @@ -1701,7 +1710,6 @@ msgid "System policy prevents sharing connections via an open WiFi network" msgstr "Systemets policy förhindrar delning av anslutningar via ett öppet trådlöst nätverk" #: ../policy/org.freedesktop.NetworkManager.policy.in.h:1 -#| msgid "Wired network connection" msgid "Allow control of network connections" msgstr "Tillåt kontroll av nätverksanslutningar" @@ -1718,7 +1726,6 @@ msgid "Enable or disable mobile broadband devices" msgstr "Aktivera eller inaktivera mobila bredbandsenheter" #: ../policy/org.freedesktop.NetworkManager.policy.in.h:5 -#| msgid "Enable _Networking" msgid "Enable or disable system networking" msgstr "Aktivera eller inaktivera systemnätverk" @@ -1727,12 +1734,10 @@ msgid "Put NetworkManager to sleep or wake it up (should only be used by system msgstr "Försätt Nätverkshanterare i vänteläge eller återställ efter det (bör endast användas av systemets strömhantering)" #: ../policy/org.freedesktop.NetworkManager.policy.in.h:7 -#| msgid "System policy prevents modification of system settings" msgid "System policy prevents control of network connections" msgstr "Systemets policy förhindrar kontroll av nätverksanslutningar" #: ../policy/org.freedesktop.NetworkManager.policy.in.h:8 -#| msgid "System policy prevents sharing connections via an open WiFi network" msgid "System policy prevents enabling or disabling WiFi devices" msgstr "Systemets policy förhindrar aktivering eller inaktivering av WiFi-enheter" @@ -1741,7 +1746,6 @@ msgid "System policy prevents enabling or disabling mobile broadband devices" msgstr "Systemets policy förhindrar aktivering eller inaktivering av mobila bredbandsenheter" #: ../policy/org.freedesktop.NetworkManager.policy.in.h:10 -#| msgid "System policy prevents modification of system settings" msgid "System policy prevents enabling or disabling system networking" msgstr "Systemets policy förhindrar aktivering eller inaktivering av systemnätverk" @@ -1750,7 +1754,6 @@ msgid "System policy prevents putting NetworkManager to sleep or waking it up" msgstr "Systemets policy förhindrar att Nätverkshanterare försätts i vänteläge eller återställs efter det" #: ../policy/org.freedesktop.NetworkManager.policy.in.h:12 -#| msgid "System policy prevents modification of system settings" msgid "System policy prevents use of user-specific connections" msgstr "Systemets policy förhindrar användning av användarspecifika anslutningar" @@ -1772,7 +1775,6 @@ msgstr "kan inte ansluta till netlink för övervakning av länkstatus: %s" #: ../src/nm-netlink-monitor.c:265 #, c-format -#| msgid "unable to allocate netlink handle: %s" msgid "unable to enable netlink handle credential passing: %s" msgstr "kunde inte aktivera behörighetshantering för netlink-handtag: %s" @@ -1798,22 +1800,21 @@ msgstr "kan inte gå med i netlink-grupp: %s" msgid "error updating link cache: %s" msgstr "fel vid uppdatering av länkcache: %s" -#: ../src/main.c:502 +#: ../src/main.c:499 #, c-format msgid "Invalid option. Please use --help to see a list of valid options.\n" msgstr "Ogiltig flagga. Använd --help för att se en lista över giltiga flaggor.\n" -#: ../src/main.c:573 +#: ../src/main.c:570 #, c-format -#| msgid "Invalid option. Please use --help to see a list of valid options.\n" msgid "%s. Please use --help to see a list of valid options.\n" msgstr "%s. Använd --help för att se en lista över giltiga flaggor.\n" -#: ../src/dhcp-manager/nm-dhcp-dhclient.c:324 +#: ../src/dhcp-manager/nm-dhcp-dhclient.c:328 msgid "# Created by NetworkManager\n" msgstr "# Skapad av Nätverkshanterare\n" -#: ../src/dhcp-manager/nm-dhcp-dhclient.c:340 +#: ../src/dhcp-manager/nm-dhcp-dhclient.c:344 #, c-format msgid "" "# Merged from %s\n" @@ -1863,6 +1864,7 @@ msgid "Auto %s" msgstr "Automatisk %s" #: ../system-settings/plugins/ifcfg-rh/reader.c:3412 +#: ../system-settings/plugins/ifnet/connection_parser.c:49 msgid "System" msgstr "System" From b46cf443c05cf385cbec6e4accd9cab1a5a3a74d Mon Sep 17 00:00:00 2001 From: Radek Vykydal Date: Tue, 11 Jan 2011 09:53:48 -0600 Subject: [PATCH 098/102] ifcfg-rh: respect GATEWAYDEV for ibft/iSCSI configs too (rh #665027) --- system-settings/plugins/ifcfg-rh/reader.c | 1 + 1 file changed, 1 insertion(+) diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c index b4ee1307b9..5b01417cb2 100644 --- a/system-settings/plugins/ifcfg-rh/reader.c +++ b/system-settings/plugins/ifcfg-rh/reader.c @@ -1162,6 +1162,7 @@ make_ip4_setting (shvarFile *ifcfg, if (!g_ascii_strcasecmp (value, "bootp") || !g_ascii_strcasecmp (value, "dhcp")) method = NM_SETTING_IP4_CONFIG_METHOD_AUTO; else if (!g_ascii_strcasecmp (value, "ibft")) { + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, never_default, NULL); /* iSCSI Boot Firmware Table: need to read values from the iSCSI * firmware for this device and create the IP4 setting using those. */ From aaa54c65a8b6807da516993ee2a9c916052f7d6c Mon Sep 17 00:00:00 2001 From: Mu Qiao Date: Tue, 11 Jan 2011 12:33:37 -0600 Subject: [PATCH 099/102] ifnet: fix memory leak; handle file format changes --- system-settings/plugins/ifnet/Makefile.am | 10 +-- system-settings/plugins/ifnet/net_utils.c | 60 +++++++++++---- system-settings/plugins/ifnet/plugin.c | 2 +- .../plugins/ifnet/tests/Makefile.am | 3 +- .../plugins/ifnet/tests/test_all.c | 77 +++++++++++-------- 5 files changed, 97 insertions(+), 55 deletions(-) diff --git a/system-settings/plugins/ifnet/Makefile.am b/system-settings/plugins/ifnet/Makefile.am index f63f8ca710..86d5ea2514 100644 --- a/system-settings/plugins/ifnet/Makefile.am +++ b/system-settings/plugins/ifnet/Makefile.am @@ -21,11 +21,10 @@ libnm_settings_plugin_ifnet_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ $(GUDEV_CFLAGS) \ -DG_DISABLE_DEPRECATED \ - -DSYSCONFDIR=\"$(sysconfdir)\"\ - -g - + -DSYSCONFDIR=\"$(sysconfdir)\" libnm_settings_plugin_ifnet_la_LDFLAGS = -module -avoid-version + libnm_settings_plugin_ifnet_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(top_builddir)/libnm-glib/libnm-glib.la \ @@ -50,12 +49,9 @@ lib_ifnet_io_la_CPPFLAGS = \ $(DBUS_CFLAGS) \ -DG_DISABLE_DEPRECATED \ -DSYSCONFDIR=\"$(sysconfdir)\" \ - -DSBINDIR=\"$(sbindir)\"\ - -g + -DSBINDIR=\"$(sbindir)\" lib_ifnet_io_la_LIBADD = \ $(top_builddir)/libnm-util/libnm-util.la \ $(GLIB_LIBS)\ $(GIO_LIBS) - - diff --git a/system-settings/plugins/ifnet/net_utils.c b/system-settings/plugins/ifnet/net_utils.c index 8a541979d8..2dc253c546 100644 --- a/system-settings/plugins/ifnet/net_utils.c +++ b/system-settings/plugins/ifnet/net_utils.c @@ -19,7 +19,6 @@ * Copyright (C) 1999-2010 Gentoo Foundation, Inc. */ -#include #include #include #include @@ -194,6 +193,32 @@ ifnet_plugin_error_quark (void) return error_quark; } +static char * +find_default_gateway_str (char *str) +{ + char *tmp; + + if ((tmp = strstr (str, "default via ")) != NULL) { + return tmp + strlen ("default via "); + } else if ((tmp = strstr (str, "default gw ")) != NULL) { + return tmp + strlen ("default gw "); + } + return NULL; +} + +static char * +find_gateway_str (char *str) +{ + char *tmp; + + if ((tmp = strstr (str, "via ")) != NULL) { + return tmp + strlen ("via "); + } else if ((tmp = strstr (str, "gw ")) != NULL) { + return tmp + strlen ("gw "); + } + return NULL; +} + gboolean reload_parsers () { @@ -362,11 +387,10 @@ has_default_route (gchar * conn_name, gboolean (*check_fn) (gchar *)) if (!tmp) return FALSE; routes = g_strdup (tmp); - tmp = strstr (routes, "default via "); + tmp = find_default_gateway_str (routes); if (!tmp) { goto error; } - tmp += strlen ("default via "); g_strstrip (tmp); if ((end = strstr (tmp, "\"")) != NULL) *end = '\0'; @@ -483,8 +507,13 @@ get_ip4_gateway (gchar * gateway) if (!gateway) return 0; - tmp = strstr (gateway, "via "); - tmp = g_strdup (tmp + strlen ("via ")); + tmp = find_gateway_str (gateway); + if (!tmp) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Couldn't obtain gateway in \"%s\"", gateway); + return 0; + } + tmp = g_strdup (tmp); strip_string (tmp, ' '); strip_string (tmp, '"'); if ((split = strstr (tmp, "\"")) != NULL) @@ -509,8 +538,13 @@ get_ip6_next_hop (gchar * next_hop) if (!next_hop) return 0; - tmp = strstr (next_hop, "via "); - tmp = g_strdup (tmp + strlen ("via ")); + tmp = find_gateway_str (next_hop); + if (!tmp) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Couldn't obtain next_hop in \"%s\"", next_hop); + return 0; + } + tmp = g_strdup (tmp); strip_string (tmp, ' '); strip_string (tmp, '"'); g_strstrip (tmp); @@ -671,8 +705,8 @@ convert_ip4_routes_block (gchar * conn_name) length = g_strv_length (ipset); for (i = 0; i < length; i++) { ip = ipset[i]; - if (strstr (ip, "default via ") || strstr (ip, "::") - || !strstr (ip, "via")) + if (find_default_gateway_str (ip) || strstr (ip, "::") + || !find_gateway_str (ip)) continue; ip = strip_string (ip, '"'); iblock = create_ip4_block (ip); @@ -712,9 +746,7 @@ convert_ip6_routes_block (gchar * conn_name) ip = strip_string (ip, '"'); if (ip[0] == '\0') continue; - printf ("ip:%s\n", ip); - if ((tmp_addr = strstr (ip, "default via ")) != NULL) { - tmp_addr += strlen ("default via "); + if ((tmp_addr = find_default_gateway_str (ip)) != NULL) { if (!is_ip6_address (tmp_addr)) continue; else { @@ -855,7 +887,7 @@ is_managed (gchar * conn_name) void get_dhcp_hostname_and_client_id (char **hostname, char **client_id) { - gchar *dhcp_client = ifnet_get_global_setting ("main", "dhcp"); + gchar *dhcp_client = NULL; const gchar *dhcpcd_conf = "/etc/dhcpcd.conf"; const gchar *dhclient_conf = "/etc/dhcp/dhclient.conf"; gchar *line = NULL, *tmp = NULL, *contents = NULL; @@ -864,6 +896,7 @@ get_dhcp_hostname_and_client_id (char **hostname, char **client_id) *hostname = NULL; *client_id = NULL; + dhcp_client = ifnet_get_global_setting ("main", "dhcp"); if (dhcp_client) { if (!strcmp (dhcp_client, "dhclient")) g_file_get_contents (dhclient_conf, &contents, NULL, @@ -871,6 +904,7 @@ get_dhcp_hostname_and_client_id (char **hostname, char **client_id) else if (!strcmp (dhcp_client, "dhcpcd")) g_file_get_contents (dhcpcd_conf, &contents, NULL, NULL); + g_free (dhcp_client); } else { if (g_file_test (dhclient_conf, G_FILE_TEST_IS_REGULAR)) g_file_get_contents (dhclient_conf, &contents, NULL, diff --git a/system-settings/plugins/ifnet/plugin.c b/system-settings/plugins/ifnet/plugin.c index 51d560246d..94f9e791f5 100644 --- a/system-settings/plugins/ifnet/plugin.c +++ b/system-settings/plugins/ifnet/plugin.c @@ -40,7 +40,7 @@ #include "connection_parser.h" #define IFNET_PLUGIN_NAME_PRINT "ifnet" -#define IFNET_PLUGIN_INFO "(C) 1999-2010 Gentoo Foundation, Inc. To report bugs please use bugs.gentoo.org with [networkmanager] or [dagger] prefix." +#define IFNET_PLUGIN_INFO "(C) 1999-2010 Gentoo Foundation, Inc. To report bugs please use bugs.gentoo.org with [networkmanager] or [qiaomuf] prefix." #define IFNET_SYSTEM_HOSTNAME_FILE "/etc/conf.d/hostname" #define IFNET_MANAGE_WELL_KNOWN_DEFAULT TRUE #define IFNET_KEY_FILE_KEY_MANAGED "managed" diff --git a/system-settings/plugins/ifnet/tests/Makefile.am b/system-settings/plugins/ifnet/tests/Makefile.am index ead3f1fc4f..17a081f54a 100644 --- a/system-settings/plugins/ifnet/tests/Makefile.am +++ b/system-settings/plugins/ifnet/tests/Makefile.am @@ -6,8 +6,7 @@ INCLUDES=-I$(top_srcdir)/system-settings/plugins/ifnet\ TESTS = check_ifnet check_PROGRAMS = check_ifnet check_ifnet_SOURCES = test_all.c -check_ifnet_LDFLAGS = -g -check_ifnet_CPPFLAGS = $(CHECK_CFLAGS) $(GLIB_CFLAGS) -g +check_ifnet_CPPFLAGS = $(CHECK_CFLAGS) $(GLIB_CFLAGS) check_ifnet_LDADD = $(top_srcdir)/libnm-util/libnm-util.la\ $(top_srcdir)/system-settings/plugins/ifnet/lib-ifnet-io.la\ $(CHECK_LIBS)\ diff --git a/system-settings/plugins/ifnet/tests/test_all.c b/system-settings/plugins/ifnet/tests/test_all.c index ba98397616..eff76af284 100644 --- a/system-settings/plugins/ifnet/tests/test_all.c +++ b/system-settings/plugins/ifnet/tests/test_all.c @@ -58,17 +58,22 @@ test_read_hostname () "get hostname", "hostname is not correctly read, read:%s, expected: gentoo", hostname); + g_free (hostname); } static void test_write_hostname () { gchar *hostname = read_hostname ("hostname"); + gchar *tmp; write_hostname ("gentoo-nm", "hostname"); - ASSERT (strcmp (read_hostname ("hostname"), "gentoo-nm") == 0, + tmp = read_hostname ("hostname"); + ASSERT (strcmp (tmp, "gentoo-nm") == 0, "write hostname", "write hostname error"); write_hostname (hostname, "hostname"); + g_free (tmp); + g_free (hostname); } static void @@ -85,14 +90,13 @@ test_is_static () static void test_has_default_route () { - ASSERT (has_default_ip4_route ("eth0"), "has default route", - "eth0 should have a default ipv4 route"); - ASSERT (has_default_ip6_route ("eth4"), "has default route", - "eth4 should have a default ipv6 route"); - + ASSERT (has_default_ip4_route ("eth0"), + "has default route", "eth0 should have a default ipv4 route"); + ASSERT (has_default_ip6_route ("eth4"), + "has default route", "eth4 should have a default ipv6 route"); ASSERT (!has_default_ip4_route ("eth5") - && !has_default_ip6_route ("eth5"), "has default route", - "eth5 shouldn't have a default route"); + && !has_default_ip6_route ("eth5"), + "has default route", "eth5 shouldn't have a default route"); } static void @@ -138,8 +142,8 @@ check_ip_block (ip_block * iblock, gchar * ip, gchar * netmask, gchar * gateway) str = malloc (INET_ADDRSTRLEN); tmp_ip4_addr.s_addr = iblock->ip; inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN); - ASSERT (strcmp (ip, str) == 0, "check ip", "ip expected:%s, find:%s", - ip, str); + ASSERT (strcmp (ip, str) == 0, "check ip", + "ip expected:%s, find:%s", ip, str); tmp_ip4_addr.s_addr = iblock->netmask; inet_ntop (AF_INET, &tmp_ip4_addr, str, INET_ADDRSTRLEN); ASSERT (strcmp (netmask, str) == 0, "check netmask", @@ -170,8 +174,8 @@ test_convert_ipv4_config_block () destroy_ip_block (iblock); iblock = convert_ip4_config_block ("eth2"); ASSERT (iblock != NULL - && iblock->next == NULL, "convert error IPv4 address", - "should only get one address"); + && iblock->next == NULL, + "convert error IPv4 address", "should only get one address"); check_ip_block (iblock, "192.168.4.121", "255.255.255.0", "0.0.0.0"); destroy_ip_block (iblock); iblock = convert_ip4_config_block ("eth3"); @@ -182,7 +186,6 @@ test_convert_ipv4_config_block () ASSERT (iblock != NULL, "convert config_block", "convert error configuration"); destroy_ip_block (iblock); - } static void @@ -209,10 +212,13 @@ test_wpa_parser () ASSERT (exist_ssid ("static-wep-test"), "exist_ssid", "ssid static-wep-test is not found"); value = wpa_get_value ("static-wep-test", "key_mgmt"); - ASSERT (value && strcmp (value, "NONE") == 0, "get wpa data", + ASSERT (value + && strcmp (value, "NONE") == 0, "get wpa data", "key_mgmt of static-wep-test should be NONE, find %s", value); value = wpa_get_value ("static-wep-test", "wep_key0"); - ASSERT (value && strcmp (value, "\"abcde\"") == 0, "get wpa data", + ASSERT (value + && strcmp (value, "\"abcde\"") == 0, + "get wpa data", "wep_key0 of static-wep-test should be abcde, find %s", value); ASSERT (exist_ssid ("leap-example"), "get wsec", "ssid leap-example is not found"); @@ -228,8 +234,9 @@ test_strip_string () result = strip_string (result, '('); result = strip_string (result, ')'); result = strip_string (result, '"'); - ASSERT (strcmp (result, "default via 202.117.16.1") == 0, - "strip_string", "string isn't stripped, result is: %s", result); + ASSERT (strcmp (result, "default via 202.117.16.1") == + 0, "strip_string", + "string isn't stripped, result is: %s", result); g_free (result_b); } @@ -265,7 +272,6 @@ test_new_connection () "new connection failed: %s", error && (*error) ? (*error)->message : "NONE"); g_object_unref (connection); - } static void @@ -280,8 +286,9 @@ test_update_connection () error == NULL ? "None" : (*error)->message); ASSERT (ifnet_update_parsers_by_connection (connection, "eth0", NULL, "net.generate", - "wpa_supplicant.conf.generate", error), "update connection", - "update connection failed %s", "eth0"); + "wpa_supplicant.conf.generate", error), + "update connection", "update connection failed %s", "eth0"); + g_object_unref (connection); connection = ifnet_update_connection_from_config_block ("0xab3ace", error); ASSERT (connection != NULL, "get connection", @@ -289,8 +296,9 @@ test_update_connection () error == NULL ? "None" : (*error)->message); ASSERT (ifnet_update_parsers_by_connection (connection, "0xab3ace", NULL, "net.generate", - "wpa_supplicant.conf.generate", error), "update connection", - "update connection failed %s", "0xab3ace"); + "wpa_supplicant.conf.generate", error), + "update connection", "update connection failed %s", "0xab3ace"); + g_object_unref (connection); } static void @@ -301,14 +309,17 @@ test_add_connection () connection = ifnet_update_connection_from_config_block ("eth0", error); ASSERT (ifnet_add_new_connection - (connection, "net.generate", "wpa_supplicant.conf.generate", - error), "add connection", "add connection failed: %s", "eth0"); + (connection, "net.generate", + "wpa_supplicant.conf.generate", error), + "add connection", "add connection failed: %s", "eth0"); + g_object_unref (connection); connection = ifnet_update_connection_from_config_block ("myxjtu2", error); ASSERT (ifnet_add_new_connection - (connection, "net.generate", "wpa_supplicant.conf.generate", - error), "add connection", "add connection failed: %s", - "myxjtu2"); + (connection, "net.generate", + "wpa_supplicant.conf.generate", error), + "add connection", "add connection failed: %s", "myxjtu2"); + g_object_unref (connection); } static void @@ -322,16 +333,20 @@ test_delete_connection () "get connection failed: %s", error == NULL ? "None" : (*error)->message); ASSERT (ifnet_delete_connection_in_parsers - ("eth7", "net.generate", "wpa_supplicant.conf.generate"), + ("eth7", "net.generate", + "wpa_supplicant.conf.generate"), "delete connection", "delete connection failed: %s", "eth7"); + g_object_unref (connection); connection = ifnet_update_connection_from_config_block ("qiaomuf", error); ASSERT (connection != NULL, "get connection", "get connection failed: %s", error == NULL ? "None" : (*error)->message); ASSERT (ifnet_delete_connection_in_parsers - ("qiaomuf", "net.generate", "wpa_supplicant.conf.generate"), + ("qiaomuf", "net.generate", + "wpa_supplicant.conf.generate"), "delete connection", "delete connection failed: %s", "qiaomuf"); + g_object_unref (connection); } static void @@ -369,10 +384,8 @@ main (void) wpa_parser_destroy (); ifnet_init ("net"); wpa_parser_init ("wpa_supplicant.conf"); - printf("Initialization complete\n"); - + printf ("Initialization complete\n"); run_all (TRUE); - ifnet_destroy (); wpa_parser_destroy (); return 0; From 1d56981c8b0f53cc3a0b314232f5d60d8bf43044 Mon Sep 17 00:00:00 2001 From: Robby Workman Date: Tue, 11 Jan 2011 13:48:06 -0600 Subject: [PATCH 100/102] slackware: remove HAL requirement from initscript --- initscript/Slackware/rc.networkmanager.in | 5 ----- 1 file changed, 5 deletions(-) diff --git a/initscript/Slackware/rc.networkmanager.in b/initscript/Slackware/rc.networkmanager.in index 048903847a..35c42a464e 100644 --- a/initscript/Slackware/rc.networkmanager.in +++ b/initscript/Slackware/rc.networkmanager.in @@ -27,11 +27,6 @@ nm_start() return fi - if [ "`pgrep hald`" = "" ]; then - echo "HAL must be running to start NetworkManager" - return - fi - # Just in case the pidfile is still there, we may need to nuke it. if [ -e "$PIDFILE" ]; then rm -f $PIDFILE From 2b9392950ea06b5f777845cf85b02cdb1d0a8a3e Mon Sep 17 00:00:00 2001 From: Robby Workman Date: Tue, 11 Jan 2011 13:48:48 -0600 Subject: [PATCH 101/102] slackware: add short sleep to initscript during service restart The restart() function almost never works here - perhaps some part of NM takes a bit too long to stop() and then blocks the start() operation - but "sleep 2" between them makes everything fine. --- initscript/Slackware/rc.networkmanager.in | 1 + 1 file changed, 1 insertion(+) diff --git a/initscript/Slackware/rc.networkmanager.in b/initscript/Slackware/rc.networkmanager.in index 35c42a464e..6eed87e196 100644 --- a/initscript/Slackware/rc.networkmanager.in +++ b/initscript/Slackware/rc.networkmanager.in @@ -62,6 +62,7 @@ nm_stop() nm_restart() { nm_stop + sleep 2 nm_start } From 5a35862a1d24fb8d515ea09339123646370c2845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Klime=C5=A1?= Date: Wed, 12 Jan 2011 16:06:18 +0100 Subject: [PATCH 102/102] man: fix formatting of NetworkManager page --- man/NetworkManager.8.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/man/NetworkManager.8.in b/man/NetworkManager.8.in index 4f700e9a38..92c6e5aa26 100644 --- a/man/NetworkManager.8.in +++ b/man/NetworkManager.8.in @@ -52,8 +52,10 @@ A VPN connection has been deactivated. .TP .I "hostname" The system hostname has been updated. Use gethostname(2) to retrieve it. +.TP .I "dhcp4\-change" The DHCPv4 lease has changed (renewed, rebound, etc). +.TP .I "dhcp6\-change" The DHCPv6 lease has changed (renewed, rebound, etc). .SH OPTIONS