2007-02-05 Tambet Ingo <tambet@ximian.com>

Make NMDevice abstract class, remove almost all references to it's
	subclasses (the last place gets removed with new policy manager). Add
	NMDeviceInterface (which NMDevice implements) so that when we have
	NMDevice exported over DBUS, there's a common NMDevice interface which
	all instances have, plus there's a device specific interface for each
	specific type.
	Remove functions (nm_device_is_802_3_ethernet) and
	(nm_device_is_802_11_wireless). There are already standard GObject macros
	for type safe checks.
	Use the updated supplican manager API.

	* src/nm-device-interface.h: 
	* src/nm-device-interface.c: 
	* src/nm-call-store.h: 
	* src/nm-call-store.c: Implement.

	* src/supplicant-manager/nm-supplicant-interface.c:
	* src/supplicant-manager/nm-supplicant-interface.h:
	* src/supplicant-manager/nm-supplicant-manager.c:
	* src/supplicant-manager/nm-supplicant-manager.h:
		- Remove all private data type references from public header files.
		- Remove all references to other NM classes, this class is just a
		  proxy between wpa_supplicant and NM so it doesn't have to know
		  any internals.
		- Convert to dbus-glib bindings.
		- Type safe checks for public methods' arguments.
		- Store pending DBUS call ids to NMCallStore.

	* src/supplicant-manager/nm-supplicant-config.c:
		- Store config values in a GHashTable instead of GSList.




git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2285 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Tambet Ingo
2007-02-05 12:14:09 +00:00
committed by Tambet Ingo
parent 58b53400a5
commit a88e1dd3a2
34 changed files with 1880 additions and 2156 deletions

View File

@@ -1,5 +1,36 @@
2007-02-05 Tambet Ingo <tambet@ximian.com> 2007-02-05 Tambet Ingo <tambet@ximian.com>
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/NetworkManagerMain.h: Remove all references to DHCP manager.
* src/NetworkManager.c: Don't initialize the DHCP manager, it's a * src/NetworkManager.c: Don't initialize the DHCP manager, it's a

View File

@@ -173,4 +173,22 @@ typedef enum NMActStage
NM_ACT_STAGE_CANCELLED NM_ACT_STAGE_CANCELLED
} NMActStage; } 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 */

View File

@@ -12,8 +12,12 @@ INCLUDES = -I${top_srcdir} \
sbin_PROGRAMS = NetworkManager sbin_PROGRAMS = NetworkManager
NetworkManager_SOURCES = \ NetworkManager_SOURCES = \
nm-call-store.c \
nm-call-store.h \
nm-device.c \ nm-device.c \
nm-device.h \ nm-device.h \
nm-device-interface.c \
nm-device-interface.h \
nm-device-private.h \ nm-device-private.h \
nm-device-802-3-ethernet.c \ nm-device-802-3-ethernet.c \
nm-device-802-3-ethernet.h \ nm-device-802-3-ethernet.h \

View File

@@ -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 * 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))) if ((dev = nm_get_device_by_iface (data, iface)))
return (NULL); return (NULL);
if ((dev = nm_device_new (iface, udi, test_device, test_device_type, data))) { if ((dev = create_nm_device (data->hal_ctx, iface, udi))) {
nm_info ("Now managing %s device '%s'.", nm_info ("Now managing %s device '%s'.",
nm_device_is_802_11_wireless (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)", NM_IS_DEVICE_802_11_WIRELESS (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)",
nm_device_get_iface (dev)); nm_device_get_iface (dev));
data->dev_list = g_slist_append (data->dev_list, dev); data->dev_list = g_slist_append (data->dev_list, dev);
nm_device_deactivate (dev); nm_device_deactivate (dev);
nm_policy_schedule_device_change_check (data); nm_policy_schedule_device_change_check (data);
nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_ADDED); nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_ADDED);
} }
return dev; 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))) 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)); 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 */ /* Stop and destroy all devices */
g_slist_foreach (data->dev_list, (GFunc) device_stop_and_free, NULL); g_slist_foreach (data->dev_list, (GFunc) device_stop_and_free, NULL);
g_slist_free (data->dev_list); 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->allowed_ap_list);
nm_ap_list_unref (data->invalid_ap_list); nm_ap_list_unref (data->invalid_ap_list);

View File

@@ -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 <hidden> */
if (((ssid_len == 8) || (ssid_len == 9))
&& (memcmp (array->data, "<hidden>", 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 * AP refcounting functions
*/ */

View File

@@ -33,6 +33,7 @@ typedef struct NMAccessPoint NMAccessPoint;
NMAccessPoint * nm_ap_new (void); NMAccessPoint * nm_ap_new (void);
NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *ap); 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_unref (NMAccessPoint *ap);
void nm_ap_ref (NMAccessPoint *ap); void nm_ap_ref (NMAccessPoint *ap);

View File

@@ -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 * nm_ap_list_copy_properties
* *
@@ -513,27 +396,23 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
* *
*/ */
void void
nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev, nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap,
NMAccessPoint *ap,
NMAccessPointList *search_list) NMAccessPointList *search_list)
{ {
NMAccessPoint * found_ap; NMAccessPoint *found_ap;
const char *essid;
g_return_if_fail (ap != NULL); g_return_if_fail (ap != NULL);
if (!search_list)
return;
/* Ignore APs that already have an ESSID */ /* Ignore APs that already have an ESSID */
if (nm_ap_get_essid (ap)) if (!search_list || nm_ap_get_essid (ap))
return; return;
found_ap = nm_ap_list_get_ap_by_address (search_list, nm_ap_get_address (ap)); 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)) essid = found_ap ? nm_ap_get_essid (found_ap) : NULL;
return;
nm_ap_set_essid (ap, nm_ap_get_essid (found_ap)); if (essid)
nm_dbus_signal_wireless_network_change (dev, ap, NETWORK_STATUS_APPEARED, 0); nm_ap_set_essid (ap, essid);
} }
@@ -546,8 +425,7 @@ nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev,
* *
*/ */
void void
nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev, nm_ap_list_copy_essids_by_address (NMAccessPointList *dest,
NMAccessPointList *dest,
NMAccessPointList *source) NMAccessPointList *source)
{ {
NMAPListIter *iter; NMAPListIter *iter;
@@ -560,7 +438,7 @@ nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev,
return; return;
while ((dest_ap = nm_ap_list_iter_next (iter))) 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); nm_ap_list_iter_free (iter);
} }

View File

