2005-03-31 Dan Williams <dcbw@redhat.com>

Tighten up handling of wireless devices that don't support wireless
	scanning (ie, Orinoco).  Due to restructuring of code, these devices
	hadn't been doing pseudo-scanning for a while either and would just
	spin waiting for an access point.  They are now manual devices where
	the user must choose the access point from the menu every time.  All
	"allowed" access points are listed in the applet's menu regardless
	of whether or not they can be seen by the card, since it can't scan
	anyway.

	* src/NetworkManager.c
		- (nm_wireless_link_state_handle): new function, but only update
			the "best" ap for non-scanning devices when its not activating,
			and when no device is being forced on the card
		- (nm_link_state_monitor): split wireless link state handling out
			into separate function

	* src/NetworkManagerDevice.c
		- (nm_device_copy_allowed_to_dev_list): new function
		- (nm_device_new): populate non-scanning cards' AP lists with
			access points from the "allowed" list
		- (nm_device_new): don't start a scanning timeout for devices that
			can't scan
		- (nm_device_activation_schedule_finish): new parameter, should be
			the AP that failed to be connected to, pass it on to the
			activation finish function in NetworkManagerPolicy.c
		- (nm_device_activate_wireless): don't ever try to get a new AP
			for non-scanning devices, just fail.  The user must choose
			a new access point manually.
		- (nm_device_activate): grab the AP that failed connection and
			pass it on
		- (nm_device_update_best_ap): Clear the best AP if we don't have
			a link to it, user must manually choose a new one
		- (nm_device_do_pseudo_scan): remove function
		- (nm_device_wireless_process_scan_results): remove bits for non-
			scanning cards since they never get here
		- (nm_device_wireless_scan): remove bits for non-scanning devices,
			and fake the scan list for test devices a bit earlier

	* src/NetworkManagerPolicy.c
		- (nm_policy_activation_finish): use the failed_ap that we get
			passed rather than getting the best_ap from the card, which
			may have changed since we were scheduled
		- (nm_policy_allowed_ap_list_update): for non-scanning devices,
			update their scan list directly from the allowed list when
			we get updates to the allowed list from NetworkManagerInfo

	* src/NetworkManagerPolicy.h
		- New member for failed access point in NMActivationResult

  -------------------------------------

	Driver Notification patch: notifies the user when their driver
		sucks.  Gives them the option to ignore further insertions
		of the card that has the sucky driver.

	* NetworkManager.h
		- Remove the SEMI_SUPPORTED member from the NMDriverSupportLevel
			enum and replace it with NO_CARRIER_DETECT and
			NO_WIRELESS_SCAN

	* panel-applet/NMWirelessApplet.[ch]
		- Merge essid.glade -> wireless-applet.glade
		- Implement the "Your driver sucks" notification dialog

	* panel-applet/NMWirelessAppletDbus.c
		- Change stuff from getSupportsCarrierDetect->getDriverSupportLevel
		- Grab hardware address for each device from NM too
		- Check whether the driver for each device sucks or not whenever
			a new device is noticed

	* panel-applet/NMWirelessAppletOtherNetworkDialog.c
		- Deal with stuff being in wireless-applet.glade now rather than essid.glade

	* src/NetworkManager.c
		- Fix a double-unref on device removal

	* src/NetworkManagerUtils.c
		- Set appropriate driver support level on a device that doesn't
			support scanning or carrier detection

	* src/nm-dbus-device.c
		- New "getHWAddress" dbus method on devices
		- getSupportsCarrierDetect -> getDriverSupportLevel


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@534 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2005-03-31 21:02:21 +00:00
parent 4c4be4c15e
commit c1979229b6
19 changed files with 1218 additions and 188 deletions

View File

@@ -1,3 +1,89 @@
2005-03-31 Dan Williams <dcbw@redhat.com>
Tighten up handling of wireless devices that don't support wireless
scanning (ie, Orinoco). Due to restructuring of code, these devices
hadn't been doing pseudo-scanning for a while either and would just
spin waiting for an access point. They are now manual devices where
the user must choose the access point from the menu every time. All
"allowed" access points are listed in the applet's menu regardless
of whether or not they can be seen by the card, since it can't scan
anyway.
* src/NetworkManager.c
- (nm_wireless_link_state_handle): new function, but only update
the "best" ap for non-scanning devices when its not activating,
and when no device is being forced on the card
- (nm_link_state_monitor): split wireless link state handling out
into separate function
* src/NetworkManagerDevice.c
- (nm_device_copy_allowed_to_dev_list): new function
- (nm_device_new): populate non-scanning cards' AP lists with
access points from the "allowed" list
- (nm_device_new): don't start a scanning timeout for devices that
can't scan
- (nm_device_activation_schedule_finish): new parameter, should be
the AP that failed to be connected to, pass it on to the
activation finish function in NetworkManagerPolicy.c
- (nm_device_activate_wireless): don't ever try to get a new AP
for non-scanning devices, just fail. The user must choose
a new access point manually.
- (nm_device_activate): grab the AP that failed connection and
pass it on
- (nm_device_update_best_ap): Clear the best AP if we don't have
a link to it, user must manually choose a new one
- (nm_device_do_pseudo_scan): remove function
- (nm_device_wireless_process_scan_results): remove bits for non-
scanning cards since they never get here
- (nm_device_wireless_scan): remove bits for non-scanning devices,
and fake the scan list for test devices a bit earlier
* src/NetworkManagerPolicy.c
- (nm_policy_activation_finish): use the failed_ap that we get
passed rather than getting the best_ap from the card, which
may have changed since we were scheduled
- (nm_policy_allowed_ap_list_update): for non-scanning devices,
update their scan list directly from the allowed list when
we get updates to the allowed list from NetworkManagerInfo
* src/NetworkManagerPolicy.h
- New member for failed access point in NMActivationResult
-------------------------------------
Driver Notification patch: notifies the user when their driver
sucks. Gives them the option to ignore further insertions
of the card that has the sucky driver.
* NetworkManager.h
- Remove the SEMI_SUPPORTED member from the NMDriverSupportLevel
enum and replace it with NO_CARRIER_DETECT and
NO_WIRELESS_SCAN
* panel-applet/NMWirelessApplet.[ch]
- Merge essid.glade -> wireless-applet.glade
- Implement the "Your driver sucks" notification dialog
* panel-applet/NMWirelessAppletDbus.c
- Change stuff from getSupportsCarrierDetect->getDriverSupportLevel
- Grab hardware address for each device from NM too
- Check whether the driver for each device sucks or not whenever
a new device is noticed
* panel-applet/NMWirelessAppletOtherNetworkDialog.c
- Deal with stuff being in wireless-applet.glade now rather than essid.glade
* src/NetworkManager.c
- Fix a double-unref on device removal
* src/NetworkManagerUtils.c
- Set appropriate driver support level on a device that doesn't
support scanning or carrier detection
* src/nm-dbus-device.c
- New "getHWAddress" dbus method on devices
- getSupportsCarrierDetect -> getDriverSupportLevel
2005-03-31 Dan Williams <dcbw@redhat.com> 2005-03-31 Dan Williams <dcbw@redhat.com>
* src/NetworkManagerDevice.c * src/NetworkManagerDevice.c

View File

@@ -78,7 +78,8 @@ typedef enum NMEncKeyType
typedef enum NMDriverSupportLevel typedef enum NMDriverSupportLevel
{ {
NM_DRIVER_UNSUPPORTED = 0, NM_DRIVER_UNSUPPORTED = 0,
NM_DRIVER_SEMI_SUPPORTED, NM_DRIVER_NO_CARRIER_DETECT,
NM_DRIVER_NO_WIRELESS_SCAN,
NM_DRIVER_FULLY_SUPPORTED NM_DRIVER_FULLY_SUPPORTED
} NMDriverSupportLevel; } NMDriverSupportLevel;

View File

@@ -8,7 +8,7 @@ INCLUDES = -I${top_srcdir} -I${top_srcdir}/utils
noinst_LTLIBRARIES = libnm_notification_applet.la noinst_LTLIBRARIES = libnm_notification_applet.la
gladedir = $(datadir)/NetworkManagerNotification gladedir = $(datadir)/NetworkManagerNotification
glade_DATA = essid.glade glade_DATA = wireless-applet.glade
libnm_notification_applet_la_CPPFLAGS = \ libnm_notification_applet_la_CPPFLAGS = \
$(DBUS_CFLAGS) \ $(DBUS_CFLAGS) \

View File

