summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore8
-rw-r--r--cli/src/connections.c108
-rw-r--r--cli/src/devices.c387
-rw-r--r--cli/src/network-manager.c52
-rw-r--r--cli/src/settings.c46
-rw-r--r--cli/src/settings.h2
-rw-r--r--configure.ac23
-rw-r--r--examples/C/Makefile.am54
-rw-r--r--examples/C/add-connection-glib.c7
-rw-r--r--examples/C/get-active-connections.c248
-rw-r--r--examples/C/get-ap-info-libnm-glib.c229
-rw-r--r--examples/C/list-connections-dbus.c83
-rw-r--r--examples/C/list-connections-libnm-glib.c176
-rw-r--r--examples/python/nm-state.py4
-rw-r--r--include/NetworkManager.h4
-rw-r--r--initscript/Slackware/rc.networkmanager.in6
-rw-r--r--introspection/Makefile.am4
-rw-r--r--introspection/all.xml2
-rw-r--r--introspection/nm-device-wimax.xml103
-rw-r--r--introspection/nm-manager-client.xml2
-rw-r--r--introspection/nm-manager.xml12
-rw-r--r--introspection/nm-wimax-nsp.xml44
-rw-r--r--libnm-glib/Makefile.am14
-rw-r--r--libnm-glib/libnm-glib.ver23
-rw-r--r--libnm-glib/nm-client.c145
-rw-r--r--libnm-glib/nm-client.h9
-rw-r--r--libnm-glib/nm-device-wimax.c853
-rw-r--r--libnm-glib/nm-device-wimax.h79
-rw-r--r--libnm-glib/nm-device.c18
-rw-r--r--libnm-glib/nm-wimax-nsp.c303
-rw-r--r--libnm-glib/nm-wimax-nsp.h78
-rw-r--r--libnm-glib/tests/Makefile.am7
-rw-r--r--libnm-glib/tests/test-remote-settings-client.c11
-rw-r--r--libnm-util/Makefile.am2
-rw-r--r--libnm-util/libnm-util.ver6
-rw-r--r--libnm-util/nm-connection.c8
-rw-r--r--libnm-util/nm-setting-wimax.c229
-rw-r--r--libnm-util/nm-setting-wimax.h70
-rw-r--r--libnm-util/nm-setting.c2
-rw-r--r--libnm-util/nm-utils.c38
-rw-r--r--man/NetworkManager.8.in2
-rw-r--r--man/NetworkManager.conf.5.in20
-rw-r--r--po/LINGUAS1
-rw-r--r--po/POTFILES.in8
-rw-r--r--po/da.po2303
-rw-r--r--po/eo.po1766
-rw-r--r--po/sv.po412
-rw-r--r--policy/org.freedesktop.NetworkManager.policy.in9
-rw-r--r--src/Makefile.am40
-rw-r--r--src/backends/NetworkManagerGentoo.c49
-rw-r--r--src/dhcp-manager/Makefile.am38
-rw-r--r--src/dhcp-manager/nm-dhcp-client.c28
-rw-r--r--src/dhcp-manager/nm-dhcp-client.h25
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient-utils.c217
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient-utils.h35
-rw-r--r--src/dhcp-manager/nm-dhcp-dhclient.c174
-rw-r--r--src/dhcp-manager/nm-dhcp-dhcpcd.c8
-rw-r--r--src/dhcp-manager/nm-dhcp-manager.c2
-rw-r--r--src/dhcp-manager/tests/Makefile.am28
-rw-r--r--src/dhcp-manager/tests/test-dhcp-dhclient.c249
-rw-r--r--src/dns-manager/Makefile.am4
-rw-r--r--src/dns-manager/nm-dns-dnsmasq.c22
-rw-r--r--src/dns-manager/nm-dns-manager.c1
-rw-r--r--src/dns-manager/nm-dns-utils.c99
-rw-r--r--src/dns-manager/nm-dns-utils.h28
-rw-r--r--src/ip6-manager/nm-ip6-manager.c398
-rw-r--r--src/logging/nm-logging.c4
-rw-r--r--src/logging/nm-logging.h1
-rw-r--r--src/main.c32
-rw-r--r--src/modem-manager/nm-modem.c6
-rw-r--r--src/nm-device-ethernet.c2
-rw-r--r--src/nm-device-olpc-mesh.c6
-rw-r--r--src/nm-device-wifi.c310
-rw-r--r--src/nm-device.c138
-rw-r--r--src/nm-device.h2
-rw-r--r--src/nm-manager-auth.h1
-rw-r--r--src/nm-manager.c66
-rw-r--r--src/nm-manager.h3
-rw-r--r--src/nm-policy-hostname.c56
-rw-r--r--src/nm-policy-hostname.h5
-rw-r--r--src/nm-policy-hosts.c520
-rw-r--r--src/nm-policy-hosts.h20
-rw-r--r--src/nm-policy.c67
-rw-r--r--src/nm-udev-manager.c21
-rw-r--r--src/nm-wifi-ap.c177
-rw-r--r--src/nm-wifi-ap.h4
-rw-r--r--src/settings/nm-default-wired-connection.c2
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.c756
-rw-r--r--src/supplicant-manager/nm-supplicant-interface.h20
-rw-r--r--src/supplicant-manager/nm-supplicant-manager.c2
-rw-r--r--src/supplicant-manager/nm-supplicant-manager.h6
-rw-r--r--src/tests/test-policy-hosts.c761
-rw-r--r--src/wimax/Makefile.am40
-rw-r--r--src/wimax/iwmxsdk.c1462
-rw-r--r--src/wimax/iwmxsdk.h109
-rw-r--r--src/wimax/nm-device-wimax.c1444
-rw-r--r--src/wimax/nm-device-wimax.h82
-rw-r--r--src/wimax/nm-wimax-nsp.c249
-rw-r--r--src/wimax/nm-wimax-nsp.h63
-rw-r--r--src/wimax/nm-wimax-types.h31
-rw-r--r--src/wimax/nm-wimax-util.c82
-rw-r--r--src/wimax/nm-wimax-util.h38
-rw-r--r--system-settings/plugins/ifcfg-rh/plugin.c11
-rw-r--r--system-settings/plugins/ifcfg-rh/reader.c8
-rw-r--r--system-settings/plugins/ifnet/Makefile.am10
-rw-r--r--system-settings/plugins/ifnet/net_utils.c59
-rw-r--r--system-settings/plugins/ifnet/plugin.c2
-rw-r--r--system-settings/plugins/ifnet/tests/Makefile.am3
-rw-r--r--system-settings/plugins/ifnet/tests/test_all.c75
-rw-r--r--system-settings/plugins/ifupdown/plugin.c51
-rw-r--r--system-settings/plugins/keyfile/plugin.c20
-rw-r--r--test/nm-tool.c119
112 files changed, 13122 insertions, 3289 deletions
diff --git a/.gitignore b/.gitignore
index 848da36b55..b87df2330d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,12 @@ docs/generate-settings-spec
docs/settings-spec.html
docs/spec.html
+examples/C/add-connection-glib
+examples/C/get-active-connections
+examples/C/get-ap-info-libnm-glib
+examples/C/list-connections-dbus
+examples/C/list-connections-libnm-glib
+
callouts/nm-dhcp-client.action
callouts/nm-avahi-autoipd.action
callouts/nm-dispatcher.action
@@ -95,6 +101,7 @@ libnm-glib/tests/test-remote-settings-client
src/tests/test-dhcp-options
src/tests/test-policy-hosts
src/tests/test-wifi-ap-utils
+src/dhcp-manager/tests/test-dhcp-dhclient
system-settings/plugins/keyfile/tests/test-keyfile
system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh
@@ -102,6 +109,7 @@ system-settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils
system-settings/plugins/ifcfg-rh/tests/network-scripts/Test_Write_*
system-settings/plugins/ifcfg-rh/tests/network-scripts/*-Test_Write_*
system-settings/plugins/ifupdown/tests/test-ifupdown
+system-settings/plugins/ifnet/tests/check_ifnet
m4/gtk-doc.m4
m4/intltool.m4
diff --git a/cli/src/connections.c b/cli/src/connections.c
index 1dd70c164e..50c1373f81 100644
--- a/cli/src/connections.c
+++ b/cli/src/connections.c
@@ -38,8 +38,10 @@
#include <nm-setting-cdma.h>
#include <nm-setting-bluetooth.h>
#include <nm-setting-olpc-mesh.h>
+#include <nm-setting-wimax.h>
#include <nm-device-ethernet.h>
#include <nm-device-wifi.h>
+#include <nm-device-wimax.h>
#include <nm-gsm-device.h>
#include <nm-cdma-device.h>
#include <nm-device-bt.h>
@@ -102,6 +104,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","\
@@ -118,7 +121,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 {
@@ -137,7 +141,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);
@@ -155,7 +159,7 @@ usage (void)
" COMMAND := { list | status | up | down }\n\n"
" list [id <id> | uuid <id>]\n"
" status\n"
- " up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [--nowait] [--timeout <timeout>]\n"
+ " up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [nsp <name>] [--nowait] [--timeout <timeout>]\n"
" down id <id> | uuid <id>\n"));
}
@@ -348,6 +352,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)
@@ -826,6 +839,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)
{
g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
@@ -839,6 +897,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;
@@ -929,13 +989,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;
@@ -1022,6 +1089,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) {
@@ -1263,6 +1349,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;
@@ -1309,6 +1396,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) {
@@ -1349,7 +1445,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 436b4b6eb8..5e67c4ef5d 100644
--- a/cli/src/devices.c
+++ b/cli/src/devices.c
@@ -29,7 +29,6 @@
#include <glib.h>
#include <glib/gi18n.h>
#include <nm-client.h>
-#include <nm-device-wifi.h>
#include <nm-client.h>
#include <nm-device.h>
@@ -39,6 +38,7 @@
#include <nm-cdma-device.h>
#include <nm-device-bt.h>
//#include <nm-device-olpc-mesh.h>
+#include <nm-device-wimax.h>
#include <nm-utils.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-ip6-config.h>
@@ -51,6 +51,7 @@
#include <nm-setting-cdma.h>
#include <nm-setting-bluetooth.h>
#include <nm-setting-olpc-mesh.h>
+#include <nm-setting-wimax.h>
#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 */
@@ -184,12 +200,28 @@ 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
+/* 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);
@@ -198,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 */
@@ -207,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 <iface>]\n"
" disconnect iface <iface> [--nowait] [--timeout <timeout>]\n"
- " wifi [list [iface <iface>] [hwaddr <hwaddr>]]\n\n"));
+ " wifi [list [iface <iface>] [hwaddr <hwaddr>]]\n"
+ " wimax [list [iface <iface>] [nsp <name>]]\n\n"));
}
/* quit main loop */
@@ -264,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");
}
@@ -431,6 +467,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);
@@ -445,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;
@@ -521,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);
@@ -631,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 */
@@ -640,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);
@@ -660,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;
@@ -674,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;
@@ -685,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<num>" */
nmc->allowed_fields[1].value = tmp;
@@ -700,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);
@@ -716,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;
@@ -730,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;
@@ -738,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<num>" */
@@ -1244,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)
@@ -1279,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 <nm-setting-bluetooth.h>
#include <nm-setting-olpc-mesh.h>
#include <nm-setting-vpn.h>
+#include <nm-setting-wimax.h>
#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 */
diff --git a/configure.ac b/configure.ac
index bc9733036e..a7b8b1a965 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
@@ -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
@@ -281,6 +281,17 @@ PKG_CHECK_MODULES(UUID, uuid)
AC_SUBST(UUID_CFLAGS)
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 >= 1.5.1, 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)
@@ -531,6 +542,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
@@ -539,6 +551,7 @@ src/dnsmasq-manager/Makefile
src/modem-manager/Makefile
src/bluez-manager/Makefile
src/settings/Makefile
+src/wimax/Makefile
src/backends/Makefile
libnm-util/libnm-util.pc
libnm-util/Makefile
@@ -637,6 +650,12 @@ else
echo ConsoleKit 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/examples/C/Makefile.am b/examples/C/Makefile.am
index 68c0697b0b..a8b5a64075 100644
--- a/examples/C/Makefile.am
+++ b/examples/C/Makefile.am
@@ -1,2 +1,54 @@
+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 \
+ get-active-connections \
+ list-connections-dbus \
+ list-connections-libnm-glib \
+ get-ap-info-libnm-glib
+
+add_connection_glib_SOURCES = add-connection-glib.c
+add_connection_glib_LDADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(DBUS_LIBS) \
+ $(GLIB_LIBS)
+
+get_active_connections_SOURCES = get-active-connections.c
+get_active_connections_LDADD = \
+ $(top_builddir)/libnm-util/libnm-util.la \
+ $(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)
+
+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
+ add-connection-glib.c \
+ get-active-connections.c \
+ list-connections-dbus.c \
+ list-connections-libnm-glib.c \
+ get-ap-info-libnm-glib.c
+
diff --git a/examples/C/add-connection-glib.c b/examples/C/add-connection-glib.c
index 0e8dc18036..d650dc2f42 100644
--- a/examples/C/add-connection-glib.c
+++ b/examples/C/add-connection-glib.c
@@ -13,7 +13,7 @@
* 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.
+ * (C) Copyright 2011 Red Hat, Inc.
*/
/*
@@ -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;
@@ -98,7 +99,7 @@ int main (int argc, char *argv[])
/* 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_SERVICE,
NM_DBUS_PATH_SETTINGS,
NM_DBUS_IFACE_SETTINGS);
diff --git a/examples/C/get-active-connections.c b/examples/C/get-active-connections.c
new file mode 100644
index 0000000000..36224d29ad
--- /dev/null
+++ b/examples/C/get-active-connections.c
@@ -0,0 +1,248 @@
+/* -*- 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 <glib.h>
+#include <dbus/dbus-glib.h>
+
+#include <nm-connection.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-ip4-config.h>
+#include <NetworkManager.h>
+#include <nm-utils.h>
+
+#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;
+
+ /* 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,
+ G_TYPE_INVALID)) {
+ g_warning ("Failed to get active connection Connection property: %s",
+ error->message);
+ g_error_free (error);
+ 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);
+ g_error_free (error);
+ goto out;
+ }
+
+ /* And finally dump all the configuration to stdout */
+ 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;
+
+ /* 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,
+ 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 out the actual connection details */
+ 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;
+
+ /* 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",
+ 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;
+ }
+
+ /* 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));
+
+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 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,
+ DBUS_INTERFACE_PROPERTIES);
+ g_assert (props_proxy);
+
+ /* Get active connections */
+ get_active_connections (bus, props_proxy);
+
+ g_object_unref (props_proxy);
+ dbus_g_connection_unref (bus);
+
+ return 0;
+}
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 <glib.h>
+#include <dbus/dbus-glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <nm-client.h>
+#include <nm-device.h>
+#include <nm-device-wifi.h>
+#include <nm-access-point.h>
+#include <NetworkManager.h>
+#include <nm-utils.h>
+
+/* 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;
+}
diff --git a/examples/C/list-connections-dbus.c b/examples/C/list-connections-dbus.c
new file mode 100644
index 0000000000..2cb584b59b
--- /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 2011 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 <glib.h>
+#include <dbus/dbus-glib.h>
+#include <stdio.h>
+
+#include <NetworkManager.h>
+#include <nm-utils.h>
+
+#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,
+ 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..edb5ccc34b
--- /dev/null
+++ b/examples/C/list-connections-libnm-glib.c
@@ -0,0 +1,176 @@
+/*
+ * 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 2011 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 <glib.h>
+#include <dbus/dbus-glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include <nm-connection.h>
+#include <nm-setting-connection.h>
+#include <NetworkManager.h>
+#include <nm-utils.h>
+#include <nm-remote-settings.h>
+
+
+/* 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 *) &timestamp));
+
+ 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 (NMRemoteSettings *settings, gpointer user_data)
+{
+ GSList *connections;
+
+ connections = nm_remote_settings_list_connections (settings);
+
+ printf ("Connections:\n===================\n");
+
+ g_slist_foreach (connections, (GFunc) show_connection, NULL);
+
+ g_slist_free (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;
+ NMRemoteSettings *settings;
+ gboolean settings_running;
+
+ /* Get system settings */
+ if (!(settings = nm_remote_settings_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 (settings, NM_REMOTE_SETTINGS_SERVICE_RUNNING, &settings_running, NULL);
+
+ if (!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 (settings, NM_REMOTE_SETTINGS_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;
+}
diff --git a/examples/python/nm-state.py b/examples/python/nm-state.py
index 42c96bf56d..051e8ce087 100644
--- a/examples/python/nm-state.py
+++ b/examples/python/nm-state.py
@@ -47,12 +47,12 @@ 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_path = prop_iface.Get("org.freedesktop.NetworkManager.Connection.Active", "Connection")
service_proxy = bus.get_object("org.freedesktop.NetworkManager", con_path)
con_iface = dbus.Interface(service_proxy, "org.freedesktop.NetworkManager.Settings.Connection")
con_details = con_iface.GetSettings()
diff --git a/include/NetworkManager.h b/include/NetworkManager.h
index 95f0653536..924d044eef 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_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"
#define NM_DBUS_INTERFACE_IP4_CONFIG NM_DBUS_INTERFACE ".IP4Config"
#define NM_DBUS_INTERFACE_DHCP4_CONFIG NM_DBUS_INTERFACE ".DHCP4Config"
@@ -82,6 +85,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/initscript/Slackware/rc.networkmanager.in b/initscript/Slackware/rc.networkmanager.in
index 048903847a..6eed87e196 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
@@ -67,6 +62,7 @@ nm_stop()
nm_restart()
{
nm_stop
+ sleep 2
nm_start
}
diff --git a/introspection/Makefile.am b/introspection/Makefile.am
index 54877c7545..42640e3020 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 \
@@ -24,5 +25,6 @@ EXTRA_DIST = \
nm-active-connection.xml \
nm-dhcp4-config.xml \
nm-dhcp6-config.xml \
- nm-agent-manager.xml
+ nm-agent-manager.xml \
+ nm-wimax-nsp.xml
diff --git a/introspection/all.xml b/introspection/all.xml
index 73084e1cec..fb2b749e8b 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.</
<xi:include href="nm-device-serial.xml"/>
<xi:include href="nm-device-bt.xml"/>
<xi:include href="nm-device-olpc-mesh.xml"/>
+<xi:include href="nm-device-wimax.xml"/>
+<xi:include href="nm-wimax-nsp.xml"/>
<xi:include href="nm-ip4-config.xml"/>
<xi:include href="nm-ip6-config.xml"/>
<xi:include href="nm-dhcp4-config.xml"/>
diff --git a/introspection/nm-device-wimax.xml b/introspection/nm-device-wimax.xml
new file mode 100644
index 0000000000..6e414087fa
--- /dev/null
+++ b/introspection/nm-device-wimax.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <interface name="org.freedesktop.NetworkManager.Device.WiMax">
+ <method name="GetNspList">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_device_get_nsp_list"/>
+ <arg name="nsps" type="ao" direction="out">
+ <tp:docstring>
+ List of NSP object paths
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Get the list of NSPs visible to this device.
+ </tp:docstring>
+ </method>
+
+ <property name="HwAddress" type="s" access="read">
+ <tp:docstring>
+ Hardware address of the device.
+ </tp:docstring>
+ </property>
+
+ <property name="CenterFrequency" type="u" access="read">
+ <tp:docstring>
+ 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.
+ </tp:docstring>
+ </property>
+
+ <property name="Rssi" type="i" access="read">
+ <tp:docstring>
+ 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.
+ </tp:docstring>
+ </property>
+
+ <property name="Cinr" type="i" access="read">
+ <tp:docstring>
+ 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.
+ </tp:docstring>
+ </property>
+
+ <property name="TxPower" type="i" access="read">
+ <tp:docstring>
+ 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.
+ </tp:docstring>
+ </property>
+
+ <property name="Bsid" type="s" access="read">
+ <tp:docstring>
+ The ID of the serving base station as received from the network. Has
+ no meaning when the device is not connected.
+ </tp:docstring>
+ </property>
+
+ <property name="ActiveNsp" type="o" access="read">
+ <tp:docstring>
+ Object path of the NSP currently used by the WiMax device.
+ </tp:docstring>
+ </property>
+
+ <signal name="PropertiesChanged">
+ <arg name="properties" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring>
+ A dictionary mapping property names to variant boxed values.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when the WiMax device's properties changed.
+ </tp:docstring>
+ </signal>
+
+ <signal name="NspAdded">
+ <arg name="nsp" type="o">
+ <tp:docstring>
+ The object path of the newly found NSP.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when a new NSP is found by the device.
+ </tp:docstring>
+ </signal>
+
+ <signal name="NspRemoved">
+ <arg name="nsp" type="o">
+ <tp:docstring>
+ The object path of the NSP that has disappeared.
+ </tp:docstring>
+ </arg>
+ <tp:docstring>
+ Emitted when an NSP disappears from view of the device.
+ </tp:docstring>
+ </signal>
+
+ </interface>
+</node>
diff --git a/introspection/nm-manager-client.xml b/introspection/nm-manager-client.xml
index 9dde9ddfb3..ba2b25b91a 100644
--- a/introspection/nm-manager-client.xml
+++ b/introspection/nm-manager-client.xml
@@ -69,6 +69,8 @@ object. dbus-glib generates the same bound function names for D-Bus the methods
<property name="WirelessHardwareEnabled" type="b" access="read"/>
<property name="WwanEnabled" type="b" access="readwrite"/>
<property name="WwanHardwareEnabled" type="b" access="read"/>
+ <property name="WimaxEnabled" type="b" access="readwrite"/>
+ <property name="WimaxHardwareEnabled" type="b" access="read"/>
<property name="ActiveConnections" type="ao" access="read"/>
<property name="Version" type="s" access="read"/>
<property name="State" type="u" access="read"/>
diff --git a/introspection/nm-manager.xml b/introspection/nm-manager.xml
index 5e087a2634..9a8f34dea7 100644
--- a/introspection/nm-manager.xml
+++ b/introspection/nm-manager.xml
@@ -243,6 +243,18 @@
</tp:docstring>
</property>
+ <property name="WimaxEnabled" type="b" access="readwrite">
+ <tp:docstring>
+ Indicates if WiMAX devices are currently enabled or not.
+ </tp:docstring>
+ </property>
+
+ <property name="WimaxHardwareEnabled" type="b" access="read">
+ <tp:docstring>
+ Indicates if the WiMAX hardware is currently enabled, i.e. the state of the RF kill switch.
+ </tp:docstring>
+ </property>
+
<property name="ActiveConnections" type="ao" access="read">
<tp:docstring>
List of active connection object paths.
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 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
+ <interface name="org.freedesktop.NetworkManager.WiMax.Nsp">
+
+ <property name="Name" type="s" access="read">
+ <tp:docstring>The name of the NSP.</tp:docstring>
+ </property>
+ <property name="SignalQuality" type="u" access="read">
+ <tp:docstring>The current signal quality of the NSP, in percent.</tp:docstring>
+ </property>
+ <property name="NetworkType" type="u" access="read" tp:type="NM_WIMAX_NSP_NETWORK_TYPE">
+ <tp:docstring>The network type of the NSP.</tp:docstring>
+ </property>
+
+ <signal name="PropertiesChanged">
+ <arg name="properties" type="a{sv}" tp:type="String_Variant_Map">
+ <tp:docstring>
+ A dictionary mapping property names to variant boxed values.
+ </tp:docstring>
+ </arg>
+ </signal>
+
+ <tp:flags name="NM_WIMAX_NSP_NETWORK_TYPE" value-prefix="NM_WIMAX_NSP_NETWORK_TYPE" type="u">
+ <tp:docstring>
+ Network type of the NSP.
+ </tp:docstring>
+ <tp:flag suffix="UNKNOWN" value="0x0">
+ <tp:docstring>Unknown network.</tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="HOME" value="0x1">
+ <tp:docstring>Home network.</tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="PARTNER" value="0x2">
+ <tp:docstring>Partner network.</tp:docstring>
+ </tp:flag>
+ <tp:flag suffix="ROAMING_PARTNER" value="0x3">
+ <tp:docstring>Roaming partner network.</tp:docstring>
+ </tp:flag>
+
+ </tp:flags>
+
+ </interface>
+</node>
diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am
index 55c994adf0..bedc9805b6 100644
--- a/libnm-glib/Makefile.am
+++ b/libnm-glib/Makefile.am
@@ -13,6 +13,7 @@ BUILT_SOURCES = \
nm-device-wifi-bindings.h \
nm-device-bt-bindings.h \
nm-sysconfig-connection-bindings.h \
+ nm-device-wimax-bindings.h \
nm-settings-bindings.h \
nm-vpn-connection-bindings.h \
nm-vpn-plugin-glue.h \
@@ -55,7 +56,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
@@ -83,7 +83,9 @@ libnminclude_HEADERS = \
nm-dhcp6-config.h \
nm-remote-connection.h \
nm-remote-settings.h \
- nm-secret-agent.h
+ nm-secret-agent.h \
+ nm-device-wimax.h \
+ nm-wimax-nsp.h
libnm_glib_la_SOURCES = \
nm-object.c \
@@ -113,7 +115,9 @@ libnm_glib_la_SOURCES = \
nm-remote-connection.c \
nm-remote-connection-private.h \
nm-remote-settings.c \
- nm-secret-agent.c
+ nm-secret-agent.c \
+ nm-device-wimax.c \
+ nm-wimax-nsp.c
libnm_glib_la_LIBADD = \
$(top_builddir)/libnm-util/libnm-util.la \
@@ -121,7 +125,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 \
@@ -211,6 +214,9 @@ nm-dhcp6-config-bindings.h: $(top_srcdir)/introspection/nm-dhcp6-config.xml
nm-secret-agent-glue.h: $(top_srcdir)/introspection/nm-secret-agent.xml
$(AM_V_GEN) dbus-binding-tool --prefix=nm_secret_agent --mode=glib-server --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 1ac3bdb5c4..6a6cea4c28 100644
--- a/libnm-glib/libnm-glib.ver
+++ b/libnm-glib/libnm-glib.ver
@@ -45,6 +45,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;
@@ -93,6 +96,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_gsm_device_get_type;
nm_gsm_device_new;
nm_ip4_config_get_addresses;
@@ -142,6 +149,22 @@ 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;
+ 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-client.c b/libnm-glib/nm-client.c
index 32a6c972d8..b00f65b692 100644
--- a/libnm-glib/nm-client.c
+++ b/libnm-glib/nm-client.c
@@ -68,6 +68,9 @@ typedef struct {
gboolean wwan_enabled;
gboolean wwan_hw_enabled;
+
+ gboolean wimax_enabled;
+ gboolean wimax_hw_enabled;
} NMClientPrivate;
enum {
@@ -79,6 +82,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
@@ -214,6 +219,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)
{
@@ -281,6 +316,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 },
};
@@ -293,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_SLEEP_WAKE "org.freedesktop.NetworkManager.sleep-wake"
#define NM_AUTH_PERMISSION_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control"
#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected"
@@ -309,6 +347,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_SLEEP_WAKE))
return NM_CLIENT_PERMISSION_SLEEP_WAKE;
else if (!strcmp (nm, NM_AUTH_PERMISSION_NETWORK_CONTROL))
@@ -505,6 +545,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));
}
@@ -586,6 +627,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;
@@ -623,6 +678,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;
@@ -739,6 +800,32 @@ nm_client_class_init (NMClientClass *client_class)
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:
*
* The active connections.
@@ -869,10 +956,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);
}
}
@@ -1299,6 +1389,61 @@ nm_client_wwan_hardware_get_enabled (NMClient *client)
}
/**
+ * 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 b28afd8c36..eae04c5d2c 100644
--- a/libnm-glib/nm-client.h
+++ b/libnm-glib/nm-client.h
@@ -48,6 +48,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"
/* Permissions */
@@ -62,8 +64,9 @@ typedef enum {
NM_CLIENT_PERMISSION_WIFI_SHARE_OPEN = 7,
NM_CLIENT_PERMISSION_SETTINGS_CONNECTION_MODIFY = 8,
NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY = 9,
+ NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX = 10,
- NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_SETTINGS_HOSTNAME_MODIFY
+ NM_CLIENT_PERMISSION_LAST = NM_CLIENT_PERMISSION_ENABLE_DISABLE_WIMAX
} NMClientPermission;
typedef enum {
@@ -140,6 +143,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/libnm-glib/nm-device-wimax.c b/libnm-glib/nm-device-wimax.c
new file mode 100644
index 0000000000..bdab0eb743
--- /dev/null
+++ b/libnm-glib/nm-device-wimax.c
@@ -0,0 +1,853 @@
+/* -*- 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.
+ */
+
+#include <string.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-device-wimax-bindings.h"
+
+G_DEFINE_TYPE (NMDeviceWimax, nm_device_wimax, NM_TYPE_DEVICE)
+
+#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_device_wimax_set_wireless_enabled (NMDeviceWimax *wimax, gboolean enabled);
+
+typedef struct {
+ gboolean disposed;
+ DBusGProxy *proxy;
+
+ char *hw_address;
+ 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_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,
+ NSP_REMOVED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/**
+ * nm_device_wimax_new:
+ * @connection: the #DBusGConnection
+ * @path: the DBus object path of the wimax
+ *
+ * Creates a new #NMDeviceWimax.
+ *
+ * Returns: a new wimax
+ **/
+GObject *
+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_DEVICE_WIMAX,
+ NM_OBJECT_DBUS_CONNECTION, connection,
+ NM_OBJECT_DBUS_PATH, path,
+ NULL);
+}
+
+/**
+ * nm_device_wimax_get_hw_address:
+ * @device: a #NMDeviceWimax
+ *
+ * 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_device_wimax_get_hw_address (NMDeviceWimax *wimax)
+{
+ NMDeviceWimaxPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL);
+
+ 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_DEVICE_WIMAX,
+ DBUS_PROP_HW_ADDRESS);
+ }
+
+ return priv->hw_address;
+}
+
+/**
+ * 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_device_wimax_get_active_nsp (NMDeviceWimax *wimax)
+{
+ NMDeviceWimaxPrivate *priv;
+ NMDeviceState state;
+ char *path;
+ GValue value = { 0, };
+
+ g_return_val_if_fail (NM_IS_DEVICE_WIMAX (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_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_DEVICE_WIMAX,
+ 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_device_wimax_get_nsps:
+ * @wimax: a #NMDeviceWimax
+ *
+ * Gets all the scanned NSPs of the #NMDeviceWimax.
+ *
+ * Returns: a #GPtrArray containing all the scanned #NMWimaxNsp<!-- -->s.
+ * The returned array is owned by the client and should not be modified.
+ **/
+const GPtrArray *
+nm_device_wimax_get_nsps (NMDeviceWimax *wimax)
+{
+ NMDeviceWimaxPrivate *priv;
+ DBusGConnection *connection;
+ GValue value = { 0, };
+ GError *error = NULL;
+ GPtrArray *temp;
+
+ g_return_val_if_fail (NM_IS_DEVICE_WIMAX (wimax), NULL);
+
+ priv = NM_DEVICE_WIMAX_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_device_wimax_get_nsp_by_path:
+ * @wimax: a #NMDeviceWimax
+ * @path: the object path of the NSP
+ *
+ * Gets a #NMWimaxNsp by path.
+ *
+ * Returns: the access point or %NULL if none is found.
+ **/
+NMWimaxNsp *
+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_DEVICE_WIMAX (wimax), NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ nsps = nm_device_wimax_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)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (user_data);
+ NMDeviceWimaxPrivate *priv;
+ GObject *nsp;
+
+ g_return_if_fail (self != NULL);
+
+ 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_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));
+ } 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)
+{
+ 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_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_DEVICE_WIMAX_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 (NMDeviceWimax *self, gboolean notify)
+{
+ NMDeviceWimaxPrivate *priv;
+
+ g_return_if_fail (NM_IS_DEVICE_WIMAX (self));
+
+ priv = NM_DEVICE_WIMAX_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;
+ }
+}
+
+/**
+ * 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
+nm_device_wimax_init (NMDeviceWimax *wimax)
+{
+}
+
+static void
+get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (object);
+
+ switch (prop_id) {
+ case PROP_HW_ADDRESS:
+ g_value_set_string (value, nm_device_wimax_get_hw_address (self));
+ break;
+ 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;
+
+ state = nm_device_get_state (device);
+ switch (state) {
+ 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_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;
+ }
+}
+
+static gboolean
+demarshal_active_nsp (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_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_DEVICE_WIMAX_ACTIVE_NSP);
+ return TRUE;
+}
+
+static void
+register_for_property_changed (NMDeviceWimax *wimax)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (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 },
+ };
+
+ _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;
+ NMDeviceWimaxPrivate *priv;
+
+ object = G_OBJECT_CLASS (nm_device_wimax_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+ if (!object)
+ return NULL;
+
+ 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_DEVICE_WIMAX);
+
+ 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_DEVICE_WIMAX (object));
+
+ g_signal_connect (object,
+ "notify::" NM_DEVICE_STATE,
+ G_CALLBACK (state_changed_cb),
+ NULL);
+
+ return object;
+}
+
+static void
+dispose (GObject *object)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (object);
+
+ if (priv->disposed) {
+ G_OBJECT_CLASS (nm_device_wimax_parent_class)->dispose (object);
+ return;
+ }
+
+ 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
+nm_device_wimax_class_init (NMDeviceWimaxClass *wimax_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (wimax_class);
+
+ g_type_class_add_private (wimax_class, sizeof (NMDeviceWimaxPrivate));
+
+ /* virtual methods */
+ object_class->constructor = constructor;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ /* 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:
+ *
+ * The active #NMWimaxNsp of the device.
+ **/
+ g_object_class_install_property
+ (object_class, PROP_ACTIVE_NSP,
+ g_param_spec_object (NM_DEVICE_WIMAX_ACTIVE_NSP,
+ "Active NSP",
+ "Active NSP",
+ 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 */
+
+ /**
+ * NMDeviceWimax::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 (NMDeviceWimaxClass, nsp_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+
+ /**
+ * NMDeviceWimax::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 (NMDeviceWimaxClass, nsp_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ G_TYPE_OBJECT);
+}
diff --git a/libnm-glib/nm-device-wimax.h b/libnm-glib/nm-device-wimax.h
new file mode 100644
index 0000000000..5e19bbaf95
--- /dev/null
+++ b/libnm-glib/nm-device-wimax.h
@@ -0,0 +1,79 @@
+/* -*- 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"
+#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;
+} 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);
+
+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/libnm-glib/nm-device.c b/libnm-glib/nm-device.c
index ea2a91d1ce..b494749ada 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-device-wimax.h"
#include "nm-device.h"
#include "nm-device-private.h"
#include "nm-object-private.h"
@@ -477,6 +478,20 @@ nm_device_class_init (NMDeviceClass *device_class)
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:
*
* The Unique Device Identifier of the device.
@@ -710,6 +725,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_DEVICE_WIMAX;
+ break;
default:
g_warning ("Unknown device type %d", g_value_get_uint (&value));
break;
diff --git a/libnm-glib/nm-wimax-nsp.c b/libnm-glib/nm-wimax-nsp.c
new file mode 100644
index 0000000000..eebdbaaac9
--- /dev/null
+++ b/libnm-glib/nm-wimax-nsp.c
@@ -0,0 +1,303 @@
+/* -*- 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 <string.h>
+
+#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;
+ guint32 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
+ **/
+guint32
+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_uint_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_uint (NM_WIMAX_NSP_SIGNAL_QUALITY,
+ "Signal Quality",
+ "Signal Quality",
+ 0, 100, 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..5507b75295
--- /dev/null
+++ b/libnm-glib/nm-wimax-nsp.h
@@ -0,0 +1,78 @@
+/* -*- 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_WIMAX_NSP_H
+#define NM_WIMAX_NSP_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <NetworkManager.h>
+#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);
+guint32 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-glib/tests/Makefile.am b/libnm-glib/tests/Makefile.am
index a22a2d35dc..06aee71252 100644
--- a/libnm-glib/tests/Makefile.am
+++ b/libnm-glib/tests/Makefile.am
@@ -11,7 +11,6 @@ test_remote_settings_client_SOURCES = \
test-remote-settings-client.c
test_remote_settings_client_CPPFLAGS = \
- -DSERVICEDIR=\"$(builddir)\" \
$(GLIB_CFLAGS) \
$(DBUS_CFLAGS)
@@ -23,12 +22,14 @@ test_remote_settings_client_LDADD = \
###########################################
-EXTRA_DIST = test-remote-settings-service.py
+TEST_RSS_BIN = test-remote-settings-service.py
+
+EXTRA_DIST = $(TEST_RSS_BIN)
if WITH_TESTS
check-local: test-remote-settings-client
- $(abs_builddir)/test-remote-settings-client
+ $(abs_builddir)/test-remote-settings-client $(abs_srcdir) $(TEST_RSS_BIN)
endif
diff --git a/libnm-glib/tests/test-remote-settings-client.c b/libnm-glib/tests/test-remote-settings-client.c
index 3285735735..619b86d8de 100644
--- a/libnm-glib/tests/test-remote-settings-client.c
+++ b/libnm-glib/tests/test-remote-settings-client.c
@@ -34,8 +34,6 @@
#include "nm-remote-settings.h"
-#define SERVICE_FILE "test-remote-settings-service.py"
-
static GPid spid = 0;
static NMRemoteSettings *settings = NULL;
@@ -209,12 +207,14 @@ typedef void (*TCFunc)(void);
int main (int argc, char **argv)
{
GTestSuite *suite;
- char *service_argv[3] = { SERVICEDIR "/" SERVICE_FILE, SERVICE_FILE, NULL };
+ char *service_argv[3] = { NULL, NULL, NULL };
int ret;
GError *error = NULL;
DBusGConnection *bus;
int i = 100;
+ g_assert (argc == 3);
+
g_type_init ();
g_test_init (&argc, &argv, NULL);
@@ -225,8 +225,9 @@ int main (int argc, char **argv)
g_assert (error == NULL);
}
- if (!g_spawn_async (SERVICEDIR, service_argv, NULL, 0, NULL, NULL, &spid, &error)) {
- g_warning ("Error spawning " SERVICE_FILE ": %s", error->message);
+ service_argv[0] = g_strdup_printf ("%s/%s", argv[1], argv[2]);
+ if (!g_spawn_async (argv[1], service_argv, NULL, 0, NULL, NULL, &spid, &error)) {
+ g_warning ("Error spawning %s: %s", argv[2], error->message);
g_assert (error == NULL);
}
diff --git a/libnm-util/Makefile.am b/libnm-util/Makefile.am
index f43fb60242..fdadc7517f 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 8eaaad6b2c..2a8181beeb 100644
--- a/libnm-util/libnm-util.ver
+++ b/libnm-util/libnm-util.ver
@@ -280,6 +280,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 105dcbe144..3aa10c6a04 100644
--- a/libnm-util/nm-connection.c
+++ b/libnm-util/nm-connection.c
@@ -38,6 +38,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"
@@ -132,7 +133,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;
@@ -228,6 +229,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 <net/ethernet.h>
+#include <dbus/dbus-glib.h>
+#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 <nm-setting.h>
+
+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/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, " (");
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;
}
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
diff --git a/man/NetworkManager.conf.5.in b/man/NetworkManager.conf.5.in
index 0f061ea048..20a8e3ad9b 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:<hwaddr>\fP;\fImac:<hwaddr>\fP;...
Set devices that should be ignored by NetworkManager when using the \fIkeyfile\fP
plugin. Devices are specified in the following format: "mac:<hwaddr>", where
-<hwaddr> is MAC address of the device to be ignored, in lowercase. Multiple
-entries are separated by a semicolon. Example:
+<hwaddr> 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.
@@ -160,11 +162,11 @@ warning messages.
.B domains=\fI<domain1>,<domain2>, ...\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, SETTINGS, SUSPEND, CORE, DEVICE, OLPC]. When "NONE" is given by itself,
-logging is disabled. MB = Mobile Broadband, AGENTS = secret agents operations
-and communication, SETTINGS = settings/config service operations, OLPC = OLPC
-Mesh device operations, CORE = core daemon operations, DEVICE = activation and
-general interface operations.
+AGENTS, SETTINGS, SUSPEND, CORE, DEVICE, OLPC, WIMAX]. When "NONE" is given by
+itself, logging is disabled. MB = Mobile Broadband, AGENTS = secret agents
+operations and communication, SETTINGS = settings/config 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/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/POTFILES.in b/po/POTFILES.in
index d4d8c4b1e6..94bb473ed7 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -15,9 +15,15 @@ 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
+src/logging/nm-logging.c
+src/modem-manager/nm-modem-cdma.c
+src/modem-manager/nm-modem-gsm.c
+src/nm-device-bt.c
+src/nm-device-ethernet.c
+src/nm-device-olpc-mesh.c
src/settings/nm-default-wired-connection.c
system-settings/plugins/ifcfg-rh/reader.c
system-settings/plugins/ifnet/connection_parser.c
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 <lbm@fatalerror.dk>\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 <anders@jenbo.dk>\n"
"Language-Team: Danish <dansk@dansk-gruppen.dk>\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"
-
-#: ../gnome/vpn-properties/nm-vpn-properties.c:417
-msgid "Cannot add VPN connection"
-msgstr "Kan ikke tilføje VPN-forbindelse"
-
-#: ../gnome/vpn-properties/nm-vpn-properties.c:419
+"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"
+
+#: ../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"
+
+#. 0
+#: ../cli/src/connections.c:61
+#: ../cli/src/connections.c:77
+msgid "UUID"
+msgstr "UUID"
+
+#. 1
+#: ../cli/src/connections.c:62
+msgid "DEVICES"
+msgstr "ENHEDER"
+
+#. 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 ""
-"No suitable VPN software was found on your system. Contact your system "
-"administrator."
+"Usage: nmcli con { COMMAND | help }\n"
+" COMMAND := { list | status | up | down }\n"
+"\n"
+" list [id <id> | uuid <id> | system | user]\n"
+" status\n"
+" up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [--nowait] [--timeout <timeout>]\n"
+" down id <id> | uuid <id>\n"
msgstr ""
-"Ingen passende VPN-programmel blev fundet på dit system. Kontakt din system-"
-"administrator."
+"Brug: nmcli con { KOMMANDO | help }\n"
+" KOMMANDO := { list | status | up | down }\n"
+"\n"
+" list [id <id> | uuid <id> | system | user]\n"
+" status\n"
+" up id <id> | uuid <id> [iface <iface>] [ap <hwadr>] [--nowait] [--timeout <tidsudløb>]\n"
+" down id <id> | uuid <id>\n"
+
+#: ../cli/src/connections.c:200
+#: ../cli/src/connections.c:541
+#, c-format
+msgid "Error: 'con list': %s"
+msgstr "Fejl: 'con list': %s"
-#: ../gnome/vpn-properties/nm-vpn-properties.c:461
-msgid "Cannot import VPN connection"
-msgstr "Kan ikke importere VPN-forbindelse"
+#: ../cli/src/connections.c:202
+#: ../cli/src/connections.c:543
+#, c-format
+msgid "Error: 'con list': %s; allowed fields: %s"
+msgstr "Fejl: 'con list': %s; tilladte felter: %s"
+
+#: ../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 "Error: %s argument is missing."
+msgstr "Fejl: %s parameter mangler."
-#: ../gnome/vpn-properties/nm-vpn-properties.c:463
+#: ../cli/src/connections.c:492
#, c-format
-msgid ""
-"Cannot find suitable software for VPN connection type '%s' to import the "
-"file '%s'. Contact your system administrator."
-msgstr ""
-"Kan ikke finde passende programmel til VPN-forbindelsestypen '%s', til "
-"import af filen '%s'. Kontakt din system-administrator."
+msgid "Error: %s - no such connection."
+msgstr "Fejl: %s - ingen sådan forbindelse."
+
+#: ../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:580
+#: ../cli/src/connections.c:533
#, c-format
-msgid "Error retrieving VPN connection '%s'"
-msgstr "Fejl ved hentning af VPN-forbindelsen '%s'"
+msgid "Error: no valid parameter specified."
+msgstr "Fejl: ingen korrekte parameter angivet."
-#: ../gnome/vpn-properties/nm-vpn-properties.c:583
+#: ../cli/src/connections.c:548
+#: ../cli/src/connections.c:1584
+#: ../cli/src/devices.c:1295
+#: ../cli/src/network-manager.c:359
#, 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: %s."
+msgstr "Fejl: %s."
-#: ../gnome/vpn-properties/nm-vpn-properties.c:727
+#: ../cli/src/connections.c:655
#, c-format
-msgid "Delete VPN connection \"%s\"?"
-msgstr "Slet VPN-forbindelsen \"%s\"?"
+msgid "Error: 'con status': %s"
+msgstr "Fejl: 'con status': %s"
-#: ../gnome/vpn-properties/nm-vpn-properties.c:730
+#: ../cli/src/connections.c:657
#, 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."
-
-#: ../gnome/vpn-properties/nm-vpn-properties.c:924
-msgid "Unable to load"
-msgstr "Kan ikke indlæse"
-
-#: ../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)!"
-
-#. 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"
-
-#. 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"
-
-#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:1
-msgid "Add a new VPN connection"
-msgstr "Tilføj ny VPN-forbindelse"
-
-#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:2
-msgid "Delete the selected VPN connection"
-msgstr "Slet den valgte VPN-forbindelse"
-
-#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:3
-msgid "E_xport"
-msgstr "E_ksportér"
-
-#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:4
-msgid "Edit the selected VPN connection"
-msgstr "Redigér den valgte VPN-forbindelse"
-
-#: ../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"
-
-#: ../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"
-
-#: ../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)"
-
-#: ../gnome/vpn-properties/nm-vpn-properties.glade.h:8
-msgid "VPN Connections"
-msgstr "VPN-forbindelser"
-
-#: ../src/nm-ap-security-wep.c:52
-msgid "40-bit WEP"
-msgstr "40-bit WEP"
-
-#: ../src/nm-ap-security-wep.c:54
-msgid "104-bit WEP"
-msgstr "104-bit WEP"
-
-#: ../src/nm-ap-security-wpa-psk.c:51
-msgid "WPA TKIP"
-msgstr "WPA TKIP"
-
-#: ../src/nm-ap-security-wpa-psk.c:53
-msgid "WPA CCMP"
-msgstr "WPA CCMP"
-
-#: ../src/nm-ap-security-wpa-psk.c:55
-msgid "WPA Automatic"
-msgstr "WPA automatisk"
-
-#: ../src/nm-ap-security-wpa-psk.c:60
-msgid "WPA2 TKIP"
-msgstr "WPA2 TKIP"
-
-#: ../src/nm-ap-security-wpa-psk.c:62
-msgid "WPA2 CCMP"
-msgstr "WPA2 CCMP"
-
-#: ../src/nm-ap-security-wpa-psk.c:64
-msgid "WPA2 Automatic"
-msgstr "WPA2 automatisk"
-
-#: ../src/nm-ap-security.c:334
+msgid "Error: 'con status': %s; allowed fields: %s"
+msgstr "Fejl: 'con status': %s; tilladte fejlter: %s"
+
+#: ../cli/src/connections.c:664
+msgid "Active connections"
+msgstr "Aktive forbindelser"
+
+#: ../cli/src/connections.c:1034
+#, c-format
+msgid "no active connection on device '%s'"
+msgstr "ingen aktiv forbindelse på enhed '%s'"
+
+#: ../cli/src/connections.c:1042
+#, c-format
+msgid "no active connection or device"
+msgstr "ingen aktiv forbindelse eller enhed"
+
+#: ../cli/src/connections.c:1092
+#, c-format
+msgid "device '%s' not compatible with connection '%s'"
+msgstr "enhed \"%s\" er ikke kompatibel med forbindelse \"%s\""
+
+#: ../cli/src/connections.c:1094
+#, c-format
+msgid "no device found for connection '%s'"
+msgstr "ingen enhed fundet til forbindelsen '%s'"
+
+#: ../cli/src/connections.c:1105
+msgid "activating"
+msgstr "aktiverer"
+
+#: ../cli/src/connections.c:1107
+msgid "activated"
+msgstr "aktiveret"
+
+#: ../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"
+
+#: ../cli/src/connections.c:1119
+msgid "VPN connecting (prepare)"
+msgstr "VPN-forbinder (forbered)"
+
+#: ../cli/src/connections.c:1121
+msgid "VPN connecting (need authentication)"
+msgstr "VPN-forbinder (kræver godkendelse)"
+
+#: ../cli/src/connections.c:1123
+msgid "VPN connecting"
+msgstr "VPN-forbinder"
+
+#: ../cli/src/connections.c:1125
+msgid "VPN connecting (getting IP configuration)"
+msgstr "VPN-forbinder (indhenter IP-konfiguration)"
+
+#: ../cli/src/connections.c:1127
+msgid "VPN connected"
+msgstr "VPN-forbundet"
+
+#: ../cli/src/connections.c:1129
+msgid "VPN connection failed"
+msgstr "VPN-forbindelse fejlede"
+
+#: ../cli/src/connections.c:1131
+msgid "VPN disconnected"
+msgstr "VPN afbrudt"
+
+#: ../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 <iface>]\n"
+" disconnect iface <iface> [--nowait] [--timeout <timeout>]\n"
+" wifi [list [iface <iface>] [hwaddr <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 <iface>]\n"
+" disconnect iface <iface> [--nowait] [--timeout <tidsudløb>]\n"
+" wifi [list [iface <iface>] [hwaddr <hwadr>]]\n"
+"\n"
+
+#: ../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"
-#: ../src/nm-netlink-monitor.c:192
+#: ../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"
+
+#: ../cli/src/network-manager.c:85
+msgid "asleep"
+msgstr "sover"
+
+#: ../cli/src/network-manager.c:87
+msgid "connecting"
+msgstr "forbinder"
+
+#: ../cli/src/network-manager.c:128
+#, c-format
+msgid "Error: 'nm status': %s"
+msgstr "Fejl: 'nm status': %s"
-#: ../src/nm-netlink-monitor.c:427
-msgid "operation took too long"
-msgstr "handlingen overskred tidsgrænsen"
+#: ../cli/src/network-manager.c:130
+#, c-format
+msgid "Error: 'nm status': %s; allowed fields: %s"
+msgstr "Fejl: 'nm status': %s; tilladte felter: %s"
+
+#: ../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"
-#: ../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:186
+#, c-format
+msgid "Error: Couldn't create D-Bus object proxy."
+msgstr "Fejl: Kunne ikke oprette proxy-objekt for D-Bus."
-#: ../src/nm-netlink-monitor.c:537
-msgid "received data from unexpected sender"
-msgstr "modtog data fra uventet afsender"
+#: ../cli/src/network-manager.c:192
+#, c-format
+msgid "Error in sleep: %s"
+msgstr "Fejl ved søvn: %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: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"
-#: ../src/nm-netlink-monitor.c:774
-msgid "error occurred while waiting for data on socket"
-msgstr "der opstod en fejl mens der blev ventet på data på sokkelen"
+#: ../cli/src/network-manager.c:245
+msgid "Networking enabled"
+msgstr "Netværk aktiveret"
-#: ../src/nm-ap-security-wpa-eap.c:93 ../src/nm-ap-security-wpa-eap.c:117
-msgid "WPA2 Enterprise"
-msgstr "WPA2 i virksomhed"
+#: ../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'."
-#: ../src/nm-ap-security-wpa-eap.c:95 ../src/nm-ap-security-wpa-eap.c:122
-msgid "WPA Enterprise"
-msgstr "WPA i virksomhed"
+#: ../cli/src/network-manager.c:265
+#, c-format
+msgid "Error: Sleeping status is not exported by NetworkManager."
+msgstr "Fejl: NetworkManager eksporterer ikke søvnstatus."
-#: ../src/nm-ap-security-leap.c:66 ../src/nm-ap-security-leap.c:82
-msgid "LEAP"
-msgstr "LEAP"
+#: ../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'."
-#~ msgid "Passphrase for wireless network %s"
-#~ msgstr "Adgangskode til trådløst netværk %s"
+#: ../cli/src/network-manager.c:294
+msgid "WiFi enabled"
+msgstr "WiFi aktiveret"
-#~ msgid "Connection to the wireless network '%s' failed."
-#~ msgstr "Tilslutning til det trådløse netværk '%s' mislykkedes."
+#: ../cli/src/network-manager.c:305
+#, c-format
+msgid "Error: invalid 'wifi' parameter: '%s'."
+msgstr "Fejl: Ugyldig 'wifi'-parameter: '%s'."
-#~ msgid "Connection to the wired network failed."
-#~ msgstr "Tilslutning til det kablede netværk mislykkedes."
+#: ../cli/src/network-manager.c:326
+msgid "WWAN enabled"
+msgstr "WWAN aktiveret"
-#~ msgid "Error displaying connection information: "
-#~ msgstr "Fejl ved visning af forbindelses-information: "
+#: ../cli/src/network-manager.c:337
+#, c-format
+msgid "Error: invalid 'wwan' parameter: '%s'."
+msgstr "Fejl: Ugyldig 'wwan'-parameter: '%s'."
-#~ msgid "Could not find some required resources (the glade file)!"
-#~ msgstr "Kunne ikke finde nogle krævede ressourcer (glade-filen)!"
+#: ../cli/src/network-manager.c:348
+#, c-format
+msgid "Error: 'nm' command '%s' is not valid."
+msgstr "Fejl: 'nm'-kommando '%s' er ikke gyldig."
-#~ msgid "No active connections!"
-#~ msgstr "Ingen aktive forbindelser!"
+#: ../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] <field1,field2,...>|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] <felt1,felt2,...>|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'."
-#~ msgid "Wired Ethernet (%s)"
-#~ msgstr "Kablet Ethernet (%s)"
+#: ../cli/src/nmcli.c:143
+#, c-format
+msgid "Error: Option '--terse' is specified the second time."
+msgstr "Fejl: Tilvalg '--terse' er angivet anden gang."
-#~ msgid "Wireless Ethernet (%s)"
-#~ msgstr "Trådløst Ethernet (%s)"
+#: ../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."
-#~ msgid "NetworkManager Applet"
-#~ msgstr "NetworkManager-panelprogram"
+#: ../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."
-#~ msgid "Copyright © 2004-2005 Red Hat, Inc."
-#~ msgstr "Copyright © 2004-2005 Red Hat, Inc."
+#: ../libnm-util/crypto_gnutls.c:49
+msgid "Failed to initialize the crypto engine."
+msgstr "Kunne ikke initialisere kryptomotor."
-#~ msgid ""
-#~ "Notification area applet for managing your network devices and "
-#~ "connections."
-#~ msgstr ""
-#~ "Statusfelt-panelprogram til håndtering af dine netværks-enheder og -"
-#~ "forbindelser."
+#: ../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."
-#~ msgid "translator-credits"
-#~ msgstr ""
-#~ "David Nielsen\n"
-#~ "Martin Willemoes Hansen\n"
-#~ "Lasse Bang Mikkelsen\n"
-#~ "\n"
-#~ "Dansk-gruppen <dansk@dansk-gruppen.dk>\n"
-#~ "Mere info: http://www.dansk-gruppen.dk"
+#: ../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)."
-#~ msgid "VPN Error"
-#~ msgstr "VPN fejl"
+#: ../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."
-#~ msgid "VPN Login Failure"
-#~ msgstr "VPN logind-fejl"
+#: ../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."
-#~ 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."
+#: ../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."
-#~ msgid "VPN Start Failure"
-#~ msgstr "VPN etablerings-fejl"
+#: ../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."
-#~ 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."
+#: ../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."
-#~ msgid "VPN Connect Failure"
-#~ msgstr "VPN tilslutnings-fejl"
+#: ../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."
-#~ 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."
+#: ../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."
-#~ msgid "VPN Configuration Error"
-#~ msgstr "VPN konfigurations-fejl"
+#: ../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."
-#~ msgid "The VPN connection '%s' was not correctly configured."
-#~ msgstr "VPN-forbindelsen '%s' er ikke konfigureret korrekt."
+#: ../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."
-#~ 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."
+#: ../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."
-#~ msgid "The VPN service said: \"%s\""
-#~ msgstr "VPN-tjenesten sagde: \"%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."
-#~ msgid "VPN connection '%s' said:"
-#~ msgstr "VPN-forbindelsen '%s' sagde:"
+#: ../libnm-util/crypto_gnutls.c:322
+#, c-format
+msgid "Failed to encrypt the data: %s / %s."
+msgstr "Kunne ikke kryptere data: %s / %s."
-#~ msgid "VPN Login Message"
-#~ msgstr "VPN logind-meddelelse"
+#: ../libnm-util/crypto_gnutls.c:362
+#, c-format
+msgid "Error initializing certificate data: %s"
+msgstr "Fejl under initialisering af certifikatdata: %s"
-#~ 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)."
+#: ../libnm-util/crypto_gnutls.c:384
+#, c-format
+msgid "Couldn't decode certificate: %s"
+msgstr "Kunne ikke afkode certifikat: %s"
-#~ msgid "The network device \"%s (%s)\" does not support wireless scanning."
-#~ msgstr "Netværks-enheden \"%s (%s)\" understøtter ikke trådløs scanning."
+#: ../libnm-util/crypto_gnutls.c:408
+#, c-format
+msgid "Couldn't initialize PKCS#12 decoder: %s"
+msgstr "Kunne ikke initialisere PKCS#12-afkoder: %s"
-#~ msgid "The network device \"%s (%s)\" does not support link detection."
-#~ msgstr "Netværks-enheden \"%s (%s)\" understøtter ikke link-detektering."
+#: ../libnm-util/crypto_gnutls.c:421
+#, c-format
+msgid "Couldn't decode PKCS#12 file: %s"
+msgstr "Kunne ikke afkode PKCS#12-fil: %s"
-#~ msgid "Preparing device %s for the wired network..."
-#~ msgstr "Klargører enheden %s til det kablede netværk..."
+#: ../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"
-#~ msgid "Preparing device %s for the wireless network '%s'..."
-#~ msgstr "Klargører enheden %s til det trådløse netværk '%s'..."
+#: ../libnm-util/crypto_nss.c:56
+#, c-format
+msgid "Failed to initialize the crypto engine: %d."
+msgstr "Kunne ikke initialisere kryptomotor: %d."
-#~ msgid "Configuring device %s for the wired network..."
-#~ msgstr "Konfigurerer enheden %s til det kablede netværk..."
+#: ../libnm-util/crypto_nss.c:111
+#, c-format
+msgid "Failed to initialize the MD5 context: %d."
+msgstr "Kunne ikke initialisere MD5-kontekst: %d."
-#~ msgid "Attempting to join the wireless network '%s'..."
-#~ msgstr "Forsøger at tilslutte til det trådløse netværk '%s'..."
+#: ../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)."
-#~ msgid "Waiting for Network Key for the wireless network '%s'..."
-#~ msgstr "Venter på netværksnøglen til det trådløse netværk '%s'..."
+#: ../libnm-util/crypto_nss.c:196
+#, c-format
+msgid "Failed to initialize the decryption cipher slot."
+msgstr "Kunne ikke initialisere cifferplads til dekryptering."
-#~ msgid "Requesting a network address from the wired network..."
-#~ msgstr "Forespørger en netværks-adresse fra det kablede netværk..."
+#: ../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."
-#~ 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'..."
+#: ../libnm-util/crypto_nss.c:216
+#, c-format
+msgid "Failed to set IV for decryption."
+msgstr "Kunne ikke sætte IV til dekryptering."
-#~ msgid "Finishing connection to the wired network..."
-#~ msgstr "Færdiggører tilslutning til det kablede netværk..."
+#: ../libnm-util/crypto_nss.c:224
+#, c-format
+msgid "Failed to initialize the decryption context."
+msgstr "Kunne ikke initialisere dekrypteringskonteksten."
-#~ msgid "Finishing connection to the wireless network '%s'..."
-#~ msgstr "Færdiggører tilslutning til det trådløse netværk '%s'..."
+#: ../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."
-#~ msgid "NetworkManager is not running"
-#~ msgstr "NetworkManager kører ikke"
+#: ../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."
-#~ msgid "Networking disabled"
-#~ msgstr "Netværks-understøttelse deaktiveret"
+#: ../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."
-#~ msgid "No network connection"
-#~ msgstr "Ingen netværks-forbindelse"
+#: ../libnm-util/crypto_nss.c:364
+#, c-format
+msgid "Failed to initialize the encryption cipher slot."
+msgstr "Kunne ikke initialisere cifferplads til kryptering."
-#~ msgid "Wired network connection"
-#~ msgstr "Kablet netværks-forbindelse"
+#: ../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."
-#~ msgid "Connected to an Ad-Hoc wireless network"
-#~ msgstr "Tilsluttet til et trådløst ad hoc netværk"
+#: ../libnm-util/crypto_nss.c:380
+#, c-format
+msgid "Failed to set IV for encryption."
+msgstr "Kunne ikke sætte IV til kryptering."
-#~ msgid "Wireless network connection to '%s' (%d%%)"
-#~ msgstr "Trådløs netværks-forbindelse til '%s' (%d%%)"
+#: ../libnm-util/crypto_nss.c:388
+#, c-format
+msgid "Failed to initialize the encryption context."
+msgstr "Kunne ikke initialisere krypteringskontekst."
-#~ msgid "VPN connection to '%s'"
-#~ msgstr "VPN-forbindelse til '%s'"
+#: ../libnm-util/crypto_nss.c:396
+#, c-format
+msgid "Failed to encrypt: %d."
+msgstr "Kunne ikke kryptere: %d."
-#~ msgid "VPN connecting to '%s'"
-#~ msgstr "VPN tilslutter til '%s'"
+#: ../libnm-util/crypto_nss.c:404
+#, c-format
+msgid "Unexpected amount of data after encrypting."
+msgstr "Uventet mængde af data efter kryptering."
-#~ msgid "_Connect to Other Wireless Network..."
-#~ msgstr "_Tilslut til andet trådløst netværk..."
+#: ../libnm-util/crypto_nss.c:447
+#, c-format
+msgid "Couldn't decode certificate: %d"
+msgstr "Kunne ikke afkode certifikat: %d"
-#~ msgid "Create _New Wireless Network..."
-#~ msgstr "Opret _nyt trådløst netværk..."
+#: ../libnm-util/crypto_nss.c:482
+#, c-format
+msgid "Couldn't convert password to UCS2: %d"
+msgstr "Kunne ikke konvertere adgangskode til UCS2: %d"
-#~ msgid "_VPN Connections"
-#~ msgstr "_VPN-forbindelser"
+#: ../libnm-util/crypto_nss.c:510
+#, c-format
+msgid "Couldn't initialize PKCS#12 decoder: %d"
+msgstr "Kunne ikke initialisere PKCS#12-afkoder: %d"
-#~ msgid "_Configure VPN..."
-#~ msgstr "_Konfigurér VPN..."
+#: ../libnm-util/crypto_nss.c:519
+#, c-format
+msgid "Couldn't decode PKCS#12 file: %d"
+msgstr "Kunne ikke afkode PKCS#12-fil: %d"
-#~ msgid "_Disconnect VPN..."
-#~ msgstr "_Afbryd VPN..."
+#: ../libnm-util/crypto_nss.c:528
+#, c-format
+msgid "Couldn't verify PKCS#12 file: %d"
+msgstr "Kunne ikke verificere PKCS#12-fil: %d"
-#~ msgid "_Dial Up Connections"
-#~ msgstr "_Opkalds-forbindelser"
+#: ../libnm-util/crypto_nss.c:557
+msgid "Could not generate random data."
+msgstr "Kunne ikke generere tilfældige data."
-#~ msgid "Connect to %s..."
-#~ msgstr "Tilslut til %s..."
+#: ../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."
-#~ msgid "Disconnect from %s..."
-#~ msgstr "Afbryd fra %s..."
+#: ../libnm-util/nm-utils.c:2085
+msgid "Could not allocate memory for PEM file creation."
+msgstr "Kunne ikke allokere hukommelse til PEM-filoprettelse."
-#~ msgid "No network devices have been found"
-#~ msgstr "Ingen netværks-enheder blev fundet"
+#: ../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."
-#~ msgid "NetworkManager is not running..."
-#~ msgstr "NetworkManager kører ikke..."
+#: ../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."
-#~ msgid "Enable _Networking"
-#~ msgstr "Aktivér _netværks-understøttelse"
+#: ../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."
-#~ msgid "Enable _Wireless"
-#~ msgstr "Aktivér _trådløst netværk"
+#: ../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"
-#~ msgid "Connection _Information"
-#~ msgstr "Forbindelses-_information"
+#: ../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"
-#~ msgid "_Help"
-#~ msgstr "_Hjælp"
+#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:3
+msgid "Modify persistent system hostname"
+msgstr "Ændr fast systemværtsnavn"
-#~ msgid "_About"
-#~ msgstr "_Om"
+#: ../policy/org.freedesktop.network-manager-settings.system.policy.in.h:4
+msgid "Modify system connections"
+msgstr "Ændr systemforbindelser"
-#~ 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"
+#: ../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"
-#~ msgid "Open System"
-#~ msgstr "Åbent system"
+#: ../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"
-#~ msgid "Shared Key"
-#~ msgstr "Delt nøgle"
+#: ../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"
-#~ msgid "TKIP (Default)"
-#~ msgstr "TKIP (forvalgt)"
+#: ../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"
-#~ msgid "AES-CCMP"
-#~ msgstr "AES-CCMP"
+#: ../policy/org.freedesktop.NetworkManager.policy.in.h:1
+msgid "Allow control of network connections"
+msgstr "Tillad kontrol af netværksforbindelser"
-#~ msgid "None"
-#~ msgstr "Ingen"
+#: ../policy/org.freedesktop.NetworkManager.policy.in.h:2
+msgid "Allow use of user-specific connections"
+msgstr "Tillad brug af brugerspecifikke forbindelser"
-#~ msgid "WEP 40/128-bit ASCII"
-#~ msgstr "WEP 40/128-bit ASCII"
+#: ../policy/org.freedesktop.NetworkManager.policy.in.h:3
+msgid "Enable or disable WiFi devices"
+msgstr "Aktiver eller deaktiver WiFi-enheder"
-#~ msgid "WEP 40/128-bit hex"
-#~ msgstr "WEP 40/128-bit hex"
+#: ../policy/org.freedesktop.NetworkManager.policy.in.h:4
+msgid "Enable or disable mobile broadband devices"
+msgstr "Aktiver eller deaktiver mobile bredbåndsenheder"
-#~ msgid "WEP Passphrase"
-#~ msgstr "WEP-adgangskode:"
+#: ../policy/org.freedesktop.NetworkManager.policy.in.h:5
+msgid "Enable or disable system networking"
+msgstr "Aktiver eller deaktiver systemnetværk"
-#~ msgid "Orientation"
-#~ msgstr "Retning"
+#: ../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)"
-#~ msgid "The orientation of the tray."
-#~ msgstr "Retningen på statusikonet."
+#: ../policy/org.freedesktop.NetworkManager.policy.in.h:7
+msgid "System policy prevents control of network connections"
+msgstr "Systempolitik forhindrer kontrol af netværksforbindelser"
-#~ msgid "Wired Network (%s)"
-#~ msgstr "Kablet netværk (%s)"
+#: ../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"
-#~ msgid "_Wired Network"
-#~ msgstr "_Kablet netværk"
+#: ../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"
-#~ 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 ""
-#~ "<span weight=\"bold\" size=\"larger\">Active Connection Information</span>"
-#~ msgstr ""
-#~ "<span weight=\"bold\" size=\"larger\">Information om aktiv forbindelse</"
-#~ "span>"
-
-#~ msgid ""
-#~ "<span weight=\"bold\" size=\"larger\">Passphrase Required by Wireless "
-#~ "Network</span>\n"
-#~ "\n"
-#~ "A passphrase or encryption key is required to access the wireless network "
-#~ "'%s'."
-#~ msgstr ""
-#~ "<span weight=\"bold\" size=\"larger\">Adgangskode påkrævet af trådløst "
-#~ "netværk</span>\n"
-#~ "\n"
-#~ "En adgangskode eller krypteringsnøgle er påkrævet, for at opnå adgang til "
-#~ "det trådløse netværk '%s'."
-
-#~ msgid ""
-#~ "<span weight=\"bold\" size=\"larger\">Reduced Network Functionality</"
-#~ "span>\n"
-#~ "\n"
-#~ "%s It will not be completely functional."
-#~ msgstr ""
-#~ "<span weight=\"bold\" size=\"larger\">Reduceret netværks-funktionalitet</"
-#~ "span>\n"
-#~ "\n"
-#~ "%s Den vil ikke være fuldstændig funktionsdygtig."
-
-#~ msgid ""
-#~ "<span weight=\"bold\" size=\"larger\">Wireless Network Login "
-#~ "Confirmation</span>\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 ""
-#~ "<span weight=\"bold\" size=\"larger\">Bekræftelse af logind på trådløst "
-#~ "netværk</span>\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:"
+#: ../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"
-#~ msgid "_Always Trust this Wireless Network"
-#~ msgstr "_Stol altid på dette trådløse netvæ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"
-#~ msgid "_Don't remind me again"
-#~ msgstr "_Påmind mig ikke igen"
+#: ../policy/org.freedesktop.NetworkManager.policy.in.h:12
+msgid "System policy prevents use of user-specific connections"
+msgstr "Systempolitik forhindrer brug af brugerspecifikke forbindelser"
-#~ msgid "_Login to Network"
-#~ msgstr "_Log på netværk"
+#: ../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"
-#~ msgid "_Network Name:"
-#~ msgstr "_Netværksnavn:"
+#: ../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å soklen"
-#~ msgid "_Wireless Security:"
-#~ msgstr "Trådløs sikkerhed:"
+#: ../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"
-#~ msgid "leap_subwindow"
-#~ msgstr "leap_subwindow"
+#: ../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"
-#~ msgid "wep_key_subwindow"
-#~ msgstr "wep_key_subwindow"
+#: ../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"
-#~ msgid "wep_passphrase_subwindow"
-#~ msgstr "wep_passphrase_subwindow"
+#: ../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"
-#~ msgid "wpa_psk_subwindow"
-#~ msgstr "wpa_psk_subwindow"
+#: ../src/nm-netlink-monitor.c:502
+#, c-format
+msgid "unable to join netlink group: %s"
+msgstr "kan ikke gå ind i netlink-gruppen: %s"
-#~ msgid "WPA2 Personal"
-#~ msgstr "Personlig WPA2"
+#: ../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"
-#~ msgid "WPA Personal"
-#~ msgstr "Personlig WPA"
+#: ../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"
-#~ msgid "Choose which type of VPN connection you wish to create."
-#~ msgstr "Vælg hvilken type VPN-forbindelse du ønsker at oprette."
+#: ../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"
-#~ msgid "Connect to:"
-#~ msgstr "Tilslut til:"
+#: ../src/dhcp-manager/nm-dhcp-dhclient.c:328
+msgid "# Created by NetworkManager\n"
+msgstr "# Oprettet af NetworkManager\n"
-#~ msgid "Create VPN Connection - 1 of 2"
-#~ msgstr "Opret VPN-forbindelse - 1 af 2"
+#: ../src/dhcp-manager/nm-dhcp-dhclient.c:344
+#, c-format
+msgid ""
+"# Merged from %s\n"
+"\n"
+msgstr ""
+"# Sammenflettet fra %s\n"
+"\n"
-#~ msgid "Create VPN Connection - 2 of 2"
-#~ msgstr "Opret VPN-forbindelse - 2 af 2"
+#: ../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"
-#~ msgid "Finish Creating VPN Connection"
-#~ msgstr "Færdiggør oprettelse af VPN-forbindelse"
+#: ../system-settings/plugins/ifcfg-rh/reader.c:3408
+#: ../system-settings/plugins/ifnet/connection_parser.c:49
+msgid "System"
+msgstr "System"
-#~ 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."
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 <kristjan.schmidt@googlemail.com>, 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 <kristjan.schmidt@googlemail.com>\n"
+"Language-Team: Esperanto <ubuntu-l10n-eo@lists.launchpad.net>\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 <id> | uuid <id> | system | user]\n"
+" status\n"
+" up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [--nowait] [--timeout "
+"<timeout>]\n"
+" down id <id> | uuid <id>\n"
+msgstr ""
+"Uzo: nmcli con { KOMANDO | help }\n"
+" KOMANDO := { list | status | up | down }\n"
+"\n"
+" list [id <id> | uuid <id> | system | user]\n"
+" status\n"
+" up id <id> | uuid <id> [iface <iface>] [ap <hwaddr>] [--nowait] [--timeout "
+"<timeout>]\n"
+" down id <id> | uuid <id>\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 <iface>]\n"
+" disconnect iface <iface> [--nowait] [--timeout <timeout>]\n"
+" wifi [list [iface <iface>] [hwaddr <hwaddr>]]\n"
+"\n"
+msgstr ""
+"Usage: nmcli dev { KOMANDO | help }\n"
+"\n"
+" KOMANDO := { status | list | disconnect | wifi }\n"
+"\n"
+" status\n"
+" list [iface <iface>]\n"
+" disconnect iface <iface> [--nowait] [--timeout <timeout>]\n"
+" wifi [list [iface <iface>] [hwaddr <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] <field1,field2,...>|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] <field1,field2,...>|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"
diff --git a/po/sv.po b/po/sv.po
index 590abfae02..eb8da2eafb 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 <po@danielnylander.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\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 <id> | uuid <id> [iface <gränssnitt>] [ap <hwaddr>] [--nowait] [--timeout <tidsgräns>]\n"
" down id <id> | uuid <id>\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 <iface>]\n"
-#| " disconnect iface <iface> [--nowait] [--timeout <timeout>]\n"
-#| " wifi [list [iface <iface>] | apinfo iface <iface> hwaddr <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"
diff --git a/policy/org.freedesktop.NetworkManager.policy.in b/policy/org.freedesktop.NetworkManager.policy.in
index af4b9a15b4..acdee8829c 100644
--- a/policy/org.freedesktop.NetworkManager.policy.in
+++ b/policy/org.freedesktop.NetworkManager.policy.in
@@ -45,6 +45,15 @@
</defaults>
</action>
+ <action id="org.freedesktop.NetworkManager.enable-disable-wimax">
+ <_description>Enable or disable WiMAX mobile broadband devices</_description>
+ <_message>System policy prevents enabling or disabling WiMAX mobile broadband devices</_message>
+ <defaults>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+
<action id="org.freedesktop.NetworkManager.network-control">
<_description>Allow control of network connections</_description>
<_message>System policy prevents control of network connections</_message>
diff --git a/src/Makefile.am b/src/Makefile.am
index 5f1b63c235..ce3c222c87 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,27 +10,34 @@ SUBDIRS= \
dnsmasq-manager \
modem-manager \
bluez-manager \
- settings \
- . \
- tests
+ 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/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
+
###########################################
# Test libraries
###########################################
@@ -254,6 +261,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 \
@@ -267,6 +280,7 @@ NetworkManager_LDADD = \
./modem-manager/libmodem-manager.la \
./bluez-manager/libbluez-manager.la \
./settings/libsettings.la \
+ $(WIMAX_LIBS) \
./backends/libnmbackend.la \
$(top_builddir)/libnm-util/libnm-util.la \
$(DBUS_LIBS) \
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 <stdio.h>
#include <string.h>
#include <stdlib.h>
+#include <gio/gio.h>
#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);
}
/*
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-client.c b/src/dhcp-manager/nm-dhcp-client.c
index 0c7f3d49b5..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);
@@ -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);
}
@@ -179,7 +183,7 @@ stop_process (GPid pid, const char *iface)
}
static void
-real_stop (NMDHCPClient *self)
+real_stop (NMDHCPClient *self, gboolean release)
{
NMDHCPClientPrivate *priv;
@@ -192,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;
}
@@ -372,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);
}
}
@@ -383,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;
@@ -394,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-utils.c b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
new file mode 100644
index 0000000000..cc5255ab59
--- /dev/null
+++ b/src/dhcp-manager/nm-dhcp-dhclient-utils.c
@@ -0,0 +1,217 @@
+/* -*- 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 <config.h>
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <string.h>
+#include <ctype.h>
+
+#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");
+ /* 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 */
+ 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 <glib.h>
+#include <glib-object.h>
+
+#include <nm-setting-ip4-config.h>
+
+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..75684459f6 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;
-
- 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);
+ 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_free (new_contents, TRUE);
return success;
}
@@ -494,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;
@@ -519,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);
+ if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) {
+ nm_log_warn (log_domain, "%s does not exist.", priv->path);
return -1;
}
- if (!g_file_test (priv->path, G_FILE_TEST_EXISTS)) {
- nm_log_warn (log_domain, "%s does not exist.", priv->path);
+ 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);
@@ -552,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);
@@ -584,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;
@@ -608,7 +541,7 @@ real_ip4_start (NMDHCPClient *client,
return -1;
}
- return dhclient_start (client, "-4", NULL);
+ return dhclient_start (client, NULL, FALSE);
}
static GPid
@@ -618,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 378a97b611..237661fe47 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 );
@@ -168,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/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..c1cd6f80c4
--- /dev/null
+++ b/src/dhcp-manager/tests/test-dhcp-dhclient.c
@@ -0,0 +1,249 @@
+/* -*- 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 <glib.h>
+#include <string.h>
+
+#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"
+ "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";
+
+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"
+ "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";
+
+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"
+ "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";
+
+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"
+ "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";
+
+static void
+test_existing_alsoreq (void)
+{
+ test_config (existing_alsoreq_orig, existing_alsoreq_expected,
+ NULL,
+ NULL,
+ "eth0",
+ NULL);
+}
+
+/*******************************************/
+
+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
+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));
+ g_test_suite_add (suite, TESTCASE (test_existing_multiline_alsoreq, NULL));
+
+ return g_test_run ();
+}
+
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-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)
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 <arpa/inet.h>
+#include <string.h>
+
+#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 */
+
diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c
index f6f6127ce7..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 */
@@ -285,7 +299,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;
}
@@ -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,13 +638,258 @@ 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;
uint16_t nd_opt_rdnss_reserved1;
uint32_t nd_opt_rdnss_lifetime;
/* 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)
+{
+ 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 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)
@@ -583,13 +897,8 @@ 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 +917,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 +926,19 @@ 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;
+ case ND_OPT_DNSSL:
+ changed = process_nduseropt_dnssl (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
@@ -1014,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;
}
diff --git a/src/logging/nm-logging.c b/src/logging/nm-logging.c
index 31a5ab3c78..2d62a3067a 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_AGENTS | \
- LOGD_SETTINGS | LOGD_SUSPEND | LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH;
+ LOGD_SETTINGS | 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 8f111e996b..3e8ef696ef 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)
diff --git a/src/main.c b/src/main.c
index bb67e41275..4e9fd6fd8e 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
@@ -306,6 +307,7 @@ parse_config_file (const char *filename,
GError **error)
{
GKeyFile *config;
+ gboolean success = FALSE;
config = g_key_file_new ();
if (!config) {
@@ -316,11 +318,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 +330,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
@@ -337,15 +342,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) {
@@ -384,6 +391,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)
@@ -426,6 +434,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;
@@ -445,7 +461,7 @@ main (int argc, char *argv[])
char *config = NULL, *plugins = NULL, *conf_plugins = NULL;
char *log_level = NULL, *log_domains = NULL;
char **dns = NULL;
- 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;
@@ -581,7 +597,7 @@ main (int argc, char *argv[])
g_free (conf_plugins);
/* 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)) {
fprintf (stderr, "State file %s parsing failed: (%d) %s\n",
state_file,
error ? error->code : -1,
@@ -686,6 +702,7 @@ main (int argc, char *argv[])
net_enabled,
wifi_enabled,
wwan_enabled,
+ wimax_enabled,
&error);
if (manager == NULL) {
nm_log_err (LOGD_CORE, "failed to initialize the network manager: %s",
@@ -721,6 +738,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/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c
index 5bba7030ba..1e8d7941d1 100644
--- a/src/modem-manager/nm-modem.c
+++ b/src/modem-manager/nm-modem.c
@@ -899,6 +899,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);
+ }
}
/*****************************************************************************/
diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c
index e38d58576b..90137b49ac 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;
diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c
index e0a05df95f..f9d0eb4462 100644
--- a/src/nm-device-olpc-mesh.c
+++ b/src/nm-device-olpc-mesh.c
@@ -696,7 +696,7 @@ dispose (GObject *object)
device_cleanup (self);
- manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL);
+ manager = nm_manager_get (NULL, 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);
@@ -895,7 +895,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, NULL, FALSE, FALSE, FALSE, NULL);
+ manager = nm_manager_get (NULL, 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;
@@ -950,7 +950,7 @@ check_companion_cb (gpointer user_data)
if (priv->device_added_id != 0)
return FALSE;
- manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, NULL);
+ manager = nm_manager_get (NULL, NULL, NULL, NULL, FALSE, FALSE, FALSE, FALSE, NULL);
priv->device_added_id = g_signal_connect (manager, "device-added",
G_CALLBACK (device_added_cb), self);
diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c
index a86890b917..4a9e50214a 100644
--- a/src/nm-device-wifi.c
+++ b/src/nm-device-wifi.c
@@ -166,9 +166,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);
@@ -179,17 +176,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_scan_request_result_cb (NMSupplicantInterface * iface,
- gboolean success,
- NMDeviceWifi * self);
+static void supplicant_iface_new_bss_cb (NMSupplicantInterface * iface,
+ GHashTable *properties,
+ 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,
@@ -308,6 +301,107 @@ ipw_rfkill_state_work (gpointer user_data)
/*****************************************************************/
/*
+ * 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
*
* Update the device's idea of the strength of its connection to the
@@ -655,26 +749,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;
@@ -1692,107 +1780,6 @@ nm_device_wifi_get_frequency (NMDeviceWifi *self)
}
/*
- * 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
*
* If a device is wireless, return the ssid that it is attempting
@@ -2101,28 +2088,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.
@@ -2130,6 +2108,7 @@ supplicant_iface_scan_results_cb (NMSupplicantInterface *iface,
cull_scan_list (self);
nm_device_wifi_ap_list_print (self);
}
+#endif
}
static gboolean
@@ -2349,48 +2328,10 @@ 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_scanned_ap_cb (NMSupplicantInterface *iface,
- GHashTable *properties,
- NMDeviceWifi *self)
+supplicant_iface_new_bss_cb (NMSupplicantInterface *iface,
+ GHashTable *properties,
+ NMDeviceWifi *self)
{
NMDeviceState state;
NMAccessPoint *ap;
@@ -2406,8 +2347,6 @@ supplicant_iface_scanned_ap_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 */
@@ -3253,7 +3192,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;
@@ -3701,12 +3640,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 {
diff --git a/src/nm-device.c b/src/nm-device.c
index 7c531c7bdb..c3e5c75b5a 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
@@ -1614,7 +1614,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))
@@ -1625,15 +1625,87 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data)
}
static NMActStageReturn
+dhcp4_start (NMDevice *self,
+ NMConnection *connection,
+ 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);
+
+ 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 ();
+
+ /* 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),
+ 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;
+}
+
+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)
{
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);
@@ -1646,9 +1718,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);
@@ -1657,42 +1726,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, 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);
@@ -2813,7 +2847,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);
@@ -2836,7 +2870,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;
@@ -2844,7 +2878,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);
@@ -2868,7 +2902,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;
@@ -2917,8 +2951,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);
@@ -3460,8 +3494,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 b96da33024..94c8510be3 100644
--- a/src/nm-device.h
+++ b/src/nm-device.h
@@ -192,6 +192,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/nm-manager-auth.h b/src/nm-manager-auth.h
index df686db440..26195bf069 100644
--- a/src/nm-manager-auth.h
+++ b/src/nm-manager-auth.h
@@ -33,6 +33,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_NETWORK_CONTROL "org.freedesktop.NetworkManager.network-control"
#define NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED "org.freedesktop.NetworkManager.wifi.share.protected"
#define NM_AUTH_PERMISSION_WIFI_SHARE_OPEN "org.freedesktop.NetworkManager.wifi.share.open"
diff --git a/src/nm-manager.c b/src/nm-manager.c
index 1067575532..c75b893320 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -38,6 +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"
@@ -266,6 +269,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 */
@@ -1390,6 +1395,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);
@@ -1705,6 +1716,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);
}
@@ -2633,6 +2652,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_NETWORK_CONTROL);
get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED);
get_perm_add_result (chain, results, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN);
@@ -2663,6 +2683,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_NETWORK_CONTROL, FALSE);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_PROTECTED, FALSE);
nm_auth_chain_add_call (chain, NM_AUTH_PERMISSION_WIFI_SHARE_OPEN, FALSE);
@@ -2919,6 +2940,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;
@@ -2978,6 +3002,7 @@ nm_manager_get (NMSettings *settings,
gboolean initial_net_enabled,
gboolean initial_wifi_enabled,
gboolean initial_wwan_enabled,
+ gboolean initial_wimax_enabled,
GError **error)
{
static NMManager *singleton = NULL;
@@ -3017,6 +3042,7 @@ nm_manager_get (NMSettings *settings,
priv->radio_states[RFKILL_TYPE_WLAN].user_enabled = initial_wifi_enabled;
priv->radio_states[RFKILL_TYPE_WWAN].user_enabled = initial_wwan_enabled;
+ priv->radio_states[RFKILL_TYPE_WIMAX].user_enabled = initial_wimax_enabled;
g_signal_connect (priv->settings, "notify::" NM_SETTINGS_UNMANAGED_SPECS,
G_CALLBACK (system_unmanaged_devices_changed_cb), singleton);
@@ -3112,10 +3138,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)
@@ -3204,6 +3231,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_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);
break;
@@ -3240,6 +3272,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, 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);
+ break;
case PROP_ACTIVE_CONNECTIONS:
g_value_take_boxed (value, get_active_connections (self, NULL));
break;
@@ -3307,8 +3345,8 @@ nm_manager_init (NMManager *manager)
priv->radio_states[RFKILL_TYPE_WIMAX].user_enabled = TRUE;
priv->radio_states[RFKILL_TYPE_WIMAX].key = "WiMAXEnabled";
- priv->radio_states[RFKILL_TYPE_WIMAX].prop = NULL;
- priv->radio_states[RFKILL_TYPE_WIMAX].hw_prop = NULL;
+ 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].rtype = RFKILL_TYPE_WIMAX;
@@ -3480,6 +3518,22 @@ nm_manager_class_init (NMManagerClass *manager_class)
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,
"Active connections",
diff --git a/src/nm-manager.h b/src/nm-manager.h
index c19ac5e874..ba9375488f 100644
--- a/src/nm-manager.h
+++ b/src/nm-manager.h
@@ -43,6 +43,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"
/* Not exported */
@@ -72,6 +74,7 @@ NMManager *nm_manager_get (NMSettings *settings,
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/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 <glib.h>
-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 <config.h>
#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-#include <netdb.h>
-#include <ctype.h>
-#include <arpa/inet.h>
#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;
-
- g_return_val_if_fail (lines != NULL, FALSE);
- g_return_val_if_fail (hostname != NULL, FALSE);
-
- hostname4_is_fallback = !strcmp (hostname, fallback_hostname4);
- hostname6_is_fallback = !strcmp (hostname, fallback_hostname6);
-
- /* 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.
- */
- if (!hostname4_is_fallback || !hostname6_is_fallback) {
- char *dot;
-
- 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;
+ char **lines = NULL, **iter;
+ GString *new_contents = NULL;
- 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 (contents_len == 0 || !strstr (contents, ADDED_TAG))
+ return NULL;
- 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;
- }
- }
+ new_contents = g_string_sized_new (contents_len);
- 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;
- }
+ /* 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');
}
-
- 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;
}
+ g_strfreev (lines);
- /* 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'.
+ /* Remove last blank line at end of file, if one exists; this is
+ * an artifact of how g_strsplit_set() works.
*/
- 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);
- }
+ if ( (new_contents->len > 2)
+ && (new_contents->str[new_contents->len - 1] == '\n'))
+ g_string_truncate (new_contents, new_contents->len - 1);
- /* 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 <glib.h>
-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 6ee493cc18..2961389b7a 100644
--- a/src/nm-policy.c
+++ b/src/nm-policy.c
@@ -36,13 +36,15 @@
#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"
#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 {
@@ -238,9 +240,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;
@@ -252,43 +251,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);
}
@@ -977,6 +940,14 @@ 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;
NMDevice *device;
@@ -1006,6 +977,11 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data)
if (NM_IS_DEVICE_WIFI (device)) {
_connect_device_signal (policy, device, "access-point-added", wireless_networks_changed);
_connect_device_signal (policy, device, "access-point-removed", wireless_networks_changed);
+#if WITH_WIMAX
+ } else if (NM_IS_DEVICE_WIMAX (device)) {
+ _connect_device_signal (policy, device, "nsp-added", nsps_changed);
+ _connect_device_signal (policy, device, "nsp-removed", nsps_changed);
+#endif
}
}
@@ -1239,15 +1215,6 @@ nm_policy_destroy (NMPolicy *policy)
}
g_slist_free (policy->dev_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);
diff --git a/src/nm-udev-manager.c b/src/nm-udev-manager.c
index ff0ef68c81..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 <config.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
@@ -38,6 +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;
@@ -335,6 +339,15 @@ is_olpc_mesh (GUdevDevice *device)
return (prop != NULL);
}
+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;
+}
+
static GObject *
device_creator (NMUdevManager *manager,
GUdevDevice *udev_device,
@@ -387,7 +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
+ else if (is_wimax (driver)) {
+#if WITH_WIMAX
+ device = (GObject *) nm_device_wimax_new (path, ifname, driver);
+#endif
+ } else
device = (GObject *) nm_device_ethernet_new (path, ifname, driver);
out:
diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c
index e596a08b8c..d216ea6a90 100644
--- a/src/nm-wifi-ap.c
+++ b/src/nm-wifi-ap.c
@@ -22,6 +22,7 @@
#include "wireless-helper.h"
#include <string.h>
+#include <stdlib.h>
#include "nm-wifi-ap.h"
#include "nm-wifi-ap-utils.h"
@@ -370,10 +371,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);
+
+ 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;
+}
-#define IEEE80211_CAP_ESS 0x0001
-#define IEEE80211_CAP_IBSS 0x0002
-#define IEEE80211_CAP_PRIVACY 0x0010
+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)
@@ -384,9 +444,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 <hidden> */
if (((len == 8) || (len == 9))
@@ -400,7 +460,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)
@@ -408,43 +468,62 @@ 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_UINT (variant)) {
+ guint32 val = g_value_get_uint (variant);
+
+ if (!strcmp (key, "Frequency"))
+ nm_ap_set_freq (ap, val);
} else if (G_VALUE_HOLDS_INT (variant)) {
- gint32 int_val = g_value_get_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;
- 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);
+ nm_ap_set_strength (ap, val);
}
- } else if (G_VALUE_HOLDS_UINT (variant)) {
- guint32 val = g_value_get_uint (variant);
+ } else if (G_VALUE_HOLDS_STRING (variant)) {
+ const char *val = g_value_get_string (variant);
- if (!strcmp (key, "capabilities")) {
- if (val & IEEE80211_CAP_ESS) {
+ if (val && !strcmp (key, "Mode")) {
+ if (strcmp (val, "infrastructure") == 0)
nm_ap_set_mode (ap, NM_802_11_MODE_INFRA);
- } else if (val & IEEE80211_CAP_IBSS) {
+ 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 (val & IEEE80211_CAP_PRIVACY) {
+ 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);
}
@@ -452,7 +531,6 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
}
}
-
NMAccessPoint *
nm_ap_new_from_properties (GHashTable *properties)
{
@@ -1171,45 +1249,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 62457765f4..2a10d3505d 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);
diff --git a/src/settings/nm-default-wired-connection.c b/src/settings/nm-default-wired-connection.c
index b2c22baf3c..63683480e2 100644
--- a/src/settings/nm-default-wired-connection.c
+++ b/src/settings/nm-default-wired-connection.c
@@ -149,7 +149,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);
diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c
index bad8f26634..93807b9360 100644
--- a/src/supplicant-manager/nm-supplicant-interface.c
+++ b/src/supplicant-manager/nm-supplicant-interface.c
@@ -34,23 +34,20 @@
#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 ".ExistsError"
+#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".InterfaceExists"
+G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT)
-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);
+static void wpas_iface_properties_changed (DBusGProxy *proxy,
+ GHashTable *props,
+ gpointer user_data);
-
-G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT)
+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, \
@@ -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,10 @@ typedef struct {
DBusGProxy * wpas_proxy;
DBusGProxy * iface_proxy;
- DBusGProxy * net_proxy;
+ DBusGProxy * props_proxy;
+ char * net_path;
+ guint32 blobs_left;
- guint scan_results_timeout;
guint32 last_scan;
NMSupplicantConfig * cfg;
@@ -199,143 +195,79 @@ 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;
-
- 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);
-}
-
-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);
+ int i;
- /* 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);
- }
+ /* Fire off a "properties" call for each returned BSSID */
+ for (i = 0; i < paths->len; i++) {
+ NMSupplicantInfo *info;
+ DBusGProxy *proxy;
+ DBusGProxyCall *call;
- 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_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;
@@ -355,9 +287,9 @@ 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)
- g_return_if_fail (new_state > priv->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 > NM_SUPPLICANT_INTERFACE_STATE_READY);
if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) {
/* Cancel all pending calls when going down */
@@ -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,123 +322,125 @@ 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);
-
- g_return_if_fail (enum_state > 0);
+ int state;
- set_state (NM_SUPPLICANT_INTERFACE (user_data), (guint32) enum_state);
+ state = wpas_state_string_to_enum (new_state);
+ g_warn_if_fail (state > 0);
+ if (state > 0)
+ set_state (self, (guint32) state);
}
-/* Explicit state request reply handler */
static void
-iface_state_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+set_scanning (NMSupplicantInterface *self, gboolean new_scanning)
{
- NMSupplicantInfo *info = (NMSupplicantInfo *) user_data;
- GError *err = NULL;
- char *state_str = NULL;
- int enum_state;
+ NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ GTimeVal cur_time;
- 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 (priv->scanning != new_scanning) {
+ priv->scanning = new_scanning;
+
+ /* Cache time of last scan completion */
+ if (priv->scanning == FALSE) {
+ g_get_current_time (&cur_time);
+ priv->last_scan = cur_time.tv_sec;
+ }
- if (enum_state > 0)
- set_state (info->interface, (guint32) enum_state);
- g_free (state_str);
+ g_object_notify (G_OBJECT (self), "scanning");
}
}
+gboolean
+nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
+{
+ NMSupplicantInterfacePrivate *priv;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
+ if (priv->scanning)
+ return TRUE;
+ if (priv->state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
+ return TRUE;
+ return FALSE;
+}
+
static void
-wpas_iface_get_state (NMSupplicantInterface *self)
+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);
- 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);
+ /* 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_scanning_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data)
+iface_get_props_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;
+ GHashTable *props = NULL;
+ GError *error = NULL;
- 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");
- }
+ 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);
+ g_hash_table_destroy (props);
+ } 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_scanning (NMSupplicantInterface *self)
+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->iface_proxy, priv->other_pcalls);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "scanning",
- iface_scanning_cb,
+ 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
-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");
- }
-}
-
-gboolean
-nm_supplicant_interface_get_scanning (NMSupplicantInterface *self)
-{
- NMSupplicantInterfacePrivate *priv;
-
- g_return_val_if_fail (self != NULL, FALSE);
-
- priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
- if (priv->scanning)
- return TRUE;
- if (priv->state == NM_SUPPLICANT_INTERFACE_STATE_SCANNING)
- return TRUE;
- return FALSE;
-}
-
-static void
interface_add_done (NMSupplicantInterface *self, char *path)
{
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self);
@@ -522,31 +454,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),
- 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_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, "Scanning", G_TYPE_BOOLEAN, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (priv->iface_proxy, "Scanning",
- G_CALLBACK (wpas_iface_handle_scanning),
+ 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);
- /* 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);
}
@@ -566,9 +505,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);
}
}
@@ -580,7 +520,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,
@@ -607,9 +547,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);
}
@@ -622,7 +572,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 +589,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);
}
@@ -684,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);
}
}
@@ -728,26 +682,23 @@ 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) {
- dbus_g_proxy_begin_call (priv->iface_proxy, "removeNetwork",
+ 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",
+ dbus_g_proxy_begin_call (priv->iface_proxy, "Disconnect",
disconnect_cb,
NULL, NULL,
G_TYPE_INVALID);
@@ -758,9 +709,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);
@@ -768,161 +718,86 @@ 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,
+ /* 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,
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)
+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);
g_error_free (err);
- } else {
- info = nm_supplicant_info_new (info->interface, priv->iface_proxy, priv->assoc_pcalls);
- call_set_network (info);
- }
-}
-
-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 (NMSupplicantInfo *info, GHashTable *orig_blobs)
-{
- NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface);
- DBusGProxyCall *call;
- GHashTable *blobs;
-
- 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 (info->interface, signals[CONNECTION_ERROR], 0, "SendBlobError", msg);
- return;
- }
-
- g_hash_table_foreach (orig_blobs, (GHFunc) convert_blob, blobs);
-
- 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);
+ } else
+ call_select_network (info->interface);
}
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;
+ GHashTableIter iter;
+ gpointer name, data;
+ DBusGProxyCall *call;
+ NMSupplicantInfo *blob_info;
+
+ 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);
+ 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
@@ -931,10 +806,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);
@@ -945,12 +820,15 @@ 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);
+ 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);
}
@@ -961,7 +839,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);
@@ -978,16 +856,21 @@ nm_supplicant_interface_set_config (NMSupplicantInterface * self,
g_object_ref (priv->cfg);
- info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
- ap_scan = nm_supplicant_config_get_ap_scan (priv->cfg);
- call = dbus_g_proxy_begin_call (priv->iface_proxy, "setAPScan",
+ 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);
+ call = dbus_g_proxy_begin_call (priv->props_proxy, "Set",
set_ap_scan_cb,
info,
nm_supplicant_info_destroy,
- G_TYPE_UINT, ap_scan,
+ G_TYPE_STRING, WPAS_DBUS_IFACE_INTERFACE,
+ G_TYPE_STRING, "ApScan",
+ G_TYPE_VALUE, &value,
G_TYPE_INVALID);
nm_supplicant_info_set_call (info, call);
+ g_value_unset (&value);
return call != NULL;
}
@@ -996,17 +879,31 @@ 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);
}
+ g_signal_emit (info->interface, signals[SCAN_DONE], 0, err ? FALSE : TRUE);
+ g_clear_error (&err);
+}
- /* Notify listeners of the result of the scan */
- g_signal_emit (info->interface, signals[SCAN_REQ_RESULT], 0, !!success);
+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
@@ -1015,17 +912,24 @@ 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;
@@ -1174,9 +1078,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;
@@ -1204,18 +1105,17 @@ 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);
- 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);
- 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);
@@ -1248,15 +1148,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",
@@ -1266,7 +1157,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),
@@ -1275,7 +1166,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),
@@ -1283,35 +1174,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,
diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c
index e1330fd7bf..8209da21d2 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
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,311 +85,25 @@ 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);
-}
-
-/*******************************************/
-
-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);
+ test_generic (generic_no_boilerplate_before, NULL);
}
/*******************************************/
-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 = \
+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"
"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_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"
"127.0.0.1 localhost.localdomain localhost\n"
"::1 localhost6.localdomain6 localhost6\n"
"192.168.1.3 comet\n"
@@ -425,416 +112,44 @@ static const char *named46_non127_other4_after = \
"127.0.0.1 lcmd.us.intellitxt.com\n";
static void
-test_hosts_named46_non127_other4 (void)
+test_hosts_leftover (void)
{
- test_generic (named46_non127_other4_before, named46_non127_other4_after, "comet", "192.168.1.2", "3001:abba::3234", FALSE);
+ test_generic (leftover_before, leftover_after);
}
/*******************************************/
-static const char *named46_non127_other4_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.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"
- "\n"
- "127.0.0.1 lcmd.us.intellitxt.com\n";
-
-static void
-test_hosts_named46_non127_other4_long (void)
-{
- test_generic (named46_non127_other4_long_before, named46_non127_other4_long_after, "comet.space", "192.168.1.2", "3001:abba::3234", FALSE);
-}
-
-/*******************************************/
-
-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"
+ "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_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";
+ "127.0.0.1 lcmd.us.intellitxt.com\n"
+ "\n";
-static const char *named46_non127_wrong_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"
- "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"
- "\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";
-
-static const char *long_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"
+ "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";
-
-static void
-test_hosts_long (void)
-{
- test_generic (long_before, long_after, "comet", NULL, NULL, FALSE);
-}
-
-/*******************************************/
-
-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";
+ "\n";
static void
-test_hosts_stale4_removed (void)
+test_hosts_leftover_double_newline (void)
{
- test_generic (stale4_removed_before, stale4_removed_after, "comet", NULL, NULL, FALSE);
+ test_generic (leftover_double_newline_before, leftover_double_newline_after);
}
/*******************************************/
-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 ();
}
diff --git a/src/wimax/Makefile.am b/src/wimax/Makefile.am
new file mode 100644
index 0000000000..91f1dc4e07
--- /dev/null
+++ b/src/wimax/Makefile.am
@@ -0,0 +1,40 @@
+INCLUDES = \
+ -I${top_srcdir}/src \
+ -I${top_srcdir}/src/logging \
+ -I${top_srcdir}/include \
+ -I${top_srcdir}/libnm-util \
+ -I${top_builddir}/marshallers
+
+noinst_LTLIBRARIES = libwimax.la
+
+libwimax_la_SOURCES = \
+ 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 \
+ iwmxsdk.c \
+ iwmxsdk.h
+
+libwimax_la_CPPFLAGS = \
+ $(DBUS_CFLAGS) \
+ $(IWMX_SDK_CFLAGS)
+
+libwimax_la_LIBADD = \
+ $(DBUS_LIBS) \
+ $(IWMX_SDK_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-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-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..0c0bc1377e
--- /dev/null
+++ b/src/wimax/iwmxsdk.c
@@ -0,0 +1,1462 @@
+/* -*- 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 <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <net/if.h>
+
+#include <glib.h>
+
+#include <WiMaxType.h>
+#include <WiMaxAPI.h>
+#include <WiMaxAPIEx.h>
+
+#include "logging/nm-logging.h"
+#include "iwmxsdk.h"
+
+static WIMAX_API_DEVICE_ID g_api;
+static GStaticMutex add_remove_mutex = G_STATIC_MUTEX_INIT;
+
+/* 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);
+}
+
+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 {
+ 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_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;
+} 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";
+ }
+}
+
+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
+ *
+ * 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;
+}
+
+/*
+ * 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
+ *
+ * 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;
+ 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
+ * 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);
+ }
+
+ /* 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, &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'",
+ 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;
+}
+
+/*
+ * 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)
+{
+ 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
+ *
+ * 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, status;
+
+ 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;
+ }
+
+ 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;
+
+ 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;
+
+ UnsubscribeMediaStatusUpdate(&wmxsdk->device_id);
+error_subscribe_media_status:
+ 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)
+{
+ UnsubscribeMediaStatusUpdate(&wmxsdk->device_id);
+ 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,
+ 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;
+ 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;
+
+ /* Notify listeners of new devices */
+ iwmx_sdk_call_new_callbacks (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);
+
+ g_static_mutex_lock(&add_remove_mutex);
+
+ 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);
+ goto out;
+ }
+
+ 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);
+ goto out;
+ }
+
+ 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);
+ }
+
+out:
+ g_static_mutex_unlock(&add_remove_mutex);
+}
+
+/*
+ * 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..bd55679ab2
--- /dev/null
+++ b/src/wimax/iwmxsdk.h
@@ -0,0 +1,109 @@
+/* -*- 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 <wimax/WiMaxType.h>
+#include <wimax/WiMaxTypesEx.h>
+#include <wimax/WiMaxAPIEx.h>
+
+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 (*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);
+
+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;
+ WimaxMediaStatusFunc media_status_cb;
+ WimaxConnectResultFunc connect_result_cb;
+ WimaxScanResultFunc scan_result_cb;
+ WimaxRemovedFunc removed_cb;
+ void *callback_data;
+
+ GStaticMutex network_mutex;
+
+ WIMAX_API_DEVICE_STATUS status;
+ WIMAX_API_MEDIA_STATUS media_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,
+ WimaxMediaStatusFunc media_status_func,
+ 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);
+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);
+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..fba108f5be
--- /dev/null
+++ b/src/wimax/nm-device-wimax.c
@@ -0,0 +1,1444 @@
+/* -*- 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 - 2011 Red Hat, Inc.
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+
+#include <WiMaxAPI.h>
+#include <WiMaxAPIEx.h>
+
+#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,
+ PROP_CENTER_FREQ,
+ PROP_RSSI,
+ PROP_CINR,
+ PROP_TX_POWER,
+ PROP_BSID,
+
+ 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;
+
+ guint link_timeout_id;
+ guint poll_id;
+
+ GSList *nsp_list;
+ NMWimaxNsp *current_nsp;
+
+ /* interesting stuff when connected */
+ guint center_freq;
+ gint rssi;
+ gint cinr;
+ gint tx_power;
+ char *bsid;
+} 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));
+}
+
+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)
+{
+ 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);
+ 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;
+ const char *iface;
+
+ 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, "(%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, "(%s): failed to %s radio",
+ iface, 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;
+ const char *iface;
+
+ iface = nm_device_get_iface (dev);
+
+ fd = socket (PF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ nm_log_warn (LOGD_HW, "(%s): couldn't open control socket.", iface);
+ 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)",
+ 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);
+ }
+
+ 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 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 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)
+{
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device);
+ NMActRequest *req;
+ GSList *iter;
+ const char *path;
+
+ clear_link_timeout (NM_DEVICE_WIMAX (device));
+
+ 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 && ret != -EINPROGRESS) {
+ 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;
+ }
+
+ /* 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;
+}
+
+static void
+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, "(%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, "(%s): failed to disconnect WiMAX device: %d",
+ iface, ret);
+ }
+ }
+}
+
+static void
+real_deactivate_quickly (NMDevice *device)
+{
+ NMDeviceWimax *self = NM_DEVICE_WIMAX (device);
+ NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self);
+
+ clear_activation_timeout (self);
+ clear_link_timeout (self);
+ clear_connected_poll (self);
+
+ set_current_nsp (self, 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.
+ */
+ force_disconnect (self, priv->sdk);
+ }
+}
+
+/*************************************************************************/
+
+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;
+
+ 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));
+
+ 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_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 (self, 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))
+ 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) {
+ /* 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 (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_device_state_changed (NM_DEVICE (self),
+ NM_DEVICE_STATE_FAILED,
+ NM_DEVICE_STATE_REASON_CONFIG_FAILED);
+ }
+ }
+}
+
+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_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);
+
+ 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;
+
+ 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 %s",
+ iface, iwmx_sdk_media_status_to_str (new_status));
+
+ /* We only care about media events while activated */
+ 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:
+ 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);
+ break;
+ }
+}
+
+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;
+ guint signalq;
+ 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);
+ 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);
+
+ 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, 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 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;
+ 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);
+ 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)),
+ nsp_name, sdk_nsp->linkQuality, net_type);
+ }
+ 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 */
+}
+
+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);
+
+ /* Request initial NSP list */
+ 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);
+
+ 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);
+ connected_poll_cb (self);
+ } else {
+ clear_link_timeout (self);
+ clear_connected_poll (self);
+ set_link_status (self, NULL);
+ }
+}
+
+/*************************************************************************/
+
+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, old_available);
+ 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_media_status_cb,
+ wmx_connect_result_cb,
+ wmx_scan_result_cb,
+ wmx_removed_cb,
+ self);
+ iwmx_sdk_set_fast_reconnect_enabled (priv->sdk, 0);
+
+ if (!priv->sdk_action_defer_id)
+ priv->sdk_action_defer_id = g_idle_add (sdk_action_defer_cb, self);
+ }
+}
+
+/*************************************************************************/
+
+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;
+ 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;
+ }
+}
+
+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);
+ clear_link_timeout (self);
+ clear_connected_poll (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, NULL);
+ wmxsdk_unref (priv->sdk);
+ }
+
+ g_free (priv->bsid);
+
+ 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));
+
+ 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",
+ 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..d70380acc8
--- /dev/null
+++ b/src/wimax/nm-device-wimax.h
@@ -0,0 +1,82 @@
+/* -*- 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 - 2011 Red Hat, Inc.
+ * Copyright (C) 2009 Novell, Inc.
+ */
+
+#ifndef NM_DEVICE_WIMAX_H
+#define NM_DEVICE_WIMAX_H
+
+#include <net/ethernet.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 ((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_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;
+} 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);
+
+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/nm-wimax-nsp.c b/src/wimax/nm-wimax-nsp.c
new file mode 100644
index 0000000000..d9e905b1fc
--- /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;
+ guint 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_uint (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_uint (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_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] =
+ 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 <glib-object.h>
+#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..bca25a1dbf
--- /dev/null
+++ b/src/wimax/nm-wimax-util.c
@@ -0,0 +1,82 @@
+/* -*- 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 <WiMaxAPI.h>
+#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_sdk_ref (void)
+{
+ int ret = 0;
+
+ 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)
+{
+ 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;
+}
+
diff --git a/src/wimax/nm-wimax-util.h b/src/wimax/nm-wimax-util.h
new file mode 100644
index 0000000000..71f5aa29d2
--- /dev/null
+++ b/src/wimax/nm-wimax-util.h
@@ -0,0 +1,38 @@
+/* -*- 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 <glib.h>
+
+#include <WiMaxType.h>
+#include <WiMaxError.h>
+#include "nm-wimax-types.h"
+
+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);
+
+#endif /* NM_WIMAX_UTIL_H */
diff --git a/system-settings/plugins/ifcfg-rh/plugin.c b/system-settings/plugins/ifcfg-rh/plugin.c
index 8ebe196499..24a4d115dc 100644
--- a/system-settings/plugins/ifcfg-rh/plugin.c
+++ b/system-settings/plugins/ifcfg-rh/plugin.c
@@ -149,7 +149,6 @@ _internal_new_connection (SCPluginIfcfg *self,
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 (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
} else {
/* Wait for the connection to become unmanaged once it knows the
* hardware IDs of its device, if/when the device gets plugged in.
@@ -245,9 +244,13 @@ connection_new_or_changed (SCPluginIfcfg *self,
if (!existing) {
/* Completely new connection */
new = _internal_new_connection (self, path, NULL, NULL);
- if (new && !nm_ifcfg_connection_get_unmanaged_spec (new)) {
- /* Only managed connections are announced to the settings service */
- g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new);
+ if (new) {
+ if (nm_ifcfg_connection_get_unmanaged_spec (new)) {
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_UNMANAGED_SPECS_CHANGED);
+ } else {
+ /* Only managed connections are announced to the settings service */
+ g_signal_emit_by_name (self, NM_SYSTEM_CONFIG_INTERFACE_CONNECTION_ADDED, new);
+ }
}
return;
}
diff --git a/system-settings/plugins/ifcfg-rh/reader.c b/system-settings/plugins/ifcfg-rh/reader.c
index 68f7141cf5..14086f231b 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 */
@@ -1167,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.
*/
diff --git a/system-settings/plugins/ifnet/Makefile.am b/system-settings/plugins/ifnet/Makefile.am
index 52056ffda2..9bf8a79a18 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 eecb5d74d3..338ead25dd 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 <config.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -188,6 +187,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 (void)
{
@@ -357,10 +382,8 @@ has_default_route (const char *conn_name, gboolean (*check_fn) (const char *))
routes = g_strdup (ifnet_get_data (conn_name, "routes"));
if (!routes)
return FALSE;
-
- tmp = strstr (routes, "default via ");
+ tmp = find_default_gateway_str (routes);
if (tmp) {
- tmp += strlen ("default via ");
g_strstrip (tmp);
if ((end = strstr (tmp, "\"")) != NULL)
*end = '\0';
@@ -476,8 +499,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)
@@ -502,8 +530,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);
@@ -668,8 +701,8 @@ convert_ip4_routes_block (const char *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);
@@ -709,9 +742,7 @@ convert_ip6_routes_block (const char *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 {
@@ -868,9 +899,9 @@ get_dhcp_hostname_and_client_id (char **hostname, char **client_id)
gchar **all_lines;
guint line_num, i;
- dhcp_client = ifnet_get_global_setting ("main", "dhcp");
*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,
diff --git a/system-settings/plugins/ifnet/plugin.c b/system-settings/plugins/ifnet/plugin.c
index c0077c8757..710b9b5b5f 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 42a91d60c1..a351f31ce5 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 1f6b9f5a21..2e9de7a21a 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
@@ -286,10 +292,10 @@ test_update_connection ()
NULL,
error);
ASSERT (success, "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",
- "get connection failed: %s",
+ ASSERT (connection != NULL, "get connection", "get connection failed: %s",
error == NULL ? "None" : (*error)->message);
success = ifnet_update_parsers_by_connection (connection, "0xab3ace",
@@ -297,8 +303,8 @@ test_update_connection ()
"wpa_supplicant.conf.generate",
NULL,
error);
- ASSERT (success, "update connection",
- "update connection failed %s", "0xab3ace");
+ ASSERT (success, "update connection", "update connection failed %s", "0xab3ace");
+ g_object_unref (connection);
}
static void
@@ -309,14 +315,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
@@ -330,16 +339,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
@@ -377,10 +390,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;
diff --git a/system-settings/plugins/ifupdown/plugin.c b/system-settings/plugins/ifupdown/plugin.c
index 0acdf0eafb..389d6d9738 100644
--- a/system-settings/plugins/ifupdown/plugin.c
+++ b/system-settings/plugins/ifupdown/plugin.c
@@ -362,12 +362,55 @@ 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) {
+ PLUGIN_PRINT("SCPlugin-Ifupdown", "deleting %s from iface_connections", block->name);
nm_sysconfig_connection_delete (NM_SYSCONFIG_CONNECTION (exported),
ignore_cb,
NULL);
@@ -377,12 +420,16 @@ 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);
}
+ next:
block = block->next;
}
diff --git a/system-settings/plugins/keyfile/plugin.c b/system-settings/plugins/keyfile/plugin.c
index 5dddf494bf..a1c654245c 100644
--- a/system-settings/plugins/keyfile/plugin.c
+++ b/system-settings/plugins/keyfile/plugin.c
@@ -23,6 +23,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
+#include <netinet/ether.h>
#include <string.h>
#include <gmodule.h>
@@ -442,8 +443,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 */
}
diff --git a/test/nm-tool.c b/test/nm-tool.c
index 922bb63b1e..65546e48e5 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 <dcbw@redhat.com>
@@ -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 <config.h>
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
@@ -38,6 +40,9 @@
#include <nm-gsm-device.h>
#include <nm-cdma-device.h>
#include <nm-device-bt.h>
+#if WITH_WIMAX
+#include <nm-device-wimax.h>
+#endif
#include <nm-utils.h>
#include <nm-setting-ip4-config.h>
#include <nm-setting-ip6-config.h>
@@ -192,6 +197,48 @@ detail_access_point (gpointer data, gpointer user_data)
g_free (tmp);
}
+#if WITH_WIMAX
+static const char *
+wimax_network_type_to_str (NMWimaxNspNetworkType type)
+{
+ switch (type) {
+ case NM_WIMAX_NSP_NETWORK_TYPE_HOME:
+ return "Home";
+ case NM_WIMAX_NSP_NETWORK_TYPE_PARTNER:
+ return "Partner";
+ case NM_WIMAX_NSP_NETWORK_TYPE_ROAMING_PARTNER:
+ return "Roaming";
+ default:
+ return "Unknown";
+ }
+}
+
+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 ("%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_str);
+ g_free (label);
+ g_free (data_str);
+}
+#endif
+
static gchar *
ip4_address_as_string (guint32 ip)
{
@@ -329,6 +376,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)");
@@ -344,6 +395,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);
@@ -409,6 +464,68 @@ 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)) {
+ 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) {
+ 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)" : "");
+
+ 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 */