@@ -26,8 +26,6 @@
#include "NetworkManager.h" #include "NetworkManager.h"
#include "NetworkManagerMain.h" #include "NetworkManagerMain.h"
#include "NetworkManagerAP.h" #include "NetworkManagerAP.h"
#include "nm-device.h"
#include "nm-device-802-11-wireless.h"
typedef struct NMAccessPointList NMAccessPointList; typedef struct NMAccessPointList NMAccessPointList;
typedef struct NMAPListIter NMAPListIter; 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); 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_properties (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_essids_by_address (NMDevice80211Wireless *dev, NMAccessPointList *dest, NMAccessPointList *source); void nm_ap_list_copy_essids_by_address (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_one_essid_by_address (NMDevice80211Wireless *dev, NMAccessPoint *ap, NMAccessPointList *search_list); void nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap, NMAccessPointList *search_list);
gboolean nm_ap_list_merge_scanned_ap (NMDevice80211Wireless *dev, NMAccessPointList *list, NMAccessPoint *merge_ap);
NMNetworkType nm_ap_list_get_type (NMAccessPointList *list); NMNetworkType nm_ap_list_get_type (NMAccessPointList *list);

View File

@@ -63,7 +63,7 @@ static gboolean nm_policy_activation_finish (gpointer user_data)
dev = nm_act_request_get_dev (req); dev = nm_act_request_get_dev (req);
g_assert (dev); 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); ap = nm_act_request_get_ap (req);
nm_device_activation_success_handler (dev, 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); 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); ap = nm_act_request_get_ap (req);
nm_info ("Activation (%s) failed.", nm_device_get_iface (dev)); 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)) if (!(caps & NM_DEVICE_CAP_NM_SUPPORTED))
continue; 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 */ /* We never automatically choose devices that don't support carrier detect */
if (!(caps & NM_DEVICE_CAP_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; 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 */ /* Don't automatically choose a device that doesn't support wireless scanning */
if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN)) 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 /* 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. * 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)) if ((NM_IS_DEVICE_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))) { || (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_info ("Old device '%s' was semi-supported and user chosen, won't change unless told to.",
nm_device_get_iface (old_dev)); nm_device_get_iface (old_dev));
goto out; 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_user_requested = nm_act_request_get_user_requested (old_act_req);
gboolean old_has_link = nm_device_has_active_link (old_dev); 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 /* 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 * 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. * 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)); nm_device_get_iface (old_dev));
do_switch = TRUE; 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 */ /* 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); NMAccessPoint *old_ap = nm_act_request_get_ap (old_act_req);
const char * old_essid = nm_ap_get_essid (old_ap); const char * old_essid = nm_ap_get_essid (old_ap);
int old_mode = nm_ap_get_mode (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); same_essid, old_has_link);
do_switch = TRUE; 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. */ /* Always prefer Ethernet over wireless, unless the user explicitly switched away. */
if (!old_user_requested) if (!old_user_requested)
do_switch = TRUE; 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; NMActRequest * act_req = NULL;
if ((act_req = nm_act_request_new (data, new_dev, ap, FALSE))) { 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); NMDevice *dev = (NMDevice *)(elt->data);
NMDevice80211Wireless * wdev; NMDevice80211Wireless * wdev;
if (!nm_device_is_802_11_wireless (dev)) if (!NM_IS_DEVICE_802_11_WIRELESS (dev))
continue; continue;
wdev = NM_DEVICE_802_11_WIRELESS (dev); 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 * broadcasting their ESSID, if we have their MAC address in our
* allowed list. * allowed list.
*/ */
nm_ap_list_copy_essids_by_address (wdev, nm_ap_list_copy_essids_by_address (nm_device_802_11_wireless_ap_list_get (wdev),
nm_device_802_11_wireless_ap_list_get (wdev),
data->allowed_ap_list); data->allowed_ap_list);
nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (wdev), nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (wdev),
data->allowed_ap_list); data->allowed_ap_list);

View File

@@ -302,7 +302,7 @@ void nm_print_device_capabilities (NMDevice *dev)
return; return;
} }
if (nm_device_is_802_3_ethernet (dev)) if (NM_IS_DEVICE_802_3_ETHERNET (dev))
{ {
if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT)) if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT))
{ {
@@ -312,7 +312,7 @@ void nm_print_device_capabilities (NMDevice *dev)
full_support = FALSE; 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)) if (!(caps & NM_DEVICE_CAP_WIRELESS_SCAN))
{ {

View File

@@ -224,9 +224,9 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip)
memset (&saddr, 0, sizeof (saddr)); memset (&saddr, 0, sizeof (saddr));
strncpy (saddr.sa_data, nm_device_get_iface (dev), sizeof (saddr.sa_data)); 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); 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); nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &addr);
else else
goto out; goto out;

View File

@@ -272,9 +272,9 @@ void nm_generic_device_add_ip6_link_address (NMDevice *dev)
struct ether_addr hw_addr; struct ether_addr hw_addr;
unsigned char eui[8]; 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); 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); 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)); memcpy (eui, &(hw_addr.ether_addr_octet), sizeof (hw_addr.ether_addr_octet));

View File

@@ -316,9 +316,9 @@ void *nm_system_device_get_system_config (NMDevice *dev, NMData *app_data)
sys_data = g_malloc0 (sizeof (SuSEDeviceConfigData)); sys_data = g_malloc0 (sizeof (SuSEDeviceConfigData));
sys_data->use_dhcp = TRUE; 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); 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); nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr);
sprintf (mac, "%02x:%02x:%02x:%02x:%02x:%02x", sprintf (mac, "%02x:%02x:%02x:%02x:%02x:%02x",

View File

@@ -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 (data != NULL, NULL);
g_return_val_if_fail (dev != 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); g_return_val_if_fail (ap != NULL, NULL);
req = g_malloc0 (sizeof (NMActRequest)); req = g_malloc0 (sizeof (NMActRequest));

147
src/nm-call-store.c Normal file
View File

@@ -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);
}

27
src/nm-call-store.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef NM_CALLBACK_STORE_H
#define NM_CALLBACK_STORE_H
#include <glib-object.h>
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 */

View File

@@ -173,9 +173,9 @@ nm_dbus_device_get_hw_address (DBusConnection *connection,
} }
memset (&addr, 0, sizeof (struct ether_addr)); 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); 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); nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (data->dev), &addr);
} }
memset (char_addr, 0, 20); 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 != NULL, NULL);
g_return_val_if_fail (data->dev != 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); reply = new_invalid_device_type_error (message);
goto out; goto out;
} }
@@ -260,7 +260,7 @@ nm_dbus_device_get_active_network (DBusConnection *connection,
/* Only wireless devices have an active network */ /* Only wireless devices have an active network */
dev = data->dev; 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); reply = new_invalid_device_type_error (message);
goto out; 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 != NULL, NULL);
g_return_val_if_fail (data->dev != 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); reply = new_invalid_device_type_error (message);
goto out; 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; act_stage = active ? nm_act_request_get_stage (nm_device_get_act_request (dev)) : NM_ACT_STAGE_UNKNOWN;
memset (hw_addr_buf, 0, 20); 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); 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); nm_device_802_11_wireless_get_address (NM_DEVICE_802_11_WIRELESS (dev), &hw_addr);
iw_ether_ntop (&hw_addr, hw_addr_buf); 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); primary_dns = nm_utils_inet_ip4_address_as_string (primary_dns_addr);
secondary_dns = nm_utils_inet_ip4_address_as_string (secondary_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); NMDevice80211Wireless * wdev = NM_DEVICE_802_11_WIRELESS (dev);
NMActRequest * req = nm_device_get_act_request (dev); NMActRequest * req = nm_device_get_act_request (dev);
NMAccessPoint * ap; NMAccessPoint * ap;

View File

@@ -266,7 +266,7 @@ nm_dbus_nm_set_active_device (DBusConnection *connection,
goto out; goto out;
} }
if (nm_device_is_802_11_wireless (dev)) { if (NM_IS_DEVICE_802_11_WIRELESS (dev)) {
NMAPSecurity * security = NULL; NMAPSecurity * security = NULL;
char * essid = NULL; char * essid = NULL;
gboolean fallback = FALSE; gboolean fallback = FALSE;
@@ -315,7 +315,7 @@ nm_dbus_nm_set_active_device (DBusConnection *connection,
g_object_unref (G_OBJECT (security)); g_object_unref (G_OBJECT (security));
nm_info ("User Switch: %s / %s", dev_path, essid); 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); nm_info ("User Switch: %s", dev_path);
} }
@@ -382,7 +382,7 @@ nm_dbus_nm_create_wireless_network (DBusConnection *connection,
goto out; 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_next (&iter)
|| (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) { || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)) {
reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE); 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)) { for (elt = data->dev_list; elt; elt = g_slist_next (elt)) {
NMDevice * dev = NM_DEVICE (elt->data); 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_deactivate (dev);
nm_device_bring_down (dev); nm_device_bring_down (dev);
} }

View File

