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