+2004-08-02 Dan Williams <dcbw@redhat.com>
+
+ * TODO
+ - new task: proper logging support
+
+ * info-daemon/NetworkManagerInfo.c
+ - Correct spelling of "canceled"
+ - Correct casting of objects for g_signal_connect()
+
+ * info-daemon/NetworkManagerInfoDbus.c
+ - Add defines for NetworkManager namespace and object path, and use them
+ - Add filter function to trap new signals from NetworkManager:
+ WirelessNetworkAppeared, WirelessNetworkDisappeared
+
+ * info-daemon/passphrase.glade
+ - Change name of "ok" button to "Login to Network..."
+ - Mark invisible
+
+ * src/NetworkManager.c
+ - Code and debug message cleanups
+ - Rename "nm_add_current_devices"->"nm_add_initial_devices"
+ - (nm_add_initial_devices) Check returned string array of devices
+ and don't try to add devices if array is NULL
+ - (main) Initialize libhal a bit later, make code a bit clearer
+
+ * src/NetworkManagerAP.[ch]
+ - New accessor and data member "matched": used to speed up AP list
+ diffing
+ - New accessor and data member "enc_method": will be used during key
+ fallback to cache which passphrase->key conversion actually works
+ so we don't have to do it every time
+
+ * src/NetworkManagerAPList.[ch]
+ - (nm_ap_list_find_ap_in_list) New: find an AP by essid in an AP list
+ - (nm_ap_list_diff) New: given two lists of access points, find the differences
+ between them, and send WirelessNetworkAppeared/Disappeared signals over
+ dbus in response to those differences
+
+ * src/NetworkManagerDbus.[ch]
+ - (nm_dbus_get_object_path_from_ap) New: given a device and an access point,
+ make an object path for that access point (NOTE that we don't yet check to
+ make sure that access point is actually in the device's AP list yet)
+ - (nm_dbus_get_ap_from_object_path) Renamed from nm_dbus_get_network_from_object_path
+ - (nm_dbus_signal_wireless_network_appeared, nm_dbus_signal_wireless_network_disappeared)
+ New: signal appearance/disappearance of wireless networks
+ - (nm_dbus_set_user_key_for_network) Mark the network/ap as invalid if the user cancelled
+ key entry
+
+ * src/NetworkManagerDevice.[ch]
+ - (nm_device_ap_list_clear) Use nm_ap_list_free rather than doing it ourselves
+ - (nm_device_ap_list_get) New: return the AP list (static function)
+ - (nm_device_do_normal_scan) Destroy old AP list later, so that we can diff the
+ new one resulting from the scan with the old one
+
+ * src/NetworkManagerWireless.c
+ - (nm_wireless_is_most_prefered_ap) "invalid" access points cannot be "best" access points
+
+ * test/nminfotest.c
+ - #define object paths and namespaces and use the #defines rather than static strings
+ - Test out user-key functionality of NetworkManagerInfo too
+
2004-07-29 Dan Williams <dcbw@redhat.com>
* info-daemon/NetworkManagerInfoDbus.c
There is currently no logic to gracefully recover from a crashed/killed dbus or hal. While we don't depend as heavily on NetworkManagerInfo, we need to make sure that we can operate effectively when it's not there. There are dbus functions for notification when services come up and go away which could be used here. Remeber that when dbus dies, hal also dies at the moment.
+- Proper logging support
+
+We need to replace NM_DEBUG_PRINT with proper logging support to syslog or something.
+
- Deal with blank ESSIDs
Access points can be set not to broadcast their ESSIDs, which the client must know. These appear as blank ESSIDs to cards doing wireless scanning, even though the rest of the AP's information is known (channel, rate, etc). There has to be a way to deal with this as many companies do not broadcast ESSIDs for security measures. Workarounds for this practice could include brute-forcing the Allowed Networks list if no suitable wireless network is found to begin with. Obviously, there would be no way to detect if a WEP key was wrong, because unless the ESSID and WEP key are both correct, we cannot associate with the access point to see if we have a link. Code exists to do this for wireless cards that do not support wireless scanning, and this code could be adapted.
#include <glib.h>
#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <getopt.h>
#include <errno.h>
const char *device = g_object_get_data (G_OBJECT (dialog), "device");
const char *network = g_object_get_data (G_OBJECT (dialog), "network");
- nmi_dbus_return_user_key (info->connection, device, network, "***cancelled***");
+ nmi_dbus_return_user_key (info->connection, device, network, "***canceled***");
nmi_clear_dialog (dialog, glade_xml_get_widget (info->xml, "passphrase_entry"));
}
}
gtk_widget_hide (dialog);
ok_button = GTK_BUTTON (glade_xml_get_widget (info->xml, "login_button"));
- g_signal_connect (GTK_OBJECT (ok_button), "clicked", GTK_SIGNAL_FUNC (ok_button_clicked), info);
+ g_signal_connect (G_OBJECT (ok_button), "clicked", GTK_SIGNAL_FUNC (ok_button_clicked), info);
gtk_widget_grab_default (GTK_WIDGET (ok_button));
cancel_button = GTK_BUTTON (glade_xml_get_widget (info->xml, "cancel_button"));
- g_signal_connect (GTK_OBJECT (cancel_button), "clicked", GTK_SIGNAL_FUNC (cancel_button_clicked), info);
+ g_signal_connect (G_OBJECT (cancel_button), "clicked", GTK_SIGNAL_FUNC (cancel_button_clicked), info);
entry = GTK_ENTRY (glade_xml_get_widget (info->xml, "passphrase_entry"));
gtk_entry_set_visibility (entry, FALSE);
#define NMI_DBUS_NMI_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManagerInfo"
#define NMI_DBUS_NMI_NAMESPACE "org.freedesktop.NetworkManagerInfo"
+#define NM_DBUS_NM_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManager"
+#define NM_DBUS_NM_NAMESPACE "org.freedesktop.NetworkManager"
/*
* nmi_dbus_create_error_message
g_return_if_fail (network != NULL);
g_return_if_fail (passphrase != NULL);
- message = dbus_message_new_method_call ("org.freedesktop.NetworkManager",
- "/org/freedesktop/NetworkManager",
- "org.freedesktop.NetworkManager",
+ message = dbus_message_new_method_call (NM_DBUS_NM_NAMESPACE,
+ NM_DBUS_NM_OBJECT_PATH_PREFIX,
+ NM_DBUS_NM_NAMESPACE,
"setKeyForNetwork");
if (message == NULL)
{
g_return_if_fail (connection != NULL);
g_return_if_fail (network != NULL);
- message = dbus_message_new_signal ("/org/freedesktop/NetworkManagerInfo", "org.freedesktop.NetworkManagerInfo",
+ message = dbus_message_new_signal (NMI_DBUS_NMI_OBJECT_PATH_PREFIX, NMI_DBUS_NMI_NAMESPACE,
"AllowedNetworkUpdate");
if (!message)
{
}
+
+static DBusHandlerResult nmi_dbus_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ char *ap_object_path;
+ DBusError error;
+ gboolean handled = FALSE;
+ NMIAppInfo *info = (NMIAppInfo *) user_data;
+ gboolean appeared = FALSE;
+ gboolean disappeared = FALSE;
+
+ g_return_val_if_fail (info != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+ if (dbus_message_is_signal (message, NM_DBUS_NM_NAMESPACE, "WirelessNetworkAppeared"))
+ appeared = TRUE;
+ else if (dbus_message_is_signal (message, NM_DBUS_NM_NAMESPACE, "WirelessNetworkDisappeared"))
+ disappeared = TRUE;
+
+ if (appeared || disappeared)
+ {
+ dbus_error_init (&error);
+ if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &ap_object_path, DBUS_TYPE_INVALID))
+ {
+ dbus_free (ap_object_path);
+ handled = TRUE;
+ }
+ }
+
+ return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+}
+
+
/*
* nmi_dbus_service_init
*
return (-1);
}
+ if (!dbus_connection_add_filter (dbus_connection, nmi_dbus_filter, info, NULL))
+ return (-1);
+
+ dbus_error_init (&dbus_error);
+ dbus_bus_add_match (dbus_connection,
+ "type='signal',"
+ "interface='"NM_DBUS_NM_NAMESPACE"',"
+ "sender='"NM_DBUS_NM_NAMESPACE"',"
+ "path='"NM_DBUS_NM_OBJECT_PATH_PREFIX"'", &dbus_error);
+ if (dbus_error_is_set (&dbus_error))
+ return (-1);
+
return (0);
}
<widget class="GtkDialog" id="passphrase_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_CENTER_ALWAYS</property>
<widget class="GtkButton" id="login_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">_Login to AP</property>
+ <property name="label" translatable="yes">_Login to Network</property>
<property name="use_underline">True</property>
<property name="relief">GTK_RELIEF_NORMAL</property>
<property name="focus_on_click">True</property>
<widget class="GtkEntry" id="passphrase_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
+ <property name="has_focus">True</property>
<property name="editable">True</property>
<property name="visibility">True</property>
<property name="max_length">0</property>
#include <glib.h>
#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <hal/libhal.h>
#include <getopt.h>
#include "NetworkManagerPolicy.h"
#include "NetworkManagerWireless.h"
#include "NetworkManagerDbus.h"
+#include "NetworkManagerAP.h"
#include "NetworkManagerAPList.h"
gchar *iface_name = hal_device_get_property_string (data->hal_ctx, udi, "net.interface");
/* Make sure the device is not already in the device list */
- dev = nm_get_device_by_iface (data, iface_name);
- if (dev)
+ if ((dev = nm_get_device_by_iface (data, iface_name)))
{
- NM_DEBUG_PRINT_1 ("nm_create_device_and_add_to_list() device %s was already in the list\n", iface_name);
hal_free_string (iface_name);
return (NULL);
}
- dev = nm_device_new (iface_name, data);
- if (dev)
+ if ((dev = nm_device_new (iface_name, data)))
{
/* Build up the device structure */
*/
if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
{
- NM_DEBUG_PRINT_3( "nm_create_device_and_add_to_list() adding udi='%s', iface='%s', iface_type=%s\n",
- nm_device_get_udi (dev), nm_device_get_iface (dev), nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET ? "wireless" : "wired" );
+ NM_DEBUG_PRINT_2( "nm_create_device_and_add_to_list(): adding device '%s' (%s)\n",
+ nm_device_get_iface (dev), nm_device_is_wireless (dev) ? "wireless" : "wired" );
data->dev_list = g_slist_append (data->dev_list, dev);
nm_device_deactivate (dev, TRUE);
nm_device_unref (dev);
dev = NULL;
}
- } else NM_DEBUG_PRINT_1( "nm_create_device_and_add_to_list(): device %s does not have 'net.interface' property\n", udi );
+ }
return (dev);
}
/*
- * nm_add_current_devices
+ * nm_add_initial_devices
*
* Add all devices that hal knows about right now (ie not hotplug devices)
*
*/
-static void nm_add_current_devices (NMData *data)
+static void nm_add_initial_devices (NMData *data)
{
char **net_devices;
int num_net_devices;
/* Grab a list of network devices */
net_devices = hal_find_device_by_capability (data->hal_ctx, "net.ethernet", &num_net_devices);
- for (i = 0; i < num_net_devices; i++)
- nm_create_device_and_add_to_list (data, net_devices[i]);
+ if (net_devices)
+ {
+ for (i = 0; i < num_net_devices; i++)
+ nm_create_device_and_add_to_list (data, net_devices[i]);
+ }
hal_free_string_array (net_devices);
}
if (strcmp (opt, "help") == 0)
{
nm_print_usage ();
- return 0;
+ exit (EXIT_SUCCESS);
}
else if (strcmp (opt, "daemon") == 0)
{
else
{
nm_print_usage ();
- return 1;
+ exit (EXIT_FAILURE);
}
}
break;
default:
nm_print_usage ();
- return 1;
+ exit (EXIT_FAILURE);
break;
}
}
if (chdir ("/") < 0)
{
fprintf( stderr, "NetworkManager could not chdir to /. errno=%d", errno);
- return 1;
+ return (1);
}
child_pid = fork ();
break;
default:
- exit (0);
+ exit (EXIT_SUCCESS);
break;
}
}
if (!g_thread_supported ())
g_thread_init (NULL);
- /* Initialize libhal. We get a connection to the hal daemon here. */
- if ((ctx = hal_initialize (&hal_functions, FALSE)) == NULL)
- {
- NM_DEBUG_PRINT("hal_initialize() failed, exiting... Make sure the hal daemon is running?\n");
- exit (1);
- }
-
/* Initialize our instance data */
nm_data = nm_data_new ();
if (!nm_data)
{
NM_DEBUG_PRINT("nm_data_new() failed... Not enough memory?\n");
- exit (1);
+ exit (EXIT_FAILURE);
}
- nm_data->hal_ctx = ctx;
- hal_ctx_set_user_data (nm_data->hal_ctx, nm_data);
-
/* Create our dbus service */
nm_data->dbus_connection = nm_dbus_init (nm_data);
- if (nm_data->dbus_connection)
+ if (!nm_data->dbus_connection)
{
- /* Initialize our list of allowed access points */
- nm_ap_list_populate (nm_data);
-
- /* Grab network devices that are already present and add them to our list */
- nm_add_current_devices (nm_data);
-
- /* Create a watch function that monitors cards for link status (hal doesn't do
- * this for wireless cards yet).
- */
- link_source = g_timeout_add (5000, nm_link_state_monitor, nm_data);
-
- /* Another watch function which handles networking state changes and applies
- * the correct policy on a change.
- */
- policy_source = g_timeout_add (3000, nm_state_modification_monitor, nm_data);
-
- /* Yet another watch function which scans for access points and
- * attempts to associate with approved ones in a users' list.
- */
- wireless_scan_source = g_timeout_add (10000, nm_wireless_scan_monitor, nm_data);
-
- /* Watch all devices that HAL knows about for state changes */
- hal_device_property_watch_all (nm_data->hal_ctx);
-
- /* We run dhclient when we need to, and we don't want any stray ones
- * lying around upon launch.
- */
- system ("killall dhclient");
-
- /* Wheeee!!! */
- loop = g_main_loop_new (NULL, FALSE);
- g_main_loop_run (loop);
-
- /* Kill the watch functions */
- g_source_remove (link_source);
- g_source_remove (policy_source);
- g_source_remove (wireless_scan_source);
+ hal_shutdown (nm_data->hal_ctx);
+ nm_data_free (nm_data);
+ exit (EXIT_FAILURE);
}
+ /* Initialize libhal. We get a connection to the hal daemon here. */
+ if ((ctx = hal_initialize (&hal_functions, FALSE)) == NULL)
+ {
+ NM_DEBUG_PRINT("hal_initialize() failed, exiting... Make sure the hal daemon is running?\n");
+ exit (EXIT_FAILURE);
+ }
+ nm_data->hal_ctx = ctx;
+ hal_ctx_set_user_data (nm_data->hal_ctx, nm_data);
+
+ /* Initialize our list of allowed access points */
+ nm_ap_list_populate (nm_data);
+
+ /* Grab network devices that are already present and add them to our list */
+ nm_add_initial_devices (nm_data);
+
+ /* Create a watch function that monitors cards for link status (hal doesn't do
+ * this for wireless cards yet).
+ */
+ link_source = g_timeout_add (5000, nm_link_state_monitor, nm_data);
+
+ /* Another watch function which handles networking state changes and applies
+ * the correct policy on a change.
+ */
+ policy_source = g_timeout_add (3000, nm_state_modification_monitor, nm_data);
+
+ /* Yet another watch function which scans for access points and
+ * attempts to associate with approved ones in a users' list.
+ */
+ wireless_scan_source = g_timeout_add (10000, nm_wireless_scan_monitor, nm_data);
+
+ /* Watch all devices that HAL knows about for state changes */
+ hal_device_property_watch_all (nm_data->hal_ctx);
+
+ /* We run dhclient when we need to, and we don't want any stray ones
+ * lying around upon launch.
+ */
+ system ("killall dhclient");
+
+ /* Wheeee!!! */
+ loop = g_main_loop_new (NULL, FALSE);
+ g_main_loop_run (loop);
+
+ /* Kill the watch functions */
+ g_source_remove (link_source);
+ g_source_remove (policy_source);
+ g_source_remove (wireless_scan_source);
+
/* Cleanup */
if (hal_shutdown (nm_data->hal_ctx) != 0)
g_warning ("hal_shutdown() failed\n");
nm_data_free (nm_data);
- return 0;
+ return (0);
}
guint16 rate;
gboolean encrypted;
gboolean invalid;
+ NMAPEncMethod enc_method;
+ gboolean matched; // used in ap list diffing
/* Things from user prefs */
gchar *wep_key;
ap->invalid = invalid;
}
+
+
+/*
+ * Get/set functions for "matched", which is used by
+ * the ap list diffing functions to speed up the diff
+ *
+ */
+gboolean nm_ap_get_matched (NMAccessPoint *ap)
+{
+ g_return_val_if_fail (ap != NULL, TRUE);
+
+ return (ap->matched);
+}
+
+void nm_ap_set_matched (NMAccessPoint *ap, gboolean matched)
+{
+ g_return_if_fail (ap != NULL);
+
+ ap->matched = matched;
+}
+
+
+/*
+ * Get/set functions for encryption method
+ * Given some sort of passphrase/wep key from the user, we try it first
+ * as a 104-bit passphrase->key conversion, and fall back from there. These
+ * functions are meant to cache which fallback succeeds so we don't have to
+ * do it every time.
+ *
+ */
+NMAPEncMethod nm_ap_get_enc_method (NMAccessPoint *ap)
+{
+ g_return_val_if_fail (ap != NULL, TRUE);
+
+ return (ap->enc_method);
+}
+
+void nm_ap_set_enc_method (NMAccessPoint *ap, NMAPEncMethod enc_method)
+{
+ g_return_if_fail (ap != NULL);
+
+ ap->enc_method = enc_method;
+}
#define NM_AP_PRIORITY_WORST 1000
+typedef enum NMAPEncMethod
+{
+ NM_AP_ENC_METHOD_NONE = 0,
+ NM_AP_ENC_METHOD_HEX_KEY,
+ NM_AP_ENC_METHOD_40_BIT_PASSPHRASE,
+ NM_AP_ENC_METHOD_104_BIT_PASSPHRASE
+} NMAPEncMethod;
+
NMAccessPoint *nm_ap_new (void);
NMAccessPoint *nm_ap_new_from_ap (NMAccessPoint *ap);
gboolean nm_ap_get_invalid (NMAccessPoint *ap);
void nm_ap_set_invalid (NMAccessPoint *ap, gboolean invalid);
+gboolean nm_ap_get_matched (NMAccessPoint *ap);
+void nm_ap_set_matched (NMAccessPoint *ap, gboolean matched);
+
+NMAPEncMethod nm_ap_get_enc_method (NMAccessPoint *ap);
+void nm_ap_set_enc_method (NMAccessPoint *ap, NMAPEncMethod enc_method);
+
#endif
extern gboolean debug;
+
+/*
+ * nm_ap_list_find_ap_in_list
+ *
+ * Helper routine to find an AP in a list.
+ *
+ */
+static NMAccessPoint * nm_ap_list_find_ap_in_list (GSList *list, const char *network)
+{
+ NMAccessPoint *found_ap = NULL;
+ GSList *element = list;
+
+ g_return_val_if_fail (network != NULL, NULL);
+ if (!list)
+ return (NULL);
+
+ while (element)
+ {
+ NMAccessPoint *ap = (NMAccessPoint *)(element->data);
+
+ if (ap && (nm_null_safe_strcmp (nm_ap_get_essid (ap), network) == 0))
+ {
+ found_ap = ap;
+ break;
+ }
+ element = g_slist_next (element);
+ }
+
+ return (found_ap);
+}
+
+
/*
* nm_ap_list_get_ap_by_essid
*
if (nm_try_acquire_mutex (data->allowed_ap_list_mutex, __FUNCTION__))
{
- GSList *element = data->allowed_ap_list;
-
- while (element)
- {
- NMAccessPoint *ap = (NMAccessPoint *)(element->data);
-
- if (ap && (nm_null_safe_strcmp (nm_ap_get_essid (ap), network) == 0))
- {
- found_ap = ap;
- break;
- }
- element = g_slist_next (element);
- }
+ found_ap = nm_ap_list_find_ap_in_list (data->allowed_ap_list, network);
nm_unlock_mutex (data->allowed_ap_list_mutex, __FUNCTION__);
}
else
g_slist_free (ap_list);
}
+
+/*
+ * nm_ap_list_diff
+ *
+ * Takes two ap lists and determines the differences. For each ap that is present
+ * in the original list, but not in the new list, a WirelessNetworkDisappeared signal is emitted
+ * over DBus. For each ap in the new list but not in the original, a WirelessNetworkAppeared
+ * signal is emitted. For each ap that is the same between the lists, the "invalid" flag is copied
+ * over from the old ap to the new ap to preserve "invalid" ap status (ie, user cancelled entering
+ * a WEP key so we cannot connect to it anyway, so why try).
+ *
+ * NOTE: it is assumed that this function is called only ONCE for each list passed into it,
+ * since the "matched" value on access points in the list are never cleared after the
+ * ap is initially created. Therefore, calling this function twice for any given ap list
+ * may result in undesired behavior.
+ *
+ */
+void nm_ap_list_diff (NMData *data, NMDevice *dev, GSList *old, GSList *new)
+{
+ GSList *element = old;
+
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (dev != NULL);
+
+ /* Iterate over each item in the old list and find it in the new list */
+ while (element)
+ {
+ NMAccessPoint *old_ap = (NMAccessPoint *)(element->data);
+ NMAccessPoint *new_ap = NULL;
+
+ if (old_ap)
+ {
+ if ((new_ap = nm_ap_list_find_ap_in_list (new, nm_ap_get_essid (old_ap))))
+ {
+ nm_ap_set_matched (old_ap, TRUE);
+ nm_ap_set_matched (new_ap, TRUE);
+ nm_ap_set_invalid (new_ap, nm_ap_get_invalid (old_ap));
+ nm_ap_set_enc_method (new_ap, nm_ap_get_enc_method (old_ap));
+ }
+ else
+ nm_dbus_signal_wireless_network_disappeared (data->dbus_connection, dev, old_ap);
+ }
+ element = g_slist_next (element);
+ }
+
+ /* Iterate over the new list and compare to the old list. Items that aren't already
+ * matched are by definition new networks.
+ */
+ element = new;
+ while (element)
+ {
+ NMAccessPoint *new_ap = (NMAccessPoint *)(element->data);
+
+ if (new_ap && !nm_ap_get_matched (new_ap))
+ nm_dbus_signal_wireless_network_appeared (data->dbus_connection, dev, new_ap);
+ element = g_slist_next (element);
+ }
+}
+
#include <glib.h>
#include "NetworkManager.h"
+#include "NetworkManagerDevice.h"
NMAccessPoint *nm_ap_list_get_ap_by_essid (NMData *data, const char *network);
void nm_ap_list_free (GSList *ap_list);
+void nm_ap_list_diff (NMData *data, NMDevice *dev, GSList *old, GSList *new);
+
#endif
*/
#include <glib.h>
+#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <stdarg.h>
#include <iwlib.h>
* Copies the object path for a device object into a provided buffer
*
*/
-void nm_dbus_get_object_path_from_device (NMDevice *dev, unsigned char *buf, unsigned int buf_len)
+static void nm_dbus_get_object_path_from_device (NMDevice *dev, unsigned char *buf, unsigned int buf_len)
{
g_return_if_fail (buf != NULL);
g_return_if_fail (buf_len > 0);
* Returns the device associated with a dbus object path
*
*/
-NMDevice *nm_dbus_get_device_from_object_path (NMData *data, const char *path)
+static NMDevice *nm_dbus_get_device_from_object_path (NMData *data, const char *path)
{
NMDevice *dev = NULL;
/*
- * nm_dbus_get_network_from_object_path
+ * nm_dbus_get_object_path_from_ap
+ *
+ * Copies the object path for a wireless network into a provided buffer
+ *
+ */
+static void nm_dbus_get_object_path_from_ap (NMDevice *dev, NMAccessPoint *ap, unsigned char *buf, unsigned int buf_len)
+{
+ g_return_if_fail (buf != NULL);
+ g_return_if_fail (buf_len > 0);
+ memset (buf, 0, buf_len);
+
+ g_return_if_fail (dev != NULL);
+ g_return_if_fail (ap != NULL);
+
+ /* FIXME: check to make sure the AP is actually in the device's ap_list */
+ snprintf (buf, buf_len-1, "%s/%s/Networks/%s", NM_DBUS_DEVICES_OBJECT_PATH_PREFIX, nm_device_get_iface (dev), nm_ap_get_essid (ap));
+}
+
+
+/*
+ * nm_dbus_get_ap_from_object_path
*
* Returns the network (ap) associated with a dbus object path
*
*/
-NMAccessPoint *nm_dbus_get_network_from_object_path (const char *path, NMDevice *dev)
+static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevice *dev)
{
NMAccessPoint *ap = NULL;
int i = 0;
dbus_message_unref (message);
}
+
+/*
+ * nm_dbus_signal_wireless_network_appeared
+ *
+ * Notifies the bus that a new wireless network has come into range
+ *
+ */
+void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap)
+{
+ DBusMessage *message;
+ unsigned char *object_path = g_new0 (unsigned char, 100);
+
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (dev != NULL);
+ g_return_if_fail (ap != NULL);
+
+ message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "WirelessNetworkAppeared");
+ if (!message)
+ {
+ NM_DEBUG_PRINT ("nm_dbus_signal_wireless_network_appeared(): Not enough memory for new dbus message!\n");
+ return;
+ }
+
+ nm_dbus_get_object_path_from_ap (dev, ap, object_path, 100);
+ dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID);
+ g_free (object_path);
+
+ if (!dbus_connection_send (connection, message, NULL))
+ NM_DEBUG_PRINT ("nnm_dbus_signal_wireless_network_appeared(): Could not raise the WirelessNetworkAppeared signal!\n");
+
+ dbus_message_unref (message);
+}
+
+
+/*
+ * nm_dbus_signal_wireless_network_disappeared
+ *
+ * Notifies the bus that a new wireless network is no longer in range
+ *
+ */
+void nm_dbus_signal_wireless_network_disappeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap)
+{
+ DBusMessage *message;
+ unsigned char *object_path = g_new0 (unsigned char, 100);
+
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (dev != NULL);
+ g_return_if_fail (ap != NULL);
+
+ message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "WirelessNetworkDisappeared");
+ if (!message)
+ {
+ NM_DEBUG_PRINT ("nm_dbus_signal_wireless_network_disappeared(): Not enough memory for new dbus message!\n");
+ return;
+ }
+
+ nm_dbus_get_object_path_from_ap (dev, ap, object_path, 100);
+ dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID);
+ g_free (object_path);
+
+ if (!dbus_connection_send (connection, message, NULL))
+ NM_DEBUG_PRINT ("nnm_dbus_signal_wireless_network_disappeared(): Could not raise the WirelessNetworkDisappeared signal!\n");
+
+ dbus_message_unref (message);
+}
+
+
#if 0
/*
* nm_dbus_get_user_key_for_network_callback
DBUS_TYPE_INVALID))
{
NMDevice *dev;
+ const char *cancel_message = "***canceled***";
+
if ((dev = nm_get_device_by_iface (data, device)))
- nm_device_pending_action_set_user_key (dev, passphrase);
+ {
+ /* If the user canceled, mark the ap as invalid */
+ if (strncmp (passphrase, cancel_message, strlen (cancel_message)))
+ {
+ NMAccessPoint *ap = nm_device_ap_list_get_ap_by_essid (dev, network);
+
+ if (ap)
+ nm_ap_set_invalid (ap, TRUE);
+ }
+ else
+ nm_device_pending_action_set_user_key (dev, passphrase);
+ }
char *key = nm_wireless_128bit_key_from_passphrase (passphrase);
g_free (key);
g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
object_path = dbus_message_get_path (message);
+
if (!object_path || (strcmp (object_path, NM_DBUS_NMI_OBJECT_PATH) != 0))
return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
g_return_val_if_fail (request != NULL, NULL);
g_return_val_if_fail (dev != NULL, NULL);
- if (!(ap = nm_dbus_get_network_from_object_path (path, dev)))
+ if (!(ap = nm_dbus_get_ap_from_object_path (path, dev)))
{
reply_message = nm_dbus_create_error_message (message, NM_DBUS_NM_NAMESPACE, "NetworkNotFound",
"The requested network does not exist for this device.");
#define NM_DBUS_NMI_NAMESPACE "org.freedesktop.NetworkManagerInfo"
-DBusConnection * nm_dbus_init (NMData *data);
+DBusConnection *nm_dbus_init (NMData *data);
-void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevice *dev);
+void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDevice *dev);
-void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev);
+void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev);
-void nm_dbus_signal_device_ip4_address_change(DBusConnection *connection, NMDevice *dev);
+void nm_dbus_signal_device_ip4_address_change(DBusConnection *connection, NMDevice *dev);
-void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, DBusPendingCall **pending);
+void nm_dbus_signal_wireless_network_appeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap);
-void nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection);
+void nm_dbus_signal_wireless_network_disappeared (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap);
-char * nm_dbus_get_allowed_network_essid (DBusConnection *connection, const char *network);
+void nm_dbus_get_user_key_for_network (DBusConnection *connection, NMDevice *dev, NMAccessPoint *ap, DBusPendingCall **pending);
-char * nm_dbus_get_allowed_network_key (DBusConnection *connection, const char *network);
+void nm_dbus_cancel_get_user_key_for_network (DBusConnection *connection);
-guint nm_dbus_get_allowed_network_priority (DBusConnection *connection, const char *network);
+char * nm_dbus_get_allowed_network_essid (DBusConnection *connection, const char *network);
-char ** nm_dbus_get_allowed_networks (DBusConnection *connection, int *num_networks);
+char * nm_dbus_get_allowed_network_key (DBusConnection *connection, const char *network);
+
+guint nm_dbus_get_allowed_network_priority (DBusConnection *connection, const char *network);
+
+char ** nm_dbus_get_allowed_networks (DBusConnection *connection, int *num_networks);
#endif
#include "NetworkManagerDbus.h"
#include "NetworkManagerWireless.h"
#include "NetworkManagerPolicy.h"
-
+#include "NetworkManagerAPList.h"
extern gboolean debug;
*/
void nm_device_ap_list_clear (NMDevice *dev)
{
- GSList *element;
-
g_return_if_fail (dev != NULL);
g_return_if_fail (nm_device_is_wireless (dev));
if (nm_try_acquire_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__))
{
- element = dev->dev_options.wireless.ap_list;
- while (element)
- {
- if (element->data)
- {
- nm_ap_unref (element->data);
- element->data = NULL;
- }
-
- element = g_slist_next (element);
- }
-
- g_slist_free (dev->dev_options.wireless.ap_list);
+ nm_ap_list_free (dev->dev_options.wireless.ap_list);
dev->dev_options.wireless.ap_list = NULL;
nm_unlock_mutex (dev->dev_options.wireless.ap_list_mutex, __FUNCTION__);
}
+/*
+ * nm_device_ap_list_get
+ *
+ * Return a pointer to the AP list
+ *
+ */
+static const GSList *nm_device_ap_list_get (NMDevice *dev)
+{
+ g_return_val_if_fail (dev != NULL, NULL);
+ g_return_val_if_fail (nm_device_is_wireless (dev), NULL);
+
+ return (dev->dev_options.wireless.ap_list);
+}
+
/*
* Get/Set functions for "best" access point
*
int err;
NMAccessPoint *highest_priority_ap = NULL;
int highest_priority = NM_AP_PRIORITY_WORST;
-
- /* Clear out the device's ap list */
- nm_device_ap_list_clear (dev);
+ GSList *old_ap_list = nm_device_ap_list_get (dev);
err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
if ((err == -1) && (errno == ENODATA))
}
}
+ /* Clear out the ap list for this device in preparation for any new ones */
+ dev->dev_options.wireless.ap_list = NULL;
+
/* Iterate over scan results and pick a "most" preferred access point. */
tmp_ap = scan_results.result;
while (tmp_ap)
nm_ap_unref (highest_priority_ap);
}
close (iwlib_socket);
+
+ /* Now do a diff of the old and new networks that we can see, and
+ * signal any changes over dbus.
+ */
+ nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev));
+ nm_ap_list_free (old_ap_list);
}
else
NM_DEBUG_PRINT_1 ("nm_device_do_normal_scan() could not get a control socket for the wireless card %s.\n", nm_device_get_iface (dev) );
*/
enum NMIfaceType
{
- NM_IFACE_TYPE_DONT_KNOW,
+ NM_IFACE_TYPE_DONT_KNOW = 0,
NM_IFACE_TYPE_WIRED_ETHERNET,
NM_IFACE_TYPE_WIRELESS_ETHERNET
};
g_return_val_if_fail (ap != NULL, FALSE);
g_return_val_if_fail (highest_priority != NULL, FALSE);
+ /* If the AP is marked as invalid, of course its not prefered */
+ if (nm_ap_get_invalid (ap))
+ return (FALSE);
+
/* Attempt to acquire mutex for device list iteration.
* If the acquire fails, just ignore the scan completely.
*/
#include <glib.h>
#include <dbus/dbus.h>
+#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <stdio.h>
+#define NMI_DBUS_NMI_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManagerInfo"
+#define NMI_DBUS_NMI_NAMESPACE "org.freedesktop.NetworkManagerInfo"
+#define NM_DBUS_NM_OBJECT_PATH_PREFIX "/org/freedesktop/NetworkManager"
+#define NM_DBUS_NM_NAMESPACE "org.freedesktop.NetworkManager"
+
char * get_network_string_property (DBusConnection *connection, char *network, char *method)
{
DBusMessageIter iter;
DBusError error;
- message = dbus_message_new_method_call ("org.freedesktop.NetworkManagerInfo",
- "/org/freedesktop/NetworkManagerInfo",
- "org.freedesktop.NetworkManagerInfo",
- method);
+ message = dbus_message_new_method_call (NMI_DBUS_NMI_NAMESPACE,
+ NMI_DBUS_NMI_OBJECT_PATH_PREFIX,
+ NMI_DBUS_NMI_NAMESPACE,
+ method);
if (message == NULL)
{
fprintf (stderr, "Couldn't allocate the dbus message\n");
g_return_val_if_fail (connection != NULL, -1);
g_return_val_if_fail (network != NULL, -1);
- message = dbus_message_new_method_call ("org.freedesktop.NetworkManagerInfo",
- "/org/freedesktop/NetworkManagerInfo",
- "org.freedesktop.NetworkManagerInfo",
- "getAllowedNetworkPriority");
+ message = dbus_message_new_method_call (NMI_DBUS_NMI_NAMESPACE,
+ NMI_DBUS_NMI_OBJECT_PATH_PREFIX,
+ NMI_DBUS_NMI_NAMESPACE,
+ "getAllowedNetworkPriority");
if (message == NULL)
{
fprintf (stderr, "Couldn't allocate the dbus message\n");
DBusMessageIter iter;
DBusError error;
- message = dbus_message_new_method_call ("org.freedesktop.NetworkManagerInfo",
- "/org/freedesktop/NetworkManagerInfo",
- "org.freedesktop.NetworkManagerInfo",
- "getAllowedNetworks");
+ message = dbus_message_new_method_call (NMI_DBUS_NMI_NAMESPACE,
+ NMI_DBUS_NMI_OBJECT_PATH_PREFIX,
+ NMI_DBUS_NMI_NAMESPACE,
+ "getAllowedNetworks");
if (message == NULL)
{
fprintf (stderr, "Couldn't allocate the dbus message\n");
dbus_free_string_array (networks);
}
+void get_user_key_for_network (DBusConnection *connection)
+{
+ DBusMessage *message;
+
+ g_return_if_fail (connection != NULL);
+
+ message = dbus_message_new_method_call (NMI_DBUS_NMI_NAMESPACE, NMI_DBUS_NMI_OBJECT_PATH_PREFIX,
+ NMI_DBUS_NMI_NAMESPACE, "getKeyForNetwork");
+ if (message == NULL)
+ {
+ fprintf (stderr, "get_user_key_for_network(): Couldn't allocate the dbus message\n");
+ return;
+ }
+
+ dbus_message_append_args (message, DBUS_TYPE_STRING, "eth1",
+ DBUS_TYPE_STRING, "wireless-ap",
+ DBUS_TYPE_INVALID);
+
+ if (!dbus_connection_send (connection, message, NULL))
+ fprintf (stderr, "get_user_key_for_network(): could not send dbus message\n");
+
+ dbus_message_unref (message);
+}
+
+
+void set_user_key_for_network (DBusConnection *connection, DBusMessage *message, GMainLoop *loop)
+{
+ DBusError error;
+ char *device;
+ char *network;
+ char *passphrase;
+
+ g_return_if_fail (connection != NULL);
+ g_return_if_fail (message != NULL);
+
+ dbus_error_init (&error);
+ if (dbus_message_get_args (message, &error,
+ DBUS_TYPE_STRING, &device,
+ DBUS_TYPE_STRING, &network,
+ DBUS_TYPE_STRING, &passphrase,
+ DBUS_TYPE_INVALID))
+ {
+ fprintf( stderr, "Device was '%s'\nNetwork was '%s'\nPassphrase was '%s'\n", device, network, passphrase);
+
+ dbus_free (device);
+ dbus_free (network);
+ dbus_free (passphrase);
+
+ g_main_loop_quit (loop);
+ }
+}
+
+
+static DBusHandlerResult nm_message_handler (DBusConnection *connection, DBusMessage *message, void *user_data)
+{
+ const char *method;
+ const char *path;
+ DBusMessage *reply_message = NULL;
+ gboolean handled = TRUE;
+
+ g_return_val_if_fail (connection != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+ g_return_val_if_fail (message != NULL, DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+
+ method = dbus_message_get_member (message);
+ path = dbus_message_get_path (message);
+
+ fprintf (stderr, "nm_dbus_nm_message_handler() got method %s for path %s\n", method, path);
+
+ if (strcmp ("setKeyForNetwork", method) == 0)
+ set_user_key_for_network (connection, message, user_data);
+ else
+ handled = FALSE;
+
+ return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
+}
+
+
+/*
+ * nm_dbus_nm_unregister_handler
+ *
+ * Nothing happens here.
+ *
+ */
+void nm_unregister_handler (DBusConnection *connection, void *user_data)
+{
+ /* do nothing */
+}
+
int main( int argc, char *argv[] )
{
- DBusConnection *connection;
- DBusError error;
+ DBusConnection *connection;
+ DBusConnection *connection2;
+ DBusError error;
+ DBusObjectPathVTable vtable = { &nm_unregister_handler, &nm_message_handler, NULL, NULL, NULL, NULL };
+ dbus_bool_t success = FALSE;
+ GMainLoop *loop = NULL;
+
+ loop = g_main_loop_new (NULL, FALSE);
g_type_init ();
+ if (!g_thread_supported ())
+ g_thread_init (NULL);
dbus_error_init (&error);
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
{
fprintf (stderr, "Error connecting to system bus: %s\n", error.message);
dbus_error_free (&error);
- return 1;
+ exit (1);
+ }
+
+ dbus_connection_setup_with_g_main (connection, NULL);
+ dbus_error_init (&error);
+ dbus_bus_acquire_service (connection, NM_DBUS_NM_NAMESPACE, 0, &error);
+ if (dbus_error_is_set (&error))
+ {
+ fprintf (stderr, "Could not acquire its service. dbus_bus_acquire_service() says: '%s'\n", error.message);
+ exit (1);
+ }
+
+ success = dbus_connection_register_object_path (connection, NM_DBUS_NM_OBJECT_PATH_PREFIX, &vtable, loop);
+ if (!success)
+ {
+ fprintf (stderr, "Could not register a handler for NetworkManager. Not enough memory?\n");
+ exit (1);
}
get_allowed_networks (connection);
+ get_user_key_for_network (connection);
+
+ g_main_loop_run (loop);
return 0;
}