@@ -33,6 +33,7 @@
#include "nm-device.h" #include "nm-device.h"
#include "nm-device-802-11-wireless.h" #include "nm-device-802-11-wireless.h"
#include "nm-device-interface.h"
#include "nm-device-private.h" #include "nm-device-private.h"
#include "NetworkManagerAPList.h" #include "NetworkManagerAPList.h"
#include "NetworkManagerDbus.h" #include "NetworkManagerDbus.h"
@@ -135,7 +136,7 @@ static void supplicant_iface_connection_state_cb (NMSupplicantInterface * iface,
NMDevice80211Wireless *self); NMDevice80211Wireless *self);
static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface, static void supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface,
DBusMessage * message, GHashTable *properties,
NMDevice80211Wireless * self); NMDevice80211Wireless * self);
static void supplicant_iface_scan_result_cb (NMSupplicantInterface * iface, 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; self->priv->supplicant.iface_error_id = 0;
memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr)); 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 static void
@@ -402,7 +405,8 @@ init_supplicant_interface (NMDevice80211Wireless * self)
sup = (Supplicant *) &self->priv->supplicant; sup = (Supplicant *) &self->priv->supplicant;
sup->iface = nm_supplicant_manager_get_iface (sup->mgr, sup->iface = nm_supplicant_manager_get_iface (sup->mgr,
NM_DEVICE (self)); nm_device_get_iface (NM_DEVICE (self)),
TRUE);
if (sup->iface == NULL) { if (sup->iface == NULL) {
nm_warning ("Couldn't initialize supplicant interface for %s.", nm_warning ("Couldn't initialize supplicant interface for %s.",
nm_device_get_iface (NM_DEVICE (self))); 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 static gboolean
link_to_specific_ap (NMDevice80211Wireless *self, link_to_specific_ap (NMDevice80211Wireless *self,
NMAccessPoint *ap, NMAccessPoint *ap,
@@ -1157,7 +1128,7 @@ nm_device_802_11_wireless_set_scan_interval (NMData *data,
if (self && (NM_DEVICE (self) != d)) if (self && (NM_DEVICE (self) != d))
continue; 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; NM_DEVICE_802_11_WIRELESS (d)->priv->scan_interval = seconds;
if (self && (NM_DEVICE (self) == d)) if (self && (NM_DEVICE (self) == d))
found = TRUE; 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 static void
cull_scan_list (NMDevice80211Wireless * self) cull_scan_list (NMDevice80211Wireless * self)
{ {
@@ -2121,28 +2196,6 @@ out:
nm_policy_schedule_device_change_check (app_data); 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) \ #define SET_QUALITY_MEMBER(qual_item, lc_member, uc_member) \
if (lc_member != -1) { \ if (lc_member != -1) { \
qual_item.lc_member = lc_member; \ qual_item.lc_member = lc_member; \
@@ -2151,176 +2204,80 @@ out:
qual_item.updated |= IW_QUAL_##uc_member##_INVALID; \ 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 static void
supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface, set_ap_strength_from_properties (NMDevice80211Wireless *self,
DBusMessage * message, NMAccessPoint *ap,
NMDevice80211Wireless * self) GHashTable *properties)
{ {
DBusMessageIter iter, iter_dict; int qual, level, noise;
NMUDictEntry entry = { .type = DBUS_TYPE_STRING }; struct iw_quality quality;
NMAccessPoint * ap = NULL; GValue *value;
GTimeVal cur_time;
NMAccessPointList * ap_list;
int qual = -1, level = -1, noise = -1;
NMData * app_data;
struct iw_quality quality;
g_return_if_fail (self != NULL); value = (GValue *) g_hash_table_lookup (properties, "quality");
g_return_if_fail (message != NULL); qual = value ? g_value_get_int (value) : -1;
g_return_if_fail (iface != NULL);
if (!(app_data = nm_device_get_app_data (NM_DEVICE (self)))) value = (GValue *) g_hash_table_lookup (properties, "level");
goto out; level = value ? g_value_get_int (value) : -1;
/* Convert the scanned AP into a NMAccessPoint */ value = (GValue *) g_hash_table_lookup (properties, "noise");
dbus_message_iter_init (message, &iter); noise = value ? g_value_get_int (value) : -1;
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 <hidden> */
if (((ssid_len == 8) || (ssid_len == 9))
&& (memcmp (entry.bytearray_value, "<hidden>", 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);
}
/* Calculate and set the AP's signal quality */ /* Calculate and set the AP's signal quality */
memset (&quality, 0, sizeof (struct iw_quality)); memset (&quality, 0, sizeof (struct iw_quality));
SET_QUALITY_MEMBER (quality, qual, QUAL); SET_QUALITY_MEMBER (quality, qual, QUAL);
SET_QUALITY_MEMBER (quality, level, LEVEL); SET_QUALITY_MEMBER (quality, level, LEVEL);
SET_QUALITY_MEMBER (quality, noise, NOISE); SET_QUALITY_MEMBER (quality, noise, NOISE);
nm_ap_set_strength (ap, wireless_qual_to_percent (&quality,
(const iwqual *)(&self->priv->max_qual), nm_ap_set_strength (ap, wireless_qual_to_percent
(const iwqual *)(&self->priv->avg_qual))); (&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 */ /* Add the AP to the device's AP list */
ap_list = nm_device_802_11_wireless_ap_list_get (self); merge_scanned_ap (self, ap);
nm_ap_list_merge_scanned_ap (self, ap_list, ap);
/* Once we have the list, copy in any relevant information from our Allowed list. */ /* 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 */ /* Remove outdated access points */
cull_scan_list (self); cull_scan_list (self);
out: nm_ap_unref (ap);
if (ap)
nm_ap_unref (ap);
} }
@@ -2389,6 +2346,7 @@ link_timeout_cb (gpointer user_data)
nm_device_set_active_link (dev, FALSE); nm_device_set_active_link (dev, FALSE);
if (nm_device_is_activating (dev)) { if (nm_device_is_activating (dev)) {
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED);
nm_policy_schedule_activation_failed (req); nm_policy_schedule_activation_failed (req);
} }
return FALSE; return FALSE;
@@ -2404,6 +2362,7 @@ link_timeout_cb (gpointer user_data)
nm_info ("Activation (%s/wireless): disconnected during association," nm_info ("Activation (%s/wireless): disconnected during association,"
" asking for new key.", nm_device_get_iface (dev)); " asking for new key.", nm_device_get_iface (dev));
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
nm_dbus_get_user_key_for_network (req, TRUE); nm_dbus_get_user_key_for_network (req, TRUE);
} else { } else {
nm_info ("%s: link timed out.", nm_device_get_iface (dev)); 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)) { if (nm_device_is_activating (dev)) {
NMActRequest * req = nm_device_get_act_request (dev); NMActRequest * req = nm_device_get_act_request (dev);
nm_device_state_changed (dev, NM_DEVICE_STATE_FAILED);
nm_policy_schedule_activation_failed (req); nm_policy_schedule_activation_failed (req);
} else if (nm_device_is_activated (dev)) { } else if (nm_device_is_activated (dev)) {
nm_policy_schedule_device_change_check (app_data); nm_policy_schedule_device_change_check (app_data);
@@ -2718,6 +2678,7 @@ supplicant_iface_connection_error_cb_handler (gpointer user_data)
cb_data->message); cb_data->message);
cleanup_association_attempt (self, TRUE); cleanup_association_attempt (self, TRUE);
nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED);
nm_policy_schedule_activation_failed (req); nm_policy_schedule_activation_failed (req);
out: out:
@@ -2794,6 +2755,7 @@ supplicant_connection_timeout_cb (gpointer user_data)
"asking for new key.", "asking for new key.",
nm_device_get_iface (dev)); nm_device_get_iface (dev));
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
nm_dbus_get_user_key_for_network (req, TRUE); nm_dbus_get_user_key_for_network (req, TRUE);
} else { } else {
if (nm_device_is_activating (dev)) { if (nm_device_is_activating (dev)) {
@@ -2801,6 +2763,7 @@ supplicant_connection_timeout_cb (gpointer user_data)
"failing activation.", "failing activation.",
nm_device_get_iface (dev)); 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)); nm_policy_schedule_activation_failed (nm_device_get_act_request (dev));
} }
} }
@@ -2812,7 +2775,6 @@ supplicant_connection_timeout_cb (gpointer user_data)
static gboolean static gboolean
start_supplicant_connection_timeout (NMDevice80211Wireless *self) start_supplicant_connection_timeout (NMDevice80211Wireless *self)
{ {
GMainContext * context;
NMDevice * dev; NMDevice * dev;
guint id; guint id;
@@ -2858,7 +2820,7 @@ build_supplicant_config (NMDevice80211Wireless *self,
ap = nm_act_request_get_ap (req); ap = nm_act_request_get_ap (req);
g_assert (ap); 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) if (config == NULL)
goto out; 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 static NMActStageReturn
real_act_stage2_config (NMDevice *dev, 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 we need an encryption key, get one */
if (ap_need_key (self, ap, &ask_user)) { 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); nm_dbus_get_user_key_for_network (req, ask_user);
return NM_ACT_STAGE_RETURN_POSTPONE; 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 */ /* 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_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_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); nm_dbus_get_user_key_for_network (req, TRUE);
ret = NM_ACT_STAGE_RETURN_POSTPONE; 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->init = real_init;
parent_class->start = real_start; parent_class->start = real_start;
parent_class->update_link = real_update_link; 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_stage2_config = real_act_stage2_config;
parent_class->act_stage3_ip_config_start = real_act_stage3_ip_config_start; 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; 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);
}

View File

@@ -29,6 +29,7 @@
#include "nm-device.h" #include "nm-device.h"
#include "NetworkManagerAP.h" #include "NetworkManagerAP.h"
#include "NetworkManagerMain.h"
struct NMAccessPointList; struct NMAccessPointList;
@@ -65,14 +66,11 @@ struct _NMDevice80211WirelessClass
GType nm_device_802_11_wireless_get_type (void); GType nm_device_802_11_wireless_get_type (void);
NMDevice80211Wireless *nm_device_802_11_wireless_new (const char *iface,
static inline gboolean nm_device_is_802_11_wireless (NMDevice *dev); const char *udi,
static inline gboolean nm_device_is_802_11_wireless (NMDevice *dev) const char *driver,
{ gboolean test_dev,
g_return_val_if_fail (dev != NULL, FALSE); NMData *app_data);
return (G_OBJECT_TYPE (dev) == NM_TYPE_DEVICE_802_11_WIRELESS);
}
void nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self, void nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self,
const char *essid); 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, void nm_device_802_11_wireless_get_address (NMDevice80211Wireless *dev,
struct ether_addr *addr); struct ether_addr *addr);
void nm_device_802_11_wireless_set_address (NMDevice80211Wireless *dev);
void nm_device_802_11_wireless_get_bssid (NMDevice80211Wireless *dev, void nm_device_802_11_wireless_get_bssid (NMDevice80211Wireless *dev,
struct ether_addr *bssid); struct ether_addr *bssid);

View File

@@ -28,6 +28,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "nm-device-802-3-ethernet.h" #include "nm-device-802-3-ethernet.h"
#include "nm-device-interface.h"
#include "nm-device-private.h" #include "nm-device-private.h"
#include "NetworkManagerMain.h" #include "NetworkManagerMain.h"
#include "nm-activation-request.h" #include "nm-activation-request.h"
@@ -76,6 +77,8 @@ nm_device_802_3_ethernet_init (NMDevice8023Ethernet * self)
self->priv->link_source_id = 0; self->priv->link_source_id = 0;
memset (&(self->priv->hw_addr), 0, sizeof (struct ether_addr)); 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 static void
@@ -99,7 +102,8 @@ real_init (NMDevice *dev)
sup_mgr = nm_supplicant_manager_get (); sup_mgr = nm_supplicant_manager_get ();
self->priv->sup_iface = nm_supplicant_manager_get_iface (sup_mgr, 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) { if (self->priv->sup_iface == NULL) {
nm_warning ("Couldn't initialize supplicant interface for %s.", nm_warning ("Couldn't initialize supplicant interface for %s.",
nm_device_get_iface (NM_DEVICE (self))); 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 * nm_device_802_3_ethernet_get_address
* *
@@ -227,35 +256,25 @@ nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *self, struct ether_a
} }
/* static void
* nm_device_802_3_ethernet_set_address real_set_hw_address (NMDevice *dev)
*
* Set a device's hardware address
*
*/
void
nm_device_802_3_ethernet_set_address (NMDevice8023Ethernet *self)
{ {
NMDevice *dev = NM_DEVICE (self); NMDevice8023Ethernet *self = NM_DEVICE_802_3_ETHERNET (dev);
struct ifreq req; struct ifreq req;
NMSock *sk; NMSock *sk;
int ret; int ret;
g_return_if_fail (self != NULL);
sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL); sk = nm_dev_sock_open (dev, DEV_GENERAL, __FUNCTION__, NULL);
if (!sk) if (!sk)
return; return;
memset (&req, 0, sizeof (struct ifreq)); memset (&req, 0, sizeof (struct ifreq));
strncpy (req.ifr_name, nm_device_get_iface (dev), sizeof (req.ifr_name) - 1); strncpy (req.ifr_name, nm_device_get_iface (dev), sizeof (req.ifr_name) - 1);
ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req); ret = ioctl (nm_dev_sock_get_fd (sk), SIOCGIFHWADDR, &req);
if (ret) if (ret == 0)
goto out; 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); 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); GObjectClass *object_class = G_OBJECT_CLASS (klass);
NMDeviceClass *parent_class = NM_DEVICE_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->dispose = nm_device_802_3_ethernet_dispose;
object_class->finalize = nm_device_802_3_ethernet_finalize; 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->start = real_start;
parent_class->update_link = real_update_link; parent_class->update_link = real_update_link;
parent_class->can_interrupt_activation = real_can_interrupt_activation; parent_class->can_interrupt_activation = real_can_interrupt_activation;
parent_class->set_hw_address = real_set_hw_address;
g_type_class_add_private (object_class, sizeof (NMDevice8023EthernetPrivate));
} }
GType GType