@@ -58,6 +58,7 @@
#include "menu-info.h" #include "menu-info.h"
#define CFG_UPDATE_INTERVAL 1 #define CFG_UPDATE_INTERVAL 1
#define NMWA_GCONF_PATH "/apps/NetworkManagerNotification"
/* Compat for GTK 2.4 and lower... */ /* Compat for GTK 2.4 and lower... */
#if (GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION < 6) #if (GTK_MAJOR_VERSION <= 2 && GTK_MINOR_VERSION < 6)
@@ -175,6 +176,247 @@ void nmwa_about_cb (NMWirelessApplet *applet)
#endif #endif
} }
/*
* nmwa_driver_notify_get_ignored_list
*
* Return list of devices for which we are supposed to ignore driver
* notifications for from GConf.
*
*/
GSList *nmwa_driver_notify_get_ignored_list (NMWirelessApplet *applet)
{
char *key;
GConfValue *value;
GSList *mac_list = NULL;
g_return_val_if_fail (applet != NULL, NULL);
g_return_val_if_fail (applet->gconf_client != NULL, NULL);
/* Get current list of access point MAC addresses for this AP from GConf */
key = g_strdup_printf ("%s/non_notify_cards", NMWA_GCONF_PATH);
value = gconf_client_get (applet->gconf_client, key, NULL);
if (value && (value->type == GCONF_VALUE_LIST) && (gconf_value_get_list_type (value) == GCONF_VALUE_STRING))
mac_list = gconf_client_get_list (applet->gconf_client, key, GCONF_VALUE_STRING, NULL);
if (value)
gconf_value_free (value);
g_free (key);
return (mac_list);
}
/*
* nmwa_driver_notify_is_device_ignored
*
* Look in GConf and determine whether or not we are supposed to
* ignore driver notifications for a particular device.
*
*/
gboolean nmwa_driver_notify_is_device_ignored (NMWirelessApplet *applet, NetworkDevice *dev)
{
gboolean found = FALSE;
GSList *mac_list = NULL;
GSList *elt;
g_return_val_if_fail (applet != NULL, TRUE);
g_return_val_if_fail (applet->gconf_client != NULL, TRUE);
g_return_val_if_fail (dev != NULL, TRUE);
g_return_val_if_fail (dev->addr != NULL, TRUE);
g_return_val_if_fail (strlen (dev->addr) > 0, TRUE);
mac_list = nmwa_driver_notify_get_ignored_list (applet);
/* Ensure that the MAC isn't already in the list */
for (elt = mac_list; elt; elt = g_slist_next (elt))
{
if (elt->data && !strcmp (dev->addr, elt->data))
{
found = TRUE;
break;
}
}
/* Free the list, since gconf_client_set_list deep-copies it */
g_slist_foreach (mac_list, (GFunc)g_free, NULL);
g_slist_free (mac_list);
return found;
}
/*
* nmwa_driver_notify_ignore_device
*
* Add a device's MAC address to the list of ones that we ignore
* in GConf. Stores user's pref for "Don't remind me".
*
*/
void nmwa_driver_notify_ignore_device (NMWirelessApplet *applet, NetworkDevice *dev)
{
gboolean found = FALSE;
GSList *new_mac_list = NULL;
GSList *elt;
g_return_if_fail (applet != NULL);
g_return_if_fail (applet->gconf_client != NULL);
g_return_if_fail (dev != NULL);
g_return_if_fail (dev->addr != NULL);
g_return_if_fail (strlen (dev->addr) > 0);
new_mac_list = nmwa_driver_notify_get_ignored_list (applet);
/* Ensure that the MAC isn't already in the list */
for (elt = new_mac_list; elt; elt = g_slist_next (elt))
{
if (elt->data && !strcmp (dev->addr, elt->data))
{
found = TRUE;
break;
}
}
/* Add the new MAC address to the end of the list */
if (!found)
{
char *key = g_strdup_printf ("%s/non_notify_cards", NMWA_GCONF_PATH);
new_mac_list = g_slist_append (new_mac_list, g_strdup (dev->addr));
gconf_client_set_list (applet->gconf_client, key, GCONF_VALUE_STRING, new_mac_list, NULL);
g_free (key);
}
/* Free the list, since gconf_client_set_list deep-copies it */
g_slist_foreach (new_mac_list, (GFunc)g_free, NULL);
g_slist_free (new_mac_list);
}
gboolean nmwa_driver_notify_dialog_delete_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
gtk_widget_destroy (widget);
return FALSE;
}
gboolean nmwa_driver_notify_dialog_destroy_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
DriverNotifyCBData *cb_data = (DriverNotifyCBData *)(user_data);
NetworkDevice *dev;
g_return_val_if_fail (cb_data != NULL, FALSE);
g_return_val_if_fail (cb_data->xml != NULL, FALSE);
dev = cb_data->dev;
g_return_val_if_fail (dev != NULL, FALSE);
network_device_unref (dev);
g_object_unref (cb_data->xml);
g_free (cb_data);
return FALSE;
}
gboolean nmwa_driver_notify_ok_cb (GtkButton *button, gpointer user_data)
{
DriverNotifyCBData *cb_data = (DriverNotifyCBData *)(user_data);
NetworkDevice *dev;
NMWirelessApplet *applet;
GtkWidget *dialog;
GtkWidget *checkbox;
g_return_val_if_fail (cb_data != NULL, FALSE);
g_return_val_if_fail (cb_data->xml != NULL, FALSE);
dev = cb_data->dev;
g_return_val_if_fail (dev != NULL, FALSE);
applet = cb_data->applet;
g_return_val_if_fail (applet != NULL, FALSE);
checkbox = glade_xml_get_widget (cb_data->xml, "dont_remind_checkbox");
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbox)))
nmwa_driver_notify_ignore_device (applet, dev);
dialog = glade_xml_get_widget (cb_data->xml, "driver_sucks_dialog");
gtk_widget_destroy (dialog);
return FALSE;
}
/*
* nmwa_driver_notify
*
* Notify the user if there's some problem with the driver
* of a specific network device.
*
*/
gboolean nmwa_driver_notify (gpointer user_data)
{
DriverNotifyCBData *cb_data = (DriverNotifyCBData *)(user_data);
NetworkDevice *dev;
NMWirelessApplet *applet;
GtkDialog *dialog;
GtkLabel *label;
char *label_text = NULL;
GtkButton *button;
g_return_val_if_fail (cb_data != NULL, FALSE);
dev = cb_data->dev;
g_return_val_if_fail (dev != NULL, FALSE);
applet = cb_data->applet;
g_return_val_if_fail (applet != NULL, FALSE);
g_return_val_if_fail (applet->glade_file != NULL, FALSE);
/* If the user has already requested that we ignore notifications for
* this device, don't do anything.
*/
if (nmwa_driver_notify_is_device_ignored (applet, dev))
return FALSE;
cb_data->xml = glade_xml_new (applet->glade_file, "driver_sucks_dialog", NULL);
if (cb_data->xml == NULL)
{
show_warning_dialog (TRUE, _("The NetworkManager Applet could not find some required resources (the glade file was not found)."));
return FALSE;
}
dialog = GTK_DIALOG (glade_xml_get_widget (cb_data->xml, "driver_sucks_dialog"));
g_signal_connect (G_OBJECT (dialog), "destroy-event", GTK_SIGNAL_FUNC (nmwa_driver_notify_dialog_destroy_cb), cb_data);
g_signal_connect (G_OBJECT (dialog), "delete-event", GTK_SIGNAL_FUNC (nmwa_driver_notify_dialog_delete_cb), cb_data);
label = GTK_LABEL (glade_xml_get_widget (cb_data->xml, "driver_sucks_label"));
if (dev->driver_support_level == NM_DRIVER_NO_WIRELESS_SCAN)
{
char *temp = g_strdup_printf (_("The network device \"%s (%s)\" does not support wireless scanning."),
dev->hal_name, dev->nm_name);
label_text = g_strdup_printf (gtk_label_get_label (label), temp);
g_free (temp);
}
if (dev->driver_support_level == NM_DRIVER_NO_CARRIER_DETECT)
{
char *temp = g_strdup_printf (_("The network device \"%s (%s)\" does not support link detection."),
dev->hal_name, dev->nm_name);
label_text = g_strdup_printf (gtk_label_get_label (label), temp);
g_free (temp);
}
if (label_text)
gtk_label_set_markup (label, label_text);
button = GTK_BUTTON (glade_xml_get_widget (cb_data->xml, "ok_button"));
g_signal_connect (G_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (nmwa_driver_notify_ok_cb), cb_data);
gtk_widget_show_all (GTK_WIDGET (dialog));
return (FALSE);
}
/* /*
* nmwa_update_network_state * nmwa_update_network_state
@@ -1274,6 +1516,14 @@ static void nmwa_setup_widgets (NMWirelessApplet *applet)
applet->context_menu = nmwa_context_menu_create (applet); applet->context_menu = nmwa_context_menu_create (applet);
applet->encryption_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); applet->encryption_size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
applet->glade_file = g_build_filename (GLADEDIR, "wireless-applet.glade", NULL);
if (!applet->glade_file || !g_file_test (applet->glade_file, G_FILE_TEST_IS_REGULAR))
{
show_warning_dialog (TRUE, _("The NetworkManager Applet could not find some required resources (the glade file was not found)."));
g_free (applet->glade_file);
applet->glade_file = NULL;
}
} }
@@ -1307,6 +1557,8 @@ static void nmwa_destroy (NMWirelessApplet *applet, gpointer user_data)
nmwa_free_gui_data_model (applet); nmwa_free_gui_data_model (applet);
nmwa_free_dbus_data_model (applet); nmwa_free_dbus_data_model (applet);
g_free (applet->glade_file);
} }

View File

@@ -32,6 +32,7 @@
#else #else
#include "eggtrayicon.h" #include "eggtrayicon.h"
#endif #endif
#include <net/ethernet.h>
typedef enum typedef enum
{ {
@@ -70,7 +71,8 @@ typedef struct
char *nm_device; char *nm_device;
int type; int type;
gboolean link; gboolean link;
gboolean supports_carrier_detect; guint32 driver_support_level;
char *addr;
char *nm_name; char *nm_name;
char *hal_name; char *hal_name;
char *udi; char *udi;
@@ -78,8 +80,6 @@ typedef struct
GSList *networks; GSList *networks;
} NetworkDevice; } NetworkDevice;
#ifdef BUILD_NOTIFICATION_ICON #ifdef BUILD_NOTIFICATION_ICON
#define NM_TYPE_WIRELESS_APPLET (nmwa_get_type()) #define NM_TYPE_WIRELESS_APPLET (nmwa_get_type())
@@ -107,8 +107,10 @@ typedef struct
DBusConnection *connection; DBusConnection *connection;
GConfClient *gconf_client; GConfClient *gconf_client;
GladeXML *ui_resources; char *glade_file;
guint redraw_timeout_id; guint redraw_timeout_id;
/* dbus thread stuff */
GThread *dbus_thread; GThread *dbus_thread;
GMainContext *thread_context; GMainContext *thread_context;
GMainLoop *thread_loop; GMainLoop *thread_loop;
@@ -163,11 +165,18 @@ typedef struct
} NMWirelessApplet; } NMWirelessApplet;
typedef struct
{
NMWirelessApplet *applet;
NetworkDevice *dev;
GladeXML *xml;
} DriverNotifyCBData;
NetworkDevice *nmwa_get_device_for_nm_device (GSList *dev_list, const char *nm_dev); NetworkDevice *nmwa_get_device_for_nm_device (GSList *dev_list, const char *nm_dev);
WirelessNetwork *nmwa_get_net_for_nm_net (NetworkDevice *dev, const char *net_path); WirelessNetwork *nmwa_get_net_for_nm_net (NetworkDevice *dev, const char *net_path);
WirelessNetwork *nmwa_get_net_by_essid (NetworkDevice *dev, const char *essid); WirelessNetwork *nmwa_get_net_by_essid (NetworkDevice *dev, const char *essid);
NMWirelessApplet *nmwa_new (void); NMWirelessApplet *nmwa_new (void);
void show_warning_dialog (gboolean error, gchar *mesg, ...); void show_warning_dialog (gboolean error, gchar *mesg, ...);
gboolean nmwa_driver_notify (gpointer user_data);
#endif #endif

