diff --git a/ChangeLog b/ChangeLog index 78cfb999c..39514efa9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +2007-06-06 Tambet Ingo + + * libnm-util/nm-setting.c: Get rid of dump virtual functions, that can happen + automagically. + Implement NMSettingIP4Config. + Finish NMSettingWired by adding all known members. + (setting_wired_verify): Implement. + Finish NMSettingWireless by adding all known members. + (setting_wireless_verify): Implement. + + * libnm-util/nm-connection.c: Register "ipv4" setting. + (nm_connection_dump): Implement. Instead of requiring every NMSetting to implement + dump function, we can introspect the GHashTable which is used for sending connections + over dbus. + + * src/nm-device-802-11-wireless.c (nm_device_802_11_wireless_set_activation_ap): + Take GByteArray for essid, it's really not a string. + + * src/nm-device.c (real_act_stage3_ip_config_start): Get information from NMSettings. + Start DHCP request if setting is not passed or if it states that DHCP should be used. + (real_act_stage4_get_ip4_config): If settings are provided, use them, even if it + means overriding the values we got from DHCP. + (real_activation_cancel_handler): Cancel DHCP transaction only if it has started, doh. + (nm_device_deactivate_quickly): Ditto. + + * src/nm-device-interface.c (impl_device_activate): Dump the connection structure + for debugging. + 2007-05-07 Tambet Ingo * libnm-glib/Makefile.am: Link with libnm-util to gain access to diff --git a/libnm-util/nm-connection.c b/libnm-util/nm-connection.c index ef717727e..3eacd48c9 100644 --- a/libnm-util/nm-connection.c +++ b/libnm-util/nm-connection.c @@ -1,3 +1,5 @@ +#include +#include #include "nm-connection.h" static GHashTable *registered_setting_creators = NULL; @@ -13,6 +15,7 @@ register_default_creators (void) { "info", nm_setting_info_new_from_hash }, { "802-3-ethernet", nm_setting_wired_new_from_hash }, { "802-11-wireless", nm_setting_wireless_new_from_hash }, + { "ipv4", nm_setting_ip4_config_new_from_hash }, { NULL, NULL} }; @@ -154,6 +157,114 @@ nm_connection_to_hash (NMConnection *connection) return connection_hash; } +static char * +garray_to_string (GArray *array) +{ + GString *str; + int i; + char c; + + str = g_string_sized_new (array->len); + for (i = 0; i < array->len; i++) { + c = array->data[i]; + + /* Convert NULLs to spaces to increase the readability. */ + if (c == '\0') + c = ' '; + str = g_string_append_c (str, c); + } + str = g_string_append_c (str, '\0'); + + return g_string_free (str, FALSE); +} + +static char * +gvalue_to_string (GValue *val) +{ + char *ret; + GType type; + + type = G_VALUE_TYPE (val); + switch (type) { + case G_TYPE_STRING: + ret = g_strdup (g_value_get_string (val)); + break; + case G_TYPE_INT: + ret = g_strdup_printf ("%d", g_value_get_int (val)); + break; + case G_TYPE_UINT: + ret = g_strdup_printf ("%u", g_value_get_uint (val)); + break; + case G_TYPE_BOOLEAN: + ret = g_strdup_printf ("%s", g_value_get_boolean (val) ? "True" : "False"); + break; + + default: + /* These return dynamic values and thus can't be 'case's */ + if (type == DBUS_TYPE_G_UCHAR_ARRAY) + ret = garray_to_string ((GArray *) g_value_get_boxed (val)); + else if (type == dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_UCHAR_ARRAY)) { + /* Array of arrays of chars, like wireless seen-bssids for example */ + GString *str; + int i; + GPtrArray *ptr_array; + gboolean need_comma = FALSE; + + str = g_string_new ("["); + + ptr_array = (GPtrArray *) g_value_get_boxed (val); + for (i = 0; i < ptr_array->len; i++) { + ret = garray_to_string ((GArray *) g_ptr_array_index (ptr_array, i)); + + if (need_comma) + g_string_append (str, ", "); + else + need_comma = TRUE; + + g_string_append (str, ret); + g_free (ret); + } + + g_string_append (str, "]"); + ret = g_string_free (str, FALSE); + } else + ret = g_strdup_printf ("Value with type %s", g_type_name (type)); + } + + return ret; +} + +static void +dump_setting_member (gpointer key, gpointer value, gpointer user_data) +{ + char *val_as_str; + + val_as_str = gvalue_to_string ((GValue *) value); + g_message ("\t%s : '%s'", (char *) key, val_as_str); + g_free (val_as_str); +} + +static void +dump_setting (gpointer key, gpointer value, gpointer user_data) +{ + g_message ("Setting '%s'", (char *) key); + g_hash_table_foreach ((GHashTable *) value, dump_setting_member, NULL); + g_message ("-------------------"); +} + +void +nm_connection_dump (NMConnection *connection) +{ + GHashTable *hash; + + g_return_if_fail (connection != NULL); + + /* Convert the connection to hash so that we can introspect it */ + hash = nm_connection_to_hash (connection); + g_hash_table_foreach (hash, dump_setting, NULL); + g_hash_table_destroy (hash); +} + void nm_connection_destroy (NMConnection *connection) { diff --git a/libnm-util/nm-connection.h b/libnm-util/nm-connection.h index 690c709fc..876817fe5 100644 --- a/libnm-util/nm-connection.h +++ b/libnm-util/nm-connection.h @@ -17,6 +17,7 @@ NMSetting *nm_connection_get_setting (NMConnection *connection, const char *setting_name); GHashTable *nm_connection_to_hash (NMConnection *connection); +void nm_connection_dump (NMConnection *connection); void nm_connection_destroy (NMConnection *connection); diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 1447803d4..cd278b11f 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -1,18 +1,9 @@ #include +#include +#include #include "nm-setting.h" -static void -dump_one_setting (gpointer key, gpointer value, gpointer user_data) -{ - NMSetting *setting = (NMSetting *) value; - - g_message ("Setting '%s'", setting->name); - if (setting->dump_fn) - setting->dump_fn (setting); - g_message ("-------------------"); -} - typedef struct { gboolean success; GHashTable *all_settings; @@ -35,9 +26,6 @@ nm_settings_verify (GHashTable *all_settings) gpointer p; VerifySettingsInfo info; - /* Debug dump */ - g_hash_table_foreach (all_settings, dump_one_setting, NULL); - /* First, make sure there's at least 'info' setting */ p = g_hash_table_lookup (all_settings, "info"); if (!p) { @@ -133,17 +121,44 @@ int_to_gvalue (int i) return val; } +static GValue * +uint_to_gvalue (guint32 i) +{ + GValue *val; + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_UINT); + g_value_set_uint (val, i); + + return val; +} + +static GValue * +byte_array_to_gvalue (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 GByteArray * +convert_array_to_byte_array (GArray *array) +{ + GByteArray *byte_array; + + byte_array = g_byte_array_sized_new (array->len); + g_byte_array_append (byte_array, (const guint8 *) array->data, array->len); + + return byte_array; +} + /***********************************************************************/ -static void -setting_info_dump (NMSetting *setting) -{ - NMSettingInfo *self = (NMSettingInfo *) setting; - - g_message ("info name: %s", self->name); - g_message ("devtype: %s", self->devtype); - g_message ("autoconnect: %s", self->autoconnect ? "Yes" : "No"); -} +/* Info */ static gboolean setting_info_verify (NMSetting *setting, GHashTable *all_settings) @@ -192,7 +207,6 @@ nm_setting_info_new (void) setting->name = g_strdup ("info"); setting->verify_fn = setting_info_verify; setting->hash_fn = setting_info_hash; - setting->dump_fn = setting_info_dump; setting->destroy_fn = setting_info_destroy; return setting; @@ -238,18 +252,127 @@ nm_setting_info_new_from_hash (GHashTable *settings) return NULL; } +/* IP4 config */ + +static gboolean +setting_ip4_config_verify (NMSetting *setting, GHashTable *all_settings) +{ + NMSettingIP4Config *self = (NMSettingIP4Config *) setting; + + if (!self->address) { + g_warning ("address is not provided"); + return FALSE; + } + + if (!self->netmask) { + g_warning ("netmask is not provided"); + return FALSE; + } + + return TRUE; +} + +static GHashTable * +setting_ip4_config_hash (NMSetting *setting) +{ + NMSettingIP4Config *self = (NMSettingIP4Config *) setting; + GHashTable *hash; + + hash = setting_hash_new (); + g_hash_table_insert (hash, "manual", boolean_to_gvalue (self->manual)); + g_hash_table_insert (hash, "address", uint_to_gvalue (self->address)); + g_hash_table_insert (hash, "netmask", uint_to_gvalue (self->netmask)); + g_hash_table_insert (hash, "gateway", uint_to_gvalue (self->gateway)); + + return hash; +} static void -setting_wired_dump (NMSetting *setting) +setting_ip4_config_destroy (NMSetting *setting) { - NMSettingWired *self = (NMSettingWired *) setting; + NMSettingIP4Config *self = (NMSettingIP4Config *) setting; - g_message ("MTU: %d", self->mtu); + g_slice_free (NMSettingIP4Config, self); } +NMSetting * +nm_setting_ip4_config_new (void) +{ + NMSetting *setting; + + setting = (NMSetting *) g_slice_new0 (NMSettingIP4Config); + + setting->name = g_strdup ("ipv4"); + setting->verify_fn = setting_ip4_config_verify; + setting->hash_fn = setting_ip4_config_hash; + setting->destroy_fn = setting_ip4_config_destroy; + + return setting; +} + +NMSetting * +nm_setting_ip4_config_new_from_hash (GHashTable *settings) +{ + NMSettingIP4Config*self; + NMSetting *setting; + GValue *value; + + g_return_val_if_fail (settings != NULL, NULL); + + setting = nm_setting_ip4_config_new (); + self = (NMSettingIP4Config *) setting; + + value = (GValue *) g_hash_table_lookup (settings, "manual"); + if (value && G_VALUE_HOLDS_BOOLEAN (value)) + self->manual = g_value_get_boolean (value); + + value = (GValue *) g_hash_table_lookup (settings, "address"); + if (value && G_VALUE_HOLDS_UINT (value)) + self->address = g_value_get_uint (value); + + value = (GValue *) g_hash_table_lookup (settings, "netmask"); + if (value && G_VALUE_HOLDS_UINT (value)) + self->netmask = g_value_get_uint (value); + + value = (GValue *) g_hash_table_lookup (settings, "gateway"); + if (value && G_VALUE_HOLDS_UINT (value)) + self->gateway = g_value_get_uint (value); + + return setting; +} + +/* Wired device */ + static gboolean setting_wired_verify (NMSetting *setting, GHashTable *all_settings) { + NMSettingWired *self = (NMSettingWired *) setting; + + if (self->port) { + char *valid_ports[] = { "tp", "aui", "bnc", "mii", NULL }; + int i; + + for (i = 0; valid_ports[i]; i++) { + if (strcmp (self->port, valid_ports[i]) == 0) + break; + } + + if (valid_ports[i] == NULL) { + g_warning ("Invalid port"); + return FALSE; + } + } + + if (self->duplex && strcmp (self->duplex, "half") && strcmp (self->duplex, "full")) { + g_warning ("Invalid duplex"); + return FALSE; + } + + if (self->mac_address && self->mac_address->len != 6) { + g_warning ("Invalid mac address"); + return FALSE; + } + return TRUE; } @@ -260,7 +383,12 @@ setting_wired_hash (NMSetting *setting) GHashTable *hash; hash = setting_hash_new (); - g_hash_table_insert (hash, "mtu", int_to_gvalue (self->mtu)); + g_hash_table_insert (hash, "port", string_to_gvalue (self->port)); + g_hash_table_insert (hash, "speed", uint_to_gvalue (self->speed)); + g_hash_table_insert (hash, "duplex", string_to_gvalue (self->duplex)); + g_hash_table_insert (hash, "auto-negotiate", boolean_to_gvalue (self->auto_negotiate)); + g_hash_table_insert (hash, "mac-address", byte_array_to_gvalue (self->mac_address)); + g_hash_table_insert (hash, "mtu", uint_to_gvalue (self->mtu)); return hash; } @@ -270,6 +398,12 @@ setting_wired_destroy (NMSetting *setting) { NMSettingWired *self = (NMSettingWired *) setting; + g_free (self->port); + g_free (self->duplex); + + if (self->mac_address) + g_byte_array_free (self->mac_address, TRUE); + g_slice_free (NMSettingWired, self); } @@ -283,7 +417,6 @@ nm_setting_wired_new (void) setting->name = g_strdup ("802-3-ethernet"); setting->verify_fn = setting_wired_verify; setting->hash_fn = setting_wired_hash; - setting->dump_fn = setting_wired_dump; setting->destroy_fn = setting_wired_destroy; return setting; @@ -301,26 +434,100 @@ nm_setting_wired_new_from_hash (GHashTable *settings) setting = nm_setting_wired_new (); self = (NMSettingWired *) setting; + value = (GValue *) g_hash_table_lookup (settings, "port"); + if (value && G_VALUE_HOLDS_STRING (value)) + self->port = g_strdup (g_value_get_string (value)); + + value = (GValue *) g_hash_table_lookup (settings, "speed"); + if (value && G_VALUE_HOLDS_UINT (value)) + self->speed = g_value_get_uint (value); + + value = (GValue *) g_hash_table_lookup (settings, "duplex"); + if (value && G_VALUE_HOLDS_STRING (value)) + self->duplex = g_strdup (g_value_get_string (value)); + + value = (GValue *) g_hash_table_lookup (settings, "auto-negotiate"); + if (value && G_VALUE_HOLDS_BOOLEAN (value)) + self->auto_negotiate = g_value_get_boolean (value); + + value = (GValue *) g_hash_table_lookup (settings, "mac-address"); + if (value && G_VALUE_HOLDS_BOXED (value)) + self->mac_address = convert_array_to_byte_array ((GArray *) g_value_get_boxed (value)); + value = (GValue *) g_hash_table_lookup (settings, "mtu"); - if (value && G_VALUE_HOLDS_INT (value)) - self->mtu = g_value_get_int (value); + if (value && G_VALUE_HOLDS_UINT (value)) + self->mtu = g_value_get_uint (value); return setting; } - -static void -setting_wireless_dump (NMSetting *setting) -{ - NMSettingWireless *self = (NMSettingWireless *) setting; - - g_message ("ssid: %s", self->ssid); - g_message ("mode: %d", self->mode); -} +/* Wireless device */ static gboolean setting_wireless_verify (NMSetting *setting, GHashTable *all_settings) { + NMSettingWireless *self = (NMSettingWireless *) setting; + GSList *iter; + + if (!self->ssid || self->ssid->len < 1 || self->ssid->len > 32) { + g_warning ("Invalid or missing ssid"); + return FALSE; + } + + if (self->mode && strcmp (self->mode, "infrastructure") && strcmp (self->mode, "adhoc")) { + g_warning ("Invalid mode. Should be either 'infrastructure' or 'adhoc'"); + return FALSE; + } + + if (self->band && strcmp (self->band, "a") && strcmp (self->band, "bg")) { + g_warning ("Invalid band. Should be either 'a' or 'bg'"); + return FALSE; + } + + if (self->channel && !self->band) { + g_warning ("Channel was provided without band"); + return FALSE; + } + + if (self->channel) { + if (!strcmp (self->band, "a")) { + int i; + int valid_channels[] = { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, + 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 0 }; + + for (i = 0; valid_channels[i]; i++) { + if (self->channel == valid_channels[i]) + break; + } + + if (valid_channels[i] == 0) { + g_warning ("Invalid channel"); + return FALSE; + } + } else if (!strcmp (self->band, "bg") && self->channel > 14) { + g_warning ("Invalid channel"); + return FALSE; + } + } + + if (self->bssid && self->bssid->len != 6) { + g_warning ("Invalid bssid"); + return FALSE; + } + + if (self->mac_address && self->mac_address->len != 6) { + g_warning ("Invalid mac address"); + return FALSE; + } + + for (iter = self->seen_bssids; iter; iter = iter->next) { + GByteArray *bssid = (GByteArray *) iter->data; + if (bssid->len != 6) { + g_warning ("Invalid bssid"); + return FALSE; + } + } + return TRUE; } @@ -331,8 +538,43 @@ setting_wireless_hash (NMSetting *setting) GHashTable *hash; hash = setting_hash_new (); - g_hash_table_insert (hash, "ssid", string_to_gvalue (self->ssid)); - g_hash_table_insert (hash, "mode", int_to_gvalue (self->mode)); + g_hash_table_insert (hash, "ssid", byte_array_to_gvalue (self->ssid)); + + if (self->mode) + g_hash_table_insert (hash, "mode", string_to_gvalue (self->mode)); + if (self->band) + g_hash_table_insert (hash, "band", string_to_gvalue (self->band)); + if (self->channel) + g_hash_table_insert (hash, "channel", uint_to_gvalue (self->channel)); + if (self->bssid) + g_hash_table_insert (hash, "bssid", byte_array_to_gvalue (self->bssid)); + if (self->rate) + g_hash_table_insert (hash, "channel", uint_to_gvalue (self->rate)); + if (self->tx_power) + g_hash_table_insert (hash, "tx-power", uint_to_gvalue (self->tx_power)); + if (self->mac_address) + g_hash_table_insert (hash, "mac-address", byte_array_to_gvalue (self->mac_address)); + if (self->mtu) + g_hash_table_insert (hash, "mtu", uint_to_gvalue (self->mtu)); + + if (self->seen_bssids) { + GArray *seen_bssids; + GValue *seen_bssids_value; + GSList *iter; + + seen_bssids = g_array_new (FALSE, FALSE, sizeof (gint)); + for (iter = self->seen_bssids; iter; iter = iter->next) + g_array_append_val (seen_bssids, iter->data); + + seen_bssids_value = g_slice_new0 (GValue); + g_value_init (seen_bssids_value, dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_UCHAR_ARRAY)); + g_value_set_boxed (seen_bssids_value, seen_bssids); + + g_hash_table_insert (hash, "seen-bssids", seen_bssids_value); + } + + if (self->security) + g_hash_table_insert (hash, "security", string_to_gvalue (self->mode)); return hash; } @@ -342,8 +584,25 @@ static void setting_wireless_destroy (NMSetting *setting) { NMSettingWireless *self = (NMSettingWireless *) setting; + GSList *iter; - g_free (self->ssid); + g_free (self->mode); + g_free (self->band); + g_free (self->security); + + if (self->ssid) + g_byte_array_free (self->ssid, TRUE); + if (self->bssid) + g_byte_array_free (self->bssid, TRUE); + if (self->mac_address) + g_byte_array_free (self->mac_address, TRUE); + + if (self->seen_bssids) { + for (iter = self->seen_bssids; iter; iter = iter->next) + g_byte_array_free ((GByteArray *) iter->data, TRUE); + g_slist_free (self->seen_bssids); + } + g_slice_free (NMSettingWireless, self); } @@ -358,7 +617,6 @@ nm_setting_wireless_new (void) setting->name = g_strdup ("802-11-wireless"); setting->verify_fn = setting_wireless_verify; setting->hash_fn = setting_wireless_hash; - setting->dump_fn = setting_wireless_dump; setting->destroy_fn = setting_wireless_destroy; return setting; @@ -377,21 +635,68 @@ nm_setting_wireless_new_from_hash (GHashTable *settings) self = (NMSettingWireless *) setting; value = (GValue *) g_hash_table_lookup (settings, "ssid"); - if (value && G_VALUE_HOLDS_STRING (value)) - self->ssid = g_strdup (g_value_get_string (value)); - else { + if (value && G_VALUE_HOLDS_BOXED (value)) { + GArray *array; + + array = (GArray *) g_value_get_boxed (value); + + self->ssid = g_byte_array_sized_new (array->len); + g_byte_array_append (self->ssid, (const guint8 *) array->data, array->len); + }else { g_warning ("Missing or invalid ssid"); goto err; } value = (GValue *) g_hash_table_lookup (settings, "mode"); - if (value && G_VALUE_HOLDS_INT (value)) { - self->mode = g_value_get_int (value); - } else { - g_warning ("Missing or invalid mode"); - goto err; + if (value && G_VALUE_HOLDS_STRING (value)) + self->mode = g_strdup (g_value_get_string (value)); + + value = (GValue *) g_hash_table_lookup (settings, "band"); + if (value && G_VALUE_HOLDS_STRING (value)) + self->band = g_strdup (g_value_get_string (value)); + + value = (GValue *) g_hash_table_lookup (settings, "channel"); + if (value && G_VALUE_HOLDS_UINT (value)) + self->channel = g_value_get_uint (value); + + value = (GValue *) g_hash_table_lookup (settings, "bssid"); + if (value && G_VALUE_HOLDS_BOXED (value)) + self->bssid = (GByteArray *) g_value_get_boxed (value); + + value = (GValue *) g_hash_table_lookup (settings, "rate"); + if (value && G_VALUE_HOLDS_UINT (value)) + self->rate = g_value_get_uint (value); + + value = (GValue *) g_hash_table_lookup (settings, "tx-power"); + if (value && G_VALUE_HOLDS_UINT (value)) + self->tx_power = g_value_get_uint (value); + + value = (GValue *) g_hash_table_lookup (settings, "mac-address"); + if (value && G_VALUE_HOLDS_BOXED (value)) + self->mac_address = convert_array_to_byte_array ((GArray *) g_value_get_boxed (value)); + + value = (GValue *) g_hash_table_lookup (settings, "mtu"); + if (value && G_VALUE_HOLDS_UINT (value)) + self->mtu = g_value_get_uint (value); + + value = (GValue *) g_hash_table_lookup (settings, "seen-bssids"); + if (value) { + int i; + GPtrArray *ptr_array; + + ptr_array = (GPtrArray *) g_value_get_boxed (value); + for (i = 0; i < ptr_array->len; i++) { + self->seen_bssids = g_slist_prepend (self->seen_bssids, + convert_array_to_byte_array ((GArray *) g_ptr_array_index (ptr_array, i))); + } + + self->seen_bssids = g_slist_reverse (self->seen_bssids); } + value = (GValue *) g_hash_table_lookup (settings, "security"); + if (value && G_VALUE_HOLDS_STRING (value)) + self->security = g_strdup (g_value_get_string (value)); + return setting; err: diff --git a/libnm-util/nm-setting.h b/libnm-util/nm-setting.h index c4ee1d4e8..5cd9056a3 100644 --- a/libnm-util/nm-setting.h +++ b/libnm-util/nm-setting.h @@ -11,7 +11,6 @@ typedef gboolean (*NMSettingVerifyFn) (NMSetting *setting, typedef GHashTable *(*NMSettingToHashFn) (NMSetting *setting); -typedef void (*NMSettingDumpFn) (NMSetting *setting); typedef void (*NMSettingDestroyFn) (NMSetting *setting); struct _NMSetting { @@ -19,7 +18,6 @@ struct _NMSetting { NMSettingVerifyFn verify_fn; NMSettingToHashFn hash_fn; - NMSettingDumpFn dump_fn; NMSettingDestroyFn destroy_fn; }; @@ -29,6 +27,8 @@ void nm_setting_destroy (NMSetting *setting); /* Default, built-in settings */ +/* Info */ + typedef struct { NMSetting parent; @@ -40,20 +40,52 @@ typedef struct { NMSetting *nm_setting_info_new (void); NMSetting *nm_setting_info_new_from_hash (GHashTable *settings); +/* IP4 config */ + typedef struct { NMSetting parent; - int mtu; + gboolean manual; + guint32 address; + guint32 netmask; + guint32 gateway; +} NMSettingIP4Config; + +NMSetting *nm_setting_ip4_config_new (void); +NMSetting *nm_setting_ip4_config_new_from_hash (GHashTable *settings); + +/* Wired device */ + +typedef struct { + NMSetting parent; + + char *port; + guint32 speed; + char *duplex; + gboolean auto_negotiate; + GByteArray *mac_address; + guint32 mtu; } NMSettingWired; NMSetting *nm_setting_wired_new (void); NMSetting *nm_setting_wired_new_from_hash (GHashTable *settings); +/* Wireless device */ + typedef struct { NMSetting parent; - char *ssid; - int mode; + GByteArray *ssid; + char *mode; + char *band; + guint32 channel; + GByteArray *bssid; + guint32 rate; + guint32 tx_power; + GByteArray *mac_address; + guint32 mtu; + GSList *seen_bssids; + char *security; } NMSettingWireless; NMSetting *nm_setting_wireless_new (void); diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index 6ebd2a880..6a702c025 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -939,16 +939,20 @@ nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *self) static gboolean nm_device_802_11_wireless_set_activation_ap (NMDevice80211Wireless *self, - const char *essid, + GByteArray *ssid, NMAPSecurity *security) { NMAccessPoint *ap = NULL; NMData * app_data; NMAccessPointList * dev_ap_list; + char *essid; app_data = nm_device_get_app_data (NM_DEVICE (self)); g_assert (app_data); + /* FIXME: handle essid everywhere as GByteArray */ + essid = (char *) ssid->data; + nm_debug ("Forcing AP '%s'", essid); /* Find the AP in our card's scan list first. diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c index a72d0c0c5..f2ebd21b2 100644 --- a/src/nm-device-interface.c +++ b/src/nm-device-interface.c @@ -164,6 +164,7 @@ impl_device_activate (NMDeviceInterface *device, NMConnection *connection; connection = nm_connection_new_from_hash (connection_hash); + nm_connection_dump (connection); nm_device_interface_activate (device, connection, TRUE); diff --git a/src/nm-device.c b/src/nm-device.c index 018594f8d..31020e5de 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -152,7 +152,6 @@ constructor (GType type, /* Grab IP config data for this device from the system configuration files */ priv->system_config_data = nm_system_device_get_system_config (dev, priv->app_data); - nm_device_set_use_dhcp (dev, nm_system_device_get_use_dhcp (dev)); /* Allow distributions to flag devices as disabled */ if (nm_system_device_get_disabled (dev)) @@ -516,16 +515,20 @@ nm_device_activate_schedule_stage2_device_config (NMActRequest *req) static NMActStageReturn real_act_stage3_ip_config_start (NMDevice *self, NMActRequest *req) -{ - NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; +{ + NMSettingIP4Config *setting; + NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; - /* DHCP devices try DHCP, non-DHCP default to SUCCESS */ - if (nm_device_get_use_dhcp (self)) - { + setting = (NMSettingIP4Config *) nm_connection_get_setting (nm_act_request_get_connection (req), "ipv4"); + + /* If we did not receive IP4 configuration information, default to DHCP */ + if (!setting || setting->manual == FALSE) { /* Begin a DHCP transaction on the interface */ NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); gboolean success; + nm_device_set_use_dhcp (self, TRUE); + /* DHCP manager will cancel any transaction already in progress and we do not want to cancel this activation if we get "down" state from that. */ g_signal_handler_block (priv->dhcp_manager, priv->dhcp_signal_id); @@ -653,6 +656,7 @@ real_act_stage4_get_ip4_config (NMDevice *self, { NMIP4Config * real_config = NULL; NMActStageReturn ret = NM_ACT_STAGE_RETURN_FAILURE; + NMSettingIP4Config *setting; g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE); g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE); @@ -666,16 +670,25 @@ real_act_stage4_get_ip4_config (NMDevice *self, if (real_config && nm_ip4_config_get_mtu (real_config) == 0) /* If the DHCP server doesn't set the MTU, get it from backend. */ nm_ip4_config_set_mtu (real_config, nm_system_get_mtu (self)); - } else - real_config = nm_system_device_new_ip4_system_config (self); + } else { + real_config = nm_ip4_config_new (); + } - if (real_config) - { + setting = (NMSettingIP4Config *) nm_connection_get_setting (nm_act_request_get_connection (req), "ipv4"); + + if (real_config && setting) { + /* If settings are provided, use them, even if it means overriding the values we got from DHCP */ + nm_ip4_config_set_address (real_config, setting->address); + nm_ip4_config_set_netmask (real_config, setting->netmask); + + if (setting->gateway) + nm_ip4_config_set_gateway (real_config, setting->gateway); + } + + if (real_config) { *config = real_config; ret = NM_ACT_STAGE_RETURN_SUCCESS; - } - else - { + } else { /* Make sure device is up even if config fails */ if (!nm_device_bring_up (self, FALSE)) ret = NM_ACT_STAGE_RETURN_FAILURE; @@ -929,10 +942,13 @@ real_activation_cancel_handler (NMDevice *self, g_return_if_fail (self != NULL); g_return_if_fail (req != NULL); - if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) + if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG && + nm_device_get_use_dhcp (self)) { + nm_dhcp_manager_cancel_transaction (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager, nm_device_get_iface (self), TRUE); + } } @@ -994,8 +1010,9 @@ nm_device_deactivate_quickly (NMDevice *self) /* Tear down an existing activation request, which may not have happened * in nm_device_activation_cancel() above, for various reasons. */ - if ((act_request = nm_device_get_act_request (self))) - { + if ((act_request = nm_device_get_act_request (self)) && + nm_device_get_use_dhcp (self)) { + nm_dhcp_manager_cancel_transaction (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager, nm_device_get_iface (self), FALSE);