View File

@@ -27,6 +27,7 @@
#include <net/ethernet.h> #include <net/ethernet.h>
#include "nm-device.h" #include "nm-device.h"
#include "NetworkManagerMain.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -58,19 +59,15 @@ struct _NMDevice8023EthernetClass
GType nm_device_802_3_ethernet_get_type (void); GType nm_device_802_3_ethernet_get_type (void);
static inline gboolean nm_device_is_802_3_ethernet (NMDevice *dev); NMDevice8023Ethernet *nm_device_802_3_ethernet_new (const char *iface,
static inline gboolean nm_device_is_802_3_ethernet (NMDevice *dev) const char *udi,
{ const char *driver,
g_return_val_if_fail (dev != NULL, FALSE); gboolean test_dev,
NMData *app_data);
return (G_OBJECT_TYPE (dev) == NM_TYPE_DEVICE_802_3_ETHERNET);
}
void nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *dev, void nm_device_802_3_ethernet_get_address (NMDevice8023Ethernet *dev,
struct ether_addr *addr); struct ether_addr *addr);
void nm_device_802_3_ethernet_set_address (NMDevice8023Ethernet *dev);
int nm_device_802_3_ethernet_get_speed (NMDevice8023Ethernet *self); int nm_device_802_3_ethernet_get_speed (NMDevice8023Ethernet *self);
G_END_DECLS G_END_DECLS

142
src/nm-device-interface.c Normal file
View File

@@ -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);
}

55
src/nm-device-interface.h Normal file
View File

@@ -0,0 +1,55 @@
#ifndef NM_DEVICE_INTERFACE_H
#define NM_DEVICE_INTERFACE_H
#include <glib-object.h>
#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 */

View File

@@ -32,11 +32,15 @@ typedef struct NMDbusCBData {
} NMDbusCBData; } NMDbusCBData;
void nm_device_set_device_type (NMDevice *dev, NMDeviceType type);
gboolean nm_device_is_activated (NMDevice *dev); gboolean nm_device_is_activated (NMDevice *dev);
NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self); NMIP4Config * nm_device_new_ip4_autoip_config (NMDevice *self);
void nm_device_activate_schedule_stage3_ip_config_start (struct NMActRequest *req); 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 */ #endif /* NM_DEVICE_PRIVATE_H */

View File