View File

@@ -34,6 +34,24 @@
#define DBUS_NO_SERVICE_ERROR "org.freedesktop.DBus.Error.ServiceDoesNotExist" #define DBUS_NO_SERVICE_ERROR "org.freedesktop.DBus.Error.ServiceDoesNotExist"
/*
* nm_null_safe_strcmp
*
* Doesn't freaking segfault if s1/s2 are NULL
*
*/
int nm_null_safe_strcmp (const char *s1, const char *s2)
{
if (!s1 && !s2)
return 0;
if (!s1 && s2)
return -1;
if (s1 && !s2)
return 1;
return (strcmp (s1, s2));
}
/* FIXME: This just seems like a bad idea. The call_nm_method function /* FIXME: This just seems like a bad idea. The call_nm_method function
* interface should just be changed to handle arrays better. * interface should just be changed to handle arrays better.
@@ -310,17 +328,17 @@ static gboolean nmwa_dbus_get_device_link_active (NMWirelessApplet *applet, char
/* /*
* nmwa_dbus_get_device_supports_carrier_detect * nmwa_dbus_get_device_driver_support_level
* *
* Returns whether or not the device supports carrier detection. * Returns whether or not the device supports carrier detection.
* *
*/ */
static gboolean nmwa_dbus_get_device_supports_carrier_detect (NMWirelessApplet *applet, char *net_path) static gboolean nmwa_dbus_get_device_driver_support_level (NMWirelessApplet *applet, char *net_path)
{ {
gboolean supports_carrier_detect = FALSE; guint32 driver_support_level = FALSE;
switch (nmwa_dbus_call_nm_method (applet->connection, net_path, "getSupportsCarrierDetect", switch (nmwa_dbus_call_nm_method (applet->connection, net_path, "getDriverSupportLevel",
DBUS_TYPE_BOOLEAN, (void **)(&supports_carrier_detect), NULL)) DBUS_TYPE_UINT32, (void **)(&driver_support_level), NULL))
{ {
case (RETURN_NO_NM): case (RETURN_NO_NM):
applet->applet_state = APPLET_STATE_NO_NM; applet->applet_state = APPLET_STATE_NO_NM;
@@ -330,7 +348,31 @@ static gboolean nmwa_dbus_get_device_supports_carrier_detect (NMWirelessApplet *
break; break;
} }
return (supports_carrier_detect); return (driver_support_level);
}
/*
* nmwa_dbus_get_hw_addr
*
* Return the hardware address of a given device
*
*/
static char * nmwa_dbus_get_hw_addr (NMWirelessApplet *applet, char *dev_path)
{
char *addr = NULL;
switch (nmwa_dbus_call_nm_method (applet->connection, dev_path, "getHWAddress", DBUS_TYPE_STRING, (void **)(&addr), NULL))
{
case (RETURN_NO_NM):
applet->applet_state = APPLET_STATE_NO_NM;
break;
default:
break;
}
return (addr);
} }
@@ -953,6 +995,7 @@ void network_device_unref (NetworkDevice *dev)
g_free (dev->nm_name); g_free (dev->nm_name);
g_free (dev->udi); g_free (dev->udi);
g_free (dev->hal_name); g_free (dev->hal_name);
g_free (dev->addr);
g_free (dev); g_free (dev);
memset (dev, 0, sizeof (NetworkDevice)); memset (dev, 0, sizeof (NetworkDevice));
} }
@@ -998,7 +1041,8 @@ NetworkDevice *network_device_copy (NetworkDevice *src)
dev->nm_device = g_strdup (src->nm_device); dev->nm_device = g_strdup (src->nm_device);
dev->type = src->type; dev->type = src->type;
dev->link = src->link; dev->link = src->link;
dev->supports_carrier_detect = src->supports_carrier_detect; dev->addr = g_strdup (src->addr);
dev->driver_support_level = src->driver_support_level;
dev->nm_name = g_strdup (src->nm_name); dev->nm_name = g_strdup (src->nm_name);
dev->hal_name = g_strdup (src->hal_name); dev->hal_name = g_strdup (src->hal_name);
dev->udi = g_strdup (src->udi); dev->udi = g_strdup (src->udi);
@@ -1231,6 +1275,10 @@ static gboolean nmwa_dbus_update_active_device_strength (gpointer user_data)
g_return_val_if_fail (user_data != NULL, FALSE); g_return_val_if_fail (user_data != NULL, FALSE);
applet = (NMWirelessApplet *)user_data; applet = (NMWirelessApplet *)user_data;
if (applet->applet_state == APPLET_STATE_NO_NM)
return TRUE;
if (applet->gui_active_device && (applet->gui_active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET)) if (applet->gui_active_device && (applet->gui_active_device->type == DEVICE_TYPE_WIRELESS_ETHERNET))
{ {
guint8 strength = nmwa_dbus_get_object_strength (applet, applet->gui_active_device->nm_device); guint8 strength = nmwa_dbus_get_object_strength (applet, applet->gui_active_device->nm_device);
@@ -1354,6 +1402,73 @@ static void nmwa_dbus_device_update_one_network (NMWirelessApplet *applet, DBusM
} }
/*
* nmwa_dbus_schedule_driver_notification
*
* Schedule the driver notification routine to run in the main loop.
*
*/
void nmwa_dbus_schedule_driver_notification (NMWirelessApplet *applet, NetworkDevice *dev)
{
DriverNotifyCBData *cb_data;
g_return_if_fail (applet != NULL);
g_return_if_fail (dev != NULL);
cb_data = g_malloc0 (sizeof (DriverNotifyCBData));
cb_data->applet = applet;
cb_data->dev = dev;
g_idle_add (nmwa_driver_notify, (gpointer)cb_data);
}
/*
* nmwa_dbus_check_drivers
*
* If a device got added, we notify the user if the device's driver
* has any problems (no carrier detect, no wireless scanning, etc).
*
*/
void nmwa_dbus_check_drivers (NMWirelessApplet *applet)
{
GSList *elt;
g_return_if_fail (applet != NULL);
/* For every device that's in the dbus data model but not in
* the gui data model, signal the user.
*/
for (elt = applet->dbus_device_list; elt; elt = g_slist_next (elt))
{
NetworkDevice *dbus_dev = (NetworkDevice *)(elt->data);
GSList *elt2;
gboolean found = FALSE;
for (elt2 = applet->gui_device_list; elt2; elt2 = g_slist_next (elt2))
{
NetworkDevice *gui_dev = (NetworkDevice *)(elt2->data);
if ( !nm_null_safe_strcmp (dbus_dev->nm_device, gui_dev->nm_device)
&& !nm_null_safe_strcmp (dbus_dev->addr, gui_dev->addr)
&& !nm_null_safe_strcmp (dbus_dev->udi, gui_dev->udi))
{
found = TRUE;
break;
}
}
if ( !found
&& ( (dbus_dev->driver_support_level == NM_DRIVER_NO_CARRIER_DETECT)
|| (dbus_dev->driver_support_level == NM_DRIVER_NO_WIRELESS_SCAN)))
{
network_device_ref (dbus_dev);
nmwa_dbus_schedule_driver_notification (applet, dbus_dev);
}
}
}
/* /*
* sort_devices_function * sort_devices_function
* *
@@ -1454,8 +1569,8 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
{ {
dev->nm_device = g_strdup (devices[i]); dev->nm_device = g_strdup (devices[i]);
dev->type = nmwa_dbus_get_device_type (applet, devices[i], APPLET_STATE_NO_CONNECTION); dev->type = nmwa_dbus_get_device_type (applet, devices[i], APPLET_STATE_NO_CONNECTION);
if (dev->type == DEVICE_TYPE_WIRED_ETHERNET) dev->driver_support_level = nmwa_dbus_get_device_driver_support_level (applet, devices[i]);
dev->supports_carrier_detect = nmwa_dbus_get_device_supports_carrier_detect (applet, devices[i]); dev->addr = nmwa_dbus_get_hw_addr (applet, devices[i]);
dev->link = nmwa_dbus_get_device_link_active (applet, devices[i]); dev->link = nmwa_dbus_get_device_link_active (applet, devices[i]);
dev->nm_name = g_strdup (name); dev->nm_name = g_strdup (name);
dev->udi = nmwa_dbus_get_device_udi (applet, devices[i]); dev->udi = nmwa_dbus_get_device_udi (applet, devices[i]);
@@ -1487,6 +1602,9 @@ static void nmwa_dbus_update_devices (NMWirelessApplet *applet)
/* Sort the devices for display */ /* Sort the devices for display */
applet->dbus_device_list = g_slist_sort (applet->dbus_device_list, sort_devices_function); applet->dbus_device_list = g_slist_sort (applet->dbus_device_list, sort_devices_function);
/* Notify user of issues with certain cards/drivers */
nmwa_dbus_check_drivers (applet);
/* Now copy the data over to the GUI side */ /* Now copy the data over to the GUI side */
g_mutex_lock (applet->data_mutex); g_mutex_lock (applet->data_mutex);

View File

@@ -215,6 +215,9 @@ static GtkDialog *nmwa_other_network_dialog_init (GladeXML *xml, NMWirelessApple
/* Set up the dialog */ /* Set up the dialog */
dialog = GTK_DIALOG (glade_xml_get_widget (xml, "custom_essid_dialog")); dialog = GTK_DIALOG (glade_xml_get_widget (xml, "custom_essid_dialog"));
if (!dialog)
return NULL;
essid_entry = glade_xml_get_widget (xml, "essid_entry"); essid_entry = glade_xml_get_widget (xml, "essid_entry");
button = glade_xml_get_widget (xml, "ok_button"); button = glade_xml_get_widget (xml, "ok_button");
@@ -303,25 +306,16 @@ void nmwa_other_network_dialog_run (NMWirelessApplet *applet, gboolean create_ne
{ {
gchar *glade_file; gchar *glade_file;
GtkDialog *dialog; GtkDialog *dialog;
GladeXML *xml;
gint response; gint response;
NetworkDevice *def_dev = NULL; NetworkDevice *def_dev = NULL;
GladeXML *xml;
g_return_if_fail (applet != NULL); g_return_if_fail (applet != NULL);
g_return_if_fail (applet->glade_file != NULL);
glade_file = g_build_filename (GLADEDIR, "essid.glade", NULL); xml = glade_xml_new (applet->glade_file, NULL, NULL);
if (!glade_file || !g_file_test (glade_file, G_FILE_TEST_IS_REGULAR))
{
show_warning_dialog (TRUE, _("The NetworkManager Applet could not find some required resources (the glade file was not found)."));
return;
}
xml = glade_xml_new (glade_file, NULL, NULL);
g_free (glade_file);
if (xml == NULL) if (xml == NULL)
{ {
/* Reuse the above string to make the translators less angry. */
show_warning_dialog (TRUE, _("The NetworkManager Applet could not find some required resources (the glade file was not found).")); show_warning_dialog (TRUE, _("The NetworkManager Applet could not find some required resources (the glade file was not found)."));
return; return;
} }

View File

@@ -97,7 +97,7 @@ void wired_menu_item_update (NMWiredMenuItem *item, NetworkDevice *dev, const gi
/* Only dim the item if the device supports carrier detection AND /* Only dim the item if the device supports carrier detection AND
* we know it doesn't have a link. * we know it doesn't have a link.
*/ */
if (dev->supports_carrier_detect == TRUE) if (dev->driver_support_level != NM_DRIVER_NO_CARRIER_DETECT)
gtk_widget_set_sensitive (GTK_WIDGET (item->check_item), dev->link); gtk_widget_set_sensitive (GTK_WIDGET (item->check_item), dev->link);
} }

View File

@@ -153,4 +153,518 @@ You have chosen log in to the wireless network '%s'. If you are sure this wirel
</child> </child>
</widget> </widget>
<widget class="GtkDialog" id="driver_sucks_dialog">
<property name="border_width">6</property>
<property name="title" translatable="yes"> </property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
<property name="modal">True</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="vbox2">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">12</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="ok_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">_OK</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox2">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">12</property>
<child>
<widget class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="stock">gtk-dialog-warning</property>
<property name="icon_size">6</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox3">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">12</property>
<child>
<widget class="GtkLabel" id="driver_sucks_label">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;span weight=&quot;bold&quot; size=&quot;larger&quot;&gt;Reduced Network Functionality&lt;/span&gt;
%s It will not be completely functional.</property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
<child>
<widget class="GtkCheckButton" id="dont_remind_checkbox">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Don't remind me again</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">False</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
<widget class="GtkDialog" id="custom_essid_dialog">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="title" translatable="yes"></property>
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
<property name="default_width">488</property>
<property name="resizable">False</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
<property name="skip_taskbar_hint">False</property>
<property name="skip_pager_hint">False</property>
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<widget class="GtkVBox" id="dialog-vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">4</property>
<child internal-child="action_area">
<widget class="GtkHButtonBox" id="dialog-action_area1">
<property name="visible">True</property>
<property name="layout_style">GTK_BUTTONBOX_END</property>
<child>
<widget class="GtkButton" id="cancel_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="can_focus">True</property>
<property name="label">gtk-cancel</property>
<property name="use_stock">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-6</property>
</widget>
</child>
<child>
<widget class="GtkButton" id="ok_button">
<property name="visible">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">C_onnect</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="response_id">-5</property>
</widget>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">GTK_PACK_END</property>
</packing>
</child>
<child>
<widget class="GtkHBox" id="hbox1">
<property name="border_width">6</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">12</property>
<child>
<widget class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="stock">gtk-dialog-question</property>
<property name="icon_size">6</property>
<property name="xalign">0.5</property>
<property name="yalign">0</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">False</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkVBox" id="vbox1">
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">12</property>
<child>
<widget class="GtkLabel" id="essid_label">
<property name="visible">True</property>
<property name="label" translatable="yes"></property>
<property name="use_underline">False</property>
<property name="use_markup">True</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">True</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
<child>
<widget class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="homogeneous">False</property>
<property name="row_spacing">12</property>
<property name="column_spacing">6</property>
<child>
<widget class="GtkLabel" id="wireless_adapter_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Wireless _adapter:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">wireless_adapter_combo</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="wireless_adapter_combo">
<property name="visible">True</property>
<property name="items" translatable="yes"></property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">Wireless _network:</property>
<property name="use_underline">True</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">essid_entry</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="essid_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">True</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkFrame" id="frame1">
<property name="visible">True</property>
<property name="label_xalign">0</property>
<property name="label_yalign">0.5</property>
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child>
<widget class="GtkAlignment" id="alignment1">
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">0.5</property>
<property name="xscale">1</property>
<property name="yscale">1</property>
<property name="top_padding">3</property>
<property name="bottom_padding">6</property>
<property name="left_padding">6</property>
<property name="right_padding">6</property>
<child>
<widget class="GtkTable" id="table2">
<property name="visible">True</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="homogeneous">False</property>
<property name="row_spacing">12</property>
<property name="column_spacing">6</property>
<child>
<widget class="GtkLabel" id="key_type_combo_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Key type:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkLabel" id="passphrase_entry_label">
<property name="visible">True</property>
<property name="label" translatable="yes">Passphrase:</property>
<property name="use_underline">False</property>
<property name="use_markup">False</property>
<property name="justify">GTK_JUSTIFY_LEFT</property>
<property name="wrap">False</property>
<property name="selectable">False</property>
<property name="xalign">0</property>
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">fill</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkEntry" id="passphrase_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
<property name="text" translatable="yes"></property>
<property name="has_frame">True</property>
<property name="invisible_char" translatable="yes">*</property>
<property name="activates_default">False</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<widget class="GtkComboBox" id="key_type_combo">
<property name="visible">True</property>
<property name="items" translatable="yes">128-bit passphrase (WEP)
Ascii key (WEP)
Hex key (WEP)</property>
</widget>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">0</property>
<property name="bottom_attach">1</property>
<property name="x_options">fill</property>
<property name="y_options">fill</property>
</packing>
</child>
</widget>
</child>
</widget>
</child>
<child>
<widget class="GtkCheckButton" id="use_encryption_checkbox">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Connect with encryption enabled</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<property name="active">False</property>
<property name="inconsistent">False</property>
<property name="draw_indicator">True</property>
</widget>
<packing>
<property name="type">label_item</property>
</packing>
</child>
</widget>
<packing>
<property name="left_attach">0</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">fill</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
<packing>
<property name="padding">0</property>
<property name="expand">True</property>
<property name="fill">True</property>
</packing>
</child>
</widget>
</child>
</widget>
</glade-interface> </glade-interface>

View File

@@ -184,14 +184,13 @@ void nm_remove_device_from_list (NMData *data, const char *udi)
nm_device_set_removed (dev, TRUE); nm_device_set_removed (dev, TRUE);
nm_device_deactivate (dev, FALSE); nm_device_deactivate (dev, FALSE);
nm_device_worker_thread_stop (dev); nm_device_worker_thread_stop (dev);
nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_LIST_CHANGE);
nm_device_unref (dev); nm_device_unref (dev);
/* Remove the device entry from the device list and free its data */ /* Remove the device entry from the device list and free its data */
data->dev_list = g_slist_remove_link (data->dev_list, elt); data->dev_list = g_slist_remove_link (data->dev_list, elt);
nm_device_unref (elt->data);
g_slist_free (elt); g_slist_free (elt);
nm_policy_schedule_state_update (data); nm_policy_schedule_state_update (data);
nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_LIST_CHANGE);
break; break;
} }
} }
@@ -407,9 +406,19 @@ gboolean nm_poll_and_update_wireless_link_state (NMData *data)
* an active link. If it lost the link, * an active link. If it lost the link,
* find a better access point. * find a better access point.
*/ */
if ((dev == data->active_device) && if ( (dev == data->active_device)
!nm_device_has_active_link (dev)) && !nm_device_has_active_link (dev))
{
if (nm_device_get_supports_wireless_scan (dev))
nm_device_update_best_ap (dev); nm_device_update_best_ap (dev);
else
{
if ( !nm_device_is_activating (dev)
&& !data->forcing_device
&& data->state_modified_idle_id == 0)
nm_device_update_best_ap (dev);
}
}
} }
} }
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__); nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);

