From a88e1dd3a227303649fc7782ee37e6e0995681dc Mon Sep 17 00:00:00 2001 From: Tambet Ingo Date: Mon, 5 Feb 2007 12:14:09 +0000 Subject: [PATCH] 2007-02-05 Tambet Ingo Make NMDevice abstract class, remove almost all references to it's subclasses (the last place gets removed with new policy manager). Add NMDeviceInterface (which NMDevice implements) so that when we have NMDevice exported over DBUS, there's a common NMDevice interface which all instances have, plus there's a device specific interface for each specific type. Remove functions (nm_device_is_802_3_ethernet) and (nm_device_is_802_11_wireless). There are already standard GObject macros for type safe checks. Use the updated supplican manager API. * src/nm-device-interface.h: * src/nm-device-interface.c: * src/nm-call-store.h: * src/nm-call-store.c: Implement. * src/supplicant-manager/nm-supplicant-interface.c: * src/supplicant-manager/nm-supplicant-interface.h: * src/supplicant-manager/nm-supplicant-manager.c: * src/supplicant-manager/nm-supplicant-manager.h: - Remove all private data type references from public header files. - Remove all references to other NM classes, this class is just a proxy between wpa_supplicant and NM so it doesn't have to know any internals. - Convert to dbus-glib bindings. - Type safe checks for public methods' arguments. - Store pending DBUS call ids to NMCallStore. * src/supplicant-manager/nm-supplicant-config.c: - Store config values in a GHashTable instead of GSList. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2285 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 31 + include/NetworkManager.h | 20 +- src/Makefile.am | 4 + src/NetworkManager.c | 105 +- src/NetworkManagerAP.c | 99 + src/NetworkManagerAP.h | 1 + src/NetworkManagerAPList.c | 140 +- src/NetworkManagerAPList.h | 8 +- src/NetworkManagerPolicy.c | 27 +- src/NetworkManagerUtils.c | 4 +- src/autoip.c | 4 +- src/backends/NetworkManagerGeneric.c | 4 +- src/backends/NetworkManagerSuSE.c | 4 +- src/nm-activation-request.c | 2 +- src/nm-call-store.c | 147 ++ src/nm-call-store.h | 27 + src/nm-dbus-device.c | 16 +- src/nm-dbus-nm.c | 8 +- src/nm-device-802-11-wireless.c | 438 ++--- src/nm-device-802-11-wireless.h | 16 +- src/nm-device-802-3-ethernet.c | 59 +- src/nm-device-802-3-ethernet.h | 15 +- src/nm-device-interface.c | 142 ++ src/nm-device-interface.h | 55 + src/nm-device-private.h | 4 + src/nm-device.c | 466 +++-- src/nm-device.h | 10 +- src/supplicant-manager/nm-supplicant-config.c | 298 +-- src/supplicant-manager/nm-supplicant-config.h | 18 +- .../nm-supplicant-interface.c | 1684 +++++------------ .../nm-supplicant-interface.h | 17 +- .../nm-supplicant-manager.c | 149 +- .../nm-supplicant-manager.h | 13 +- .../nm-supplicant-marshal.list | 1 + 34 files changed, 1880 insertions(+), 2156 deletions(-) create mode 100644 src/nm-call-store.c create mode 100644 src/nm-call-store.h create mode 100644 src/nm-device-interface.c create mode 100644 src/nm-device-interface.h diff --git a/ChangeLog b/ChangeLog index cfcf1d9682..ec17b44163 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,36 @@ 2007-02-05 Tambet Ingo + Make NMDevice abstract class, remove almost all references to it's + subclasses (the last place gets removed with new policy manager). Add + NMDeviceInterface (which NMDevice implements) so that when we have + NMDevice exported over DBUS, there's a common NMDevice interface which + all instances have, plus there's a device specific interface for each + specific type. + Remove functions (nm_device_is_802_3_ethernet) and + (nm_device_is_802_11_wireless). There are already standard GObject macros + for type safe checks. + Use the updated supplican manager API. + + * src/nm-device-interface.h: + * src/nm-device-interface.c: + * src/nm-call-store.h: + * src/nm-call-store.c: Implement. + + * src/supplicant-manager/nm-supplicant-interface.c: + * src/supplicant-manager/nm-supplicant-interface.h: + * src/supplicant-manager/nm-supplicant-manager.c: + * src/supplicant-manager/nm-supplicant-manager.h: + - Remove all private data type references from public header files. + - Remove all references to other NM classes, this class is just a + proxy between wpa_supplicant and NM so it doesn't have to know + any internals. + - Convert to dbus-glib bindings. + - Type safe checks for public methods' arguments. + - Store pending DBUS call ids to NMCallStore. + + * src/supplicant-manager/nm-supplicant-config.c: + - Store config values in a GHashTable instead of GSList. + * src/NetworkManagerMain.h: Remove all references to DHCP manager. * src/NetworkManager.c: Don't initialize the DHCP manager, it's a diff --git a/include/NetworkManager.h b/include/NetworkManager.h index 2cc9d3fb5f..e553764265 100644 --- a/include/NetworkManager.h +++ b/include/NetworkManager.h @@ -173,4 +173,22 @@ typedef enum NMActStage NM_ACT_STAGE_CANCELLED } NMActStage; -#endif + +/* + * Device states. Will obsolete NMActStage soon. + */ +typedef enum +{ + NM_DEVICE_STATE_UNKNOWN = 0, + NM_DEVICE_STATE_DISCONNECTED, + NM_DEVICE_STATE_PREPARE, + NM_DEVICE_STATE_CONFIG, + NM_DEVICE_STATE_NEED_AUTH, + NM_DEVICE_STATE_IP_CONFIG, + NM_DEVICE_STATE_ACTIVATED, + NM_DEVICE_STATE_FAILED, + NM_DEVICE_STATE_CANCELLED, +} NMDeviceState; + + +#endif /* NETWORK_MANAGER_H */ diff --git a/src/Makefile.am b/src/Makefile.am index 53cb168214..811470adf5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,8 +12,12 @@ INCLUDES = -I${top_srcdir} \ sbin_PROGRAMS = NetworkManager NetworkManager_SOURCES = \ + nm-call-store.c \ + nm-call-store.h \ nm-device.c \ nm-device.h \ + nm-device-interface.c \ + nm-device-interface.h \ nm-device-private.h \ nm-device-802-3-ethernet.c \ nm-device-802-3-ethernet.h \ diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 04f224aa8c..73fd6de278 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -103,6 +103,84 @@ static char *nm_get_device_interface_from_hal (LibHalContext *ctx, const char *u } +/* + * nm_device_test_wireless_extensions + * + * Test whether a given device is a wireless one or not. + * + */ +static NMDeviceType +discover_device_type (LibHalContext *ctx, const char *udi) +{ + char * category = NULL; + + if (libhal_device_property_exists (ctx, udi, "info.category", NULL)) + category = libhal_device_get_property_string(ctx, udi, "info.category", NULL); + if (category && (!strcmp (category, "net.80211"))) + return DEVICE_TYPE_802_11_WIRELESS; + else if (category && (!strcmp (category, "net.80203"))) + return DEVICE_TYPE_802_3_ETHERNET; + return DEVICE_TYPE_UNKNOWN; +} + +/* + * nm_get_device_driver_name + * + * Get the device's driver name from HAL. + * + */ +static char * +nm_get_device_driver_name (LibHalContext *ctx, const char *udi) +{ + char * driver_name = NULL; + char * physdev_udi = NULL; + + g_return_val_if_fail (ctx != NULL, NULL); + g_return_val_if_fail (udi != NULL, NULL); + + physdev_udi = libhal_device_get_property_string (ctx, udi, "net.physical_device", NULL); + if (physdev_udi && libhal_device_property_exists (ctx, physdev_udi, "info.linux.driver", NULL)) + { + char *drv = libhal_device_get_property_string (ctx, physdev_udi, "info.linux.driver", NULL); + driver_name = g_strdup (drv); + g_free (drv); + } + g_free (physdev_udi); + + return driver_name; +} + + +static NMDevice * +create_nm_device (LibHalContext *ctx, + const char *iface, + const char *udi) +{ + NMDevice *dev; + char *driver; + NMDeviceType type; + + type = discover_device_type (ctx, udi); + driver = nm_get_device_driver_name (ctx, udi); + + switch (type) { + case DEVICE_TYPE_802_11_WIRELESS: + dev = (NMDevice *) nm_device_802_11_wireless_new (iface, udi, driver, FALSE, nm_data); + break; + case DEVICE_TYPE_802_3_ETHERNET: + dev = (NMDevice *) nm_device_802_3_ethernet_new (iface, udi, driver, FALSE, nm_data); + break; + + default: + g_assert_not_reached (); + } + + g_free (driver); + + return dev; +} + + /* * nm_create_device_and_add_to_list * @@ -136,16 +214,16 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, cons if ((dev = nm_get_device_by_iface (data, iface))) return (NULL); - if ((dev = nm_device_new (iface, udi, test_device, test_device_type, data))) { - nm_info ("Now managing %s device '%s'.", - nm_device_is_802_11_wireless (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)", - nm_device_get_iface (dev)); + if ((dev = create_nm_device (data->hal_ctx, iface, udi))) { + nm_info ("Now managing %s device '%s'.", + NM_IS_DEVICE_802_11_WIRELESS (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)", + nm_device_get_iface (dev)); - data->dev_list = g_slist_append (data->dev_list, dev); - nm_device_deactivate (dev); + data->dev_list = g_slist_append (data->dev_list, dev); + nm_device_deactivate (dev); - nm_policy_schedule_device_change_check (data); - nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_ADDED); + nm_policy_schedule_device_change_check (data); + nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_ADDED); } return dev; @@ -549,16 +627,15 @@ static void nm_data_free (NMData *data) if ((req = nm_vpn_manager_get_vpn_act_request (data->vpn_manager))) nm_vpn_manager_deactivate_vpn_connection (data->vpn_manager, nm_vpn_act_request_get_parent_dev (req)); - if (data->netlink_monitor) - { - g_object_unref (G_OBJECT (data->netlink_monitor)); - data->netlink_monitor = NULL; - } - /* Stop and destroy all devices */ g_slist_foreach (data->dev_list, (GFunc) device_stop_and_free, NULL); g_slist_free (data->dev_list); + if (data->netlink_monitor) { + g_object_unref (G_OBJECT (data->netlink_monitor)); + data->netlink_monitor = NULL; + } + nm_ap_list_unref (data->allowed_ap_list); nm_ap_list_unref (data->invalid_ap_list); diff --git a/src/NetworkManagerAP.c b/src/NetworkManagerAP.c index 7ba16d9d04..6328b7675e 100644 --- a/src/NetworkManagerAP.c +++ b/src/NetworkManagerAP.c @@ -133,6 +133,105 @@ NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *src_ap) } +#define IEEE80211_CAP_ESS 0x0001 +#define IEEE80211_CAP_IBSS 0x0002 +#define IEEE80211_CAP_PRIVACY 0x0010 + + +static void +foreach_property_cb (gpointer key, gpointer value, gpointer user_data) +{ + GValue *variant = (GValue *) value; + NMAccessPoint *ap = (NMAccessPoint *) user_data; + + if (G_VALUE_HOLDS_BOXED (variant)) { + GArray *array = g_value_get_boxed (variant); + + if (!strcmp (key, "ssid")) { + char ssid[33]; + int ssid_len = sizeof (ssid); + + if (array->len < sizeof (ssid)) + ssid_len = array->len; + if (ssid_len <= 0) + return; + /* Stupid ieee80211 layer uses */ + if (((ssid_len == 8) || (ssid_len == 9)) + && (memcmp (array->data, "", 8) == 0)) + return; + memset (&ssid, 0, sizeof (ssid)); + memcpy (&ssid, array->data, ssid_len); + ssid[32] = '\0'; + nm_ap_set_essid (ap, ssid); + } else if (!strcmp (key, "bssid")) { + struct ether_addr addr; + + if (array->len != ETH_ALEN) + return; + 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; + if (array->len <= 0 || array->len > WPA_MAX_IE_LEN) + return; + nm_ap_add_capabilities_from_ie (ap, ie, array->len); + } else if (!strcmp (key, "rsnie")) { + guint8 * ie = (guint8 *) array->data; + if (array->len <= 0 || array->len > WPA_MAX_IE_LEN) + return; + nm_ap_add_capabilities_from_ie (ap, ie, array->len); + } + } else if (G_VALUE_HOLDS_INT (variant)) { + gint32 int_val = g_value_get_int (variant); + + if (!strcmp (key, "frequency")) { + double freq = (double) int_val; + nm_ap_set_freq (ap, freq); + } else if (!strcmp (key, "maxrate")) { + nm_ap_set_rate (ap, int_val); + } + } else if (G_VALUE_HOLDS_UINT (variant)) { + guint32 val = g_value_get_uint (variant); + + if (!strcmp (key, "capabilities")) { + if (val & IEEE80211_CAP_ESS) { + nm_ap_set_mode (ap, IW_MODE_INFRA); + } else if (val & IEEE80211_CAP_IBSS) { + nm_ap_set_mode (ap, IW_MODE_ADHOC); + } + + if (val & IEEE80211_CAP_PRIVACY) { + if (nm_ap_get_capabilities (ap) & NM_802_11_CAP_PROTO_NONE) + nm_ap_add_capabilities_for_wep (ap); + } + } + } +} + + +NMAccessPoint * +nm_ap_new_from_properties (GHashTable *properties) +{ + NMAccessPoint *ap; + GTimeVal cur_time; + + g_return_val_if_fail (properties != NULL, NULL); + + ap = nm_ap_new (); + + g_hash_table_foreach (properties, foreach_property_cb, ap); + + g_get_current_time (&cur_time); + nm_ap_set_last_seen (ap, &cur_time); + + if (!nm_ap_get_essid (ap)) + nm_ap_set_broadcast (ap, FALSE); + + return ap; +} + + /* * AP refcounting functions */ diff --git a/src/NetworkManagerAP.h b/src/NetworkManagerAP.h index dd2135eb12..7ba390d2f3 100644 --- a/src/NetworkManagerAP.h +++ b/src/NetworkManagerAP.h @@ -33,6 +33,7 @@ typedef struct NMAccessPoint NMAccessPoint; NMAccessPoint * nm_ap_new (void); NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *ap); +NMAccessPoint * nm_ap_new_from_properties (GHashTable *properties); void nm_ap_unref (NMAccessPoint *ap); void nm_ap_ref (NMAccessPoint *ap); diff --git a/src/NetworkManagerAPList.c b/src/NetworkManagerAPList.c index 1209f0b462..c968fc4c3d 100644 --- a/src/NetworkManagerAPList.c +++ b/src/NetworkManagerAPList.c @@ -353,123 +353,6 @@ NMAccessPoint *nm_ap_list_get_ap_by_address (NMAccessPointList *list, const stru } -/* - * nm_ap_list_merge_scanned_ap - * - * Given an AP list and an access point, merge the access point into the list. - * If the AP is already in the list, merge just the /attributes/ together for that - * AP, if its not already in the list then just add it. This doesn't merge all - * attributes, just ones that are likely to be new from the scan. - * - * Returns: FALSE if the AP was not new and was merged - * TRUE if the ap was completely new - * - */ -gboolean -nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, - NMAccessPointList *list, - NMAccessPoint *merge_ap) -{ - NMAccessPoint * list_ap = NULL; - gboolean strength_changed = FALSE; - gboolean new = FALSE; - const struct ether_addr * merge_bssid; - - g_return_val_if_fail (dev != NULL, FALSE); - g_return_val_if_fail (list != NULL, FALSE); - g_return_val_if_fail (merge_ap != NULL, FALSE); - - merge_bssid = nm_ap_get_address (merge_ap); - if (nm_ethernet_address_is_valid (merge_bssid) && (list_ap = nm_ap_list_get_ap_by_address (list, merge_bssid))) - { - /* First, we check for an address match. If the merge AP has a valid - * BSSID and the same address as a list AP, then the merge AP and - * the list AP must be the same physical AP. The list AP properties must - * be from a previous scan so the time_last_seen's are not equal. Update - * encryption, authentication method, strength, and the time_last_seen. */ - - const char * devlist_essid = nm_ap_get_essid (list_ap); - const char * merge_essid = nm_ap_get_essid (merge_ap); - const GTimeVal *merge_ap_seen = nm_ap_get_last_seen (merge_ap); - - /* Did the AP's name change? */ - if (!devlist_essid || !merge_essid || nm_null_safe_strcmp (devlist_essid, merge_essid)) - { - nm_dbus_signal_wireless_network_change (dev, list_ap, - NETWORK_STATUS_DISAPPEARED, -1); - new = TRUE; - } - - nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap)); - if (nm_ap_get_strength (merge_ap) != nm_ap_get_strength (list_ap)) { - nm_ap_set_strength (list_ap, nm_ap_get_strength (merge_ap)); - strength_changed = TRUE; - } - nm_ap_set_last_seen (list_ap, merge_ap_seen); - nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap)); - - /* If the AP is noticed in a scan, it's automatically no longer - * artificial, since it clearly exists somewhere. - */ - nm_ap_set_artificial (list_ap, FALSE); - - /* Have to change AP's name _after_ dbus signal for old network name - * has gone out. - */ - nm_ap_set_essid (list_ap, merge_essid); - } - else if ((list_ap = nm_ap_list_get_ap_by_essid (list, nm_ap_get_essid (merge_ap)))) - { - /* Second, we check for an ESSID match. In this case, - * a list AP has the same non-NULL ESSID as the merge AP. Update the - * encryption and authentication method. Update the strength and address - * except when the time_last_seen of the list AP is the same as the - * time_last_seen of the merge AP and the strength of the list AP is greater - * than or equal to the strength of the merge AP. If the time_last_seen's are - * equal, the merge AP and the list AP come from the same scan. - * Update the time_last_seen. */ - - const GTimeVal * merge_ap_seen = nm_ap_get_last_seen (merge_ap); - const GTimeVal * list_ap_seen = nm_ap_get_last_seen (list_ap); - const int merge_ap_strength = nm_ap_get_strength (merge_ap); - - nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap)); - - if (!((list_ap_seen->tv_sec == merge_ap_seen->tv_sec) - && (nm_ap_get_strength (list_ap) >= merge_ap_strength))) - { - nm_ap_set_strength (list_ap, merge_ap_strength); - nm_ap_set_address (list_ap, nm_ap_get_address (merge_ap)); - } - nm_ap_set_last_seen (list_ap, merge_ap_seen); - nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap)); - - /* If the AP is noticed in a scan, it's automatically no longer - * artificial, since it clearly exists somewhere. - */ - nm_ap_set_artificial (list_ap, FALSE); - } else { - /* Add the merge AP to the list. */ - nm_ap_list_append_ap (list, merge_ap); - list_ap = merge_ap; - new = TRUE; - } - - if (list_ap && strength_changed && !new) { - const int new_strength = nm_ap_get_strength (list_ap); - nm_dbus_signal_wireless_network_change (dev, list_ap, - NETWORK_STATUS_STRENGTH_CHANGED, new_strength); - } - - if (list_ap && new) { - nm_dbus_signal_wireless_network_change (dev, list_ap, - NETWORK_STATUS_APPEARED, -1); - } - - return TRUE; -} - - /* * nm_ap_list_copy_properties * @@ -513,27 +396,23 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou * */ void -nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev, - NMAccessPoint *ap, +nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap, NMAccessPointList *search_list) { - NMAccessPoint * found_ap; + NMAccessPoint *found_ap; + const char *essid; g_return_if_fail (ap != NULL); - if (!search_list) - return; - /* Ignore APs that already have an ESSID */ - if (nm_ap_get_essid (ap)) + if (!search_list || nm_ap_get_essid (ap)) return; found_ap = nm_ap_list_get_ap_by_address (search_list, nm_ap_get_address (ap)); - if (!found_ap || !nm_ap_get_essid (found_ap)) - return; + essid = found_ap ? nm_ap_get_essid (found_ap) : NULL; - nm_ap_set_essid (ap, nm_ap_get_essid (found_ap)); - nm_dbus_signal_wireless_network_change (dev, ap, NETWORK_STATUS_APPEARED, 0); + if (essid) + nm_ap_set_essid (ap, essid); } @@ -546,8 +425,7 @@ nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev, * */ void -nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev, - NMAccessPointList *dest, +nm_ap_list_copy_essids_by_address (NMAccessPointList *dest, NMAccessPointList *source) { NMAPListIter *iter; @@ -560,7 +438,7 @@ nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev, return; while ((dest_ap = nm_ap_list_iter_next (iter))) - nm_ap_list_copy_one_essid_by_address (dev, dest_ap, source); + nm_ap_list_copy_one_essid_by_address (dest_ap, source); nm_ap_list_iter_free (iter); } diff --git a/src/NetworkManagerAPList.h b/src/NetworkManagerAPList.h index 972156b07f..d3b0e43201 100644 --- a/src/NetworkManagerAPList.h +++ b/src/NetworkManagerAPList.h @@ -26,8 +26,6 @@ #include "NetworkManager.h" #include "NetworkManagerMain.h" #include "NetworkManagerAP.h" -#include "nm-device.h" -#include "nm-device-802-11-wireless.h" typedef struct NMAccessPointList NMAccessPointList; typedef struct NMAPListIter NMAPListIter; @@ -48,10 +46,8 @@ NMAccessPoint * nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char NMAccessPoint * nm_ap_list_get_ap_by_address (NMAccessPointList *list, const struct ether_addr *addr); void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source); -void nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev, NMAccessPointList *dest, NMAccessPointList *source); -void nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev, NMAccessPoint *ap, NMAccessPointList *search_list); - -gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointList *list, NMAccessPoint *merge_ap); +void nm_ap_list_copy_essids_by_address (NMAccessPointList *dest, NMAccessPointList *source); +void nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap, NMAccessPointList *search_list); NMNetworkType nm_ap_list_get_type (NMAccessPointList *list); diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 05299c3e89..5f8ac40b8a 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -63,7 +63,7 @@ static gboolean nm_policy_activation_finish (gpointer user_data) dev = nm_act_request_get_dev (req); g_assert (dev); - if (nm_device_is_802_11_wireless (dev)) + if (NM_IS_DEVICE_802_11_WIRELESS (dev)) ap = nm_act_request_get_ap (req); nm_device_activation_success_handler (dev, req); @@ -126,7 +126,7 @@ static gboolean nm_policy_activation_failed (gpointer user_data) nm_device_activation_failure_handler (dev, req); - if (nm_device_is_802_11_wireless (dev)) + if (NM_IS_DEVICE_802_11_WIRELESS (dev)) ap = nm_act_request_get_ap (req); nm_info ("Activation (%s) failed.", nm_device_get_iface (dev)); @@ -204,7 +204,7 @@ static NMDevice * nm_policy_auto_get_best_device (NMData *data, NMAccessPoint ** if (!(caps & NM_DEVICE_CAP_NM_SUPPORTED)) continue; - if (nm_device_is_802_3_ethernet (dev)) + if (NM_IS_DEVICE_802_3_ETHERNET (dev)) { /* We never automatically choose devices that don't support carrier detect */ if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) @@ -222,7 +222,7 @@ static NMDevice * nm_policy_auto_get_best_device (NMData *data, NMAccessPoint ** best_wired_prio = prio; } } - else if (nm_device_is_802_11_wireless (dev) && data->wireless_enabled) + else if (NM_IS_DEVICE_802_11_WIRELESS (dev) && data->wireless_enabled) { /* Don't automatically choose a device that doesn't support wireless scanning */ if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN)) @@ -309,8 +309,8 @@ nm_policy_device_change_check (gpointer user_data) /* Don't interrupt semi-supported devices either. If the user chose one, they must * explicitly choose to move to another device, we're not going to move for them. */ - if ((nm_device_is_802_3_ethernet (old_dev) && !(caps & NM_DEVICE_CAP_CARRIER_DETECT)) - || (nm_device_is_802_11_wireless (old_dev) && !(caps & NM_DEVICE_CAP_WIRELESS_SCAN))) { + if ((NM_IS_DEVICE_802_3_ETHERNET (old_dev) && !(caps & NM_DEVICE_CAP_CARRIER_DETECT)) + || (NM_IS_DEVICE_802_11_WIRELESS (old_dev) && !(caps & NM_DEVICE_CAP_WIRELESS_SCAN))) { nm_info ("Old device '%s' was semi-supported and user chosen, won't change unless told to.", nm_device_get_iface (old_dev)); goto out; @@ -353,7 +353,7 @@ nm_policy_device_change_check (gpointer user_data) gboolean old_user_requested = nm_act_request_get_user_requested (old_act_req); gboolean old_has_link = nm_device_has_active_link (old_dev); - if (nm_device_is_802_3_ethernet (old_dev)) { + if (NM_IS_DEVICE_802_3_ETHERNET (old_dev)) { /* Only switch if the old device was not user requested, and we are switching to * a new device. Note that new_dev will never be wireless since automatic device picking * above will prefer a wired device to a wireless device. @@ -365,9 +365,9 @@ nm_policy_device_change_check (gpointer user_data) nm_device_get_iface (old_dev)); do_switch = TRUE; } - } else if (nm_device_is_802_11_wireless (old_dev)) { + } else if (NM_IS_DEVICE_802_11_WIRELESS (old_dev)) { /* Only switch if the old device's wireless config is invalid */ - if (nm_device_is_802_11_wireless (new_dev)) { + if (NM_IS_DEVICE_802_11_WIRELESS (new_dev)) { NMAccessPoint *old_ap = nm_act_request_get_ap (old_act_req); const char * old_essid = nm_ap_get_essid (old_ap); int old_mode = nm_ap_get_mode (old_ap); @@ -398,7 +398,7 @@ nm_policy_device_change_check (gpointer user_data) same_essid, old_has_link); do_switch = TRUE; } - } else if (nm_device_is_802_3_ethernet (new_dev)) { + } else if (NM_IS_DEVICE_802_3_ETHERNET (new_dev)) { /* Always prefer Ethernet over wireless, unless the user explicitly switched away. */ if (!old_user_requested) do_switch = TRUE; @@ -406,7 +406,7 @@ nm_policy_device_change_check (gpointer user_data) } } - if (do_switch && (nm_device_is_802_3_ethernet (new_dev) || (nm_device_is_802_11_wireless (new_dev) && ap))) { + if (do_switch && (NM_IS_DEVICE_802_3_ETHERNET (new_dev) || (NM_IS_DEVICE_802_11_WIRELESS (new_dev) && ap))) { NMActRequest * act_req = NULL; if ((act_req = nm_act_request_new (data, new_dev, ap, FALSE))) { @@ -582,7 +582,7 @@ nm_policy_device_list_update_from_allowed_list (gpointer user_data) NMDevice *dev = (NMDevice *)(elt->data); NMDevice80211Wireless * wdev; - if (!nm_device_is_802_11_wireless (dev)) + if (!NM_IS_DEVICE_802_11_WIRELESS (dev)) continue; wdev = NM_DEVICE_802_11_WIRELESS (dev); @@ -592,8 +592,7 @@ nm_policy_device_list_update_from_allowed_list (gpointer user_data) * broadcasting their ESSID, if we have their MAC address in our * allowed list. */ - nm_ap_list_copy_essids_by_address (wdev, - nm_device_802_11_wireless_ap_list_get (wdev), + nm_ap_list_copy_essids_by_address (nm_device_802_11_wireless_ap_list_get (wdev), data->allowed_ap_list); nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (wdev), data->allowed_ap_list); diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index e3aabbb57c..3f7cfc1810 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -302,7 +302,7 @@ void nm_print_device_capabilities (NMDevice *dev) return; } - if (nm_device_is_802_3_ethernet (dev)) + if (NM_IS_DEVICE_802_3_ETHERNET (dev)) { if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) { @@ -312,7 +312,7 @@ void nm_print_device_capabilities (NMDevice *dev) full_support = FALSE; } } - else if (nm_device_is_802_11_wireless (dev)) + else if (NM_IS_DEVICE_802_11_WIRELESS (dev)) { if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN)) { diff --git a/src/autoip.c b/src/autoip.c index 0a0a81a59b..3ae1b747e3 100644 --- a/src/autoip.c +++ b/src/autoip.c @@ -224,9 +224,9 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip) memset (&saddr, 0, sizeof (saddr)); strncpy (saddr.sa_data, nm_device_get_iface (dev), sizeof (saddr.sa_data)); - if (nm_device_is_802_3_ethernet (dev)) + if (NM_IS_DEVICE_802_3_ETHERNET (dev)) nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &addr); - else if (nm_device_is_802_11_wireless (dev)) + else if (NM_IS_DEVICE_802_11_WIRELESS (dev)) nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &addr); else goto out; diff --git a/src/backends/NetworkManagerGeneric.c b/src/backends/NetworkManagerGeneric.c index 1b683a725a..a4201dfe6f 100644 --- a/src/backends/NetworkManagerGeneric.c +++ b/src/backends/NetworkManagerGeneric.c @@ -272,9 +272,9 @@ void nm_generic_device_add_ip6_link_address (NMDevice *dev) struct ether_addr hw_addr; unsigned char eui[8]; - if (nm_device_is_802_3_ethernet (dev)) + if (NM_IS_DEVICE_802_3_ETHERNET (dev)) nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr); - else if (nm_device_is_802_11_wireless (dev)) + else if (NM_IS_DEVICE_802_11_WIRELESS (dev)) nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr); memcpy (eui, &(hw_addr.ether_addr_octet), sizeof (hw_addr.ether_addr_octet)); diff --git a/src/backends/NetworkManagerSuSE.c b/src/backends/NetworkManagerSuSE.c index b7b33761b1..cae800a87b 100644 --- a/src/backends/NetworkManagerSuSE.c +++ b/src/backends/NetworkManagerSuSE.c @@ -316,9 +316,9 @@ void *nm_system_device_get_system_config (NMDevice *dev, NMData *app_data) sys_data = g_malloc0 (sizeof (SuSEDeviceConfigData)); sys_data->use_dhcp = TRUE; - if (nm_device_is_802_3_ethernet (dev)) + if (NM_IS_DEVICE_802_3_ETHERNET (dev)) nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr); - else if (nm_device_is_802_11_wireless (dev)) + else if (NM_IS_DEVICE_802_11_WIRELESS (dev)) nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr); sprintf (mac, "%02x:%02x:%02x:%02x:%02x:%02x", diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 7d159245af..ed702cdf42 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -52,7 +52,7 @@ NMActRequest * nm_act_request_new (NMData *data, NMDevice *dev, NMAccessPoint *a g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (dev != NULL, NULL); - if (nm_device_is_802_11_wireless (dev)) + if (NM_IS_DEVICE_802_11_WIRELESS (dev)) g_return_val_if_fail (ap != NULL, NULL); req = g_malloc0 (sizeof (NMActRequest)); diff --git a/src/nm-call-store.c b/src/nm-call-store.c new file mode 100644 index 0000000000..4019e83214 --- /dev/null +++ b/src/nm-call-store.c @@ -0,0 +1,147 @@ +#include "nm-call-store.h" +#include "nm-utils.h" + +NMCallStore * +nm_call_store_new (void) +{ + return g_hash_table_new_full (NULL, NULL, NULL, + (GDestroyNotify) g_hash_table_destroy); +} + +static void +object_destroyed_cb (gpointer data, GObject *object) +{ + g_hash_table_remove ((NMCallStore *) data, object); +} + +void +nm_call_store_add (NMCallStore *store, + GObject *object, + gpointer *call_id) +{ + GHashTable *call_ids_hash; + + g_return_if_fail (store != NULL); + g_return_if_fail (object != NULL); + g_return_if_fail (call_id != NULL); + + call_ids_hash = g_hash_table_lookup (store, object); + if (!call_ids_hash) { + call_ids_hash = g_hash_table_new (NULL, NULL); + g_hash_table_insert (store, object, call_ids_hash); + g_object_weak_ref (object, object_destroyed_cb, store); + } + + g_hash_table_insert (call_ids_hash, call_id, NULL); +} + +void +nm_call_store_remove (NMCallStore *store, + GObject *object, + gpointer call_id) +{ + GHashTable *call_ids_hash; + + g_return_if_fail (store != NULL); + g_return_if_fail (object != NULL); + g_return_if_fail (call_id != NULL); + + call_ids_hash = g_hash_table_lookup (store, object); + if (!call_ids_hash) { + nm_warning ("Trying to move a non-existant call id."); + return; + } + + if (!g_hash_table_remove (call_ids_hash, call_id)) + nm_warning ("Trying to move a non-existant call id."); + + if (g_hash_table_size (call_ids_hash) == 0) { + g_hash_table_remove (store, object); + g_object_weak_unref (object, object_destroyed_cb, store); + } +} + +typedef struct { + GObject *object; + gint count; + NMCallStoreFunc callback; + gpointer user_data; +} StoreForeachInfo; + +static void +call_callback (gpointer key, gpointer value, gpointer user_data) +{ + StoreForeachInfo *info = (StoreForeachInfo *) user_data; + + if (info->count >= 0) { + if (info->callback (info->object, key, info->user_data)) + info->count++; + else + info->count = -1; + } +} + +static void +call_all_callbacks (gpointer key, gpointer value, gpointer user_data) +{ + StoreForeachInfo *info = (StoreForeachInfo *) user_data; + + info->object = G_OBJECT (key); + g_hash_table_foreach ((GHashTable *) value, call_callback, info); +} + +int +nm_call_store_foreach (NMCallStore *store, + GObject *object, + NMCallStoreFunc callback, + gpointer user_data) +{ + StoreForeachInfo info; + + g_return_val_if_fail (store != NULL, -1); + g_return_val_if_fail (callback != NULL, -1); + + info.object = object; + info.count = 0; + info.callback = callback; + info.user_data = user_data; + + if (object) { + GHashTable *call_ids_hash; + + call_ids_hash = g_hash_table_lookup (store, object); + if (!call_ids_hash) { + nm_warning ("Object not in store"); + return -1; + } + + g_hash_table_foreach (call_ids_hash, call_callback, &info); + } else { + g_hash_table_foreach (store, call_all_callbacks, &info); + } + + return info.count; +} + +static void +remove_weakref (gpointer key, gpointer value, gpointer user_data) +{ + g_object_weak_unref (G_OBJECT (key), object_destroyed_cb, user_data); +} + +void +nm_call_store_clear (NMCallStore *store) +{ + g_return_if_fail (store); + + g_hash_table_foreach (store, remove_weakref, store); + g_hash_table_remove_all (store); +} + +void +nm_call_store_destroy (NMCallStore *store) +{ + g_return_if_fail (store); + + g_hash_table_destroy (store); +} diff --git a/src/nm-call-store.h b/src/nm-call-store.h new file mode 100644 index 0000000000..a4574cbffb --- /dev/null +++ b/src/nm-call-store.h @@ -0,0 +1,27 @@ +#ifndef NM_CALLBACK_STORE_H +#define NM_CALLBACK_STORE_H + +#include + +typedef GHashTable NMCallStore; + +typedef gboolean (*NMCallStoreFunc) (GObject *object, gpointer call_id, gpointer user_data); + +NMCallStore *nm_call_store_new (void); +void nm_call_store_add (NMCallStore *store, + GObject *object, + gpointer *call_id); + +void nm_call_store_remove (NMCallStore *store, + GObject *object, + gpointer call_id); + +int nm_call_store_foreach (NMCallStore *store, + GObject *object, + NMCallStoreFunc callback, + gpointer user_data); + +void nm_call_store_clear (NMCallStore *store); +void nm_call_store_destroy (NMCallStore *store); + +#endif /* NM_CALLBACK_STORE_H */ diff --git a/src/nm-dbus-device.c b/src/nm-dbus-device.c index 896262e890..98b93d1dc4 100644 --- a/src/nm-dbus-device.c +++ b/src/nm-dbus-device.c @@ -173,9 +173,9 @@ nm_dbus_device_get_hw_address (DBusConnection *connection, } memset (&addr, 0, sizeof (struct ether_addr)); - if (nm_device_is_802_3_ethernet (data->dev)) { + if (NM_IS_DEVICE_802_3_ETHERNET (data->dev)) { nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (data->dev), &addr); - } else if (nm_device_is_802_11_wireless (data->dev)) { + } else if (NM_IS_DEVICE_802_11_WIRELESS (data->dev)) { nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (data->dev), &addr); } memset (char_addr, 0, 20); @@ -199,7 +199,7 @@ nm_dbus_device_get_mode (DBusConnection *connection, g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data->dev != NULL, NULL); - if (!nm_device_is_802_11_wireless (data->dev)) { + if (!NM_IS_DEVICE_802_11_WIRELESS (data->dev)) { reply = new_invalid_device_type_error (message); goto out; } @@ -260,7 +260,7 @@ nm_dbus_device_get_active_network (DBusConnection *connection, /* Only wireless devices have an active network */ dev = data->dev; - if (!nm_device_is_802_11_wireless (dev)) + if (!NM_IS_DEVICE_802_11_WIRELESS (dev)) { reply = new_invalid_device_type_error (message); goto out; @@ -318,7 +318,7 @@ nm_dbus_device_get_networks (DBusConnection *connection, g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (data->dev != NULL, NULL); - if (!nm_device_is_802_11_wireless (data->dev)) { + if (!NM_IS_DEVICE_802_11_WIRELESS (data->dev)) { reply = new_invalid_device_type_error (message); goto out; } @@ -516,9 +516,9 @@ nm_dbus_device_get_properties (DBusConnection *connection, act_stage = active ? nm_act_request_get_stage (nm_device_get_act_request (dev)) : NM_ACT_STAGE_UNKNOWN; memset (hw_addr_buf, 0, 20); - if (nm_device_is_802_3_ethernet (dev)) + if (NM_IS_DEVICE_802_3_ETHERNET (dev)) nm_device_802_3_ethernet_get_address (NM_DEVICE_802_3_ETHERNET (dev), &hw_addr); - else if (nm_device_is_802_11_wireless (dev)) + else if (NM_IS_DEVICE_802_11_WIRELESS (dev)) nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr); iw_ether_ntop (&hw_addr, hw_addr_buf); @@ -543,7 +543,7 @@ nm_dbus_device_get_properties (DBusConnection *connection, primary_dns = nm_utils_inet_ip4_address_as_string (primary_dns_addr); secondary_dns = nm_utils_inet_ip4_address_as_string (secondary_dns_addr); - if (nm_device_is_802_11_wireless (dev)) { + if (NM_IS_DEVICE_802_11_WIRELESS (dev)) { NMDevice80211Wireless * wdev = NM_DEVICE_802_11_WIRELESS (dev); NMActRequest * req = nm_device_get_act_request (dev); NMAccessPoint * ap; diff --git a/src/nm-dbus-nm.c b/src/nm-dbus-nm.c index 2b5dcb8321..d75c6c4b6c 100644 --- a/src/nm-dbus-nm.c +++ b/src/nm-dbus-nm.c @@ -266,7 +266,7 @@ nm_dbus_nm_set_active_device (DBusConnection *connection, goto out; } - if (nm_device_is_802_11_wireless (dev)) { + if (NM_IS_DEVICE_802_11_WIRELESS (dev)) { NMAPSecurity * security = NULL; char * essid = NULL; gboolean fallback = FALSE; @@ -315,7 +315,7 @@ nm_dbus_nm_set_active_device (DBusConnection *connection, g_object_unref (G_OBJECT (security)); nm_info ("User Switch: %s / %s", dev_path, essid); - } else if (nm_device_is_802_3_ethernet (dev)) { + } else if (NM_IS_DEVICE_802_3_ETHERNET (dev)) { nm_info ("User Switch: %s", dev_path); } @@ -382,7 +382,7 @@ nm_dbus_nm_create_wireless_network (DBusConnection *connection, goto out; } - if ( !nm_device_is_802_11_wireless (dev) + if ( !NM_IS_DEVICE_802_11_WIRELESS (dev) || !dbus_message_iter_next (&iter) || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) { reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE); @@ -551,7 +551,7 @@ nm_dbus_nm_set_wireless_enabled (DBusConnection *connection, for (elt = data->dev_list; elt; elt = g_slist_next (elt)) { NMDevice * dev = NM_DEVICE (elt->data); - if (nm_device_is_802_11_wireless (dev)) { + if (NM_IS_DEVICE_802_11_WIRELESS (dev)) { nm_device_deactivate (dev); nm_device_bring_down (dev); } diff --git a/src/nm-device-802-11-wireless.c b/src/nm-device-802-11-wireless.c index 19ecc77775..7889c3c036 100644 --- a/src/nm-device-802-11-wireless.c +++ b/src/nm-device-802-11-wireless.c @@ -33,6 +33,7 @@ #include "nm-device.h" #include "nm-device-802-11-wireless.h" +#include "nm-device-interface.h" #include "nm-device-private.h" #include "NetworkManagerAPList.h" #include "NetworkManagerDbus.h" @@ -135,7 +136,7 @@ static void supplicant_iface_connection_state_cb (NMSupplicantInterface * iface, NMDevice80211Wireless *self); static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface, - DBusMessage * message, + GHashTable *properties, NMDevice80211Wireless * self); static void supplicant_iface_scan_result_cb (NMSupplicantInterface * iface, @@ -390,6 +391,8 @@ nm_device_802_11_wireless_init (NMDevice80211Wireless * self) self->priv->supplicant.iface_error_id = 0; memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr)); + + nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_802_11_WIRELESS); } static void @@ -402,7 +405,8 @@ init_supplicant_interface (NMDevice80211Wireless * self) sup = (Supplicant *) &self->priv->supplicant; sup->iface = nm_supplicant_manager_get_iface (sup->mgr, - NM_DEVICE (self)); + nm_device_get_iface (NM_DEVICE (self)), + TRUE); if (sup->iface == NULL) { nm_warning ("Couldn't initialize supplicant interface for %s.", nm_device_get_iface (NM_DEVICE (self))); @@ -647,39 +651,6 @@ nm_device_802_11_wireless_get_address (NMDevice80211Wireless *self, } -/* - * nm_device_802_11_wireless_set_address - * - * Set a device's hardware address - * - */ -void -nm_device_802_11_wireless_set_address (NMDevice80211Wireless *self) -{ - NMDevice *dev = NM_DEVICE (self); - struct ifreq req; - NMSock *sk; - int ret; - - g_return_if_fail (self != NULL); - - sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL); - if (!sk) - return; - memset (&req, 0, sizeof (struct ifreq)); - strncpy (req.ifr_name, nm_device_get_iface (dev), sizeof (req.ifr_name) - 1); - - ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req); - if (ret) - goto out; - - memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr)); - -out: - nm_dev_sock_close (sk); -} - - static gboolean link_to_specific_ap (NMDevice80211Wireless *self, NMAccessPoint *ap, @@ -1157,7 +1128,7 @@ nm_device_802_11_wireless_set_scan_interval (NMData *data, if (self && (NM_DEVICE (self) != d)) continue; - if (d && nm_device_is_802_11_wireless (d)) { + if (d && NM_IS_DEVICE_802_11_WIRELESS (d)) { NM_DEVICE_802_11_WIRELESS (d)->priv->scan_interval = seconds; if (self && (NM_DEVICE (self) == d)) found = TRUE; @@ -2054,6 +2025,110 @@ ap_is_auth_required (NMAccessPoint *ap, gboolean *has_key) * */ +/* + * merge_scanned_ap + * + * Given an AP list and an access point, merge the access point into the list. + * If the AP is already in the list, merge just the /attributes/ together for that + * AP, if its not already in the list then just add it. This doesn't merge all + * attributes, just ones that are likely to be new from the scan. + * + */ +static void +merge_scanned_ap (NMDevice80211Wireless *dev, + NMAccessPoint *merge_ap) +{ + + NMAccessPointList *list; + NMAccessPoint *list_ap = NULL; + gboolean strength_changed = FALSE; + gboolean new = FALSE; + const struct ether_addr *merge_bssid; + + list = nm_device_802_11_wireless_ap_list_get (dev); + + merge_bssid = nm_ap_get_address (merge_ap); + if (nm_ethernet_address_is_valid (merge_bssid) && (list_ap = nm_ap_list_get_ap_by_address (list, merge_bssid))) + { + /* First, we check for an address match. If the merge AP has a valid + * BSSID and the same address as a list AP, then the merge AP and + * the list AP must be the same physical AP. The list AP properties must + * be from a previous scan so the time_last_seen's are not equal. Update + * encryption, authentication method, strength, and the time_last_seen. */ + + const char * devlist_essid = nm_ap_get_essid (list_ap); + const char * merge_essid = nm_ap_get_essid (merge_ap); + const GTimeVal *merge_ap_seen = nm_ap_get_last_seen (merge_ap); + + /* Did the AP's name change? */ + if (!devlist_essid || !merge_essid || nm_null_safe_strcmp (devlist_essid, merge_essid)) { + nm_dbus_signal_wireless_network_change (dev, list_ap, + NETWORK_STATUS_DISAPPEARED, -1); + new = TRUE; + } + + nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap)); + if (nm_ap_get_strength (merge_ap) != nm_ap_get_strength (list_ap)) { + nm_ap_set_strength (list_ap, nm_ap_get_strength (merge_ap)); + strength_changed = TRUE; + } + + nm_ap_set_last_seen (list_ap, merge_ap_seen); + nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap)); + + /* If the AP is noticed in a scan, it's automatically no longer + * artificial, since it clearly exists somewhere. + */ + nm_ap_set_artificial (list_ap, FALSE); + + /* Have to change AP's name _after_ dbus signal for old network name + * has gone out. + */ + nm_ap_set_essid (list_ap, merge_essid); + } + else if ((list_ap = nm_ap_list_get_ap_by_essid (list, nm_ap_get_essid (merge_ap)))) + { + /* Second, we check for an ESSID match. In this case, + * a list AP has the same non-NULL ESSID as the merge AP. Update the + * encryption and authentication method. Update the strength and address + * except when the time_last_seen of the list AP is the same as the + * time_last_seen of the merge AP and the strength of the list AP is greater + * than or equal to the strength of the merge AP. If the time_last_seen's are + * equal, the merge AP and the list AP come from the same scan. + * Update the time_last_seen. */ + + const GTimeVal * merge_ap_seen = nm_ap_get_last_seen (merge_ap); + const GTimeVal * list_ap_seen = nm_ap_get_last_seen (list_ap); + const int merge_ap_strength = nm_ap_get_strength (merge_ap); + + nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap)); + + if (!((list_ap_seen->tv_sec == merge_ap_seen->tv_sec) + && (nm_ap_get_strength (list_ap) >= merge_ap_strength))) + { + nm_ap_set_strength (list_ap, merge_ap_strength); + nm_ap_set_address (list_ap, nm_ap_get_address (merge_ap)); + } + nm_ap_set_last_seen (list_ap, merge_ap_seen); + nm_ap_set_broadcast (list_ap, nm_ap_get_broadcast (merge_ap)); + + /* If the AP is noticed in a scan, it's automatically no longer + * artificial, since it clearly exists somewhere. + */ + nm_ap_set_artificial (list_ap, FALSE); + } else { + /* Add the merge AP to the list. */ + nm_ap_list_append_ap (list, merge_ap); + list_ap = merge_ap; + new = TRUE; + } + + if (list_ap && new) { + nm_dbus_signal_wireless_network_change (dev, list_ap, + NETWORK_STATUS_APPEARED, -1); + } +} + static void cull_scan_list (NMDevice80211Wireless * self) { @@ -2121,28 +2196,6 @@ out: nm_policy_schedule_device_change_check (app_data); } -#define HANDLE_DICT_ITEM(in_key, in_type, op) \ - if (!strcmp (entry.key, in_key)) { \ - if (entry.type != in_type) { \ - nm_warning (in_key "had invalid type in scanned AP message."); \ - } else { \ - op \ - } \ - goto next; \ - } - -#define HANDLE_DICT_ARRAY_ITEM(in_key, in_ary_type, op) \ - if (!strcmp (entry.key, in_key)) { \ - if (entry.type != DBUS_TYPE_ARRAY) { \ - nm_warning (in_key "had invalid type in scanned AP message."); \ - } else if (entry.array_type != in_ary_type) { \ - nm_warning (in_key "had invalid array type in scanned AP message."); \ - } else { \ - op \ - } \ - goto next; \ - } - #define SET_QUALITY_MEMBER(qual_item, lc_member, uc_member) \ if (lc_member != -1) { \ qual_item.lc_member = lc_member; \ @@ -2151,176 +2204,80 @@ out: qual_item.updated |= IW_QUAL_##uc_member##_INVALID; \ } - -#define IEEE80211_CAP_ESS 0x0001 -#define IEEE80211_CAP_IBSS 0x0002 -#define IEEE80211_CAP_PRIVACY 0x0010 - static void -supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface, - DBusMessage * message, - NMDevice80211Wireless * self) +set_ap_strength_from_properties (NMDevice80211Wireless *self, + NMAccessPoint *ap, + GHashTable *properties) { - DBusMessageIter iter, iter_dict; - NMUDictEntry entry = { .type = DBUS_TYPE_STRING }; - NMAccessPoint * ap = NULL; - GTimeVal cur_time; - NMAccessPointList * ap_list; - int qual = -1, level = -1, noise = -1; - NMData * app_data; - struct iw_quality quality; + int qual, level, noise; + struct iw_quality quality; + GValue *value; - g_return_if_fail (self != NULL); - g_return_if_fail (message != NULL); - g_return_if_fail (iface != NULL); + value = (GValue *) g_hash_table_lookup (properties, "quality"); + qual = value ? g_value_get_int (value) : -1; - if (!(app_data = nm_device_get_app_data (NM_DEVICE (self)))) - goto out; + value = (GValue *) g_hash_table_lookup (properties, "level"); + level = value ? g_value_get_int (value) : -1; - /* Convert the scanned AP into a NMAccessPoint */ - dbus_message_iter_init (message, &iter); - - if (!nmu_dbus_dict_open_read (&iter, &iter_dict)) { - nm_warning ("Warning: couldn't get properties dictionary" - " from scanned AP message."); - goto out; - } - - /* First arg: Dict Type */ - if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) { - nm_warning ("Error: couldn't get properties dictionary" - " from scanned AP message."); - goto out; - } - - ap = nm_ap_new (); - if (!ap) { - nm_warning ("could not allocate new access point."); - goto out; - } - - while (nmu_dbus_dict_has_dict_entry (&iter_dict)) { - if (!nmu_dbus_dict_get_entry (&iter_dict, &entry)) { - nm_warning ("Error: couldn't read properties dictionary entry" - " from scanned AP message."); - goto out; - } - - HANDLE_DICT_ARRAY_ITEM("ssid", DBUS_TYPE_BYTE, - { - char ssid[33]; - int ssid_len = sizeof (ssid); - - if (entry.array_len < sizeof (ssid)) - ssid_len = entry.array_len; - if (ssid_len <= 0) - goto next; - /* Stupid ieee80211 layer uses */ - if (((ssid_len == 8) || (ssid_len == 9)) - && (memcmp (entry.bytearray_value, "", 8) == 0)) - goto next; - memset (&ssid, 0, sizeof (ssid)); - memcpy (&ssid, entry.bytearray_value, ssid_len); - ssid[32] = '\0'; - nm_ap_set_essid (ap, ssid); - }); - HANDLE_DICT_ARRAY_ITEM("bssid", DBUS_TYPE_BYTE, - { - struct ether_addr addr; - if (entry.array_len != ETH_ALEN) - goto next; - memset (&addr, 0, sizeof (struct ether_addr)); - memcpy (&addr, entry.bytearray_value, ETH_ALEN); - nm_ap_set_address (ap, &addr); - }); - - HANDLE_DICT_ARRAY_ITEM("wpaie", DBUS_TYPE_BYTE, - { - guint8 * ie = (guint8 *) entry.bytearray_value; - if (entry.array_len <= 0 || entry.array_len > WPA_MAX_IE_LEN) - goto next; - nm_ap_add_capabilities_from_ie (ap, ie, entry.array_len); - }); - - HANDLE_DICT_ARRAY_ITEM("rsnie", DBUS_TYPE_BYTE, - { - guint8 * ie = (guint8 *) entry.bytearray_value; - if (entry.array_len <= 0 || entry.array_len > WPA_MAX_IE_LEN) - goto next; - nm_ap_add_capabilities_from_ie (ap, ie, entry.array_len); - }); - - HANDLE_DICT_ITEM("frequency", DBUS_TYPE_INT32, - { - double freq = (double) entry.double_value; - nm_ap_set_freq (ap, freq); - }); - - HANDLE_DICT_ITEM("maxrate", DBUS_TYPE_INT32, - { nm_ap_set_rate (ap, entry.int32_value); }); - - HANDLE_DICT_ITEM("quality", DBUS_TYPE_INT32, - { qual = entry.int32_value; }); - - HANDLE_DICT_ITEM("level", DBUS_TYPE_INT32, - { level = entry.int32_value; }); - - HANDLE_DICT_ITEM("noise", DBUS_TYPE_INT32, - { noise = entry.int32_value; }); - - HANDLE_DICT_ITEM("capabilities", DBUS_TYPE_UINT16, - { - guint32 caps = entry.uint16_value; - - if (caps & IEEE80211_CAP_ESS) - nm_ap_set_mode (ap, IW_MODE_INFRA); - else if (caps & IEEE80211_CAP_IBSS) - nm_ap_set_mode (ap, IW_MODE_ADHOC); - - if (caps & IEEE80211_CAP_PRIVACY) { - if (nm_ap_get_capabilities (ap) & NM_802_11_CAP_PROTO_NONE) - nm_ap_add_capabilities_for_wep (ap); - } - }); - - next: - nmu_dbus_dict_entry_clear (&entry); - }; - - g_get_current_time (&cur_time); - self->priv->last_scan = cur_time.tv_sec; - nm_ap_set_last_seen (ap, &cur_time); - - /* If the AP is not broadcasting its ESSID, try to fill it in here from our - * allowed list where we cache known MAC->ESSID associations. - */ - if (!nm_ap_get_essid (ap)) { - nm_ap_set_broadcast (ap, FALSE); - nm_ap_list_copy_one_essid_by_address (self, ap, app_data->allowed_ap_list); - } + 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); - nm_ap_set_strength (ap, wireless_qual_to_percent (&quality, - (const iwqual *)(&self->priv->max_qual), - (const iwqual *)(&self->priv->avg_qual))); + + nm_ap_set_strength (ap, wireless_qual_to_percent + (&quality, + (const iwqual *)(&self->priv->max_qual), + (const iwqual *)(&self->priv->avg_qual))); +} + +static void +supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface, + GHashTable *properties, + NMDevice80211Wireless * self) +{ + NMAccessPoint *ap; + GTimeVal *last_seen; + NMData *app_data; + + g_return_if_fail (self != NULL); + g_return_if_fail (properties != NULL); + g_return_if_fail (iface != NULL); + + if (!(app_data = nm_device_get_app_data (NM_DEVICE (self)))) + return; + + ap = nm_ap_new_from_properties (properties); + if (!ap) + return; + + set_ap_strength_from_properties (self, ap, properties); + + last_seen = (GTimeVal *) nm_ap_get_last_seen (ap); + self->priv->last_scan = last_seen->tv_sec; + + /* If the AP is not broadcasting its ESSID, try to fill it in here from our + * allowed list where we cache known MAC->ESSID associations. + */ + if (!nm_ap_get_essid (ap)) { + nm_ap_set_broadcast (ap, FALSE); + nm_ap_list_copy_one_essid_by_address (ap, app_data->allowed_ap_list); + } /* Add the AP to the device's AP list */ - ap_list = nm_device_802_11_wireless_ap_list_get (self); - nm_ap_list_merge_scanned_ap (self, ap_list, ap); + merge_scanned_ap (self, ap); /* Once we have the list, copy in any relevant information from our Allowed list. */ - nm_ap_list_copy_properties (ap_list, app_data->allowed_ap_list); + nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (self), + app_data->allowed_ap_list); /* Remove outdated access points */ cull_scan_list (self); -out: - if (ap) - nm_ap_unref (ap); + nm_ap_unref (ap); } @@ -2389,6 +2346,7 @@ link_timeout_cb (gpointer user_data) nm_device_set_active_link (dev, FALSE); if (nm_device_is_activating (dev)) { cleanup_association_attempt (self, TRUE); + nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (req); } return FALSE; @@ -2404,6 +2362,7 @@ link_timeout_cb (gpointer user_data) nm_info ("Activation (%s/wireless): disconnected during association," " asking for new key.", nm_device_get_iface (dev)); cleanup_association_attempt (self, TRUE); + nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); nm_dbus_get_user_key_for_network (req, TRUE); } else { nm_info ("%s: link timed out.", nm_device_get_iface (dev)); @@ -2659,6 +2618,7 @@ supplicant_mgr_state_cb_handler (gpointer user_data) if (nm_device_is_activating (dev)) { NMActRequest * req = nm_device_get_act_request (dev); + nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (req); } else if (nm_device_is_activated (dev)) { nm_policy_schedule_device_change_check (app_data); @@ -2718,6 +2678,7 @@ supplicant_iface_connection_error_cb_handler (gpointer user_data) cb_data->message); cleanup_association_attempt (self, TRUE); + nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (req); out: @@ -2794,6 +2755,7 @@ supplicant_connection_timeout_cb (gpointer user_data) "asking for new key.", nm_device_get_iface (dev)); + nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); nm_dbus_get_user_key_for_network (req, TRUE); } else { if (nm_device_is_activating (dev)) { @@ -2801,6 +2763,7 @@ supplicant_connection_timeout_cb (gpointer user_data) "failing activation.", nm_device_get_iface (dev)); + nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (nm_device_get_act_request (dev)); } } @@ -2812,7 +2775,6 @@ supplicant_connection_timeout_cb (gpointer user_data) static gboolean start_supplicant_connection_timeout (NMDevice80211Wireless *self) { - GMainContext * context; NMDevice * dev; guint id; @@ -2858,7 +2820,7 @@ build_supplicant_config (NMDevice80211Wireless *self, ap = nm_act_request_get_ap (req); g_assert (ap); - config = nm_supplicant_config_new (NM_DEVICE (self)); + config = nm_supplicant_config_new (nm_device_get_iface (NM_DEVICE (self))); if (config == NULL) goto out; @@ -2900,6 +2862,28 @@ error: /****************************************************************************/ +static void +real_set_hw_address (NMDevice *dev) +{ + NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (dev); + struct ifreq req; + NMSock *sk; + int ret; + + sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL); + if (!sk) + return; + + memset (&req, 0, sizeof (struct ifreq)); + strncpy (req.ifr_name, nm_device_get_iface (dev), sizeof (req.ifr_name) - 1); + + ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req); + if (ret == 0) + memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr)); + + nm_dev_sock_close (sk); +} + static NMActStageReturn real_act_stage2_config (NMDevice *dev, @@ -2919,6 +2903,7 @@ real_act_stage2_config (NMDevice *dev, /* If we need an encryption key, get one */ if (ap_need_key (self, ap, &ask_user)) { + nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); nm_dbus_get_user_key_for_network (req, ask_user); return NM_ACT_STAGE_RETURN_POSTPONE; } @@ -3062,6 +3047,7 @@ real_act_stage4_ip_config_timeout (NMDevice *dev, /* Activation failed, we must have bad encryption key */ nm_debug ("Activation (%s/wireless): could not get IP configuration info for '%s', asking for new key.", nm_device_get_iface (dev), nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)"); + nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH); nm_dbus_get_user_key_for_network (req, TRUE); ret = NM_ACT_STAGE_RETURN_POSTPONE; } @@ -3275,6 +3261,7 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass) parent_class->init = real_init; parent_class->start = real_start; parent_class->update_link = real_update_link; + parent_class->set_hw_address = real_set_hw_address; parent_class->act_stage2_config = real_act_stage2_config; parent_class->act_stage3_ip_config_start = real_act_stage3_ip_config_start; @@ -3317,3 +3304,32 @@ nm_device_802_11_wireless_get_type (void) return type; } +NMDevice80211Wireless * +nm_device_802_11_wireless_new (const char *iface, + const char *udi, + const char *driver, + gboolean test_dev, + NMData *app_data) +{ + GObject *obj; + + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (driver != NULL, NULL); + g_return_val_if_fail (app_data != NULL, NULL); + + obj = g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS, + NM_DEVICE_INTERFACE_UDI, udi, + NM_DEVICE_INTERFACE_IFACE, iface, + NM_DEVICE_INTERFACE_DRIVER, driver, + NM_DEVICE_INTERFACE_APP_DATA, app_data, + NULL); + + /* FIXME */ +/* g_signal_connect (obj, "state-changed", */ +/* (GCallback) state_changed_cb, */ +/* NULL); */ + + return NM_DEVICE_802_11_WIRELESS (obj); + +} diff --git a/src/nm-device-802-11-wireless.h b/src/nm-device-802-11-wireless.h index 70f379be37..7d5dcaf81a 100644 --- a/src/nm-device-802-11-wireless.h +++ b/src/nm-device-802-11-wireless.h @@ -29,6 +29,7 @@ #include "nm-device.h" #include "NetworkManagerAP.h" +#include "NetworkManagerMain.h" struct NMAccessPointList; @@ -65,14 +66,11 @@ struct _NMDevice80211WirelessClass GType nm_device_802_11_wireless_get_type (void); - -static inline gboolean nm_device_is_802_11_wireless (NMDevice *dev); -static inline gboolean nm_device_is_802_11_wireless (NMDevice *dev) -{ - g_return_val_if_fail (dev != NULL, FALSE); - - return (G_OBJECT_TYPE (dev) == NM_TYPE_DEVICE_802_11_WIRELESS); -} +NMDevice80211Wireless *nm_device_802_11_wireless_new (const char *iface, + const char *udi, + const char *driver, + gboolean test_dev, + NMData *app_data); void nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self, const char *essid); @@ -80,8 +78,6 @@ void nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self, void nm_device_802_11_wireless_get_address (NMDevice80211Wireless *dev, struct ether_addr *addr); -void nm_device_802_11_wireless_set_address (NMDevice80211Wireless *dev); - void nm_device_802_11_wireless_get_bssid (NMDevice80211Wireless *dev, struct ether_addr *bssid); diff --git a/src/nm-device-802-3-ethernet.c b/src/nm-device-802-3-ethernet.c index 9b5cb651e9..d8ffa4ddd6 100644 --- a/src/nm-device-802-3-ethernet.c +++ b/src/nm-device-802-3-ethernet.c @@ -28,6 +28,7 @@ #include #include "nm-device-802-3-ethernet.h" +#include "nm-device-interface.h" #include "nm-device-private.h" #include "NetworkManagerMain.h" #include "nm-activation-request.h" @@ -76,6 +77,8 @@ nm_device_802_3_ethernet_init (NMDevice8023Ethernet * self) self->priv->link_source_id = 0; memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr)); + + nm_device_set_device_type (NM_DEVICE (self), DEVICE_TYPE_802_3_ETHERNET); } static void @@ -99,7 +102,8 @@ real_init (NMDevice *dev) sup_mgr = nm_supplicant_manager_get (); self->priv->sup_iface = nm_supplicant_manager_get_iface (sup_mgr, - NM_DEVICE (self)); + nm_device_get_iface (NM_DEVICE (self)), + FALSE); if (self->priv->sup_iface == NULL) { nm_warning ("Couldn't initialize supplicant interface for %s.", nm_device_get_iface (NM_DEVICE (self))); @@ -211,6 +215,31 @@ real_start (NMDevice *dev) } +NMDevice8023Ethernet * +nm_device_802_3_ethernet_new (const char *iface, + const char *udi, + const char *driver, + gboolean test_dev, + NMData *app_data) +{ + GObject *obj; + + g_return_val_if_fail (iface != NULL, NULL); + g_return_val_if_fail (udi != NULL, NULL); + g_return_val_if_fail (driver != NULL, NULL); + g_return_val_if_fail (app_data != NULL, NULL); + + obj = g_object_new (NM_TYPE_DEVICE_802_3_ETHERNET, + NM_DEVICE_INTERFACE_UDI, udi, + NM_DEVICE_INTERFACE_IFACE, iface, + NM_DEVICE_INTERFACE_DRIVER, driver, + NM_DEVICE_INTERFACE_APP_DATA, app_data, + NULL); + + return NM_DEVICE_802_3_ETHERNET (obj); +} + + /* * nm_device_802_3_ethernet_get_address * @@ -227,35 +256,25 @@ nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *self, struct ether_a } -/* - * nm_device_802_3_ethernet_set_address - * - * Set a device's hardware address - * - */ -void -nm_device_802_3_ethernet_set_address (NMDevice8023Ethernet *self) +static void +real_set_hw_address (NMDevice *dev) { - NMDevice *dev = NM_DEVICE (self); + NMDevice8023Ethernet *self = NM_DEVICE_802_3_ETHERNET (dev); struct ifreq req; NMSock *sk; int ret; - g_return_if_fail (self != NULL); - sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL); if (!sk) return; + memset (&req, 0, sizeof (struct ifreq)); strncpy (req.ifr_name, nm_device_get_iface (dev), sizeof (req.ifr_name) - 1); ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req); - if (ret) - goto out; + if (ret == 0) + memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr)); - memcpy (&(self->priv->hw_addr), &(req.ifr_hwaddr.sa_data), sizeof (struct ether_addr)); - -out: nm_dev_sock_close (sk); } @@ -370,6 +389,9 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); NMDeviceClass *parent_class = NM_DEVICE_CLASS (klass); + g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate)); + + /* virtual methods */ object_class->dispose = nm_device_802_3_ethernet_dispose; object_class->finalize = nm_device_802_3_ethernet_finalize; @@ -378,8 +400,7 @@ nm_device_802_3_ethernet_class_init (NMDevice8023EthernetClass *klass) parent_class->start = real_start; parent_class->update_link = real_update_link; parent_class->can_interrupt_activation = real_can_interrupt_activation; - - g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate)); + parent_class->set_hw_address = real_set_hw_address; } GType diff --git a/src/nm-device-802-3-ethernet.h b/src/nm-device-802-3-ethernet.h index 5d5a70b08e..74fa118a1d 100644 --- a/src/nm-device-802-3-ethernet.h +++ b/src/nm-device-802-3-ethernet.h @@ -27,6 +27,7 @@ #include #include "nm-device.h" +#include "NetworkManagerMain.h" G_BEGIN_DECLS @@ -58,19 +59,15 @@ struct _NMDevice8023EthernetClass GType nm_device_802_3_ethernet_get_type (void); -static inline gboolean nm_device_is_802_3_ethernet (NMDevice *dev); -static inline gboolean nm_device_is_802_3_ethernet (NMDevice *dev) -{ - g_return_val_if_fail (dev != NULL, FALSE); - - return (G_OBJECT_TYPE (dev) == NM_TYPE_DEVICE_802_3_ETHERNET); -} +NMDevice8023Ethernet *nm_device_802_3_ethernet_new (const char *iface, + const char *udi, + const char *driver, + gboolean test_dev, + NMData *app_data); void nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *dev, struct ether_addr *addr); -void nm_device_802_3_ethernet_set_address (NMDevice8023Ethernet *dev); - int nm_device_802_3_ethernet_get_speed (NMDevice8023Ethernet *self); G_END_DECLS diff --git a/src/nm-device-interface.c b/src/nm-device-interface.c new file mode 100644 index 0000000000..45513ffb2b --- /dev/null +++ b/src/nm-device-interface.c @@ -0,0 +1,142 @@ + +#include "nm-device-interface.h" + +static void +nm_device_interface_init (gpointer g_iface) +{ + GType iface_type = G_TYPE_FROM_INTERFACE (g_iface); + static gboolean initialized = FALSE; + + if (initialized) + return; + + /* Properties */ + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_DEVICE_INTERFACE_UDI, + "Udi", + "HAL Udi", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_DEVICE_INTERFACE_IFACE, + "Interface", + "Interface", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_interface_install_property + (g_iface, + g_param_spec_string (NM_DEVICE_INTERFACE_DRIVER, + "Driver", + "Driver", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_interface_install_property + (g_iface, + g_param_spec_uint (NM_DEVICE_INTERFACE_CAPABILITIES, + "Capabilities", + "Capabilities", + 0, G_MAXUINT32, NM_DEVICE_CAP_NONE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_interface_install_property + (g_iface, + g_param_spec_pointer (NM_DEVICE_INTERFACE_APP_DATA, + "AppData", + "AppData", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_interface_install_property + (g_iface, + g_param_spec_uint (NM_DEVICE_INTERFACE_IP4_ADDRESS, + "IP4 address", + "IP4 address", + 0, G_MAXUINT32, 0, /* FIXME */ + G_PARAM_READWRITE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_boolean (NM_DEVICE_INTERFACE_USE_DHCP, + "Use DHCP", + "Use DHCP", + TRUE, + G_PARAM_READWRITE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_uint (NM_DEVICE_INTERFACE_STATE, + "State", + "State", + 0, G_MAXUINT32, NM_DEVICE_STATE_UNKNOWN, + G_PARAM_READABLE)); + + g_object_interface_install_property + (g_iface, + g_param_spec_uint (NM_DEVICE_INTERFACE_DEVICE_TYPE, + "DeviceType", + "DeviceType", + 0, G_MAXUINT32, DEVICE_TYPE_UNKNOWN, + G_PARAM_READABLE)); + + /* Signals */ + g_signal_new ("state_changed", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDeviceInterface, state_changed), + NULL, NULL, + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, + G_TYPE_UINT); + + g_signal_new ("carrier_changed", + iface_type, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDeviceInterface, carrier_changed), + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); + + initialized = TRUE; +} + + +GType +nm_device_interface_get_type (void) +{ + static GType device_interface_type = 0; + + if (!device_interface_type) { + const GTypeInfo device_interface_info = { + sizeof (NMDeviceInterface), /* class_size */ + nm_device_interface_init, /* base_init */ + NULL, /* base_finalize */ + NULL, + NULL, /* class_finalize */ + NULL, /* class_data */ + 0, + 0, /* n_preallocs */ + NULL + }; + + device_interface_type = g_type_register_static (G_TYPE_INTERFACE, + "NMDeviceInterface", + &device_interface_info, 0); + + g_type_interface_add_prerequisite (device_interface_type, G_TYPE_OBJECT); + } + + return device_interface_type; +} + +void +nm_device_interface_deactivate (NMDeviceInterface *device) +{ + g_return_if_fail (NM_IS_DEVICE_INTERFACE (device)); + + NM_DEVICE_INTERFACE_GET_INTERFACE (device)->deactivate (device); +} diff --git a/src/nm-device-interface.h b/src/nm-device-interface.h new file mode 100644 index 0000000000..13083466b7 --- /dev/null +++ b/src/nm-device-interface.h @@ -0,0 +1,55 @@ + +#ifndef NM_DEVICE_INTERFACE_H +#define NM_DEVICE_INTERFACE_H + +#include +#include "NetworkManager.h" + +#define NM_TYPE_DEVICE_INTERFACE (nm_device_interface_get_type ()) +#define NM_DEVICE_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_INTERFACE, NmDeviceInterface)) +#define NM_IS_DEVICE_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_INTERFACE)) +#define NM_DEVICE_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_DEVICE_INTERFACE, NMDeviceInterface)) + + +#define NM_DEVICE_INTERFACE_UDI "udi" +#define NM_DEVICE_INTERFACE_IFACE "interface" +#define NM_DEVICE_INTERFACE_DRIVER "driver" +#define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities" +#define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4_address" +#define NM_DEVICE_INTERFACE_USE_DHCP "use_dhcp" +#define NM_DEVICE_INTERFACE_STATE "state" +#define NM_DEVICE_INTERFACE_APP_DATA "app_data" /* Ugh */ +#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device_type" /* ugh */ + +typedef enum { + NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000, + + NM_DEVICE_INTERFACE_PROP_UDI = NM_DEVICE_INTERFACE_PROP_FIRST, + NM_DEVICE_INTERFACE_PROP_IFACE, + NM_DEVICE_INTERFACE_PROP_DRIVER, + NM_DEVICE_INTERFACE_PROP_CAPABILITIES, + NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS, + NM_DEVICE_INTERFACE_PROP_USE_DHCP, + NM_DEVICE_INTERFACE_PROP_STATE, + NM_DEVICE_INTERFACE_PROP_APP_DATA, + NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE +} NMDeviceInterfaceProp; + + +typedef struct _NMDeviceInterface NMDeviceInterface; + +struct _NMDeviceInterface { + GTypeInterface g_iface; + + /* Methods */ + void (*deactivate) (NMDeviceInterface *device); + + /* Signals */ + void (*state_changed) (NMDeviceInterface *device, NMDeviceState state); + void (*carrier_changed) (NMDeviceInterface *device, gboolean carrier_on); +}; + +GType nm_device_interface_get_type (void); + + +#endif /* NM_DEVICE_INTERFACE_H */ diff --git a/src/nm-device-private.h b/src/nm-device-private.h index bb20028c27..6702bf3911 100644 --- a/src/nm-device-private.h +++ b/src/nm-device-private.h @@ -32,11 +32,15 @@ typedef struct NMDbusCBData { } NMDbusCBData; +void nm_device_set_device_type (NMDevice *dev, NMDeviceType type); + gboolean nm_device_is_activated (NMDevice *dev); NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self); void nm_device_activate_schedule_stage3_ip_config_start (struct NMActRequest *req); +void nm_device_state_changed (NMDevice *device, NMDeviceState state); + #endif /* NM_DEVICE_PRIVATE_H */ diff --git a/src/nm-device.c b/src/nm-device.c index bc47bd061f..c1211fe371 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -26,6 +26,7 @@ #include #include "nm-device.h" +#include "nm-device-interface.h" #include "nm-device-private.h" #include "nm-device-802-3-ethernet.h" #include "nm-device-802-11-wireless.h" @@ -39,12 +40,21 @@ #include "nm-utils.h" #include "autoip.h" +static void device_interface_init (NMDeviceInterface *device_interface_class); + +G_DEFINE_TYPE_EXTENDED (NMDevice, nm_device, G_TYPE_OBJECT, + G_TYPE_FLAG_ABSTRACT, + G_IMPLEMENT_INTERFACE (NM_TYPE_DEVICE_INTERFACE, + device_interface_init)) + #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate)) struct _NMDevicePrivate { gboolean dispose_has_run; + NMDeviceState state; + char * udi; char * iface; NMDeviceType type; @@ -72,128 +82,17 @@ static void nm_device_activate_schedule_stage5_ip_config_commit (NMActRequest * void nm_device_bring_up (NMDevice *dev); gboolean nm_device_bring_up_wait (NMDevice *self, gboolean cancelable); -/* - * nm_device_test_wireless_extensions - * - * Test whether a given device is a wireless one or not. - * - */ -static NMDeviceType -discover_device_type (LibHalContext *ctx, const char *udi) -{ - char * category = NULL; - if (libhal_device_property_exists (ctx, udi, "info.category", NULL)) - category = libhal_device_get_property_string(ctx, udi, "info.category", NULL); - if (category && (!strcmp (category, "net.80211"))) - return DEVICE_TYPE_802_11_WIRELESS; - else if (category && (!strcmp (category, "net.80203"))) - return DEVICE_TYPE_802_3_ETHERNET; - return DEVICE_TYPE_UNKNOWN; +static void +nm_device_set_address (NMDevice *device) +{ + if (NM_DEVICE_GET_CLASS (device)->set_hw_address) + NM_DEVICE_GET_CLASS (device)->set_hw_address (device); } -/* - * nm_get_device_driver_name - * - * Get the device's driver name from HAL. - * - */ -static char * -nm_get_device_driver_name (LibHalContext *ctx, const char *udi) +static void +device_interface_init (NMDeviceInterface *device_interface_class) { - char * driver_name = NULL; - char * physdev_udi = NULL; - - g_return_val_if_fail (ctx != NULL, NULL); - g_return_val_if_fail (udi != NULL, NULL); - - physdev_udi = libhal_device_get_property_string (ctx, udi, "net.physical_device", NULL); - if (physdev_udi && libhal_device_property_exists (ctx, physdev_udi, "info.linux.driver", NULL)) - { - char *drv = libhal_device_get_property_string (ctx, physdev_udi, "info.linux.driver", NULL); - driver_name = g_strdup (drv); - g_free (drv); - } - g_free (physdev_udi); - - return driver_name; -} - - -NMDevice * -nm_device_new (const char *iface, - const char *udi, - gboolean test_dev, - NMDeviceType test_dev_type, - NMData *app_data) -{ - NMDevice * dev; - NMDeviceType type; - - g_return_val_if_fail (iface != NULL, NULL); - g_return_val_if_fail (udi != NULL, NULL); - g_return_val_if_fail (strlen (iface) > 0, NULL); - g_return_val_if_fail (app_data != NULL, NULL); - - type = discover_device_type (app_data->hal_ctx, udi); - switch (type) - { - case DEVICE_TYPE_802_11_WIRELESS: - dev = NM_DEVICE (g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS, NULL)); - break; - case DEVICE_TYPE_802_3_ETHERNET: - dev = NM_DEVICE (g_object_new (NM_TYPE_DEVICE_802_3_ETHERNET, NULL)); - break; - - default: - g_assert_not_reached (); - } - - g_assert (dev); - dev->priv->iface = g_strdup (iface); - dev->priv->udi = g_strdup (udi); - dev->priv->driver = nm_get_device_driver_name (app_data->hal_ctx, udi); - dev->priv->app_data = app_data; - dev->priv->type = type; - - dev->priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev); - if (!(dev->priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) - { - g_object_unref (G_OBJECT (dev)); - return NULL; - } - - /* Have to bring the device up before checking link status and other stuff */ - nm_device_bring_up_wait (dev, FALSE); - - nm_device_update_ip4_address (dev); - - /* Update the device's hardware address */ - if (nm_device_is_802_3_ethernet (dev)) - nm_device_802_3_ethernet_set_address (NM_DEVICE_802_3_ETHERNET (dev)); - else if (nm_device_is_802_11_wireless (dev)) - nm_device_802_11_wireless_set_address (NM_DEVICE_802_11_WIRELESS (dev)); - - /* Grab IP config data for this device from the system configuration files */ - dev->priv->system_config_data = nm_system_device_get_system_config (dev, 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)) - { - g_object_unref (G_OBJECT (dev)); - return NULL; - } - - nm_print_device_capabilities (dev); - - /* Call type-specific initialization */ - if (NM_DEVICE_GET_CLASS (dev)->init) - NM_DEVICE_GET_CLASS (dev)->init (dev); - - NM_DEVICE_GET_CLASS (dev)->start (dev); - - return dev; } @@ -214,13 +113,70 @@ nm_device_init (NMDevice * self) memset (&self->priv->ip6_address, 0, sizeof (struct in6_addr)); self->priv->app_data = NULL; - self->priv->act_request = NULL; self->priv->act_source_id = 0; self->priv->system_config_data = NULL; self->priv->ip4_config = NULL; + + self->priv->state = NM_DEVICE_STATE_DISCONNECTED; } + +static GObject* +constructor (GType type, + guint n_construct_params, + GObjectConstructParam *construct_params) +{ + GObject *object; + NMDevice *dev; + + object = G_OBJECT_CLASS (nm_device_parent_class)->constructor (type, + n_construct_params, + construct_params); + + if (!object) + return NULL; + + dev = NM_DEVICE (object); + + dev->priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev); + if (!(dev->priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) + { + g_object_unref (G_OBJECT (dev)); + return NULL; + } + + /* Have to bring the device up before checking link status and other stuff */ + nm_device_bring_up_wait (dev, FALSE); + + nm_device_update_ip4_address (dev); + + /* Update the device's hardware address */ + nm_device_set_address (dev); + + /* Grab IP config data for this device from the system configuration files */ + dev->priv->system_config_data = nm_system_device_get_system_config (dev, 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)) + { + g_object_unref (G_OBJECT (dev)); + return NULL; + } + + nm_print_device_capabilities (dev); + + /* Call type-specific initialization */ + if (NM_DEVICE_GET_CLASS (dev)->init) + NM_DEVICE_GET_CLASS (dev)->init (dev); + + NM_DEVICE_GET_CLASS (dev)->start (dev); + + return object; +} + + static guint32 real_get_generic_capabilities (NMDevice *dev) { @@ -346,6 +302,16 @@ nm_device_get_device_type (NMDevice *self) } +void +nm_device_set_device_type (NMDevice *dev, NMDeviceType type) +{ + g_return_if_fail (NM_IS_DEVICE (dev)); + g_return_if_fail (NM_DEVICE_GET_PRIVATE (dev)->type == DEVICE_TYPE_UNKNOWN); + + NM_DEVICE_GET_PRIVATE (dev)->type = type; +} + + static gboolean real_is_test_device (NMDevice *dev) { @@ -483,13 +449,13 @@ nm_device_set_active_link (NMDevice *self, * must manually choose semi-supported devices. * */ - if (nm_device_is_802_3_ethernet (self) && (nm_device_get_capabilities (self) & NM_DEVICE_CAP_CARRIER_DETECT)) + if (NM_IS_DEVICE_802_3_ETHERNET (self) && (nm_device_get_capabilities (self) & NM_DEVICE_CAP_CARRIER_DETECT)) { gboolean do_switch = act_dev ? FALSE : TRUE; /* If no currently active device, switch to this one */ NMActRequest * act_req; /* If active device is wireless, switch to this one */ - if (act_dev && nm_device_is_802_11_wireless (act_dev) && act_dev_req && !nm_act_request_get_user_requested (act_dev_req)) + if (act_dev && NM_IS_DEVICE_802_11_WIRELESS (act_dev) && act_dev_req && !nm_act_request_get_user_requested (act_dev_req)) do_switch = TRUE; if (do_switch && (act_req = nm_act_request_new (app_data, self, NULL, TRUE))) @@ -499,6 +465,8 @@ nm_device_set_active_link (NMDevice *self, } } } + + g_signal_emit_by_name (self, "carrier_changed", link_active); nm_dbus_schedule_device_status_change_signal (app_data, self, NULL, link_active ? DEVICE_CARRIER_ON : DEVICE_CARRIER_OFF); } @@ -515,6 +483,7 @@ nm_device_set_active_link (NMDevice *self, gboolean nm_device_activation_start (NMActRequest *req) { + NMDevicePrivate *priv; NMData * data = NULL; NMDevice * self = NULL; @@ -526,7 +495,11 @@ nm_device_activation_start (NMActRequest *req) self = nm_act_request_get_dev (req); g_assert (self); - g_return_val_if_fail (!nm_device_is_activating (self), TRUE); /* Return if activation has already begun */ + priv = NM_DEVICE_GET_PRIVATE (self); + + if (priv->state != NM_DEVICE_STATE_DISCONNECTED) + /* Already activating or activated */ + return FALSE; nm_act_request_ref (req); self->priv->act_request = req; @@ -572,11 +545,13 @@ nm_device_activate_stage1_device_prepare (gpointer user_data) iface = nm_device_get_iface (self); nm_info ("Activation (%s) Stage 1 of 5 (Device Prepare) started...", iface); + nm_device_state_changed (self, NM_DEVICE_STATE_PREPARE); ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, req); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { goto out; } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (req); goto out; } @@ -659,6 +634,7 @@ nm_device_activate_stage2_device_config (gpointer user_data) iface = nm_device_get_iface (self); nm_info ("Activation (%s) Stage 2 of 5 (Device Configure) starting...", iface); + nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG); /* Bring the device up */ if (!nm_device_is_up (self)) @@ -669,6 +645,7 @@ nm_device_activate_stage2_device_config (gpointer user_data) goto out; else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (req); goto out; } @@ -778,12 +755,14 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data) iface = nm_device_get_iface (self); nm_info ("Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface); + nm_device_state_changed (self, NM_DEVICE_STATE_IP_CONFIG); ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip_config_start (self, req); if (ret == NM_ACT_STAGE_RETURN_POSTPONE) goto out; else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (req); goto out; } @@ -929,6 +908,7 @@ nm_device_activate_stage4_ip_config_get (gpointer user_data) goto out; else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (req); goto out; } @@ -1022,6 +1002,7 @@ nm_device_activate_stage4_ip_config_timeout (gpointer user_data) if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { goto out; } else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (req); goto out; } @@ -1105,10 +1086,14 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data) nm_system_set_hostname (self->priv->ip4_config); nm_system_activate_nis (self->priv->ip4_config); nm_system_set_mtu (self); + if (NM_DEVICE_GET_CLASS (self)->update_link) NM_DEVICE_GET_CLASS (self)->update_link (self); + + nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED); nm_policy_schedule_activation_finish (req); } else { + nm_device_state_changed (self, NM_DEVICE_STATE_FAILED); nm_policy_schedule_activation_failed (req); } @@ -1150,7 +1135,7 @@ real_activation_cancel_handler (NMDevice *self, g_return_if_fail (self != NULL); g_return_if_fail (req != NULL); - if (nm_act_request_get_stage (req) == NM_ACT_STAGE_IP_CONFIG_START) + if (nm_device_get_state (self) == NM_DEVICE_STATE_IP_CONFIG) nm_dhcp_manager_cancel_transaction (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager, nm_device_get_iface (self), TRUE); @@ -1217,7 +1202,7 @@ nm_device_deactivate_quickly (NMDevice *self) app_data = self->priv->app_data; nm_vpn_manager_deactivate_vpn_connection (app_data->vpn_manager, self); - if (nm_device_is_activated (self)) + if (nm_device_get_state (self) == NM_DEVICE_STATE_ACTIVATED) nm_dbus_schedule_device_status_change_signal (app_data, self, NULL, DEVICE_NO_LONGER_ACTIVE); else if (nm_device_is_activating (self)) nm_device_activation_cancel (self); @@ -1278,6 +1263,7 @@ nm_device_deactivate (NMDevice *self) if (NM_DEVICE_GET_CLASS (self)->deactivate) NM_DEVICE_GET_CLASS (self)->deactivate (self); + nm_device_state_changed (self, NM_DEVICE_STATE_DISCONNECTED); nm_schedule_state_change_signal_broadcast (self->priv->app_data); } @@ -1289,38 +1275,22 @@ nm_device_deactivate (NMDevice *self) * */ gboolean -nm_device_is_activating (NMDevice *dev) +nm_device_is_activating (NMDevice *device) { - NMActRequest * req; - NMActStage stage; - gboolean activating = FALSE; + g_return_val_if_fail (NM_IS_DEVICE (device), FALSE); - g_return_val_if_fail (dev != NULL, FALSE); - - if (!(req = nm_device_get_act_request (dev))) - return FALSE; - - stage = nm_act_request_get_stage (req); - switch (stage) - { - case NM_ACT_STAGE_DEVICE_PREPARE: - case NM_ACT_STAGE_DEVICE_CONFIG: - case NM_ACT_STAGE_NEED_USER_KEY: - case NM_ACT_STAGE_IP_CONFIG_START: - case NM_ACT_STAGE_IP_CONFIG_GET: - case NM_ACT_STAGE_IP_CONFIG_COMMIT: - activating = TRUE; - break; - - case NM_ACT_STAGE_ACTIVATED: - case NM_ACT_STAGE_FAILED: - case NM_ACT_STAGE_CANCELLED: - case NM_ACT_STAGE_UNKNOWN: - default: - break; + switch (nm_device_get_state (device)) { + case NM_DEVICE_STATE_PREPARE: + case NM_DEVICE_STATE_CONFIG: + case NM_DEVICE_STATE_NEED_AUTH: + case NM_DEVICE_STATE_IP_CONFIG: + return TRUE; + break; + default: + break; } - return activating; + return FALSE; } @@ -1563,10 +1533,7 @@ nm_device_set_up_down (NMDevice *self, * Make sure that we have a valid MAC address, some cards reload firmware when they * are brought up. */ - if (nm_device_is_802_3_ethernet (self)) - nm_device_802_3_ethernet_set_address (NM_DEVICE_802_3_ETHERNET (self)); - else if (nm_device_is_802_11_wireless (self)) - nm_device_802_11_wireless_set_address (NM_DEVICE_802_11_WIRELESS (self)); + nm_device_set_address (self); } @@ -1684,9 +1651,7 @@ nm_device_get_system_config_data (NMDevice *self) static void nm_device_dispose (GObject *object) { - NMDevice * self = NM_DEVICE (object); - NMDeviceClass * klass; - GObjectClass * parent_class; + NMDevice *self = NM_DEVICE (object); if (self->priv->dispose_has_run) /* If dispose did already run, return. */ @@ -1722,27 +1687,95 @@ nm_device_dispose (GObject *object) nm_device_set_use_dhcp (self, FALSE); - /* Chain up to the parent class */ - klass = NM_DEVICE_CLASS (g_type_class_peek (NM_TYPE_DEVICE)); - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - parent_class->dispose (object); + G_OBJECT_CLASS (nm_device_parent_class)->dispose (object); } static void nm_device_finalize (GObject *object) { - NMDevice * self = NM_DEVICE (object); - NMDeviceClass * klass; - GObjectClass * parent_class; + NMDevice *self = NM_DEVICE (object); g_free (self->priv->udi); g_free (self->priv->iface); g_free (self->priv->driver); - /* Chain up to the parent class */ - klass = NM_DEVICE_CLASS (g_type_class_peek (NM_TYPE_DEVICE)); - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - parent_class->finalize (object); + G_OBJECT_CLASS (nm_device_parent_class)->finalize (object); +} + + +static void +set_property (GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + + switch (prop_id) { + case NM_DEVICE_INTERFACE_PROP_UDI: + /* construct-only */ + priv->udi = g_strdup (g_value_get_string (value)); + break; + case NM_DEVICE_INTERFACE_PROP_IFACE: + priv->iface = g_strdup (g_value_get_string (value)); + break; + case NM_DEVICE_INTERFACE_PROP_DRIVER: + priv->driver = g_strdup (g_value_get_string (value)); + break; + case NM_DEVICE_INTERFACE_PROP_APP_DATA: + priv->app_data = g_value_get_pointer (value); + break; + case NM_DEVICE_INTERFACE_PROP_CAPABILITIES: + priv->capabilities = g_value_get_uint (value); + break; + case NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS: + priv->ip4_address = g_value_get_uint (value); + break; + case NM_DEVICE_INTERFACE_PROP_USE_DHCP: + nm_device_set_use_dhcp (NM_DEVICE (object), g_value_get_boolean (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) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object); + + switch (prop_id) { + case NM_DEVICE_INTERFACE_PROP_UDI: + g_value_set_string (value, priv->udi); + break; + case NM_DEVICE_INTERFACE_PROP_IFACE: + g_value_set_string (value, priv->iface); + break; + case NM_DEVICE_INTERFACE_PROP_DRIVER: + g_value_set_string (value, priv->driver); + break; + case NM_DEVICE_INTERFACE_PROP_APP_DATA: + g_value_set_pointer (value, priv->app_data); + break; + case NM_DEVICE_INTERFACE_PROP_CAPABILITIES: + g_value_set_uint (value, priv->capabilities); + break; + case NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS: + g_value_set_uint (value, priv->ip4_address); + break; + case NM_DEVICE_INTERFACE_PROP_USE_DHCP: + g_value_set_boolean (value, nm_device_get_use_dhcp (NM_DEVICE (object))); + break; + case NM_DEVICE_INTERFACE_PROP_STATE: + g_value_set_uint (value, priv->state); + break; + case NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE: + g_value_set_uint (value, priv->type); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } } @@ -1751,8 +1784,14 @@ nm_device_class_init (NMDeviceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + g_type_class_add_private (object_class, sizeof (NMDevicePrivate)); + + /* Virtual methods */ object_class->dispose = nm_device_dispose; object_class->finalize = nm_device_finalize; + object_class->set_property = set_property; + object_class->get_property = get_property; + object_class->constructor = constructor; klass->is_test_device = real_is_test_device; klass->activation_cancel_handler = real_activation_cancel_handler; @@ -1765,31 +1804,72 @@ nm_device_class_init (NMDeviceClass *klass) klass->act_stage4_get_ip4_config = real_act_stage4_get_ip4_config; klass->act_stage4_ip_config_timeout = real_act_stage4_ip_config_timeout; - g_type_class_add_private (object_class, sizeof (NMDevicePrivate)); + /* Properties */ + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_UDI, + NM_DEVICE_INTERFACE_UDI); + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_IFACE, + NM_DEVICE_INTERFACE_IFACE); + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_DRIVER, + NM_DEVICE_INTERFACE_DRIVER); + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_CAPABILITIES, + NM_DEVICE_INTERFACE_CAPABILITIES); + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_IP4_ADDRESS, + NM_DEVICE_INTERFACE_IP4_ADDRESS); + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_USE_DHCP, + NM_DEVICE_INTERFACE_USE_DHCP); + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_STATE, + NM_DEVICE_INTERFACE_STATE); + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_APP_DATA, + NM_DEVICE_INTERFACE_APP_DATA); + + g_object_class_override_property (object_class, + NM_DEVICE_INTERFACE_PROP_DEVICE_TYPE, + NM_DEVICE_INTERFACE_DEVICE_TYPE); } -GType -nm_device_get_type (void) +void +nm_device_state_changed (NMDevice *device, NMDeviceState state) { - static GType type = 0; - if (type == 0) - { - static const GTypeInfo info = - { - sizeof (NMDeviceClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) nm_device_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (NMDevice), - 0, /* n_preallocs */ - (GInstanceInitFunc) nm_device_init, - NULL /* value_table */ - }; - type = g_type_register_static (G_TYPE_OBJECT, - "NMDevice", - &info, 0); + g_return_if_fail (NM_IS_DEVICE (device)); + + device->priv->state = state; + + switch (state) { + case NM_DEVICE_STATE_ACTIVATED: + nm_info ("Activation (%s) successful, device activated.", nm_device_get_iface (device)); + break; + case NM_DEVICE_STATE_FAILED: + nm_info ("Activation (%s) failed.", nm_device_get_iface (device)); + nm_device_deactivate (device); + break; + default: + break; } - return type; + + g_signal_emit_by_name (device, "state_changed", state); +} + + +NMDeviceState +nm_device_get_state (NMDevice *device) +{ + g_return_val_if_fail (NM_IS_DEVICE (device), NM_DEVICE_STATE_UNKNOWN); + + return NM_DEVICE_GET_PRIVATE (device)->state; } diff --git a/src/nm-device.h b/src/nm-device.h index 40f53d179d..7d0b7068f2 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -94,6 +94,8 @@ struct _NMDeviceClass void (* bring_up) (NMDevice *self); void (* bring_down) (NMDevice *self); + void (* set_hw_address) (NMDevice *self); + guint32 (* get_type_capabilities) (NMDevice *self); guint32 (* get_generic_capabilities) (NMDevice *self); @@ -125,12 +127,6 @@ struct _NMDeviceClass GType nm_device_get_type (void); -NMDevice * nm_device_new (const char *iface, - const char *udi, - gboolean test_dev, - NMDeviceType test_dev_type, - struct NMData *app_data); - void nm_device_stop (NMDevice *self); const char * nm_device_get_udi (NMDevice *dev); @@ -197,6 +193,8 @@ void nm_device_activation_success_handler (NMDevice *dev, gboolean nm_device_can_interrupt_activation (NMDevice *self); +NMDeviceState nm_device_get_state (NMDevice *device); + G_END_DECLS #endif /* NM_DEVICE_H */ diff --git a/src/supplicant-manager/nm-supplicant-config.c b/src/supplicant-manager/nm-supplicant-config.c index d1f7a5f943..09b0e015fc 100644 --- a/src/supplicant-manager/nm-supplicant-config.c +++ b/src/supplicant-manager/nm-supplicant-config.c @@ -32,56 +32,53 @@ NM_TYPE_SUPPLICANT_CONFIG, \ NMSupplicantConfigPrivate)) +G_DEFINE_TYPE (NMSupplicantConfig, nm_supplicant_config, G_TYPE_OBJECT) -static void nm_supplicant_config_set_device (NMSupplicantConfig *con, - NMDevice *dev); - - -struct option { - char * key; - char * value; - guint32 len; +typedef struct { + char *value; + guint32 len; enum OptType type; -}; +} ConfigOption; -struct _NMSupplicantConfigPrivate +typedef struct { - NMDevice * dev; - GSList * config; + char * ifname; + GHashTable *config; guint32 ap_scan; gboolean dispose_has_run; -}; +} NMSupplicantConfigPrivate; NMSupplicantConfig * -nm_supplicant_config_new (NMDevice *dev) +nm_supplicant_config_new (const char *ifname) { NMSupplicantConfig * scfg; - g_return_val_if_fail (dev != NULL, NULL); + g_return_val_if_fail (ifname != NULL, NULL); scfg = g_object_new (NM_TYPE_SUPPLICANT_CONFIG, NULL); - nm_supplicant_config_set_device (scfg, dev); + NM_SUPPLICANT_CONFIG_GET_PRIVATE (scfg)->ifname = g_strdup (ifname); + return scfg; } +static void +config_option_free (ConfigOption *opt) +{ + g_free (opt->value); + g_slice_free (ConfigOption, opt); +} + static void nm_supplicant_config_init (NMSupplicantConfig * self) { - self->priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); - self->priv->config = NULL; - self->priv->ap_scan = 1; - self->priv->dispose_has_run = FALSE; -} + NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); -static void -nm_supplicant_config_set_device (NMSupplicantConfig *self, - NMDevice *dev) -{ - g_return_if_fail (self != NULL); - g_return_if_fail (dev != NULL); - - g_object_ref (G_OBJECT (dev)); - self->priv->dev = dev; + priv->config = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) config_option_free); + + priv->ap_scan = 1; + priv->dispose_has_run = FALSE; } gboolean @@ -90,14 +87,17 @@ nm_supplicant_config_add_option (NMSupplicantConfig *self, const char * value, gint32 len) { - GSList * elt; - struct option * opt; + NMSupplicantConfigPrivate *priv; + ConfigOption *old_opt; + ConfigOption *opt; OptType type; - g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE); + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); + if (len < 0) len = strlen (value); @@ -110,130 +110,52 @@ nm_supplicant_config_add_option (NMSupplicantConfig *self, return FALSE; } - for (elt = self->priv->config; elt; elt = g_slist_next (elt)) { - struct option * tmp_opt = (struct option *) elt->data; - - if (strcmp (tmp_opt->key, key) == 0) { - nm_debug ("Key '%s' already in table.", key); - return FALSE; - } + old_opt = (ConfigOption *) g_hash_table_lookup (priv->config, key); + if (old_opt) { + nm_debug ("Key '%s' already in table.", key); + return FALSE; } - opt = g_slice_new0 (struct option); + opt = g_slice_new0 (ConfigOption); if (opt == NULL) { nm_debug ("Couldn't allocate memory for new config option."); return FALSE; } - opt->key = g_strdup (key); - if (opt->key == NULL) { - nm_debug ("Couldn't allocate memory for new config option key."); - g_slice_free (struct option, opt); - return FALSE; - } + opt->value = g_malloc0 (sizeof (char) * len); if (opt->value == NULL) { nm_debug ("Couldn't allocate memory for new config option value."); - g_free (opt->key); - g_slice_free (struct option, opt); + g_slice_free (ConfigOption, opt); return FALSE; } memcpy (opt->value, value, len); opt->len = len; opt->type = type; - self->priv->config = g_slist_append (self->priv->config, opt); + + g_hash_table_insert (priv->config, g_strdup (key), opt); return TRUE; } -static void -free_option (struct option * opt) -{ - g_return_if_fail (opt != NULL); - g_free (opt->key); - g_free (opt->value); -} - gboolean nm_supplicant_config_remove_option (NMSupplicantConfig *self, const char * key) { - GSList * elt; - GSList * found = NULL; - - g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (key != NULL, FALSE); - for (elt = self->priv->config; elt; elt = g_slist_next (elt)) { - struct option * opt = (struct option *) elt->data; - - if (strcmp (opt->key, key) == 0) { - found = elt; - break; - } - } - - if (!found) - return FALSE; - - self->priv->config = g_slist_remove_link (self->priv->config, found); - free_option (found->data); - g_slice_free (struct option, found->data); - g_slist_free1 (found); - return TRUE; -} - -static void -nm_supplicant_config_dispose (GObject *object) -{ - NMSupplicantConfig * self = NM_SUPPLICANT_CONFIG (object); - NMSupplicantConfigClass * klass; - GObjectClass * parent_class; - - if (self->priv->dispose_has_run) - /* If dispose did already run, return. */ - return; - - /* Make sure dispose does not run twice. */ - self->priv->dispose_has_run = TRUE; - - /* - * In dispose, you are supposed to free all types referenced from this - * object which might themselves hold a reference to self. Generally, - * the most simple solution is to unref all members on which you own a - * reference. - */ - if (self->priv->dev) { - g_object_unref (G_OBJECT (self->priv->dev)); - self->priv->dev = NULL; - } - - /* Chain up to the parent class */ - klass = NM_SUPPLICANT_CONFIG_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_CONFIG)); - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - parent_class->dispose (object); + return g_hash_table_remove (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->config, key); } static void nm_supplicant_config_finalize (GObject *object) { - NMSupplicantConfig * self = NM_SUPPLICANT_CONFIG (object); - NMSupplicantConfigClass * klass; - GObjectClass * parent_class; - GSList * elt; - /* Complete object destruction */ - for (elt = self->priv->config; elt; elt = g_slist_next (elt)) { - free_option (elt->data); - g_slice_free (struct option, elt->data); - } - g_slist_free (self->priv->config); - self->priv->config = NULL; + g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->config); /* Chain up to the parent class */ - klass = NM_SUPPLICANT_CONFIG_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_CONFIG)); - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - parent_class->finalize (object); + G_OBJECT_CLASS (nm_supplicant_config_parent_class)->finalize (object); } @@ -242,117 +164,61 @@ nm_supplicant_config_class_init (NMSupplicantConfigClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->dispose = nm_supplicant_config_dispose; object_class->finalize = nm_supplicant_config_finalize; g_type_class_add_private (object_class, sizeof (NMSupplicantConfigPrivate)); } -GType -nm_supplicant_config_get_type (void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (NMSupplicantConfigClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) nm_supplicant_config_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (NMSupplicantConfig), - 0, /* n_preallocs */ - (GInstanceInitFunc) nm_supplicant_config_init, - NULL /* value_table */ - }; - - type = g_type_register_static (G_TYPE_OBJECT, - "NMSupplicantConfig", - &info, 0); - } - return type; -} - guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self) { - g_return_val_if_fail (self != NULL, 1); + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), 1); - return self->priv->ap_scan; + return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan; } void nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self, guint32 ap_scan) { - g_return_if_fail (self != NULL); - g_return_if_fail (ap_scan >= 0 && ap_scan <=2); + g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self)); + g_return_if_fail (ap_scan >= 0 && ap_scan <= 2); - self->priv->ap_scan = ap_scan; + NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan = ap_scan; } -gboolean -nm_supplicant_config_add_to_dbus_message (NMSupplicantConfig * self, - DBusMessage * message) +static void +get_hash_cb (gpointer key, gpointer value, gpointer user_data) { - GSList * elt; - DBusMessageIter iter, iter_dict; - gboolean success = FALSE; + ConfigOption *opt = (ConfigOption *) value; + GValue *variant; - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (message != NULL, FALSE); + variant = g_slice_new0 (GValue); + g_value_init (variant, G_TYPE_STRING); + g_value_set_string (variant, opt->value); - dbus_message_iter_init_append (message, &iter); - - if (!nmu_dbus_dict_open_write (&iter, &iter_dict)) { - nm_warning ("dict open write failed!"); - goto out; - } - - for (elt = self->priv->config; elt; elt = g_slist_next (elt)) { - struct option * opt = (struct option *) elt->data; - - switch (opt->type) { - case TYPE_INT: - if (!nmu_dbus_dict_append_string (&iter_dict, opt->key, opt->value)) { - nm_warning ("couldn't append INT option '%s' to dict", opt->key); - goto out; - } - break; - - case TYPE_KEYWORD: - if (!nmu_dbus_dict_append_string (&iter_dict, opt->key, opt->value)) { - nm_warning ("couldn't append KEYWORD option '%s' to dict", opt->key); - goto out; - } - break; - - case TYPE_BYTES: - { - if (!nmu_dbus_dict_append_byte_array (&iter_dict, - opt->key, - opt->value, - opt->len)) { - nm_warning ("couldn't append BYTES option '%s' to dict", opt->key); - goto out; - } - } - break; - - default: - nm_warning ("unknown option '%s', type %d", opt->key, opt->type); - goto out; - break; - } - } - - if (!nmu_dbus_dict_close_write (&iter, &iter_dict)) { - nm_warning ("dict close write failed!"); - goto out; - } - - success = TRUE; - -out: - return success; + g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), variant); +} + +static void +destroy_hash_value (gpointer data) +{ + g_slice_free (GValue, data); +} + +GHashTable * +nm_supplicant_config_get_hash (NMSupplicantConfig * self) +{ + GHashTable *hash; + + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL); + + hash = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + destroy_hash_value); + + g_hash_table_foreach (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->config, + get_hash_cb, hash); + + return hash; } diff --git a/src/supplicant-manager/nm-supplicant-config.h b/src/supplicant-manager/nm-supplicant-config.h index feb357b1f2..f492ab1b3d 100644 --- a/src/supplicant-manager/nm-supplicant-config.h +++ b/src/supplicant-manager/nm-supplicant-config.h @@ -24,7 +24,6 @@ #include #include "nm-supplicant-types.h" -#include "nm-device.h" G_BEGIN_DECLS @@ -35,28 +34,20 @@ G_BEGIN_DECLS #define NM_IS_SUPPLICANT_CONFIG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_CONFIG)) #define NM_SUPPLICANT_CONFIG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_CONFIG, NMSupplicantConfigClass)) -typedef struct _NMSupplicantConfigClass NMSupplicantConfigClass; -typedef struct _NMSupplicantConfigPrivate NMSupplicantConfigPrivate; - struct _NMSupplicantConfig { GObject parent; - - /*< private >*/ - NMSupplicantConfigPrivate *priv; }; -struct _NMSupplicantConfigClass +typedef struct { GObjectClass parent; - - /* class members */ -}; +} NMSupplicantConfigClass; GType nm_supplicant_config_get_type (void); -NMSupplicantConfig * nm_supplicant_config_new (NMDevice *dev); +NMSupplicantConfig * nm_supplicant_config_new (const char *ifname); gboolean nm_supplicant_config_add_option (NMSupplicantConfig *scfg, const char * key, @@ -71,8 +62,7 @@ guint32 nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self); void nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self, guint32 ap_scan); -gboolean nm_supplicant_config_add_to_dbus_message (NMSupplicantConfig * self, - DBusMessage * message); +GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig * self); G_END_DECLS diff --git a/src/supplicant-manager/nm-supplicant-interface.c b/src/supplicant-manager/nm-supplicant-interface.c index aac2f7f723..81e2da9479 100644 --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -19,22 +19,27 @@ * (C) Copyright 2006 Red Hat, Inc. */ +#include #include #include #include "nm-supplicant-interface.h" #include "nm-supplicant-manager.h" -#include "nm-device.h" -#include "nm-device-802-3-ethernet.h" #include "nm-utils.h" #include "nm-supplicant-marshal.h" #include "nm-supplicant-config.h" #include "nm-dbus-manager.h" #include "dbus-dict-helpers.h" -#include "NetworkManagerMain.h" +#include "nm-call-store.h" #define WPAS_DBUS_IFACE_INTERFACE WPAS_DBUS_INTERFACE ".Interface" #define WPAS_DBUS_IFACE_BSSID WPAS_DBUS_INTERFACE ".BSSID" +#define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network" +#define WPAS_ERROR_INVALID_IFACE WPAS_DBUS_INTERFACE ".InvalidInterface" +#define WPAS_ERROR_EXISTS_ERROR WPAS_DBUS_INTERFACE ".ExistsError" + + +G_DEFINE_TYPE (NMSupplicantInterface, nm_supplicant_interface, G_TYPE_OBJECT) #define NM_SUPPLICANT_INTERFACE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ @@ -89,101 +94,105 @@ enum { }; -struct _NMSupplicantInterfacePrivate +typedef struct { NMSupplicantManager * smgr; gulong smgr_state_sig_handler; NMDBusManager * dbus_mgr; - NMDevice * dev; + char * dev; + gboolean is_wireless; guint32 state; - GSList * assoc_pcalls; - GSList * other_pcalls; + NMCallStore * assoc_pcalls; + NMCallStore * other_pcalls; guint32 con_state; - char * wpas_iface_op; - char * wpas_net_op; - guint32 wpas_sig_handler_id; + DBusGProxy * iface_proxy; + DBusGProxy * net_proxy; + GSource * scan_results_timeout; guint32 last_scan; NMSupplicantConfig * cfg; gboolean dispose_has_run; -}; +} NMSupplicantInterfacePrivate; -static GSList * -pcall_list_add_pcall (GSList * pcall_list, - DBusPendingCall * pcall) +static gboolean +cancel_all_cb (GObject *object, gpointer call_id, gpointer user_data) { - GSList * elt; + dbus_g_proxy_cancel_call (DBUS_G_PROXY (object), (DBusGProxyCall *) call_id); - g_return_val_if_fail (pcall != NULL, pcall_list); - - for (elt = pcall_list; elt; elt = g_slist_next (elt)) { - if (pcall == elt->data) - return pcall_list; - } - - return g_slist_append (pcall_list, pcall); + return TRUE; } -static GSList * -pcall_list_remove_pcall (GSList * pcall_list, - DBusPendingCall * pcall) +static void +cancel_all_callbacks (NMCallStore *store) { - GSList * elt; - - g_return_val_if_fail (pcall != NULL, pcall_list); - - for (elt = pcall_list; elt; elt = g_slist_next (elt)) { - DBusPendingCall * item = (DBusPendingCall *) elt->data; - - if (item == pcall) { - if (!dbus_pending_call_get_completed (pcall)) - dbus_pending_call_cancel (pcall); - dbus_pending_call_unref (pcall); - pcall_list = g_slist_remove_link (pcall_list, elt); - g_slist_free_1 (elt); - goto out; - } - } - -out: - return pcall_list; + nm_call_store_foreach (store, NULL, cancel_all_cb, NULL); + nm_call_store_clear (store); } -static GSList * -pcall_list_clear (GSList * pcall_list) +typedef struct { + NMSupplicantInterface *interface; + DBusGProxy *proxy; + NMCallStore *store; + DBusGProxyCall *call; +} NMSupplicantInfo; + +NMSupplicantInfo * +nm_supplicant_info_new (NMSupplicantInterface *interface, + DBusGProxy *proxy, + NMCallStore *store) { - GSList * elt; + NMSupplicantInfo *info; - for (elt = pcall_list; elt; elt = g_slist_next (elt)) { - DBusPendingCall * pcall = (DBusPendingCall *) elt->data; + info = g_slice_new0 (NMSupplicantInfo); + info->interface = interface; + info->proxy = g_object_ref (proxy); + info->store = store; - if (!dbus_pending_call_get_completed (pcall)) - dbus_pending_call_cancel (pcall); - dbus_pending_call_unref (pcall); + return info; +} + +static void +nm_supplicant_info_set_call (NMSupplicantInfo *info, DBusGProxyCall *call) +{ + if (call) { + nm_call_store_add (info->store, g_object_ref (info->proxy), (gpointer) call); + info->call = call; } - g_slist_free (pcall_list); - return NULL; +} + +static void +nm_supplicant_info_destroy (gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + + if (info->call) + nm_call_store_remove (info->store, G_OBJECT (info->proxy), info->call); + + g_object_unref (info->proxy); + + g_slice_free (NMSupplicantInfo, info); } NMSupplicantInterface * -nm_supplicant_interface_new (NMSupplicantManager * smgr, NMDevice * dev) +nm_supplicant_interface_new (NMSupplicantManager * smgr, const char *ifname, gboolean is_wireless) { NMSupplicantInterface * iface; - g_return_val_if_fail (smgr != NULL, NULL); - g_return_val_if_fail (dev != NULL, NULL); + g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (smgr), NULL); + g_return_val_if_fail (ifname != NULL, NULL); iface = g_object_new (NM_TYPE_SUPPLICANT_INTERFACE, "supplicant-manager", smgr, - "device", dev, + "device", ifname, NULL); if (iface) { + NM_SUPPLICANT_INTERFACE_GET_PRIVATE (iface)->is_wireless = is_wireless; nm_supplicant_interface_start (iface); } @@ -193,18 +202,16 @@ nm_supplicant_interface_new (NMSupplicantManager * smgr, NMDevice * dev) static void nm_supplicant_interface_init (NMSupplicantInterface * self) { - self->priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - self->priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT; - self->priv->con_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED; - self->priv->smgr = NULL; - self->priv->dev = NULL; - self->priv->wpas_iface_op = NULL; - self->priv->assoc_pcalls = NULL; - self->priv->other_pcalls = NULL; - self->priv->dispose_has_run = FALSE; + priv->state = NM_SUPPLICANT_INTERFACE_STATE_INIT; + priv->con_state = NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED; + priv->assoc_pcalls = nm_call_store_new (); + priv->other_pcalls = nm_call_store_new (); - self->priv->dbus_mgr = nm_dbus_manager_get (); + priv->dispose_has_run = FALSE; + + priv->dbus_mgr = nm_dbus_manager_get (); } @@ -214,23 +221,23 @@ nm_supplicant_interface_set_property (GObject * object, const GValue * value, GParamSpec * pspec) { - NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object); gulong id; switch (prop_id) { case PROP_SUPPLICANT_MANAGER: - self->priv->smgr = NM_SUPPLICANT_MANAGER (g_value_get_object (value)); - g_object_ref (G_OBJECT (self->priv->smgr)); + priv->smgr = NM_SUPPLICANT_MANAGER (g_value_get_object (value)); + g_object_ref (G_OBJECT (priv->smgr)); - id = g_signal_connect (G_OBJECT (self->priv->smgr), + id = g_signal_connect (priv->smgr, "state", G_CALLBACK (nm_supplicant_interface_smgr_state_changed), - self); - self->priv->smgr_state_sig_handler = id; + object); + priv->smgr_state_sig_handler = id; break; case PROP_DEVICE: - self->priv->dev = NM_DEVICE (g_value_get_object (value)); - g_object_ref (G_OBJECT (self->priv->dev)); + /* Construct-only */ + priv->dev = g_strdup (g_value_get_string (value)); break; case PROP_STATE: /* warn on setting read-only property */ @@ -250,20 +257,20 @@ nm_supplicant_interface_get_property (GObject * object, GValue * value, GParamSpec * pspec) { - NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object); switch (prop_id) { case PROP_SUPPLICANT_MANAGER: - g_value_set_object (value, G_OBJECT (self->priv->smgr)); + g_value_set_object (value, G_OBJECT (priv->smgr)); break; case PROP_DEVICE: - g_value_set_object (value, G_OBJECT (self->priv->dev)); + g_value_set_string (value, priv->dev); break; case PROP_STATE: - g_value_set_uint (value, self->priv->state); + g_value_set_uint (value, priv->state); break; case PROP_CONNECTION_STATE: - g_value_set_uint (value, self->priv->con_state); + g_value_set_uint (value, priv->con_state); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -274,17 +281,15 @@ nm_supplicant_interface_get_property (GObject * object, static void nm_supplicant_interface_dispose (GObject *object) { - NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object); - NMSupplicantInterfaceClass * klass; - GObjectClass * parent_class; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (object); - if (self->priv->dispose_has_run) { + if (priv->dispose_has_run) { /* If dispose did already run, return. */ return; } /* Make sure dispose does not run twice. */ - self->priv->dispose_has_run = TRUE; + priv->dispose_has_run = TRUE; /* * In dispose, you are supposed to free all types referenced from this @@ -292,85 +297,52 @@ nm_supplicant_interface_dispose (GObject *object) * the most simple solution is to unref all members on which you own a * reference. */ - if (self->priv->scan_results_timeout) { - g_source_destroy (self->priv->scan_results_timeout); - self->priv->scan_results_timeout = NULL; + + if (priv->iface_proxy) + g_object_unref (priv->iface_proxy); + + if (priv->net_proxy) + g_object_unref (priv->net_proxy); + + if (priv->scan_results_timeout) + g_source_destroy (priv->scan_results_timeout); + + if (priv->smgr) { + g_signal_handler_disconnect (priv->smgr, + priv->smgr_state_sig_handler); + g_object_unref (priv->smgr); } - if (self->priv->smgr) { - g_signal_handler_disconnect (G_OBJECT (self->priv->smgr), - self->priv->smgr_state_sig_handler); - g_object_unref (self->priv->smgr); - self->priv->smgr = NULL; - } - - if (self->priv->dev) { - g_object_unref (self->priv->dev); - self->priv->dev = NULL; - } + g_free (priv->dev); /* Cancel pending calls before unrefing the dbus manager */ - self->priv->other_pcalls = pcall_list_clear (self->priv->other_pcalls); - self->priv->assoc_pcalls = pcall_list_clear (self->priv->assoc_pcalls); + cancel_all_callbacks (priv->other_pcalls); + nm_call_store_destroy (priv->other_pcalls); - if (self->priv->dbus_mgr) { - if (self->priv->wpas_sig_handler_id) { - nm_dbus_manager_remove_signal_handler (self->priv->dbus_mgr, - self->priv->wpas_sig_handler_id); - self->priv->wpas_sig_handler_id = 0; - } + cancel_all_callbacks (priv->assoc_pcalls); + nm_call_store_destroy (priv->assoc_pcalls); - g_object_unref (self->priv->dbus_mgr); - self->priv->dbus_mgr = NULL; - } + if (priv->dbus_mgr) + g_object_unref (priv->dbus_mgr); - if (self->priv->cfg) { - g_object_unref (self->priv->cfg); - self->priv->cfg = NULL; - } + if (priv->cfg) + g_object_unref (priv->cfg); /* Chain up to the parent class */ - klass = NM_SUPPLICANT_INTERFACE_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_INTERFACE)); - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - parent_class->dispose (object); + G_OBJECT_CLASS (nm_supplicant_interface_parent_class)->dispose (object); } -static void -nm_supplicant_interface_finalize (GObject *object) -{ - NMSupplicantInterface * self = NM_SUPPLICANT_INTERFACE (object); - NMSupplicantInterfaceClass * klass; - GObjectClass * parent_class; - - if (self->priv->wpas_iface_op) { - g_free (self->priv->wpas_iface_op); - self->priv->wpas_iface_op = NULL; - } - - if (self->priv->wpas_net_op) { - g_free (self->priv->wpas_net_op); - self->priv->wpas_net_op = NULL; - } - - /* Chain up to the parent class */ - klass = NM_SUPPLICANT_INTERFACE_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_INTERFACE)); - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - parent_class->finalize (object); -} - - static void nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate)); + object_class->dispose = nm_supplicant_interface_dispose; - object_class->finalize = nm_supplicant_interface_finalize; object_class->set_property = nm_supplicant_interface_set_property; object_class->get_property = nm_supplicant_interface_get_property; - g_type_class_add_private (object_class, sizeof (NMSupplicantInterfacePrivate)); - /* Properties */ g_object_class_install_property (object_class, PROP_SUPPLICANT_MANAGER, @@ -378,18 +350,18 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) "Supplicant Manager", "Supplicant manager to which this interface belongs", NM_TYPE_SUPPLICANT_MANAGER, - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, PROP_DEVICE, - g_param_spec_object ("device", + g_param_spec_string ("device", "Device", "Device which this interface represents to the supplicant", - NM_TYPE_DEVICE, - G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (object_class, - PROP_DEVICE, + PROP_STATE, g_param_spec_uint ("state", "State", "State of the supplicant interface; INIT, READY, or DOWN", @@ -407,7 +379,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) NULL, NULL, nm_supplicant_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); - klass->state = NULL; nm_supplicant_interface_signals[REMOVED] = g_signal_new ("removed", @@ -417,7 +388,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - klass->removed = NULL; nm_supplicant_interface_signals[SCANNED_AP] = g_signal_new ("scanned-ap", @@ -427,7 +397,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - klass->scanned_ap = NULL; nm_supplicant_interface_signals[SCAN_RESULT] = g_signal_new ("scan-result", @@ -437,7 +406,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT); - klass->scan_result = NULL; nm_supplicant_interface_signals[CONNECTION_STATE] = g_signal_new ("connection-state", @@ -447,7 +415,6 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) NULL, NULL, nm_supplicant_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); - klass->connection_state = NULL; nm_supplicant_interface_signals[CONNECTION_ERROR] = g_signal_new ("connection-error", @@ -457,301 +424,146 @@ nm_supplicant_interface_class_init (NMSupplicantInterfaceClass *klass) NULL, NULL, nm_supplicant_marshal_VOID__CHAR_CHAR, G_TYPE_NONE, 2, G_TYPE_CHAR, G_TYPE_CHAR); - klass->connection_error = NULL; -} - -GType -nm_supplicant_interface_get_type (void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (NMSupplicantInterfaceClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) nm_supplicant_interface_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (NMSupplicantInterface), - 0, /* n_preallocs */ - (GInstanceInitFunc) nm_supplicant_interface_init, - NULL /* value_table */ - }; - - type = g_type_register_static (G_TYPE_OBJECT, - "NMSupplicantInterface", - &info, 0); - } - return type; } static void -emit_error_helper (NMSupplicantInterface * self, - const char * name, - const char * message) +emit_error_helper (NMSupplicantInterface *self, + GError *err) { - g_return_if_fail (self != NULL); - g_return_if_fail (name != NULL); - g_return_if_fail (message != NULL); + const char *name = NULL; - g_signal_emit (G_OBJECT (self), + if (err->domain == DBUS_GERROR && err->code == DBUS_GERROR_REMOTE_EXCEPTION) + name = dbus_g_error_get_name (err); + + g_signal_emit (self, nm_supplicant_interface_signals[CONNECTION_ERROR], 0, name, - message); + err->message); } - static void -set_wpas_iface_op_from_message (NMSupplicantInterface * self, - DBusMessage * message) +bssid_properties_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - char * path = NULL; + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + GHashTable *hash = NULL; - dbus_error_init (&error); - - /* Interface was found; cache its object path */ - if (!dbus_message_get_args (message, - &error, - DBUS_TYPE_OBJECT_PATH, &path, - DBUS_TYPE_INVALID)) { - nm_warning ("Error getting interface path from supplicant: %s - %s", - error.name, - error.message); + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &hash, + G_TYPE_INVALID)) { + nm_warning ("Couldn't retrieve BSSID properties: %s.", err->message); + g_error_free (err); } else { - if (self->priv->wpas_iface_op) - g_free (self->priv->wpas_iface_op); - self->priv->wpas_iface_op = g_strdup (path); + g_signal_emit (info->interface, + nm_supplicant_interface_signals[SCANNED_AP], + 0, + hash); + + g_hash_table_destroy (hash); } - - if (dbus_error_is_set (&error)) - dbus_error_free (&error); -} - -static void -bssid_properties_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) -{ - DBusError error; - DBusMessage * reply = NULL; - - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); - - dbus_error_init (&error); - - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) - goto out; - - if (!(reply = dbus_pending_call_steal_reply (pcall))) - goto out; - - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - if (!dbus_set_error_from_message (&error, reply)) { - nm_warning ("Couldn't set error from DBus message."); - goto out; - } - nm_warning ("Couldn't retrieve BSSID properties: %s - %s", - error.name, - error.message); - goto out; - } - - g_signal_emit (G_OBJECT (self), - nm_supplicant_interface_signals[SCANNED_AP], - 0, - reply); - -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall); } static void request_bssid_properties (NMSupplicantInterface * self, const char * op) { - DBusMessage * message = NULL; - DBusConnection * connection = NULL; - DBusPendingCall * pcall = NULL; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxy *proxy; + DBusGProxyCall *call; - g_return_if_fail (self != NULL); - g_return_if_fail (op != NULL); - - connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!connection) { - nm_warning ("could not get dbus connection."); - goto out; - } - - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - op, - WPAS_DBUS_IFACE_BSSID, - "properties"); - if (!message) { - nm_warning ("could not allocate dbus message."); - goto out; - } - - pcall = nm_dbus_send_with_callback (connection, - message, - (DBusPendingCallNotifyFunction) bssid_properties_cb, - self, - NULL, - __func__); - if (!pcall) { - nm_warning ("could not send dbus message."); - goto out; - } - self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall); - -out: - if (message) - dbus_message_unref (message); + 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 (DBusPendingCall * pcall, - NMSupplicantInterface * self) +scan_results_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - DBusMessage * reply = NULL; - char ** bssids; - int num_bssids; - char ** item; + GError *err = NULL; + GPtrArray *array = NULL; - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &array, + G_TYPE_INVALID)) { + nm_warning ("could not get scan results: %s.", err->message); + g_error_free (err); + } else { + int i; + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; - dbus_error_init (&error); + /* Notify listeners of the result of the scan */ + g_signal_emit (info->interface, + nm_supplicant_interface_signals[SCAN_RESULT], + 0, + NM_SUPPLICANT_INTERFACE_SCAN_RESULT_SUCCESS); - nm_dbus_send_with_callback_replied (pcall, __func__); + /* Fire off a "properties" call for each returned BSSID */ + for (i = 0; i < array->len; i++) { + request_bssid_properties (info->interface, g_ptr_array_index (array, i)); + } - if (!dbus_pending_call_get_completed (pcall)) - goto out; - - if (!(reply = dbus_pending_call_steal_reply (pcall))) - goto out; - - if (!dbus_message_get_args (reply, - &error, - DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &bssids, &num_bssids, - DBUS_TYPE_INVALID)) { - nm_warning ("could not get scan results: %s - %s.", - error.name, - error.message); - goto out; + g_ptr_array_free (array, TRUE); } - - /* Notify listeners of the result of the scan */ - g_signal_emit (G_OBJECT (self), - nm_supplicant_interface_signals[SCAN_RESULT], - 0, - NM_SUPPLICANT_INTERFACE_SCAN_RESULT_SUCCESS); - - /* Fire off a "properties" call for each returned BSSID */ - for (item = bssids; *item; item++) { - request_bssid_properties (self, *item); - } - dbus_free_string_array (bssids); - -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall); } static gboolean request_scan_results (gpointer user_data) { - NMSupplicantInterface * self = (NMSupplicantInterface *) user_data; - DBusMessage * message = NULL; - DBusPendingCall * pcall; - DBusConnection * connection; - GTimeVal cur_time; + NMSupplicantInterface *self = NM_SUPPLICANT_INTERFACE (user_data); + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxyCall *call; + GTimeVal cur_time; - if (!self || !self->priv->wpas_iface_op) { - nm_warning ("Invalid user_data or bad supplicant interface object path."); - goto out; - } - - connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!connection) { - nm_warning ("could not get dbus connection."); - goto out; - } - - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - self->priv->wpas_iface_op, - WPAS_DBUS_IFACE_INTERFACE, - "scanResults"); - if (!message) { - nm_warning ("could not allocate dbus message."); - goto out; - } - - pcall = nm_dbus_send_with_callback (connection, - message, - (DBusPendingCallNotifyFunction) scan_results_cb, - self, - NULL, - __func__); - if (!pcall) { - nm_warning ("could not send dbus message."); - goto out; - } - self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall); + 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); - self->priv->last_scan = cur_time.tv_sec; + priv->last_scan = cur_time.tv_sec; -out: - if (message) - dbus_message_unref (message); - - if (self->priv->scan_results_timeout) { - g_source_unref (self->priv->scan_results_timeout); - self->priv->scan_results_timeout = NULL; + if (priv->scan_results_timeout) { + g_source_unref (priv->scan_results_timeout); + priv->scan_results_timeout = NULL; } return FALSE; } static void -wpas_iface_query_scan_results (NMSupplicantInterface * self) +wpas_iface_query_scan_results (DBusGProxy *proxy, gpointer user_data) { + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data); guint id; GSource * source; - NMData * app_data; - - g_return_if_fail (self != NULL); - g_return_if_fail (self->priv->dev); /* Only query scan results if a query is not queued */ - if (self->priv->scan_results_timeout) - return; - - app_data = nm_device_get_app_data (self->priv->dev); - if (!app_data) + if (priv->scan_results_timeout) return; /* Only fetch scan results every 4s max, but initially do it right away */ - if (self->priv->last_scan == 0) { - id = g_idle_add (request_scan_results, self); + if (priv->last_scan == 0) { + id = g_idle_add (request_scan_results, user_data); } else { - id = g_timeout_add (4000, request_scan_results, self); + id = g_timeout_add (4000, request_scan_results, user_data); } if (id > 0) { source = g_main_context_find_source_by_id (NULL, id); - self->priv->scan_results_timeout = source; + priv->scan_results_timeout = source; } } @@ -782,323 +594,174 @@ wpas_state_string_to_enum (const char * str_state) } static void -wpas_iface_handle_state_change (NMSupplicantInterface * self, - DBusMessage * message) +wpas_iface_handle_state_change (DBusGProxy *proxy, + const char *str_new_state, + const char *str_old_state, + gpointer user_data) { - DBusError error; - char * str_old_state; - char * str_new_state; - guint32 old_state, enum_new_state; - - dbus_error_init (&error); - if (!dbus_message_get_args (message, - &error, - DBUS_TYPE_STRING, &str_new_state, - DBUS_TYPE_STRING, &str_old_state, - DBUS_TYPE_INVALID)) { - nm_warning ("could not get message arguments: %s - %s", - error.name, - error.message); - goto out; - } + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (user_data); + guint32 old_state, enum_new_state; enum_new_state = wpas_state_string_to_enum (str_new_state); - old_state = self->priv->con_state; - self->priv->con_state = enum_new_state; - if (self->priv->con_state != old_state) { - g_signal_emit (G_OBJECT (self), + old_state = priv->con_state; + priv->con_state = enum_new_state; + if (priv->con_state != old_state) { + g_signal_emit (user_data, nm_supplicant_interface_signals[CONNECTION_STATE], 0, - self->priv->con_state, + priv->con_state, old_state); } - -out: - if (dbus_error_is_set (&error)) - dbus_error_free (&error); } -static gboolean -wpas_iface_signal_handler (DBusConnection * connection, - DBusMessage * message, - gpointer user_data) -{ - NMSupplicantInterface * self = (NMSupplicantInterface *) user_data; - const char * op = dbus_message_get_path (message); - gboolean handled = FALSE; - - g_return_val_if_fail (self != NULL, FALSE); - - if (!op || !self->priv->wpas_iface_op) - return FALSE; - - /* Only handle signals for our interface */ - if (strcmp (op, self->priv->wpas_iface_op) != 0) - return FALSE; - - if (dbus_message_is_signal (message, - WPAS_DBUS_IFACE_INTERFACE, - "ScanResultsAvailable")) { - wpas_iface_query_scan_results (self); - handled = TRUE; - } else if (dbus_message_is_signal (message, - WPAS_DBUS_IFACE_INTERFACE, - "StateChange")) { - wpas_iface_handle_state_change (self, message); - handled = TRUE; - } - - return handled; -} static void -iface_state_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) +iface_state_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - DBusMessage * reply = NULL; - char * state_str = NULL; + GError *err = NULL; + char *state_str = NULL; - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + G_TYPE_STRING, &state_str, + G_TYPE_INVALID)) { + nm_warning ("could not get interface state: %s.", err->message); + g_error_free (err); + } else { + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; - dbus_error_init (&error); - - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) - goto out; - - if (!(reply = dbus_pending_call_steal_reply (pcall))) - goto out; - - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - if (!dbus_set_error_from_message (&error, reply)) { - nm_warning ("couldn't get error information."); - } else { - nm_warning ("could not get interface state: %s - %s.", - error.name, - error.message); - } - goto out; + NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface)->con_state = wpas_state_string_to_enum (state_str); + nm_supplicant_interface_set_state (info->interface, + NM_SUPPLICANT_INTERFACE_STATE_READY); } - - if (!dbus_message_get_args (reply, - &error, - DBUS_TYPE_STRING, &state_str, - DBUS_TYPE_INVALID)) { - nm_warning ("could not get interface state: %s - %s.", - error.name, - error.message); - goto out; - } - - self->priv->con_state = wpas_state_string_to_enum (state_str); - nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_READY); - -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall); } static void wpas_iface_get_state (NMSupplicantInterface *self) { - DBusMessage * message = NULL; - DBusPendingCall * pcall; - DBusConnection * connection; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxyCall *call; - if (!self || !self->priv->wpas_iface_op) { - nm_warning ("Invalid user_data or bad supplicant interface object path."); - goto out; - } - - connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!connection) { - nm_warning ("could not get dbus connection."); - goto out; - } - - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - self->priv->wpas_iface_op, - WPAS_DBUS_IFACE_INTERFACE, - "state"); - if (!message) { - nm_warning ("could not allocate dbus message."); - goto out; - } - - pcall = nm_dbus_send_with_callback (connection, - message, - (DBusPendingCallNotifyFunction) iface_state_cb, - self, - NULL, - __func__); - if (!pcall) { - nm_warning ("could not send dbus message."); - goto out; - } - self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall); - -out: - if (message) - dbus_message_unref (message); + 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); } -#define WPAS_ERROR_INVALID_IFACE \ - WPAS_DBUS_INTERFACE ".InvalidInterface" -#define WPAS_ERROR_EXISTS_ERROR \ - WPAS_DBUS_INTERFACE ".ExistsError" - static void -nm_supplicant_interface_add_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) +nm_supplicant_interface_add_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - DBusMessage * reply = NULL; + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + char *path = NULL; - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + DBUS_TYPE_G_OBJECT_PATH, &path, + G_TYPE_INVALID)) { - dbus_error_init (&error); + if (dbus_g_error_has_name (err, WPAS_ERROR_INVALID_IFACE)) { + /* Interface not added, try to add it */ + nm_supplicant_interface_add_to_supplicant (info->interface, FALSE); + } else if (dbus_g_error_has_name (err, WPAS_ERROR_EXISTS_ERROR)) { + /* Interface already added, just try to get the interface */ + nm_supplicant_interface_add_to_supplicant (info->interface, TRUE); + } else { + nm_warning ("Unexpected supplicant error getting interface: %s", err->message); + } - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) - goto out; - - if (!(reply = dbus_pending_call_steal_reply (pcall))) - goto out; - - if (dbus_message_is_error (reply, WPAS_ERROR_INVALID_IFACE)) { - /* Interface not added, try to add it */ - nm_supplicant_interface_add_to_supplicant (self, FALSE); - } else if (dbus_message_is_error (reply, WPAS_ERROR_EXISTS_ERROR)) { - /* Interface already added, just try to get the interface */ - nm_supplicant_interface_add_to_supplicant (self, TRUE); - } else if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - if (!dbus_set_error_from_message (&error, reply)) - goto out; - - nm_warning ("Unexpected supplicant error getting interface: %s - %s", - error.name, - error.message); + g_error_free (err); } else { - guint32 id; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); - /* Success; cache the object path */ - set_wpas_iface_op_from_message (self, reply); + priv->iface_proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + path, + WPAS_DBUS_IFACE_INTERFACE); - /* Attach to the scan results signal */ - id = nm_dbus_manager_register_signal_handler (self->priv->dbus_mgr, - WPAS_DBUS_IFACE_INTERFACE, - WPAS_DBUS_SERVICE, - wpas_iface_signal_handler, - self); - self->priv->wpas_sig_handler_id = id; + dbus_g_proxy_add_signal (priv->iface_proxy, "ScanResultsAvailable", G_TYPE_INVALID); + + dbus_g_object_register_marshaller (nm_supplicant_marshal_VOID__STRING_STRING, + G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, 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, "ScanResultsAvailable", + G_CALLBACK (wpas_iface_query_scan_results), + info->interface, + NULL); + + dbus_g_proxy_connect_signal (priv->iface_proxy, "StateChange", + G_CALLBACK (wpas_iface_handle_state_change), + info->interface, + NULL); /* Interface added to the supplicant; get its initial state. */ - wpas_iface_get_state (self); + wpas_iface_get_state (info->interface); } - -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall); } - static void nm_supplicant_interface_add_to_supplicant (NMSupplicantInterface * self, gboolean get_only) { - DBusConnection * dbus_connection; - DBusMessage * message = NULL; - DBusMessageIter iter; - const char * dev_iface; - DBusPendingCall * pcall; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); + NMSupplicantInfo *info; + DBusGProxy *proxy; + DBusGProxyCall *call; - g_return_if_fail (self != NULL); + proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (priv->dbus_mgr), + WPAS_DBUS_SERVICE, + WPAS_DBUS_PATH, + WPAS_DBUS_INTERFACE); + info = nm_supplicant_info_new (self, proxy, priv->other_pcalls); - dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!dbus_connection) { - nm_warning ("could not get the dbus connection."); - goto out; + if (get_only) { + call = dbus_g_proxy_begin_call (proxy, + "getInterface", + nm_supplicant_interface_add_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_STRING, priv->dev, + G_TYPE_INVALID); + } else { + GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal); + GValue *driver; + + driver = g_new0 (GValue, 1); + g_value_init (driver, G_TYPE_STRING); + g_value_set_string (driver, priv->is_wireless ? "wext" : "wired"); + g_hash_table_insert (hash, "driver", driver); + + call = dbus_g_proxy_begin_call (proxy, + "addInterface", + nm_supplicant_interface_add_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_STRING, priv->dev, + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), hash, + G_TYPE_INVALID); + + g_hash_table_destroy (hash); } - /* Request the interface object from the supplicant */ - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - WPAS_DBUS_PATH, - WPAS_DBUS_INTERFACE, - get_only ? "getInterface" : "addInterface"); - if (!message) { - nm_warning ("Not enough memory to allocate dbus message."); - goto out; - } + g_object_unref (proxy); - dbus_message_iter_init_append (message, &iter); - dev_iface = nm_device_get_iface (self->priv->dev); - if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &dev_iface)) { - nm_warning ("Couldn't add device interface to message."); - goto out; - } - - /* Add the supplicant driver name if we're adding */ - if (!get_only) { - DBusMessageIter iter_dict; - char * driver = "wext"; - - if (!nmu_dbus_dict_open_write (&iter, &iter_dict)) { - nm_warning ("dict open write failed!"); - goto out; - } - - if (nm_device_is_802_3_ethernet (self->priv->dev)) - driver = "wired"; - if (!nmu_dbus_dict_append_string (&iter_dict, "driver", driver)) { - nm_warning ("couldn't append driver to dict"); - goto out; - } - - if (!nmu_dbus_dict_close_write (&iter, &iter_dict)) { - nm_warning ("dict close write failed!"); - goto out; - } - } - - pcall = nm_dbus_send_with_callback (dbus_connection, - message, - (DBusPendingCallNotifyFunction) nm_supplicant_interface_add_cb, - self, - NULL, - __func__); - if (!pcall) { - nm_warning ("could not send dbus message."); - goto out; - } - self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall); - -out: - if (message) - dbus_message_unref (message); + nm_supplicant_info_set_call (info, call); } static void nm_supplicant_interface_start (NMSupplicantInterface * self) { + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); guint32 state; - g_return_if_fail (self != NULL); - /* Can only start the interface from INIT state */ - g_return_if_fail (self->priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT); + g_return_if_fail (priv->state == NM_SUPPLICANT_INTERFACE_STATE_INIT); - state = nm_supplicant_manager_get_state (self->priv->smgr); + state = nm_supplicant_manager_get_state (priv->smgr); if (state == NM_SUPPLICANT_MANAGER_STATE_IDLE) { nm_supplicant_interface_set_state (self, NM_SUPPLICANT_INTERFACE_STATE_STARTING); nm_supplicant_interface_add_to_supplicant (self, FALSE); @@ -1114,9 +777,7 @@ nm_supplicant_interface_start (NMSupplicantInterface * self) static void nm_supplicant_interface_handle_supplicant_manager_idle_state (NMSupplicantInterface * self) { - g_return_if_fail (self != NULL); - - switch (self->priv->state) { + switch (NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state) { case NM_SUPPLICANT_INTERFACE_STATE_INIT: /* Move to STARTING state when supplicant is ready */ nm_supplicant_interface_start (self); @@ -1141,28 +802,28 @@ static void nm_supplicant_interface_set_state (NMSupplicantInterface * self, guint32 new_state) { + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); guint32 old_state; - g_return_if_fail (self != NULL); g_return_if_fail (new_state < NM_SUPPLICANT_INTERFACE_STATE_LAST); - if (new_state == self->priv->state) + if (new_state == priv->state) return; - old_state = self->priv->state; + old_state = priv->state; if (new_state == NM_SUPPLICANT_INTERFACE_STATE_DOWN) { /* If the interface is transitioning to DOWN and there's are * in-progress pending calls, cancel them. */ - self->priv->other_pcalls = pcall_list_clear (self->priv->other_pcalls); - self->priv->assoc_pcalls = pcall_list_clear (self->priv->assoc_pcalls); + cancel_all_callbacks (priv->other_pcalls); + cancel_all_callbacks (priv->assoc_pcalls); } - self->priv->state = new_state; - g_signal_emit (G_OBJECT (self), + priv->state = new_state; + g_signal_emit (self, nm_supplicant_interface_signals[STATE], 0, - self->priv->state, + priv->state, old_state); } @@ -1194,612 +855,291 @@ nm_supplicant_interface_smgr_state_changed (NMSupplicantManager * smgr, static void -remove_network_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) +remove_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - DBusMessage * reply = NULL; + GError *err = NULL; + guint tmp; - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); - - dbus_error_init (&error); - - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) - goto out; - - if (!(reply = dbus_pending_call_steal_reply (pcall))) - goto out; - - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - dbus_set_error_from_message (&error, reply); - nm_warning ("Couldn't remove network from supplicant interface: %s - %s", - error.name, - error.message); + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_warning ("Couldn't remove network from supplicant interface: %s.", err->message); + g_error_free (err); } - -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall); } static void -disconnect_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) +disconnect_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - DBusMessage * reply = NULL; + GError *err = NULL; + guint tmp; - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); - - dbus_error_init (&error); - - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) - goto out; - - if (!(reply = dbus_pending_call_steal_reply (pcall))) - goto out; - - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - dbus_set_error_from_message (&error, reply); - nm_warning ("Couldn't disconnect supplicant interface: %s - %s", - error.name, - error.message); + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_warning ("Couldn't disconnect supplicant interface: %s.", err->message); + g_error_free (err); } +} -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall); +static void +interface_disconnect_done (gpointer data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) data; + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + + g_object_unref (priv->net_proxy); + priv->net_proxy = NULL; + + nm_supplicant_info_destroy (data); } void nm_supplicant_interface_disconnect (NMSupplicantInterface * self) { - DBusMessage * message = NULL; - DBusPendingCall * pcall = NULL; - DBusConnection * dbus_connection; + NMSupplicantInterfacePrivate *priv; + NMSupplicantInfo *info; + DBusGProxyCall *call; - g_return_if_fail (self != NULL); + g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (self)); + + priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); /* Clear and cancel all pending calls related to a prior * connection attempt. */ - self->priv->assoc_pcalls = pcall_list_clear (self->priv->assoc_pcalls); + cancel_all_callbacks (priv->assoc_pcalls); /* Don't do anything if there is no connection to the supplicant yet. */ - if (!self->priv->wpas_iface_op) + if (!priv->iface_proxy) return; - dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!dbus_connection) { - nm_warning ("could not get the dbus connection."); - goto out; - } - /* Don't try to disconnect if the supplicant interface is already * disconnected. */ - if (self->priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED - || self->priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) { - if (self->priv->wpas_net_op) { - g_free (self->priv->wpas_net_op); - self->priv->wpas_net_op = NULL; + if (priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED + || priv->con_state == NM_SUPPLICANT_INTERFACE_CON_STATE_INACTIVE) { + if (priv->net_proxy) { + g_object_unref (priv->net_proxy); + priv->net_proxy = NULL; } + return; } /* Remove any network that was added by NetworkManager */ - if (self->priv->wpas_net_op) { - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - self->priv->wpas_iface_op, - WPAS_DBUS_IFACE_INTERFACE, - "removeNetwork"); - if (!message) { - nm_warning ("Couldn't create dbus message."); - goto out; - } - - if (!dbus_message_append_args (message, - DBUS_TYPE_OBJECT_PATH, &self->priv->wpas_net_op, - DBUS_TYPE_INVALID)) { - nm_warning ("Couldn't compose removeNetwork dbus message."); - goto out; - } - - pcall = nm_dbus_send_with_callback (dbus_connection, - message, - (DBusPendingCallNotifyFunction) remove_network_cb, - self, - NULL, - __func__); - dbus_message_unref (message); - g_free (self->priv->wpas_net_op); - self->priv->wpas_net_op = NULL; + if (priv->net_proxy) { + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "removeNetwork", remove_network_cb, + info, + interface_disconnect_done, + DBUS_TYPE_G_OBJECT_PATH, dbus_g_proxy_get_path (priv->net_proxy), + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); } - /* Send a general disconnect command */ - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - self->priv->wpas_iface_op, - WPAS_DBUS_IFACE_INTERFACE, - "disconnect"); - if (!message) { - nm_warning ("Couldn't create dbus message."); - goto out; - } - - pcall = nm_dbus_send_with_callback (dbus_connection, - message, - (DBusPendingCallNotifyFunction) disconnect_cb, - self, - NULL, - __func__); - -out: - if (message) - dbus_message_unref (message); -} - -#define WPAS_DBUS_IFACE_NETWORK WPAS_DBUS_INTERFACE ".Network" - -static void -select_network_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) -{ - DBusError error; - DBusMessage * reply = NULL; - - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); - - dbus_error_init (&error); - - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) { - emit_error_helper (self, "SelectNetworkError", "pending call not yet completed"); - goto out; - } - - if (!(reply = dbus_pending_call_steal_reply (pcall))) { - emit_error_helper (self, "SelectNetworkError", "could not steal reply"); - goto out; - } - - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - dbus_set_error_from_message (&error, reply); - nm_warning ("Couldn't select network config: %s - %s", - error.name, - error.message); - emit_error_helper (self, error.name, error.message); - goto out; - } - -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->assoc_pcalls = pcall_list_remove_pcall (self->priv->assoc_pcalls, pcall); + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "disconnect", disconnect_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); } static void -set_network_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) +select_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - DBusMessage * reply = NULL; - DBusConnection * dbus_connection; - DBusMessage * message = NULL; + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + guint tmp; - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); - - dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!dbus_connection) { - nm_warning ("could not get the dbus connection."); - emit_error_helper (self, "SetNetworkError", "could not get the dbus connection."); - goto out; + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_warning ("Couldn't select network config: %s.", err->message); + emit_error_helper (info->interface, err); + g_error_free (err); } - - dbus_error_init (&error); - - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) { - emit_error_helper (self, "SetNetworkError", "pending call not yet completed"); - goto out; - } - - if (!(reply = dbus_pending_call_steal_reply (pcall))) { - emit_error_helper (self, "SetNetworkError", "could not steal reply"); - goto out; - } - - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - dbus_set_error_from_message (&error, reply); - nm_warning ("Couldn't set network config: %s - %s", - error.name, - error.message); - emit_error_helper (self, error.name, error.message); - goto out; - } - - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - self->priv->wpas_iface_op, - WPAS_DBUS_IFACE_INTERFACE, - "selectNetwork"); - if (!message) { - nm_warning ("Couldn't create dbus message."); - emit_error_helper (self, "SetNetworkError", "could not create dbus message."); - goto out; - } - - if (!dbus_message_append_args (message, - DBUS_TYPE_OBJECT_PATH, &self->priv->wpas_net_op, - DBUS_TYPE_INVALID)) { - emit_error_helper (self, "SetNetworkError", "could not add arguments to message."); - goto out; - } - - nm_dbus_send_with_callback (dbus_connection, - message, - (DBusPendingCallNotifyFunction) select_network_cb, - self, - NULL, - __func__); - -out: - if (reply) - dbus_message_unref (reply); - if (message) - dbus_message_unref (message); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->assoc_pcalls = pcall_list_remove_pcall (self->priv->assoc_pcalls, pcall); } static void -add_network_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) +set_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - DBusMessage * reply = NULL; - DBusMessage * message = NULL; - DBusConnection * dbus_connection = NULL; - char * net_op = NULL; + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + guint tmp; - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_warning ("Couldn't set network config: %s.", err->message); + emit_error_helper (info->interface, err); + g_error_free (err); + } else { + NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface); + DBusGProxyCall *call; - dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!dbus_connection) { - nm_warning ("could not get the dbus connection."); - emit_error_helper (self, "AddNetworkError", "could not get the dbus connection."); - goto out; + info = nm_supplicant_info_new (info->interface, priv->iface_proxy, + NM_SUPPLICANT_INTERFACE_GET_PRIVATE (info->interface)->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); } - - dbus_error_init (&error); - - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) { - emit_error_helper (self, "AddNetworkError", "pending call not yet completed."); - goto out; - } - - if (!(reply = dbus_pending_call_steal_reply (pcall))) { - emit_error_helper (self, "AddNetworkError", "could not steal reply"); - goto out; - } - - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - dbus_set_error_from_message (&error, reply); - nm_warning ("Couldn't add a network to the supplicant interface: %s - %s", - error.name, - error.message); - emit_error_helper (self, error.name, error.message); - goto out; - } - - if (!dbus_message_get_args (reply, - &error, - DBUS_TYPE_OBJECT_PATH, &net_op, - DBUS_TYPE_INVALID)) { - nm_warning ("couldn't get network object path from the supplicant: %s - %s", - error.name, - error.message); - emit_error_helper (self, error.name, error.message); - goto out; - } - self->priv->wpas_net_op = g_strdup (net_op); - - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - self->priv->wpas_net_op, - WPAS_DBUS_IFACE_NETWORK, - "set"); - if (!message) { - nm_warning ("Couldn't create dbus message."); - emit_error_helper (self, "AddNetworkError", "could not create dbus message."); - goto out; - } - - if (!nm_supplicant_config_add_to_dbus_message (self->priv->cfg, message)) { - emit_error_helper (self, "AddNetworkError", "could not add config to dbus message."); - goto out; - } - - nm_dbus_send_with_callback (dbus_connection, - message, - (DBusPendingCallNotifyFunction) set_network_cb, - self, - NULL, - __func__); - dbus_message_unref (message); - -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->assoc_pcalls = pcall_list_remove_pcall (self->priv->assoc_pcalls, pcall); } static void -set_ap_scan_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) +add_network_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - DBusMessage * reply = NULL; - DBusMessage * message = NULL; - DBusConnection * dbus_connection = NULL; + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + char *path = NULL; - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + DBUS_TYPE_G_OBJECT_PATH, &path, + G_TYPE_INVALID)) { + nm_warning ("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 *config_hash; + DBusGProxyCall *call; - dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!dbus_connection) { - nm_warning ("could not get the dbus connection."); - emit_error_helper (self, "SetAPScanError", "could not get the dbus connection."); - goto out; + config_hash = nm_supplicant_config_get_hash (priv->cfg); + + 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); + + info = nm_supplicant_info_new (info->interface, priv->net_proxy, priv->assoc_pcalls); + call = dbus_g_proxy_begin_call (priv->net_proxy, "set", set_network_cb, + info, + nm_supplicant_info_destroy, + dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), config_hash, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); + + g_hash_table_destroy (config_hash); + } +} + +static void +set_ap_scan_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) +{ + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + guint32 tmp; + + if (!dbus_g_proxy_end_call (proxy, call_id, &err, G_TYPE_UINT, &tmp, G_TYPE_INVALID)) { + nm_warning ("Couldn't send AP scan mode to the supplicant interface: %s.", err->message); + emit_error_helper (info->interface, err); + g_error_free (err); + } else { + DBusGProxyCall *call; + + info = nm_supplicant_info_new (info->interface, proxy, info->store); + call = dbus_g_proxy_begin_call (proxy, "addNetwork", add_network_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); } - - dbus_error_init (&error); - - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) { - emit_error_helper (self, "SetAPScanError", "pending call not yet completed."); - goto out; - } - - if (!(reply = dbus_pending_call_steal_reply (pcall))) { - emit_error_helper (self, "SetAPScanError", "could not steal reply"); - goto out; - } - - if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) { - dbus_set_error_from_message (&error, reply); - nm_warning ("Couldn't send AP scan mode to the supplicant interface: %s - %s", - error.name, - error.message); - emit_error_helper (self, error.name, error.message); - goto out; - } - - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - self->priv->wpas_iface_op, - WPAS_DBUS_IFACE_INTERFACE, - "addNetwork"); - if (!message) { - nm_warning ("Couldn't create dbus message."); - emit_error_helper (self, "SetAPScanError", "couldn't create addNetwork message"); - goto out; - } - - pcall = nm_dbus_send_with_callback (dbus_connection, - message, - (DBusPendingCallNotifyFunction) add_network_cb, - self, - NULL, - __func__); - -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->assoc_pcalls = pcall_list_remove_pcall (self->priv->assoc_pcalls, pcall); } -#include gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * self, NMSupplicantConfig * cfg) { - DBusConnection * dbus_connection; - DBusMessage * message = NULL; - DBusPendingCall * pcall = NULL; - gboolean success = FALSE; - guint32 ap_scan; + NMSupplicantInterfacePrivate *priv; + NMSupplicantInfo *info; + DBusGProxyCall *call; + guint32 ap_scan; - g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE); - dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!dbus_connection) { - nm_warning ("could not get the dbus connection."); - goto out; - } + priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); nm_supplicant_interface_disconnect (self); + + if (priv->cfg) + g_object_unref (priv->cfg); + priv->cfg = cfg; - if (self->priv->cfg) - g_object_unref (self->priv->cfg); - self->priv->cfg = cfg; + if (cfg == NULL) + return TRUE; - if (cfg == NULL) { - success = TRUE; - goto out; - } + g_object_ref (priv->cfg); - g_object_ref (self->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", set_ap_scan_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_UINT, ap_scan, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - self->priv->wpas_iface_op, - WPAS_DBUS_IFACE_INTERFACE, - "setAPScan"); - if (!message) { - nm_warning ("Couldn't create dbus message."); - goto out; - } - - ap_scan = nm_supplicant_config_get_ap_scan (self->priv->cfg); - if (!dbus_message_append_args (message, - DBUS_TYPE_UINT32, &ap_scan, - DBUS_TYPE_INVALID)) - { - nm_warning ("couldn't set ap scan message arguments."); - goto out; - } - - pcall = nm_dbus_send_with_callback (dbus_connection, - message, - (DBusPendingCallNotifyFunction) set_ap_scan_cb, - self, - NULL, - __func__); - success = TRUE; - -out: - if (message) - dbus_message_unref (message); - return success; + return call != NULL; } -NMDevice * +const char * nm_supplicant_interface_get_device (NMSupplicantInterface * self) { - g_return_val_if_fail (self != NULL, NULL); + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NULL); - return self->priv->dev; + return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->dev; } static void -scan_request_cb (DBusPendingCall * pcall, - NMSupplicantInterface * self) +scan_request_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, gpointer user_data) { - DBusError error; - DBusMessage * reply = NULL; - guint32 success = FALSE; - guint32 scan_result = NM_SUPPLICANT_INTERFACE_SCAN_RESULT_ERROR; + NMSupplicantInfo *info = (NMSupplicantInfo *) user_data; + GError *err = NULL; + guint32 success = 0; - g_return_if_fail (pcall != NULL); - g_return_if_fail (self != NULL); - - dbus_error_init (&error); - - nm_dbus_send_with_callback_replied (pcall, __func__); - - if (!dbus_pending_call_get_completed (pcall)) - goto out; - - if (!(reply = dbus_pending_call_steal_reply (pcall))) - goto out; - - if (!dbus_message_get_args (reply, - &error, - DBUS_TYPE_UINT32, &success, - DBUS_TYPE_INVALID)) { - nm_warning ("could not get scan request result: %s - %s.", - error.name, - error.message); - goto out; - } + if (!dbus_g_proxy_end_call (proxy, call_id, &err, + G_TYPE_UINT, &success, + G_TYPE_INVALID)) { + nm_warning ("Could not get scan request result: %s", err->message); + g_error_free (err); + } /* Notify listeners of the result of the scan */ - if (success == 1) - scan_result = NM_SUPPLICANT_INTERFACE_SCAN_RESULT_SUCCESS; - g_signal_emit (G_OBJECT (self), + g_signal_emit (info->interface, nm_supplicant_interface_signals[SCAN_RESULT], 0, - scan_result); - -out: - if (reply) - dbus_message_unref (reply); - if (dbus_error_is_set (&error)) - dbus_error_free (&error); - self->priv->other_pcalls = pcall_list_remove_pcall (self->priv->other_pcalls, pcall); + success ? NM_SUPPLICANT_INTERFACE_SCAN_RESULT_SUCCESS : NM_SUPPLICANT_INTERFACE_SCAN_RESULT_ERROR); } gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self) { - DBusConnection * dbus_connection; - DBusMessage * message = NULL; - gboolean success = FALSE; - DBusPendingCall * pcall; + NMSupplicantInterfacePrivate *priv; + NMSupplicantInfo *info; + DBusGProxyCall *call; - g_return_val_if_fail (self != NULL, FALSE); - g_return_val_if_fail (self->priv->state == NM_SUPPLICANT_INTERFACE_STATE_READY, FALSE); + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE); - dbus_connection = nm_dbus_manager_get_dbus_connection (self->priv->dbus_mgr); - if (!dbus_connection) { - nm_warning ("could not get the dbus connection."); - goto out; - } + priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self); - message = dbus_message_new_method_call (WPAS_DBUS_SERVICE, - self->priv->wpas_iface_op, - WPAS_DBUS_IFACE_INTERFACE, - "scan"); - if (!message) { - nm_warning ("Not enough memory to allocate dbus message."); - goto out; - } + info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls); + call = dbus_g_proxy_begin_call (priv->iface_proxy, "scan", scan_request_cb, + info, + nm_supplicant_info_destroy, + G_TYPE_INVALID); + nm_supplicant_info_set_call (info, call); - pcall = nm_dbus_send_with_callback (dbus_connection, - message, - (DBusPendingCallNotifyFunction) scan_request_cb, - self, - NULL, - __func__); - if (!pcall) { - nm_warning ("could not send dbus message."); - goto out; - } - self->priv->other_pcalls = pcall_list_add_pcall (self->priv->other_pcalls, pcall); - success = TRUE; - -out: - if (message) - dbus_message_unref (message); - return success; + return call != NULL; } guint32 nm_supplicant_interface_get_state (NMSupplicantInterface * self) { - g_return_val_if_fail (self != NULL, NM_SUPPLICANT_INTERFACE_STATE_DOWN); + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NM_SUPPLICANT_INTERFACE_STATE_DOWN); - return self->priv->state; + return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->state; } guint32 nm_supplicant_interface_get_connection_state (NMSupplicantInterface * self) { - g_return_val_if_fail (self != NULL, NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED); + g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED); - return self->priv->con_state; + return NM_SUPPLICANT_INTERFACE_GET_PRIVATE (self)->con_state; } - diff --git a/src/supplicant-manager/nm-supplicant-interface.h b/src/supplicant-manager/nm-supplicant-interface.h index d0c7afa6b7..f4fe44916c 100644 --- a/src/supplicant-manager/nm-supplicant-interface.h +++ b/src/supplicant-manager/nm-supplicant-interface.h @@ -23,8 +23,8 @@ #define NM_SUPPLICANT_INTERFACE_H #include +#include #include "nm-supplicant-types.h" -#include "nm-device.h" G_BEGIN_DECLS @@ -79,18 +79,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)) -typedef struct _NMSupplicantInterfaceClass NMSupplicantInterfaceClass; -typedef struct _NMSupplicantInterfacePrivate NMSupplicantInterfacePrivate; - struct _NMSupplicantInterface { GObject parent; - - /*< private >*/ - NMSupplicantInterfacePrivate *priv; }; -struct _NMSupplicantInterfaceClass +typedef struct { GObjectClass parent; @@ -113,20 +107,21 @@ struct _NMSupplicantInterfaceClass void (* connection_error) (NMSupplicantInterface * iface, const char * name, const char * message); -}; +} NMSupplicantInterfaceClass; GType nm_supplicant_interface_get_type (void); NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr, - NMDevice * dev); + const char *ifname, + gboolean is_wireless); gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface, NMSupplicantConfig * cfg); void nm_supplicant_interface_disconnect (NMSupplicantInterface * iface); -NMDevice * nm_supplicant_interface_get_device (NMSupplicantInterface * iface); +const char * nm_supplicant_interface_get_device (NMSupplicantInterface * iface); gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self); diff --git a/src/supplicant-manager/nm-supplicant-manager.c b/src/supplicant-manager/nm-supplicant-manager.c index 2b6bcf98d8..6b080ecdf3 100644 --- a/src/supplicant-manager/nm-supplicant-manager.c +++ b/src/supplicant-manager/nm-supplicant-manager.c @@ -28,11 +28,20 @@ #include "nm-dbus-manager.h" #include "nm-supplicant-marshal.h" +typedef struct { + NMDBusManager * dbus_mgr; + guint32 state; + GSList * ifaces; + gboolean dispose_has_run; +} NMSupplicantManagerPrivate; #define NM_SUPPLICANT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \ NM_TYPE_SUPPLICANT_MANAGER, \ NMSupplicantManagerPrivate)) +G_DEFINE_TYPE (NMSupplicantManager, nm_supplicant_manager, G_TYPE_OBJECT) + + static void nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr, DBusConnection *connection, const char *name, @@ -54,14 +63,6 @@ enum { static guint nm_supplicant_manager_signals[LAST_SIGNAL] = { 0 }; -struct _NMSupplicantManagerPrivate { - NMDBusManager * dbus_mgr; - guint32 state; - GSList * ifaces; - gboolean dispose_has_run; -}; - - NMSupplicantManager * nm_supplicant_manager_get (void) { @@ -81,15 +82,15 @@ nm_supplicant_manager_get (void) static void nm_supplicant_manager_init (NMSupplicantManager * self) { - self->priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); - self->priv->dispose_has_run = FALSE; - self->priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN; - self->priv->dbus_mgr = nm_dbus_manager_get (); + priv->dispose_has_run = FALSE; + priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN; + priv->dbus_mgr = nm_dbus_manager_get (); nm_supplicant_manager_startup (self); - g_signal_connect (G_OBJECT (self->priv->dbus_mgr), + g_signal_connect (priv->dbus_mgr, "name-owner-changed", G_CALLBACK (nm_supplicant_manager_name_owner_changed), self); @@ -98,17 +99,15 @@ nm_supplicant_manager_init (NMSupplicantManager * self) static void nm_supplicant_manager_dispose (GObject *object) { - NMSupplicantManager * self = NM_SUPPLICANT_MANAGER (object); - NMSupplicantManagerClass * klass; - GObjectClass * parent_class; + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object); - if (self->priv->dispose_has_run) { + if (priv->dispose_has_run) { /* If dispose did already run, return. */ return; } /* Make sure dispose does not run twice. */ - self->priv->dispose_has_run = TRUE; + priv->dispose_has_run = TRUE; /* * In dispose, you are supposed to free all types referenced from this @@ -116,27 +115,13 @@ nm_supplicant_manager_dispose (GObject *object) * the most simple solution is to unref all members on which you own a * reference. */ - if (self->priv->dbus_mgr) { - g_object_unref (G_OBJECT (self->priv->dbus_mgr)); - self->priv->dbus_mgr = NULL; + if (priv->dbus_mgr) { + g_object_unref (G_OBJECT (priv->dbus_mgr)); + priv->dbus_mgr = NULL; } /* Chain up to the parent class */ - klass = NM_SUPPLICANT_MANAGER_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_MANAGER)); - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - parent_class->dispose (object); -} - -static void -nm_supplicant_manager_finalize (GObject *object) -{ - NMSupplicantManagerClass * klass; - GObjectClass * parent_class; - - /* Chain up to the parent class */ - klass = NM_SUPPLICANT_MANAGER_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_MANAGER)); - parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass)); - parent_class->finalize (object); + G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object); } static void @@ -144,11 +129,10 @@ nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass) { GObjectClass * object_class = G_OBJECT_CLASS (klass); - object_class->dispose = nm_supplicant_manager_dispose; - object_class->finalize = nm_supplicant_manager_finalize; - g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate)); + object_class->dispose = nm_supplicant_manager_dispose; + /* Signals */ nm_supplicant_manager_signals[STATE] = g_signal_new ("state", @@ -158,32 +142,6 @@ nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass) NULL, NULL, nm_supplicant_marshal_VOID__UINT_UINT, G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); - klass->state = NULL; -} - -GType -nm_supplicant_manager_get_type (void) -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof (NMSupplicantManagerClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) nm_supplicant_manager_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (NMSupplicantManager), - 0, /* n_preallocs */ - (GInstanceInitFunc) nm_supplicant_manager_init, - NULL /* value_table */ - }; - - type = g_type_register_static (G_TYPE_OBJECT, - "NMSupplicantManager", - &info, 0); - } - return type; } static void @@ -215,28 +173,26 @@ nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr, guint32 nm_supplicant_manager_get_state (NMSupplicantManager * self) { - g_return_val_if_fail (self != NULL, FALSE); + g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), FALSE); - return self->priv->state; + return NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->state; } static void nm_supplicant_manager_set_state (NMSupplicantManager * self, guint32 new_state) { + NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); guint32 old_state; - g_return_if_fail (self != NULL); - g_return_if_fail (new_state < NM_SUPPLICANT_MANAGER_STATE_LAST); - - if (new_state == self->priv->state) + if (new_state == priv->state) return; - old_state = self->priv->state; - self->priv->state = new_state; - g_signal_emit (G_OBJECT (self), + old_state = priv->state; + priv->state = new_state; + g_signal_emit (self, nm_supplicant_manager_signals[STATE], 0, - self->priv->state, + priv->state, old_state); } @@ -246,7 +202,7 @@ nm_supplicant_manager_startup (NMSupplicantManager * self) gboolean running; /* FIXME: convert to pending call */ - running = nm_dbus_manager_name_has_owner (self->priv->dbus_mgr, + running = nm_dbus_manager_name_has_owner (NM_SUPPLICANT_MANAGER_GET_PRIVATE (self)->dbus_mgr, WPAS_DBUS_SERVICE); if (running) { nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_IDLE); @@ -255,39 +211,34 @@ nm_supplicant_manager_startup (NMSupplicantManager * self) NMSupplicantInterface * nm_supplicant_manager_get_iface (NMSupplicantManager * self, - NMDevice * dev) + const char *ifname, + gboolean is_wireless) { + NMSupplicantManagerPrivate *priv; NMSupplicantInterface * iface = NULL; GSList * elt; - const char * ifname; - g_return_val_if_fail (self != NULL, NULL); - g_return_val_if_fail (dev != NULL, NULL); + g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL); + g_return_val_if_fail (ifname != NULL, NULL); + + priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); /* Ensure we don't already have this interface */ - ifname = nm_device_get_iface (dev); - for (elt = self->priv->ifaces; elt; elt = g_slist_next (elt)) { + for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) { NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data; - NMDevice * if_dev = nm_supplicant_interface_get_device (if_tmp); - if (!strcmp (nm_device_get_iface (if_dev), ifname)) { + if (!strcmp (ifname, nm_supplicant_interface_get_device (if_tmp))) { iface = if_tmp; break; } } if (!iface) { - iface = nm_supplicant_interface_new (self, dev); + iface = nm_supplicant_interface_new (self, ifname, is_wireless); if (iface) - self->priv->ifaces = g_slist_append (self->priv->ifaces, iface); + priv->ifaces = g_slist_append (priv->ifaces, iface); } - /* Object should have 2 references by now; one from the object's creation - * which is for the caller of this function, and one for the supplicant - * manager (because it's kept in the ifaces list) which is grabbed below. - */ - g_object_ref (iface); - return iface; } @@ -295,25 +246,25 @@ void nm_supplicant_manager_release_iface (NMSupplicantManager * self, NMSupplicantInterface * iface) { + NMSupplicantManagerPrivate *priv; GSList * elt; - g_return_if_fail (self != NULL); - g_return_if_fail (iface != NULL); + g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self)); + g_return_if_fail (NM_IS_SUPPLICANT_INTERFACE (iface)); - for (elt = self->priv->ifaces; elt; elt = g_slist_next (elt)) { + priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self); + + for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) { NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data; if (if_tmp == iface) { /* Remove the iface from the supplicant manager's list and * dereference to match additional reference in get_iface. */ - self->priv->ifaces = g_slist_remove_link (self->priv->ifaces, elt); + priv->ifaces = g_slist_remove_link (priv->ifaces, elt); g_slist_free_1 (elt); g_object_unref (iface); break; } } - - /* One further dereference to match g_object_new() initial refcount of 1 */ - g_object_unref (iface); } diff --git a/src/supplicant-manager/nm-supplicant-manager.h b/src/supplicant-manager/nm-supplicant-manager.h index d3f88d3400..148fadbe2c 100644 --- a/src/supplicant-manager/nm-supplicant-manager.h +++ b/src/supplicant-manager/nm-supplicant-manager.h @@ -57,24 +57,18 @@ enum { #define NM_IS_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_MANAGER)) #define NM_SUPPLICANT_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_MANAGER, NMSupplicantManagerClass)) -typedef struct _NMSupplicantManagerClass NMSupplicantManagerClass; -typedef struct _NMSupplicantManagerPrivate NMSupplicantManagerPrivate; - struct _NMSupplicantManager { GObject parent; - - /*< private >*/ - NMSupplicantManagerPrivate *priv; }; -struct _NMSupplicantManagerClass +typedef struct { GObjectClass parent; /* class members */ void (* state) (NMSupplicantManager * mgr, guint32 new_state, guint32 old_state); -}; +} NMSupplicantManagerClass; GType nm_supplicant_manager_get_type (void); @@ -83,7 +77,8 @@ NMSupplicantManager * nm_supplicant_manager_get (void); guint32 nm_supplicant_manager_get_state (NMSupplicantManager * mgr); NMSupplicantInterface * nm_supplicant_manager_get_iface (NMSupplicantManager * mgr, - NMDevice * dev); + const char *ifname, + gboolean is_wireless); void nm_supplicant_manager_release_iface (NMSupplicantManager * mgr, NMSupplicantInterface * iface); diff --git a/src/supplicant-manager/nm-supplicant-marshal.list b/src/supplicant-manager/nm-supplicant-marshal.list index 3cf9be041a..cb33f78b40 100644 --- a/src/supplicant-manager/nm-supplicant-marshal.list +++ b/src/supplicant-manager/nm-supplicant-marshal.list @@ -1,2 +1,3 @@ VOID:UINT,UINT VOID:CHAR,CHAR +VOID:STRING,STRING