@@ -26,6 +26,7 @@
#include <string.h> #include <string.h>
#include "nm-device.h" #include "nm-device.h"
#include "nm-device-interface.h"
#include "nm-device-private.h" #include "nm-device-private.h"
#include "nm-device-802-3-ethernet.h" #include "nm-device-802-3-ethernet.h"
#include "nm-device-802-11-wireless.h" #include "nm-device-802-11-wireless.h"
@@ -39,12 +40,21 @@
#include "nm-utils.h" #include "nm-utils.h"
#include "autoip.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)) #define NM_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE, NMDevicePrivate))
struct _NMDevicePrivate struct _NMDevicePrivate
{ {
gboolean dispose_has_run; gboolean dispose_has_run;
NMDeviceState state;
char * udi; char * udi;
char * iface; char * iface;
NMDeviceType type; NMDeviceType type;
@@ -72,128 +82,17 @@ static void nm_device_activate_schedule_stage5_ip_config_commit (NMActRequest *
void nm_device_bring_up (NMDevice *dev); void nm_device_bring_up (NMDevice *dev);
gboolean nm_device_bring_up_wait (NMDevice *self, gboolean cancelable); 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)) static void
category = libhal_device_get_property_string(ctx, udi, "info.category", NULL); nm_device_set_address (NMDevice *device)
if (category && (!strcmp (category, "net.80211"))) {
return DEVICE_TYPE_802_11_WIRELESS; if (NM_DEVICE_GET_CLASS (device)->set_hw_address)
else if (category && (!strcmp (category, "net.80203"))) NM_DEVICE_GET_CLASS (device)->set_hw_address (device);
return DEVICE_TYPE_802_3_ETHERNET;
return DEVICE_TYPE_UNKNOWN;
} }
/* static void
* nm_get_device_driver_name device_interface_init (NMDeviceInterface *device_interface_class)
*
* 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;
}
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)); memset (&self->priv->ip6_address, 0, sizeof (struct in6_addr));
self->priv->app_data = NULL; self->priv->app_data = NULL;
self->priv->act_request = NULL;
self->priv->act_source_id = 0; self->priv->act_source_id = 0;
self->priv->system_config_data = NULL; self->priv->system_config_data = NULL;
self->priv->ip4_config = 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 static guint32
real_get_generic_capabilities (NMDevice *dev) 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 static gboolean
real_is_test_device (NMDevice *dev) real_is_test_device (NMDevice *dev)
{ {
@@ -483,13 +449,13 @@ nm_device_set_active_link (NMDevice *self,
* must manually choose semi-supported devices. * 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 */ gboolean do_switch = act_dev ? FALSE : TRUE; /* If no currently active device, switch to this one */
NMActRequest * act_req; NMActRequest * act_req;
/* If active device is wireless, switch to this one */ /* 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; do_switch = TRUE;
if (do_switch && (act_req = nm_act_request_new (app_data, self, NULL, 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); 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 gboolean
nm_device_activation_start (NMActRequest *req) nm_device_activation_start (NMActRequest *req)
{ {
NMDevicePrivate *priv;
NMData * data = NULL; NMData * data = NULL;
NMDevice * self = NULL; NMDevice * self = NULL;
@@ -526,7 +495,11 @@ nm_device_activation_start (NMActRequest *req)
self = nm_act_request_get_dev (req); self = nm_act_request_get_dev (req);
g_assert (self); 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); nm_act_request_ref (req);
self->priv->act_request = 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); iface = nm_device_get_iface (self);
nm_info ("Activation (%s) Stage 1 of 5 (Device Prepare) started...", iface); 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); ret = NM_DEVICE_GET_CLASS (self)->act_stage1_prepare (self, req);
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
goto out; goto out;
} else if (ret == NM_ACT_STAGE_RETURN_FAILURE) { } else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
nm_policy_schedule_activation_failed (req); nm_policy_schedule_activation_failed (req);
goto out; goto out;
} }
@@ -659,6 +634,7 @@ nm_device_activate_stage2_device_config (gpointer user_data)
iface = nm_device_get_iface (self); iface = nm_device_get_iface (self);
nm_info ("Activation (%s) Stage 2 of 5 (Device Configure) starting...", iface); 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 */ /* Bring the device up */
if (!nm_device_is_up (self)) if (!nm_device_is_up (self))
@@ -669,6 +645,7 @@ nm_device_activate_stage2_device_config (gpointer user_data)
goto out; goto out;
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) else if (ret == NM_ACT_STAGE_RETURN_FAILURE)
{ {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
nm_policy_schedule_activation_failed (req); nm_policy_schedule_activation_failed (req);
goto out; goto out;
} }
@@ -778,12 +755,14 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data)
iface = nm_device_get_iface (self); iface = nm_device_get_iface (self);
nm_info ("Activation (%s) Stage 3 of 5 (IP Configure Start) started...", iface); 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); ret = NM_DEVICE_GET_CLASS (self)->act_stage3_ip_config_start (self, req);
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) if (ret == NM_ACT_STAGE_RETURN_POSTPONE)
goto out; goto out;
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) else if (ret == NM_ACT_STAGE_RETURN_FAILURE)
{ {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
nm_policy_schedule_activation_failed (req); nm_policy_schedule_activation_failed (req);
goto out; goto out;
} }
@@ -929,6 +908,7 @@ nm_device_activate_stage4_ip_config_get (gpointer user_data)
goto out; goto out;
else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) 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); nm_policy_schedule_activation_failed (req);
goto out; goto out;
} }
@@ -1022,6 +1002,7 @@ nm_device_activate_stage4_ip_config_timeout (gpointer user_data)
if (ret == NM_ACT_STAGE_RETURN_POSTPONE) { if (ret == NM_ACT_STAGE_RETURN_POSTPONE) {
goto out; goto out;
} else if (!ip4_config || (ret == NM_ACT_STAGE_RETURN_FAILURE)) { } 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); nm_policy_schedule_activation_failed (req);
goto out; 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_set_hostname (self->priv->ip4_config);
nm_system_activate_nis (self->priv->ip4_config); nm_system_activate_nis (self->priv->ip4_config);
nm_system_set_mtu (self); nm_system_set_mtu (self);
if (NM_DEVICE_GET_CLASS (self)->update_link) if (NM_DEVICE_GET_CLASS (self)->update_link)
NM_DEVICE_GET_CLASS (self)->update_link (self); NM_DEVICE_GET_CLASS (self)->update_link (self);
nm_device_state_changed (self, NM_DEVICE_STATE_ACTIVATED);
nm_policy_schedule_activation_finish (req); nm_policy_schedule_activation_finish (req);
} else { } else {
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED);
nm_policy_schedule_activation_failed (req); 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 (self != NULL);
g_return_if_fail (req != 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_dhcp_manager_cancel_transaction (NM_DEVICE_GET_PRIVATE (self)->dhcp_manager,
nm_device_get_iface (self), nm_device_get_iface (self),
TRUE); TRUE);
@@ -1217,7 +1202,7 @@ nm_device_deactivate_quickly (NMDevice *self)
app_data = self->priv->app_data; app_data = self->priv->app_data;
nm_vpn_manager_deactivate_vpn_connection (app_data->vpn_manager, self); 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); nm_dbus_schedule_device_status_change_signal (app_data, self, NULL, DEVICE_NO_LONGER_ACTIVE);
else if (nm_device_is_activating (self)) else if (nm_device_is_activating (self))
nm_device_activation_cancel (self); nm_device_activation_cancel (self);
@@ -1278,6 +1263,7 @@ nm_device_deactivate (NMDevice *self)
if (NM_DEVICE_GET_CLASS (self)->deactivate) if (NM_DEVICE_GET_CLASS (self)->deactivate)
NM_DEVICE_GET_CLASS (self)->deactivate (self); 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); nm_schedule_state_change_signal_broadcast (self->priv->app_data);
} }
@@ -1289,38 +1275,22 @@ nm_device_deactivate (NMDevice *self)
* *
*/ */
gboolean gboolean
nm_device_is_activating (NMDevice *dev) nm_device_is_activating (NMDevice *device)
{ {
NMActRequest * req; g_return_val_if_fail (NM_IS_DEVICE (device), FALSE);
NMActStage stage;
gboolean activating = FALSE;
g_return_val_if_fail (dev != NULL, FALSE); switch (nm_device_get_state (device)) {
case NM_DEVICE_STATE_PREPARE:
if (!(req = nm_device_get_act_request (dev))) case NM_DEVICE_STATE_CONFIG:
return FALSE; case NM_DEVICE_STATE_NEED_AUTH:
case NM_DEVICE_STATE_IP_CONFIG:
stage = nm_act_request_get_stage (req); return TRUE;
switch (stage) break;
{ default:
case NM_ACT_STAGE_DEVICE_PREPARE: break;
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;
} }
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 * Make sure that we have a valid MAC address, some cards reload firmware when they
* are brought up. * are brought up.
*/ */
if (nm_device_is_802_3_ethernet (self)) nm_device_set_address (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));
} }
@@ -1684,9 +1651,7 @@ nm_device_get_system_config_data (NMDevice *self)
static void static void
nm_device_dispose (GObject *object) nm_device_dispose (GObject *object)
{ {
NMDevice * self = NM_DEVICE (object); NMDevice *self = NM_DEVICE (object);
NMDeviceClass * klass;
GObjectClass * parent_class;
if (self->priv->dispose_has_run) if (self->priv->dispose_has_run)
/* If dispose did already run, return. */ /* If dispose did already run, return. */
@@ -1722,27 +1687,95 @@ nm_device_dispose (GObject *object)
nm_device_set_use_dhcp (self, FALSE); nm_device_set_use_dhcp (self, FALSE);
/* Chain up to the parent class */ G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
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);
} }
static void static void
nm_device_finalize (GObject *object) nm_device_finalize (GObject *object)
{ {
NMDevice * self = NM_DEVICE (object); NMDevice *self = NM_DEVICE (object);
NMDeviceClass * klass;
GObjectClass * parent_class;
g_free (self->priv->udi); g_free (self->priv->udi);
g_free (self->priv->iface); g_free (self->priv->iface);
g_free (self->priv->driver); g_free (self->priv->driver);
/* Chain up to the parent class */ G_OBJECT_CLASS (nm_device_parent_class)->finalize (object);
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);
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); 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->dispose = nm_device_dispose;
object_class->finalize = nm_device_finalize; 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->is_test_device = real_is_test_device;
klass->activation_cancel_handler = real_activation_cancel_handler; 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_get_ip4_config = real_act_stage4_get_ip4_config;
klass->act_stage4_ip_config_timeout = real_act_stage4_ip_config_timeout; 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 void
nm_device_get_type (void) nm_device_state_changed (NMDevice *device, NMDeviceState state)
{ {
static GType type = 0; g_return_if_fail (NM_IS_DEVICE (device));
if (type == 0)
{ device->priv->state = state;
static const GTypeInfo info =
{ switch (state) {
sizeof (NMDeviceClass), case NM_DEVICE_STATE_ACTIVATED:
NULL, /* base_init */ nm_info ("Activation (%s) successful, device activated.", nm_device_get_iface (device));
NULL, /* base_finalize */ break;
(GClassInitFunc) nm_device_class_init, case NM_DEVICE_STATE_FAILED:
NULL, /* class_finalize */ nm_info ("Activation (%s) failed.", nm_device_get_iface (device));
NULL, /* class_data */ nm_device_deactivate (device);
sizeof (NMDevice), break;
0, /* n_preallocs */ default:
(GInstanceInitFunc) nm_device_init, break;
NULL /* value_table */
};
type = g_type_register_static (G_TYPE_OBJECT,
"NMDevice",
&info, 0);
} }
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;
} }