View File

@@ -193,6 +193,50 @@ NMDevice *nm_get_device_by_iface (NMData *data, const char *iface)
/* NMDevice object routines */ /* NMDevice object routines */
/*****************************************************************************/ /*****************************************************************************/
/*
* nm_device_copy_allowed_to_dev_list
*
* For devices that don't support wireless scanning, copy
* the allowed AP list to the device's ap list.
*
*/
void nm_device_copy_allowed_to_dev_list (NMDevice *dev, NMAccessPointList *allowed_list)
{
NMAPListIter *iter;
NMAccessPoint *src_ap;
NMAccessPointList *dev_list;
g_return_if_fail (dev != NULL);
if (allowed_list == NULL)
return;
nm_device_ap_list_clear (dev);
dev->options.wireless.ap_list = nm_ap_list_new (NETWORK_TYPE_ALLOWED);
if (!(iter = nm_ap_list_iter_new (allowed_list)))
return;
dev_list = nm_device_ap_list_get (dev);
while ((src_ap = nm_ap_list_iter_next (iter)))
{
NMAccessPoint *dst_ap = nm_ap_new_from_ap (src_ap);
/* Assume that if the allowed list AP has a saved encryption
* key that the AP is encrypted.
*/
if ( (nm_ap_get_auth_method (src_ap) == NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM)
|| (nm_ap_get_auth_method (src_ap) == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
nm_ap_set_encrypted (dst_ap, TRUE);
nm_ap_list_append_ap (dev_list, dst_ap);
nm_ap_unref (dst_ap);
}
nm_ap_list_iter_free (iter);
}
/* /*
* nm_device_new * nm_device_new
* *
@@ -279,6 +323,12 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
opts->supports_wireless_scan = nm_device_supports_wireless_scan (dev); opts->supports_wireless_scan = nm_device_supports_wireless_scan (dev);
/* Non-scanning devices show the entire allowed AP list as their
* available networks.
*/
if (opts->supports_wireless_scan == FALSE)
nm_device_copy_allowed_to_dev_list (dev, app_data->allowed_ap_list);
if ((sk = iw_sockets_open ()) >= 0) if ((sk = iw_sockets_open ()) >= 0)
{ {
iwrange range; iwrange range;
@@ -309,6 +359,9 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
dev->options.wired.has_carrier_detect = TRUE; dev->options.wired.has_carrier_detect = TRUE;
} }
/* Must be called after carrier detect or wireless scan detect. */
dev->driver_support_level = nm_get_driver_support_level (dev->app_data->hal_ctx, dev);
if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED) if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED)
{ {
if (nm_device_is_wireless (dev)) if (nm_device_is_wireless (dev))
@@ -423,8 +476,8 @@ static gpointer nm_device_worker (gpointer user_data)
exit (1); exit (1);
} }
/* Do an initial wireless scan */ /* Start the scanning timeout for devices that can do scanning */
if (nm_device_is_wireless (dev)) if (nm_device_is_wireless (dev) && nm_device_get_supports_wireless_scan (dev))
{ {
GSource *source = g_idle_source_new (); GSource *source = g_idle_source_new ();
guint source_id = 0; guint source_id = 0;
@@ -1427,11 +1480,12 @@ void nm_device_get_ip6_address(NMDevice *dev)
* Get a device's hardware address * Get a device's hardware address
* *
*/ */
void nm_device_get_hw_address(NMDevice *dev, unsigned char hw_addr[ETH_ALEN]) void nm_device_get_hw_address(NMDevice *dev, unsigned char *eth_addr)
{ {
g_return_if_fail (eth_addr != NULL);
g_return_if_fail (dev != NULL); g_return_if_fail (dev != NULL);
memcpy (hw_addr, dev->hw_addr, ETH_ALEN); memcpy (eth_addr, dev->hw_addr, ETH_ALEN);
} }
void nm_device_update_hw_address (NMDevice *dev) void nm_device_update_hw_address (NMDevice *dev)
@@ -1592,7 +1646,7 @@ gboolean nm_device_bring_up_wait (NMDevice *dev, gboolean cancelable)
nm_completion_device_is_up_test, dev, nm_completion_device_is_up_test, dev,
&err, cancelable); &err, cancelable);
if (err) if (err)
syslog (LOG_INFO, "failed to bring device up"); nm_info ("failed to bring device up");
return err; return err;
} }
@@ -1633,7 +1687,7 @@ gboolean nm_device_bring_down_wait (NMDevice *dev, gboolean cancelable)
nm_completion_device_is_down_test, dev, nm_completion_device_is_down_test, dev,
&err, cancelable); &err, cancelable);
if (err) if (err)
syslog (LOG_INFO, "failed to bring device down"); nm_info ("failed to bring device down");
return err; return err;
} }
@@ -1747,7 +1801,7 @@ gboolean nm_device_set_mode (NMDevice *dev, const NMNetworkMode mode)
* Schedule an idle routine in the main thread to finish the activation. * Schedule an idle routine in the main thread to finish the activation.
* *
*/ */
void nm_device_activation_schedule_finish (NMDevice *dev, DeviceStatus activation_result) void nm_device_activation_schedule_finish (NMDevice *dev, NMAccessPoint *failed_ap, DeviceStatus activation_result)
{ {
GSource *source = NULL; GSource *source = NULL;
NMActivationResult *result = NULL; NMActivationResult *result = NULL;
@@ -1758,6 +1812,7 @@ void nm_device_activation_schedule_finish (NMDevice *dev, DeviceStatus activatio
result = g_malloc0 (sizeof (NMActivationResult)); result = g_malloc0 (sizeof (NMActivationResult));
nm_device_ref (dev); /* Ref device for idle handler */ nm_device_ref (dev); /* Ref device for idle handler */
result->dev = dev; result->dev = dev;
result->failed_ap = failed_ap;
result->result = activation_result; result->result = activation_result;
source = g_idle_source_new (); source = g_idle_source_new ();
@@ -2435,6 +2490,12 @@ try_connect:
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)"); nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
} }
/* Don't try other APs for non-scanning devices.
* User must pick a new one manually.
*/
if (!nm_device_get_supports_wireless_scan (dev))
goto out;
/* All applicable modes failed, invalidate current best_ap and get a new one */ /* All applicable modes failed, invalidate current best_ap and get a new one */
invalidate_ap (dev, best_ap); invalidate_ap (dev, best_ap);
goto get_ap; goto get_ap;
@@ -2481,6 +2542,12 @@ try_connect:
} }
else else
{ {
/* Don't try other APs for non-scanning devices.
* User must pick a new one manually.
*/
if (!nm_device_get_supports_wireless_scan (dev))
goto out;
/* All applicable modes failed, invalidate current best_ap and get a new one */ /* All applicable modes failed, invalidate current best_ap and get a new one */
invalidate_ap (dev, best_ap); invalidate_ap (dev, best_ap);
goto get_ap; goto get_ap;
@@ -2578,6 +2645,7 @@ static gboolean nm_device_activate (gpointer user_data)
NMDevice *dev = (NMDevice *)user_data; NMDevice *dev = (NMDevice *)user_data;
gboolean success = FALSE; gboolean success = FALSE;
gboolean finished = FALSE; gboolean finished = FALSE;
NMAccessPoint *failed_best_ap = NULL;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (dev->app_data != NULL, FALSE); g_return_val_if_fail (dev->app_data != NULL, FALSE);
@@ -2625,10 +2693,15 @@ static gboolean nm_device_activate (gpointer user_data)
out: out:
nm_info ("Activation (%s) ended.", nm_device_get_iface (dev)); nm_info ("Activation (%s) ended.", nm_device_get_iface (dev));
if (finished)
{
if (nm_device_is_wireless (dev) && !success)
failed_best_ap = nm_device_get_best_ap (dev);
}
dev->activating = FALSE; dev->activating = FALSE;
dev->quit_activation = FALSE; dev->quit_activation = FALSE;
if (finished) if (finished)
nm_device_activation_schedule_finish (dev, success ? DEVICE_NOW_ACTIVE : DEVICE_ACTIVATION_FAILED); nm_device_activation_schedule_finish (dev, failed_best_ap, success ? DEVICE_NOW_ACTIVE : DEVICE_ACTIVATION_FAILED);
return FALSE; return FALSE;
} }
@@ -3084,6 +3157,22 @@ void nm_device_update_best_ap (NMDevice *dev)
g_return_if_fail (dev->app_data != NULL); g_return_if_fail (dev->app_data != NULL);
g_return_if_fail (nm_device_is_wireless (dev)); g_return_if_fail (nm_device_is_wireless (dev));
/* Devices that can't scan don't do anything automatic.
* The user must choose the access point from the menu.
*/
if (!nm_device_get_supports_wireless_scan (dev))
{
/* If we lost a link to the AP, clear it out.
*
* FIXME: take samples over 5 seconds or so of the
* whether or not the link is active and only blow away
* the best_ap if its been down for 5 seconds or more.
*/
if (!nm_device_has_active_link (dev))
nm_device_set_best_ap (dev, NULL);
return;
}
if (!(ap_list = nm_device_ap_list_get (dev))) if (!(ap_list = nm_device_ap_list_get (dev)))
return; return;
@@ -3293,86 +3382,6 @@ void nm_device_schedule_force_use (NMDevice *dev, const char *network, const cha
} }
/*
* nm_device_do_pseudo_scan
*
* Brute-force the allowed access point list to find one that works, if any.
*
* FIXME
* There's probably a better way to do the non-scanning access point discovery
* than brute forcing it like this, but that makes the state machine here oh so
* much more complicated.
*/
static void nm_device_do_pseudo_scan (NMDevice *dev)
{
NMAPListIter *iter;
NMAccessPoint *ap;
g_return_if_fail (dev != NULL);
g_return_if_fail (dev->app_data != NULL);
/* Test devices shouldn't get here since we fake the AP list earlier */
g_return_if_fail (!dev->test_device);
nm_device_ref (dev);
if (!(iter = nm_ap_list_iter_new (dev->app_data->allowed_ap_list)))
return;
nm_device_set_essid (dev, "");
while ((ap = nm_ap_list_iter_next (iter)))
{
gboolean valid = FALSE;
struct ether_addr save_ap_addr;
struct ether_addr cur_ap_addr;
if (!nm_device_is_up (dev));
nm_device_bring_up (dev);
/* Save the MAC address */
nm_device_get_ap_address (dev, &save_ap_addr);
if (nm_ap_get_enc_key_source (ap))
{
char *hashed_key = nm_ap_get_enc_key_hashed (ap);
nm_device_set_enc_key (dev, hashed_key, NM_DEVICE_AUTH_METHOD_SHARED_KEY);
g_free (hashed_key);
}
else
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
nm_device_set_essid (dev, nm_ap_get_essid (ap));
/* Wait a bit for association */
nm_device_is_up_and_associated_wait (dev, 2, 100);
/* Do we have a valid MAC address? */
nm_device_get_ap_address (dev, &cur_ap_addr);
valid = nm_ethernet_address_is_valid (&cur_ap_addr);
/* If the ap address we had before, and the ap address we
* have now, are the same, AP is invalid. Certain cards (orinoco)
* will let the essid change, but the the card won't actually de-associate
* from the previous access point if it can't associate with the new one
* (ie signal too weak, etc).
*/
if (valid && (memcmp (&save_ap_addr, &cur_ap_addr, sizeof (struct ether_addr)) == 0))
valid = FALSE;
if (valid)
{
nm_info ("%s: setting AP '%s' best", nm_device_get_iface (dev), nm_ap_get_essid (ap));
nm_device_set_best_ap (dev, ap);
nm_policy_schedule_state_update (dev->app_data);
break;
}
}
nm_ap_list_iter_free (iter);
nm_device_unref (dev);
}
/* /*
* nm_device_fake_ap_list * nm_device_fake_ap_list
* *
@@ -3476,26 +3485,9 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
g_return_val_if_fail (results != NULL, FALSE); g_return_val_if_fail (results != NULL, FALSE);
dev = results->dev; dev = results->dev;
if (!dev || !results->scan_head.result) if (!dev || !results->scan_head.result)
return FALSE; return FALSE;
/* Test devices get their info faked */
if (dev->test_device)
{
nm_device_fake_ap_list (dev);
return FALSE;
}
/* Devices that don't support scanning have their pseudo-scanning done in
* the main thread anyway.
*/
if (!nm_device_get_supports_wireless_scan (dev))
{
nm_device_do_pseudo_scan (dev);
return FALSE;
}
g_get_current_time (&cur_time); g_get_current_time (&cur_time);
/* Translate iwlib scan results to NM access point list */ /* Translate iwlib scan results to NM access point list */
@@ -3704,10 +3696,6 @@ static gboolean nm_device_wireless_scan (gpointer user_data)
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (dev->app_data != NULL, FALSE); g_return_val_if_fail (dev->app_data != NULL, FALSE);
/* We don't scan on test devices or devices that don't have scanning support */
if (dev->test_device || !nm_device_get_supports_wireless_scan (dev))
return FALSE;
/* Just reschedule ourselves if scanning or all wireless is disabled */ /* Just reschedule ourselves if scanning or all wireless is disabled */
if ( (dev->app_data->scanning_enabled == FALSE) if ( (dev->app_data->scanning_enabled == FALSE)
|| (dev->app_data->wireless_enabled == FALSE) || (dev->app_data->wireless_enabled == FALSE)
@@ -3717,6 +3705,14 @@ static gboolean nm_device_wireless_scan (gpointer user_data)
goto reschedule; goto reschedule;
} }
/* Test devices get a fake ap list */
if (dev->test_device)
{
nm_device_fake_ap_list (dev);
dev->options.wireless.scan_interval = 20;
goto reschedule;
}
/* Grab the scan mutex */ /* Grab the scan mutex */
if (nm_try_acquire_mutex (dev->options.wireless.scan_mutex, __FUNCTION__)) if (nm_try_acquire_mutex (dev->options.wireless.scan_mutex, __FUNCTION__))
{ {

View File

@@ -70,7 +70,7 @@ NMNetworkMode nm_device_get_mode (NMDevice *dev);
guint32 nm_device_get_ip4_address (NMDevice *dev); guint32 nm_device_get_ip4_address (NMDevice *dev);
void nm_device_update_ip4_address (NMDevice *dev); void nm_device_update_ip4_address (NMDevice *dev);
void nm_device_get_hw_address (NMDevice *dev, unsigned char hw_addr[ETH_ALEN]); void nm_device_get_hw_address (NMDevice *dev, unsigned char *eth_addr);
void nm_device_update_hw_address (NMDevice *dev); void nm_device_update_hw_address (NMDevice *dev);
void nm_device_get_ip6_address (NMDevice *dev); void nm_device_get_ip6_address (NMDevice *dev);
@@ -121,6 +121,7 @@ void nm_device_ap_list_clear (NMDevice *dev);
struct NMAccessPointList *nm_device_ap_list_get (NMDevice *dev); struct NMAccessPointList *nm_device_ap_list_get (NMDevice *dev);
NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *essid); NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *essid);
NMAccessPoint *nm_device_ap_list_get_ap_by_address(NMDevice *dev, const struct ether_addr *addr); NMAccessPoint *nm_device_ap_list_get_ap_by_address(NMDevice *dev, const struct ether_addr *addr);
void nm_device_copy_allowed_to_dev_list (NMDevice *dev, struct NMAccessPointList *allowed_list);
/* System config data accessors */ /* System config data accessors */
gboolean nm_device_config_get_use_dhcp (NMDevice *dev); gboolean nm_device_config_get_use_dhcp (NMDevice *dev);