View File

@@ -94,6 +94,8 @@ struct _NMDeviceClass
void (* bring_up) (NMDevice *self); void (* bring_up) (NMDevice *self);
void (* bring_down) (NMDevice *self); void (* bring_down) (NMDevice *self);
void (* set_hw_address) (NMDevice *self);
guint32 (* get_type_capabilities) (NMDevice *self); guint32 (* get_type_capabilities) (NMDevice *self);
guint32 (* get_generic_capabilities) (NMDevice *self); guint32 (* get_generic_capabilities) (NMDevice *self);
@@ -125,12 +127,6 @@ struct _NMDeviceClass
GType nm_device_get_type (void); 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); void nm_device_stop (NMDevice *self);
const char * nm_device_get_udi (NMDevice *dev); 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); gboolean nm_device_can_interrupt_activation (NMDevice *self);
NMDeviceState nm_device_get_state (NMDevice *device);
G_END_DECLS G_END_DECLS
#endif /* NM_DEVICE_H */ #endif /* NM_DEVICE_H */

View File

@@ -32,56 +32,53 @@
NM_TYPE_SUPPLICANT_CONFIG, \ NM_TYPE_SUPPLICANT_CONFIG, \
NMSupplicantConfigPrivate)) NMSupplicantConfigPrivate))
G_DEFINE_TYPE (NMSupplicantConfig, nm_supplicant_config, G_TYPE_OBJECT)
static void nm_supplicant_config_set_device (NMSupplicantConfig *con, typedef struct {
NMDevice *dev); char *value;
guint32 len;
struct option {
char * key;
char * value;
guint32 len;
enum OptType type; enum OptType type;
}; } ConfigOption;
struct _NMSupplicantConfigPrivate typedef struct
{ {
NMDevice * dev; char * ifname;
GSList * config; GHashTable *config;
guint32 ap_scan; guint32 ap_scan;
gboolean dispose_has_run; gboolean dispose_has_run;
}; } NMSupplicantConfigPrivate;
NMSupplicantConfig * NMSupplicantConfig *
nm_supplicant_config_new (NMDevice *dev) nm_supplicant_config_new (const char *ifname)
{ {
NMSupplicantConfig * scfg; 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); 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; return scfg;
} }
static void
config_option_free (ConfigOption *opt)
{
g_free (opt->value);
g_slice_free (ConfigOption, opt);
}
static void static void
nm_supplicant_config_init (NMSupplicantConfig * self) nm_supplicant_config_init (NMSupplicantConfig * self)
{ {
self->priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
self->priv->config = NULL;
self->priv->ap_scan = 1;
self->priv->dispose_has_run = FALSE;
}
static void priv->config = g_hash_table_new_full (g_str_hash, g_str_equal,
nm_supplicant_config_set_device (NMSupplicantConfig *self, (GDestroyNotify) g_free,
NMDevice *dev) (GDestroyNotify) config_option_free);
{
g_return_if_fail (self != NULL); priv->ap_scan = 1;
g_return_if_fail (dev != NULL); priv->dispose_has_run = FALSE;
g_object_ref (G_OBJECT (dev));
self->priv->dev = dev;
} }
gboolean gboolean
@@ -90,14 +87,17 @@ nm_supplicant_config_add_option (NMSupplicantConfig *self,
const char * value, const char * value,
gint32 len) gint32 len)
{ {
GSList * elt; NMSupplicantConfigPrivate *priv;
struct option * opt; ConfigOption *old_opt;
ConfigOption *opt;
OptType type; 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 (key != NULL, FALSE);
g_return_val_if_fail (value != NULL, FALSE); g_return_val_if_fail (value != NULL, FALSE);
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self);
if (len < 0) if (len < 0)
len = strlen (value); len = strlen (value);
@@ -110,130 +110,52 @@ nm_supplicant_config_add_option (NMSupplicantConfig *self,
return FALSE; return FALSE;
} }
for (elt = self->priv->config; elt; elt = g_slist_next (elt)) { old_opt = (ConfigOption *) g_hash_table_lookup (priv->config, key);
struct option * tmp_opt = (struct option *) elt->data; if (old_opt) {
nm_debug ("Key '%s' already in table.", key);
if (strcmp (tmp_opt->key, key) == 0) { return FALSE;
nm_debug ("Key '%s' already in table.", key);
return FALSE;
}
} }
opt = g_slice_new0 (struct option); opt = g_slice_new0 (ConfigOption);
if (opt == NULL) { if (opt == NULL) {
nm_debug ("Couldn't allocate memory for new config option."); nm_debug ("Couldn't allocate memory for new config option.");
return FALSE; 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); opt->value = g_malloc0 (sizeof (char) * len);
if (opt->value == NULL) { if (opt->value == NULL) {
nm_debug ("Couldn't allocate memory for new config option value."); nm_debug ("Couldn't allocate memory for new config option value.");
g_free (opt->key); g_slice_free (ConfigOption, opt);
g_slice_free (struct option, opt);
return FALSE; return FALSE;
} }
memcpy (opt->value, value, len); memcpy (opt->value, value, len);
opt->len = len; opt->len = len;
opt->type = type; 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; return TRUE;
} }
static void
free_option (struct option * opt)
{
g_return_if_fail (opt != NULL);
g_free (opt->key);
g_free (opt->value);
}
gboolean gboolean
nm_supplicant_config_remove_option (NMSupplicantConfig *self, nm_supplicant_config_remove_option (NMSupplicantConfig *self,
const char * key) const char * key)
{ {
GSList * elt; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE);
GSList * found = NULL;
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (key != NULL, FALSE); g_return_val_if_fail (key != NULL, FALSE);
for (elt = self->priv->config; elt; elt = g_slist_next (elt)) { return g_hash_table_remove (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->config, key);
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);
} }
static void static void
nm_supplicant_config_finalize (GObject *object) nm_supplicant_config_finalize (GObject *object)
{ {
NMSupplicantConfig * self = NM_SUPPLICANT_CONFIG (object);
NMSupplicantConfigClass * klass;
GObjectClass * parent_class;
GSList * elt;
/* Complete object destruction */ /* Complete object destruction */
for (elt = self->priv->config; elt; elt = g_slist_next (elt)) { g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->config);
free_option (elt->data);
g_slice_free (struct option, elt->data);
}
g_slist_free (self->priv->config);
self->priv->config = NULL;
/* Chain up to the parent class */ /* Chain up to the parent class */
klass = NM_SUPPLICANT_CONFIG_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_CONFIG)); G_OBJECT_CLASS (nm_supplicant_config_parent_class)->finalize (object);
parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
parent_class->finalize (object);
} }
@@ -242,117 +164,61 @@ nm_supplicant_config_class_init (NMSupplicantConfigClass *klass)
{ {
GObjectClass *object_class = G_OBJECT_CLASS (klass); GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->dispose = nm_supplicant_config_dispose;
object_class->finalize = nm_supplicant_config_finalize; object_class->finalize = nm_supplicant_config_finalize;
g_type_class_add_private (object_class, sizeof (NMSupplicantConfigPrivate)); 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 guint32
nm_supplicant_config_get_ap_scan (NMSupplicantConfig * self) 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 void
nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self, nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self,
guint32 ap_scan) guint32 ap_scan)
{ {
g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self));
g_return_if_fail (ap_scan >= 0 && ap_scan <=2); 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 static void
nm_supplicant_config_add_to_dbus_message (NMSupplicantConfig * self, get_hash_cb (gpointer key, gpointer value, gpointer user_data)
DBusMessage * message)
{ {
GSList * elt; ConfigOption *opt = (ConfigOption *) value;
DBusMessageIter iter, iter_dict; GValue *variant;
gboolean success = FALSE;
g_return_val_if_fail (self != NULL, FALSE); variant = g_slice_new0 (GValue);
g_return_val_if_fail (message != NULL, FALSE); g_value_init (variant, G_TYPE_STRING);
g_value_set_string (variant, opt->value);
dbus_message_iter_init_append (message, &iter); g_hash_table_insert ((GHashTable *) user_data, g_strdup (key), variant);
}
if (!nmu_dbus_dict_open_write (&iter, &iter_dict)) {
nm_warning ("dict open write failed!"); static void
goto out; destroy_hash_value (gpointer data)
} {
g_slice_free (GValue, data);
for (elt = self->priv->config; elt; elt = g_slist_next (elt)) { }
struct option * opt = (struct option *) elt->data;
GHashTable *
switch (opt->type) { nm_supplicant_config_get_hash (NMSupplicantConfig * self)
case TYPE_INT: {
if (!nmu_dbus_dict_append_string (&iter_dict, opt->key, opt->value)) { GHashTable *hash;
nm_warning ("couldn't append INT option '%s' to dict", opt->key);
goto out; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL);
}
break; hash = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
case TYPE_KEYWORD: destroy_hash_value);
if (!nmu_dbus_dict_append_string (&iter_dict, opt->key, opt->value)) {
nm_warning ("couldn't append KEYWORD option '%s' to dict", opt->key); g_hash_table_foreach (NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->config,
goto out; get_hash_cb, hash);
}
break; return hash;
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;
} }

View File

@@ -24,7 +24,6 @@
#include <glib-object.h> #include <glib-object.h>
#include "nm-supplicant-types.h" #include "nm-supplicant-types.h"
#include "nm-device.h"
G_BEGIN_DECLS 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_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)) #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 struct _NMSupplicantConfig
{ {
GObject parent; GObject parent;
/*< private >*/
NMSupplicantConfigPrivate *priv;
}; };
struct _NMSupplicantConfigClass typedef struct
{ {
GObjectClass parent; GObjectClass parent;
} NMSupplicantConfigClass;
/* class members */
};
GType nm_supplicant_config_get_type (void); 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, gboolean nm_supplicant_config_add_option (NMSupplicantConfig *scfg,
const char * key, 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, void nm_supplicant_config_set_ap_scan (NMSupplicantConfig * self,
guint32 ap_scan); guint32 ap_scan);
gboolean nm_supplicant_config_add_to_dbus_message (NMSupplicantConfig * self, GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig * self);
DBusMessage * message);
G_END_DECLS G_END_DECLS

File diff suppressed because it is too large Load Diff

View File

@@ -23,8 +23,8 @@
#define NM_SUPPLICANT_INTERFACE_H #define NM_SUPPLICANT_INTERFACE_H
#include <glib-object.h> #include <glib-object.h>
#include <dbus/dbus.h>
#include "nm-supplicant-types.h" #include "nm-supplicant-types.h"
#include "nm-device.h"
G_BEGIN_DECLS 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_IS_SUPPLICANT_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_INTERFACE))
#define NM_SUPPLICANT_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass)) #define NM_SUPPLICANT_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SUPPLICANT_INTERFACE, NMSupplicantInterfaceClass))
typedef struct _NMSupplicantInterfaceClass NMSupplicantInterfaceClass;
typedef struct _NMSupplicantInterfacePrivate NMSupplicantInterfacePrivate;
struct _NMSupplicantInterface struct _NMSupplicantInterface
{ {
GObject parent; GObject parent;
/*< private >*/
NMSupplicantInterfacePrivate *priv;
}; };
struct _NMSupplicantInterfaceClass typedef struct
{ {
GObjectClass parent; GObjectClass parent;
@@ -113,20 +107,21 @@ struct _NMSupplicantInterfaceClass
void (* connection_error) (NMSupplicantInterface * iface, void (* connection_error) (NMSupplicantInterface * iface,
const char * name, const char * name,
const char * message); const char * message);
}; } NMSupplicantInterfaceClass;
GType nm_supplicant_interface_get_type (void); GType nm_supplicant_interface_get_type (void);
NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr, NMSupplicantInterface * nm_supplicant_interface_new (NMSupplicantManager * smgr,
NMDevice * dev); const char *ifname,
gboolean is_wireless);
gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface, gboolean nm_supplicant_interface_set_config (NMSupplicantInterface * iface,
NMSupplicantConfig * cfg); NMSupplicantConfig * cfg);
void nm_supplicant_interface_disconnect (NMSupplicantInterface * iface); 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); gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self);

View File