View File

@@ -234,6 +234,7 @@ gboolean nm_policy_activation_finish (gpointer user_data)
{ {
NMActivationResult *result = (NMActivationResult *)user_data; NMActivationResult *result = (NMActivationResult *)user_data;
NMDevice *dev = NULL; NMDevice *dev = NULL;
NMAccessPoint *failed_ap = NULL;
NMData *data = NULL; NMData *data = NULL;
g_return_val_if_fail (result != NULL, FALSE); g_return_val_if_fail (result != NULL, FALSE);
@@ -241,6 +242,8 @@ gboolean nm_policy_activation_finish (gpointer user_data)
if (!(dev = result->dev)) if (!(dev = result->dev))
goto out; goto out;
failed_ap = result->failed_ap;
if (!(data = nm_device_get_app_data (dev))) if (!(data = nm_device_get_app_data (dev)))
goto out; goto out;
@@ -275,22 +278,29 @@ gboolean nm_policy_activation_finish (gpointer user_data)
nm_dbus_signal_device_status_change (data->dbus_connection, dev, result->result); nm_dbus_signal_device_status_change (data->dbus_connection, dev, result->result);
if (nm_device_is_wireless (dev)) if (nm_device_is_wireless (dev))
{ {
NMAccessPoint *ap = nm_device_get_best_ap (dev); if (failed_ap)
if (ap)
{ {
/* Add the AP to the invalid list and force a best ap update */ /* Add the AP to the invalid list and force a best ap update */
nm_ap_list_append_ap (data->invalid_ap_list, ap); nm_ap_list_append_ap (data->invalid_ap_list, failed_ap);
nm_device_update_best_ap (dev); nm_device_update_best_ap (dev);
/* Unref because nm_device_get_best_ap() refs it before returning. */
nm_ap_unref (ap);
} }
nm_info ("Activation (%s) failed for access point (%s)", nm_device_get_iface (dev), ap ? nm_ap_get_essid (ap) : "(none)");
nm_info ("Activation (%s) failed for access point (%s)", nm_device_get_iface (dev),
failed_ap ? nm_ap_get_essid (failed_ap) : "(none)");
/* Failed AP got reffed by nm_device_get_best_ap() during activation,
* must unref it here.
*/
if (failed_ap)
nm_ap_unref (failed_ap);
} }
else else
nm_info ("Activation (%s) failed.", nm_device_get_iface (dev)); nm_info ("Activation (%s) failed.", nm_device_get_iface (dev));
if (data->active_device == dev) if (data->active_device == dev)
{
nm_device_unref (dev);
data->active_device = NULL; data->active_device = NULL;
}
nm_device_deactivate (dev, FALSE); nm_device_deactivate (dev, FALSE);
break; break;
@@ -493,6 +503,8 @@ static gboolean nm_policy_allowed_ap_list_update (gpointer user_data)
{ {
NMDevice *dev = (NMDevice *)(elt->data); NMDevice *dev = (NMDevice *)(elt->data);
if (nm_device_is_wireless (dev)) if (nm_device_is_wireless (dev))
{
if (nm_device_get_supports_wireless_scan (dev))
{ {
/* Once we have the list, copy in any relevant information from our Allowed list and fill /* Once we have the list, copy in any relevant information from our Allowed list and fill
* in the ESSID of base stations that aren't broadcasting their ESSID, if we have their * in the ESSID of base stations that aren't broadcasting their ESSID, if we have their
@@ -501,6 +513,9 @@ static gboolean nm_policy_allowed_ap_list_update (gpointer user_data)
nm_ap_list_copy_essids_by_address (nm_device_ap_list_get (dev), data->allowed_ap_list); nm_ap_list_copy_essids_by_address (nm_device_ap_list_get (dev), data->allowed_ap_list);
nm_ap_list_copy_properties (nm_device_ap_list_get (dev), data->allowed_ap_list); nm_ap_list_copy_properties (nm_device_ap_list_get (dev), data->allowed_ap_list);
} }
else
nm_device_copy_allowed_to_dev_list (dev, data->allowed_ap_list);
}
} }
/* If the active device doesn't have a best_ap already, make it update to /* If the active device doesn't have a best_ap already, make it update to

View File

@@ -29,6 +29,7 @@
typedef struct typedef struct
{ {
NMDevice *dev; NMDevice *dev;
NMAccessPoint *failed_ap;
DeviceStatus result; DeviceStatus result;
} NMActivationResult; } NMActivationResult;

View File

@@ -173,7 +173,6 @@ int nm_null_safe_strcmp (const char *s1, const char *s2)
} }
/* /*
* nm_ethernet_address_is_valid * nm_ethernet_address_is_valid
* *
@@ -337,6 +336,10 @@ NMDriverSupportLevel nm_get_wireless_driver_support_level (LibHalContext *ctx, N
g_free (driver_name); g_free (driver_name);
} }
/* Check for carrier detection support */
if ((level != NM_DRIVER_UNSUPPORTED) && !nm_device_get_supports_wireless_scan (dev))
level = NM_DRIVER_NO_WIRELESS_SCAN;
return (level); return (level);
} }
@@ -387,6 +390,10 @@ NMDriverSupportLevel nm_get_wired_driver_support_level (LibHalContext *ctx, NMDe
level = NM_DRIVER_UNSUPPORTED; level = NM_DRIVER_UNSUPPORTED;
} }
/* Check for carrier detection support */
if ((level != NM_DRIVER_UNSUPPORTED) && !nm_device_get_supports_carrier_detect(dev))
level = NM_DRIVER_NO_CARRIER_DETECT;
return (level); return (level);
} }
@@ -412,8 +419,13 @@ NMDriverSupportLevel nm_get_driver_support_level (LibHalContext *ctx, NMDevice *
switch (level) switch (level)
{ {
case NM_DRIVER_SEMI_SUPPORTED: case NM_DRIVER_NO_CARRIER_DETECT:
nm_info ("%s: Driver support level for '%s' is semi-supported", nm_info ("%s: Driver '%s' does not support carrier detection.\n"
"\tYou must switch to it manually.", nm_device_get_iface (dev), driver);
break;
case NM_DRIVER_NO_WIRELESS_SCAN:
nm_info ("%s: Driver '%s' does not support wireless scanning.\n"
"\tNetworkManager will not be able to fully use the card.",
nm_device_get_iface (dev), driver); nm_device_get_iface (dev), driver);
break; break;
case NM_DRIVER_FULLY_SUPPORTED: case NM_DRIVER_FULLY_SUPPORTED:

View File

@@ -179,6 +179,7 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip)
int nprobes = 0; int nprobes = 0;
int nannounce = 0; int nannounce = 0;
gboolean success = FALSE; gboolean success = FALSE;
char *temp_addr;
g_return_val_if_fail (dev != NULL, FALSE); g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (out_ip != NULL, FALSE); g_return_val_if_fail (out_ip != NULL, FALSE);
@@ -203,7 +204,7 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip)
goto out; goto out;
} }
nm_device_get_hw_address (dev, addr.ether_addr_octet); nm_device_get_hw_address (dev, &(addr.ether_addr_octet[0]));
/* initialize pseudo random selection of IP addresses */ /* initialize pseudo random selection of IP addresses */
srandom ( (addr.ether_addr_octet[ETHER_ADDR_LEN-4] << 24) | srandom ( (addr.ether_addr_octet[ETHER_ADDR_LEN-4] << 24) |

View File

@@ -334,9 +334,10 @@ void nm_system_restart_mdns_responder (void)
void nm_system_device_add_ip6_link_address (NMDevice *dev) void nm_system_device_add_ip6_link_address (NMDevice *dev)
{ {
char *buf; char *buf;
char *addr;
unsigned char eui[8]; unsigned char eui[8];
nm_device_get_hw_address(dev, eui); nm_device_get_hw_address(dev, &eui[0]);
memmove(eui+5, eui+3, 3); memmove(eui+5, eui+3, 3);
eui[3] = 0xff; eui[3] = 0xff;

View File

@@ -349,9 +349,10 @@ void nm_system_restart_mdns_responder (void)
void nm_system_device_add_ip6_link_address (NMDevice *dev) void nm_system_device_add_ip6_link_address (NMDevice *dev)
{ {
char *buf; char *buf;
char *addr;
unsigned char eui[8]; unsigned char eui[8];
nm_device_get_hw_address(dev, eui); nm_device_get_hw_address(dev, &eui[0]);
memmove(eui+5, eui+3, 3); memmove(eui+5, eui+3, 3);
eui[3] = 0xff; eui[3] = 0xff;

View File

@@ -25,6 +25,7 @@
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
#include <stdarg.h> #include <stdarg.h>
#include <syslog.h> #include <syslog.h>
#include <netinet/ether.h>
#include "nm-utils.h" #include "nm-utils.h"
#include "NetworkManagerDevice.h" #include "NetworkManagerDevice.h"
@@ -102,6 +103,29 @@ static DBusMessage *nm_dbus_device_get_ip4_address (DBusConnection *connection,
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_hw_address (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
DBusMessage *reply = NULL;
NMDevice *dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
dev = data->dev;
if ((reply = dbus_message_new_method_return (message)))
{
struct ether_addr addr;
char char_addr[20];
char *ptr = &char_addr[0];
nm_device_get_hw_address (dev, (unsigned char *)&(addr.ether_addr_octet));
memset (char_addr, 0, 20);
ether_ntoa_r (&addr, &char_addr[0]);
dbus_message_append_args (reply, DBUS_TYPE_STRING, &ptr, DBUS_TYPE_INVALID);
}
return reply;
}
static DBusMessage *nm_dbus_device_get_mode (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *nm_dbus_device_get_mode (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{ {
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
@@ -279,24 +303,18 @@ static DBusMessage *nm_dbus_device_get_networks (DBusConnection *connection, DBu
return reply; return reply;
} }
static DBusMessage *nm_dbus_device_get_supports_carrier_detect (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data) static DBusMessage *nm_dbus_device_get_driver_support_level (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{ {
DBusMessage *reply = NULL; DBusMessage *reply = NULL;
NMDevice *dev; NMDevice *dev;
g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL); g_return_val_if_fail (data && data->data && data->dev && connection && message, NULL);
/* Wired devices only for now */
dev = data->dev; dev = data->dev;
if (!nm_device_is_wired (dev)) if ((reply = dbus_message_new_method_return (message)))
{ {
reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotWired", dbus_uint32_t driver_support_level = nm_device_get_driver_support_level (dev);
"Carrier detection is only supported for wired devices."); dbus_message_append_args (reply, DBUS_TYPE_UINT32, &driver_support_level, DBUS_TYPE_INVALID);
}
else if ((reply = dbus_message_new_method_return (message))) {
dbus_bool_t supports_carrier_detect;
supports_carrier_detect = nm_device_get_supports_carrier_detect (dev);
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &supports_carrier_detect, DBUS_TYPE_INVALID);
} }
return reply; return reply;
@@ -347,13 +365,14 @@ NMDbusMethodList *nm_dbus_device_methods_setup (void)
nm_dbus_method_list_add_method (list, "getType", nm_dbus_device_get_type); nm_dbus_method_list_add_method (list, "getType", nm_dbus_device_get_type);
nm_dbus_method_list_add_method (list, "getHalUdi", nm_dbus_device_get_hal_udi); nm_dbus_method_list_add_method (list, "getHalUdi", nm_dbus_device_get_hal_udi);
nm_dbus_method_list_add_method (list, "getIP4Address", nm_dbus_device_get_ip4_address); nm_dbus_method_list_add_method (list, "getIP4Address", nm_dbus_device_get_ip4_address);
nm_dbus_method_list_add_method (list, "getHWAddress", nm_dbus_device_get_hw_address);
nm_dbus_method_list_add_method (list, "getMode", nm_dbus_device_get_mode); nm_dbus_method_list_add_method (list, "getMode", nm_dbus_device_get_mode);
nm_dbus_method_list_add_method (list, "getStrength", nm_dbus_device_get_strength); nm_dbus_method_list_add_method (list, "getStrength", nm_dbus_device_get_strength);
nm_dbus_method_list_add_method (list, "getActiveNetwork", nm_dbus_device_get_active_network); nm_dbus_method_list_add_method (list, "getActiveNetwork", nm_dbus_device_get_active_network);
nm_dbus_method_list_add_method (list, "getNetworks", nm_dbus_device_get_networks); nm_dbus_method_list_add_method (list, "getNetworks", nm_dbus_device_get_networks);
nm_dbus_method_list_add_method (list, "getLinkActive", nm_dbus_device_get_link_active); nm_dbus_method_list_add_method (list, "getLinkActive", nm_dbus_device_get_link_active);
nm_dbus_method_list_add_method (list, "setLinkActive", nm_dbus_device_set_link_active); nm_dbus_method_list_add_method (list, "setLinkActive", nm_dbus_device_set_link_active);
nm_dbus_method_list_add_method (list, "getSupportsCarrierDetect", nm_dbus_device_get_supports_carrier_detect); nm_dbus_method_list_add_method (list, "getDriverSupportLevel", nm_dbus_device_get_driver_support_level);
return (list); return (list);
} }