@@ -28,11 +28,20 @@
#include "nm-dbus-manager.h" #include "nm-dbus-manager.h"
#include "nm-supplicant-marshal.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), \ #define NM_SUPPLICANT_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
NM_TYPE_SUPPLICANT_MANAGER, \ NM_TYPE_SUPPLICANT_MANAGER, \
NMSupplicantManagerPrivate)) NMSupplicantManagerPrivate))
G_DEFINE_TYPE (NMSupplicantManager, nm_supplicant_manager, G_TYPE_OBJECT)
static void nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr, static void nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr,
DBusConnection *connection, DBusConnection *connection,
const char *name, const char *name,
@@ -54,14 +63,6 @@ enum {
static guint nm_supplicant_manager_signals[LAST_SIGNAL] = { 0 }; static guint nm_supplicant_manager_signals[LAST_SIGNAL] = { 0 };
struct _NMSupplicantManagerPrivate {
NMDBusManager * dbus_mgr;
guint32 state;
GSList * ifaces;
gboolean dispose_has_run;
};
NMSupplicantManager * NMSupplicantManager *
nm_supplicant_manager_get (void) nm_supplicant_manager_get (void)
{ {
@@ -81,15 +82,15 @@ nm_supplicant_manager_get (void)
static void static void
nm_supplicant_manager_init (NMSupplicantManager * self) 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; priv->dispose_has_run = FALSE;
self->priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN; priv->state = NM_SUPPLICANT_MANAGER_STATE_DOWN;
self->priv->dbus_mgr = nm_dbus_manager_get (); priv->dbus_mgr = nm_dbus_manager_get ();
nm_supplicant_manager_startup (self); nm_supplicant_manager_startup (self);
g_signal_connect (G_OBJECT (self->priv->dbus_mgr), g_signal_connect (priv->dbus_mgr,
"name-owner-changed", "name-owner-changed",
G_CALLBACK (nm_supplicant_manager_name_owner_changed), G_CALLBACK (nm_supplicant_manager_name_owner_changed),
self); self);
@@ -98,17 +99,15 @@ nm_supplicant_manager_init (NMSupplicantManager * self)
static void static void
nm_supplicant_manager_dispose (GObject *object) nm_supplicant_manager_dispose (GObject *object)
{ {
NMSupplicantManager * self = NM_SUPPLICANT_MANAGER (object); NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (object);
NMSupplicantManagerClass * klass;
GObjectClass * parent_class;
if (self->priv->dispose_has_run) { if (priv->dispose_has_run) {
/* If dispose did already run, return. */ /* If dispose did already run, return. */
return; return;
} }
/* Make sure dispose does not run twice. */ /* 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 * 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 * the most simple solution is to unref all members on which you own a
* reference. * reference.
*/ */
if (self->priv->dbus_mgr) { if (priv->dbus_mgr) {
g_object_unref (G_OBJECT (self->priv->dbus_mgr)); g_object_unref (G_OBJECT (priv->dbus_mgr));
self->priv->dbus_mgr = NULL; priv->dbus_mgr = NULL;
} }
/* Chain up to the parent class */ /* Chain up to the parent class */
klass = NM_SUPPLICANT_MANAGER_CLASS (g_type_class_peek (NM_TYPE_SUPPLICANT_MANAGER)); G_OBJECT_CLASS (nm_supplicant_manager_parent_class)->dispose (object);
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);
} }
static void static void
@@ -144,11 +129,10 @@ nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass)
{ {
GObjectClass * object_class = G_OBJECT_CLASS (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)); g_type_class_add_private (object_class, sizeof (NMSupplicantManagerPrivate));
object_class->dispose = nm_supplicant_manager_dispose;
/* Signals */ /* Signals */
nm_supplicant_manager_signals[STATE] = nm_supplicant_manager_signals[STATE] =
g_signal_new ("state", g_signal_new ("state",
@@ -158,32 +142,6 @@ nm_supplicant_manager_class_init (NMSupplicantManagerClass *klass)
NULL, NULL, NULL, NULL,
nm_supplicant_marshal_VOID__UINT_UINT, nm_supplicant_marshal_VOID__UINT_UINT,
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_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 static void
@@ -215,28 +173,26 @@ nm_supplicant_manager_name_owner_changed (NMDBusManager *dbus_mgr,
guint32 guint32
nm_supplicant_manager_get_state (NMSupplicantManager * self) 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 static void
nm_supplicant_manager_set_state (NMSupplicantManager * self, guint32 new_state) nm_supplicant_manager_set_state (NMSupplicantManager * self, guint32 new_state)
{ {
NMSupplicantManagerPrivate *priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
guint32 old_state; guint32 old_state;
g_return_if_fail (self != NULL); if (new_state == priv->state)
g_return_if_fail (new_state < NM_SUPPLICANT_MANAGER_STATE_LAST);
if (new_state == self->priv->state)
return; return;
old_state = self->priv->state; old_state = priv->state;
self->priv->state = new_state; priv->state = new_state;
g_signal_emit (G_OBJECT (self), g_signal_emit (self,
nm_supplicant_manager_signals[STATE], nm_supplicant_manager_signals[STATE],
0, 0,
self->priv->state, priv->state,
old_state); old_state);
} }
@@ -246,7 +202,7 @@ nm_supplicant_manager_startup (NMSupplicantManager * self)
gboolean running; gboolean running;
/* FIXME: convert to pending call */ /* 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); WPAS_DBUS_SERVICE);
if (running) { if (running) {
nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_IDLE); nm_supplicant_manager_set_state (self, NM_SUPPLICANT_MANAGER_STATE_IDLE);
@@ -255,39 +211,34 @@ nm_supplicant_manager_startup (NMSupplicantManager * self)
NMSupplicantInterface * NMSupplicantInterface *
nm_supplicant_manager_get_iface (NMSupplicantManager * self, nm_supplicant_manager_get_iface (NMSupplicantManager * self,
NMDevice * dev) const char *ifname,
gboolean is_wireless)
{ {
NMSupplicantManagerPrivate *priv;
NMSupplicantInterface * iface = NULL; NMSupplicantInterface * iface = NULL;
GSList * elt; GSList * elt;
const char * ifname;
g_return_val_if_fail (self != NULL, NULL); g_return_val_if_fail (NM_IS_SUPPLICANT_MANAGER (self), NULL);
g_return_val_if_fail (dev != NULL, NULL); g_return_val_if_fail (ifname != NULL, NULL);
priv = NM_SUPPLICANT_MANAGER_GET_PRIVATE (self);
/* Ensure we don't already have this interface */ /* Ensure we don't already have this interface */
ifname = nm_device_get_iface (dev); for (elt = priv->ifaces; elt; elt = g_slist_next (elt)) {
for (elt = self->priv->ifaces; elt; elt = g_slist_next (elt)) {
NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data; 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; iface = if_tmp;
break; break;
} }
} }
if (!iface) { if (!iface) {
iface = nm_supplicant_interface_new (self, dev); iface = nm_supplicant_interface_new (self, ifname, is_wireless);
if (iface) 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; return iface;
} }
@@ -295,25 +246,25 @@ void
nm_supplicant_manager_release_iface (NMSupplicantManager * self, nm_supplicant_manager_release_iface (NMSupplicantManager * self,
NMSupplicantInterface * iface) NMSupplicantInterface * iface)
{ {
NMSupplicantManagerPrivate *priv;
GSList * elt; GSList * elt;
g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_SUPPLICANT_MANAGER (self));
g_return_if_fail (iface != NULL); 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; NMSupplicantInterface * if_tmp = (NMSupplicantInterface *) elt->data;
if (if_tmp == iface) { if (if_tmp == iface) {
/* Remove the iface from the supplicant manager's list and /* Remove the iface from the supplicant manager's list and
* dereference to match additional reference in get_iface. * 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_slist_free_1 (elt);
g_object_unref (iface); g_object_unref (iface);
break; break;
} }
} }
/* One further dereference to match g_object_new() initial refcount of 1 */
g_object_unref (iface);
} }

View File

@@ -57,24 +57,18 @@ enum {
#define NM_IS_SUPPLICANT_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SUPPLICANT_MANAGER)) #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)) #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 struct _NMSupplicantManager
{ {
GObject parent; GObject parent;
/*< private >*/
NMSupplicantManagerPrivate *priv;
}; };
struct _NMSupplicantManagerClass typedef struct
{ {
GObjectClass parent; GObjectClass parent;
/* class members */ /* class members */
void (* state) (NMSupplicantManager * mgr, guint32 new_state, guint32 old_state); void (* state) (NMSupplicantManager * mgr, guint32 new_state, guint32 old_state);
}; } NMSupplicantManagerClass;
GType nm_supplicant_manager_get_type (void); 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); guint32 nm_supplicant_manager_get_state (NMSupplicantManager * mgr);
NMSupplicantInterface * nm_supplicant_manager_get_iface (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, void nm_supplicant_manager_release_iface (NMSupplicantManager * mgr,
NMSupplicantInterface * iface); NMSupplicantInterface * iface);

View File

@@ -1,2 +1,3 @@
VOID:UINT,UINT VOID:UINT,UINT
VOID:CHAR,CHAR VOID:CHAR,CHAR
VOID:STRING,STRING