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

* src/NetworkManager.c:
		- Set up all the shiny new managers.

	* src/NetworkManagerPolicy.c:
		- Add the beginnings of new NMPolicy code. Instead of requireing all
		  classes to call into policy code, make the policy code kind of like
		  a supervisor that monitors what's going on and drives the whole NM.

	* src/nm-hal-manager.c: 
	* src/nm-hal-manager.h:
		- Collect all libhal code scattered around NM to this one class.
		- Listen libhal and NMManager events and add/remove devices to
		  NMManager.

	* src/nm-manager.c:
	* src/nm-manager.h:
		- Implment a replacement for NMData. NMData is now officially
		deprecated.



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2291 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Tambet Ingo 2007-02-08 15:34:26 +00:00 committed by Tambet Ingo
parent be52910469
commit 371de4c2d0
20 changed files with 1109 additions and 619 deletions

View file

@ -42,6 +42,8 @@ NetworkManager_SOURCES = \
nm-dbus-net.h \
nm-dbus-nmi.c \
nm-dbus-nmi.h \
nm-hal-manager.c \
nm-hal-manager.h \
nm-ip4-config.c \
nm-ip4-config.h \
NetworkManager.c \
@ -54,6 +56,8 @@ NetworkManager_SOURCES = \
NetworkManagerSystem.h \
nm-logging.c \
nm-logging.h \
nm-manager.c \
nm-manager.h \
nm-netlink-monitor.c \
nm-netlink-monitor.h \
nm-activation-request.c \

View file

@ -27,7 +27,6 @@
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <libhal.h>
#include <getopt.h>
#include <errno.h>
#include <stdlib.h>
@ -41,6 +40,8 @@
#include "NetworkManager.h"
#include "nm-utils.h"
#include "NetworkManagerUtils.h"
#include "nm-manager.h"
#include "nm-hal-manager.h"
#include "nm-device.h"
#include "nm-device-802-3-ethernet.h"
#include "nm-device-802-11-wireless.h"
@ -64,329 +65,14 @@
#define NM_DEFAULT_PID_FILE LOCALSTATEDIR"/run/NetworkManager.pid"
#define NO_HAL_MSG "Could not initialize connection to the HAL daemon."
/*
* Globals
*/
static NMData *nm_data = NULL;
static NMManager *manager = NULL;
static gboolean sigterm_pipe_handler (GIOChannel *src, GIOCondition condition, gpointer data);
static void nm_data_free (NMData *data);
static void nm_hal_deinit (NMData *data);
/*
* nm_get_device_interface_from_hal
*
*/
static char *nm_get_device_interface_from_hal (LibHalContext *ctx, const char *udi)
{
char *iface = NULL;
if (libhal_device_property_exists (ctx, udi, "net.interface", NULL))
{
/* Only use Ethernet and Wireless devices at the moment */
if (libhal_device_property_exists (ctx, udi, "info.category", NULL))
{
char *category = libhal_device_get_property_string (ctx, udi, "info.category", NULL);
if (category && (!strcmp (category, "net.80203") || !strcmp (category, "net.80211")))
{
char *temp = libhal_device_get_property_string (ctx, udi, "net.interface", NULL);
iface = g_strdup (temp);
libhal_free_string (temp);
}
libhal_free_string (category);
}
}
return (iface);
}
/*
* nm_device_test_wireless_extensions
*
* Test whether a given device is a wireless one or not.
*
*/
static NMDeviceType
discover_device_type (LibHalContext *ctx, const char *udi)
{
char * category = NULL;
if (libhal_device_property_exists (ctx, udi, "info.category", NULL))
category = libhal_device_get_property_string(ctx, udi, "info.category", NULL);
if (category && (!strcmp (category, "net.80211")))
return DEVICE_TYPE_802_11_WIRELESS;
else if (category && (!strcmp (category, "net.80203")))
return DEVICE_TYPE_802_3_ETHERNET;
return DEVICE_TYPE_UNKNOWN;
}
/*
* nm_get_device_driver_name
*
* Get the device's driver name from HAL.
*
*/
static char *
nm_get_device_driver_name (LibHalContext *ctx, const char *udi)
{
char * driver_name = NULL;
char * physdev_udi = NULL;
g_return_val_if_fail (ctx != NULL, NULL);
g_return_val_if_fail (udi != NULL, NULL);
physdev_udi = libhal_device_get_property_string (ctx, udi, "net.physical_device", NULL);
if (physdev_udi && libhal_device_property_exists (ctx, physdev_udi, "info.linux.driver", NULL))
{
char *drv = libhal_device_get_property_string (ctx, physdev_udi, "info.linux.driver", NULL);
driver_name = g_strdup (drv);
g_free (drv);
}
g_free (physdev_udi);
return driver_name;
}
static NMDevice *
create_nm_device (LibHalContext *ctx,
const char *iface,
const char *udi)
{
NMDevice *dev;
char *driver;
NMDeviceType type;
type = discover_device_type (ctx, udi);
driver = nm_get_device_driver_name (ctx, udi);
switch (type) {
case DEVICE_TYPE_802_11_WIRELESS:
dev = (NMDevice *) nm_device_802_11_wireless_new (iface, udi, driver, FALSE, nm_data);
break;
case DEVICE_TYPE_802_3_ETHERNET:
dev = (NMDevice *) nm_device_802_3_ethernet_new (iface, udi, driver, FALSE, nm_data);
break;
default:
g_assert_not_reached ();
}
g_free (driver);
return dev;
}
/*
* nm_create_device_and_add_to_list
*
* Create a new network device and add it to our device list.
*
* Returns: newly allocated device on success
* NULL on failure
*/
NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, const char *iface,
gboolean test_device, NMDeviceType test_device_type)
{
NMDevice *dev = NULL;
g_return_val_if_fail (data != NULL, NULL);
g_return_val_if_fail (udi != NULL, NULL);
g_return_val_if_fail (iface != NULL, NULL);
g_return_val_if_fail (strlen (iface) > 0, NULL);
/* If we are called to create a test devices, but test devices weren't enabled
* on the command-line, don't create the device.
*/
if (!data->enable_test_devices && test_device)
{
nm_warning ("attempted to create a test device, "
"but test devices were not enabled "
"on the command line.");
return (NULL);
}
/* Make sure the device is not already in the device list */
if ((dev = nm_get_device_by_iface (data, iface)))
return (NULL);
if ((dev = create_nm_device (data->hal_ctx, iface, udi))) {
nm_info ("Now managing %s device '%s'.",
NM_IS_DEVICE_802_11_WIRELESS (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)",
nm_device_get_iface (dev));
data->dev_list = g_slist_append (data->dev_list, dev);
nm_device_deactivate (dev);
nm_policy_schedule_device_change_check (data);
nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_ADDED);
}
return dev;
}
/*
* nm_remove_device
*
* Removes a particular device from the device list.
*/
void nm_remove_device (NMData *data, NMDevice *dev)
{
g_return_if_fail (data != NULL);
g_return_if_fail (dev != NULL);
nm_device_set_removed (dev, TRUE);
nm_device_stop (dev);
nm_dbus_schedule_device_status_change_signal (data, dev, NULL, DEVICE_REMOVED);
g_object_unref (G_OBJECT (dev));
/* Remove the device entry from the device list and free its data */
data->dev_list = g_slist_remove (data->dev_list, dev);
}
/*
* nm_get_active_device
*
* Return the currently active device.
*
*/
NMDevice *nm_get_active_device (NMData *data)
{
GSList * elt;
g_return_val_if_fail (data != NULL, NULL);
for (elt = data->dev_list; elt; elt = g_slist_next (elt)) {
NMDevice * dev = NM_DEVICE (elt->data);
g_assert (dev);
if (nm_device_get_act_request (dev))
return dev;
}
return NULL;
}
/*
* nm_hal_device_added
*
*/
static void nm_hal_device_added (LibHalContext *ctx, const char *udi)
{
NMData *data = (NMData *)libhal_ctx_get_user_data (ctx);
char *iface = NULL;
g_return_if_fail (data != NULL);
nm_debug ("New device added (hal udi is '%s').", udi );
/* Sometimes the device's properties (like net.interface) are not set up yet,
* so this call will fail, and it will actually be added when hal sets the device's
* capabilities a bit later on.
*/
if ((iface = nm_get_device_interface_from_hal (data->hal_ctx, udi)))
{
nm_create_device_and_add_to_list (data, udi, iface, FALSE, DEVICE_TYPE_UNKNOWN);
g_free (iface);
}
}
/*
* nm_hal_device_removed
*
*/
static void nm_hal_device_removed (LibHalContext *ctx, const char *udi)
{
NMData * data;
NMDevice * dev;
data = (NMData *) libhal_ctx_get_user_data (ctx);
g_return_if_fail (data != NULL);
nm_debug ("Device removed (hal udi is '%s').", udi );
if ((dev = nm_get_device_by_udi (data, udi))) {
nm_remove_device (data, dev);
nm_policy_schedule_device_change_check (data);
}
}
/*
* nm_hal_device_new_capability
*
*/
static void nm_hal_device_new_capability (LibHalContext *ctx, const char *udi, const char *capability)
{
NMData *data = (NMData *)libhal_ctx_get_user_data (ctx);
g_return_if_fail (data != NULL);
/*nm_debug ("nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );*/
if (capability && ((strcmp (capability, "net.80203") == 0) || (strcmp (capability, "net.80211") == 0)))
{
char *iface;
if ((iface = nm_get_device_interface_from_hal (data->hal_ctx, udi)))
{
nm_create_device_and_add_to_list (data, udi, iface, FALSE, DEVICE_TYPE_UNKNOWN);
g_free (iface);
}
}
}
/*
* nm_add_initial_devices
*
* Add all devices that hal knows about right now (ie not hotplug devices)
*
*/
void nm_add_initial_devices (NMData *data)
{
char ** net_devices;
int num_net_devices;
int i;
DBusError error;
g_return_if_fail (data != NULL);
dbus_error_init (&error);
/* Grab a list of network devices */
net_devices = libhal_find_device_by_capability (data->hal_ctx, "net", &num_net_devices, &error);
if (dbus_error_is_set (&error))
{
nm_warning ("could not find existing networking devices: %s", error.message);
dbus_error_free (&error);
}
if (net_devices)
{
for (i = 0; i < num_net_devices; i++)
{
char *iface;
if ((iface = nm_get_device_interface_from_hal (data->hal_ctx, net_devices[i])))
{
nm_create_device_and_add_to_list (data, net_devices[i], iface, FALSE, DEVICE_TYPE_UNKNOWN);
g_free (iface);
}
}
}
libhal_free_string_array (net_devices);
}
/*
* nm_state_change_signal_broadcast
@ -394,17 +80,18 @@ void nm_add_initial_devices (NMData *data)
*/
static gboolean nm_state_change_signal_broadcast (gpointer user_data)
{
NMData *data = (NMData *)user_data;
NMDBusManager *dbus_mgr = NULL;
DBusConnection *dbus_connection = NULL;
NMState state;
NMDBusManager *dbus_mgr;
DBusConnection *dbus_connection;
g_return_val_if_fail (data != NULL, FALSE);
state = nm_manager_get_state (manager);
dbus_mgr = nm_dbus_manager_get ();
dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
if (dbus_connection)
nm_dbus_signal_state_change (dbus_connection, data);
nm_dbus_signal_state_change (dbus_connection, state);
g_object_unref (dbus_mgr);
return FALSE;
}
@ -415,16 +102,10 @@ static gboolean nm_state_change_signal_broadcast (gpointer user_data)
*/
void nm_schedule_state_change_signal_broadcast (NMData *data)
{
guint id = 0;
GSource * source;
g_return_if_fail (data != NULL);
id = g_idle_add (nm_state_change_signal_broadcast, data);
source = g_main_context_find_source_by_id (NULL, id);
if (source) {
g_source_set_priority (source, G_PRIORITY_HIGH);
}
g_idle_add_full (G_PRIORITY_HIGH,
nm_state_change_signal_broadcast,
NULL,
NULL);
}
@ -466,88 +147,6 @@ nm_monitor_setup (NMData *data)
return monitor;
}
static gboolean
nm_hal_init (NMData *data,
DBusConnection *connection)
{
gboolean success = FALSE;
DBusError error;
g_return_val_if_fail (data != NULL, FALSE);
g_return_val_if_fail (connection != NULL, FALSE);
/* Clean up an old context */
if (data->hal_ctx) {
nm_warning ("a HAL context already existed. BUG.");
nm_hal_deinit (data);
}
/* Initialize a new libhal context */
if (!(data->hal_ctx = libhal_ctx_new ())) {
nm_warning ("Could not get connection to the HAL service.");
goto out;
}
libhal_ctx_set_dbus_connection (data->hal_ctx, connection);
dbus_error_init (&error);
if (!libhal_ctx_init (data->hal_ctx, &error)) {
nm_error ("libhal_ctx_init() failed: %s\n"
"Make sure the hal daemon is running?",
error.message);
goto out;
}
libhal_ctx_set_user_data (data->hal_ctx, data);
libhal_ctx_set_device_added (data->hal_ctx, nm_hal_device_added);
libhal_ctx_set_device_removed (data->hal_ctx, nm_hal_device_removed);
libhal_ctx_set_device_new_capability (data->hal_ctx, nm_hal_device_new_capability);
libhal_device_property_watch_all (data->hal_ctx, &error);
if (dbus_error_is_set (&error)) {
nm_error ("libhal_device_property_watch_all(): %s", error.message);
libhal_ctx_shutdown (data->hal_ctx, NULL);
goto out;
}
/* Add any devices we know about */
nm_add_initial_devices (data);
success = TRUE;
out:
if (!success) {
if (dbus_error_is_set (&error))
dbus_error_free (&error);
if (data->hal_ctx) {
libhal_ctx_free (data->hal_ctx);
data->hal_ctx = NULL;
}
}
return success;
}
static void
nm_hal_deinit (NMData *data)
{
DBusError error;
g_return_if_fail (data != NULL);
if (!data->hal_ctx)
return;
dbus_error_init (&error);
libhal_ctx_shutdown (data->hal_ctx, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("libhal shutdown failed - %s", error.message);
dbus_error_free (&error);
}
libhal_ctx_free (data->hal_ctx);
data->hal_ctx = NULL;
}
/*
* nm_data_new
*
@ -601,16 +200,6 @@ static NMData *nm_data_new (gboolean enable_test_devices)
}
static void device_stop_and_free (NMDevice *dev, gpointer user_data)
{
g_return_if_fail (dev != NULL);
nm_device_set_removed (dev, TRUE);
nm_device_deactivate (dev);
g_object_unref (G_OBJECT (dev));
}
/*
* nm_data_free
*
@ -627,10 +216,6 @@ static void nm_data_free (NMData *data)
if ((req = nm_vpn_manager_get_vpn_act_request (data->vpn_manager)))
nm_vpn_manager_deactivate_vpn_connection (data->vpn_manager, nm_vpn_act_request_get_parent_dev (req));
/* Stop and destroy all devices */
g_slist_foreach (data->dev_list, (GFunc) device_stop_and_free, NULL);
g_slist_free (data->dev_list);
if (data->netlink_monitor) {
g_object_unref (G_OBJECT (data->netlink_monitor));
data->netlink_monitor = NULL;
@ -648,8 +233,6 @@ static void nm_data_free (NMData *data)
g_main_loop_unref (data->main_loop);
g_io_channel_unref(data->sigterm_iochannel);
nm_hal_deinit (data);
g_slice_free (NMData, data);
}
@ -679,19 +262,7 @@ nm_name_owner_changed_handler (NMDBusManager *mgr,
gboolean old_owner_good = (old && (strlen (old) > 0));
gboolean new_owner_good = (new && (strlen (new) > 0));
/* Only care about signals from HAL */
if (strcmp (name, "org.freedesktop.Hal") == 0) {
if (!old_owner_good && new_owner_good) {
/* HAL just appeared */
if (!nm_hal_init (data, connection)) {
nm_error (NO_HAL_MSG);
exit (EXIT_FAILURE);
}
} else if (old_owner_good && !new_owner_good) {
/* HAL went away. Bad HAL. */
nm_hal_deinit (data);
}
} else if (strcmp (name, NMI_DBUS_SERVICE) == 0) {
if (strcmp (name, NMI_DBUS_SERVICE) == 0) {
if (!old_owner_good && new_owner_good) {
/* NMI appeared, update stuff */
nm_policy_schedule_allowed_ap_list_update (data);
@ -702,28 +273,6 @@ nm_name_owner_changed_handler (NMDBusManager *mgr,
}
}
static void
nm_dbus_connection_changed_handler (NMDBusManager *mgr,
DBusConnection *connection,
gpointer user_data)
{
NMData *data = (NMData *) user_data;
char * owner;
if (!connection) {
nm_hal_deinit (data);
return;
}
if ((owner = nm_dbus_manager_get_name_owner (mgr, "org.freedesktop.Hal"))) {
if (!nm_hal_init (data, connection)) {
nm_error (NO_HAL_MSG);
exit (EXIT_FAILURE);
}
g_free (owner);
}
}
static void
write_pidfile (const char *pidfile)
{
@ -774,6 +323,8 @@ main (int argc, char *argv[])
gboolean show_usage = FALSE;
char * pidfile = NULL;
char * user_pidfile = NULL;
NMPolicy *policy;
NMHalManager *hal_manager = NULL;
NMDBusManager * dbus_mgr;
DBusConnection *dbus_connection;
NMSupplicantManager * sup_mgr = NULL;
@ -864,8 +415,6 @@ main (int argc, char *argv[])
}
g_signal_connect (G_OBJECT (dbus_mgr), "name-owner-changed",
G_CALLBACK (nm_name_owner_changed_handler), nm_data);
g_signal_connect (G_OBJECT (dbus_mgr), "dbus-connection-changed",
G_CALLBACK (nm_dbus_connection_changed_handler), nm_data);
id = nm_dbus_manager_register_signal_handler (dbus_mgr,
NMI_DBUS_INTERFACE,
NULL,
@ -880,6 +429,9 @@ main (int argc, char *argv[])
nm_dbus_manager_register_method_list (dbus_mgr, nm_data->device_methods);
nm_data->net_methods = nm_dbus_net_methods_setup (nm_data);
manager = nm_manager_new ();
policy = nm_policy_new (manager);
/* Initialize the supplicant manager */
sup_mgr = nm_supplicant_manager_get ();
if (!sup_mgr) {
@ -887,7 +439,7 @@ main (int argc, char *argv[])
goto done;
}
nm_data->vpn_manager = nm_vpn_manager_new (nm_data);
nm_data->vpn_manager = nm_vpn_manager_new (manager, nm_data);
if (!nm_data->vpn_manager) {
nm_warning ("Failed to start the VPN manager.");
goto done;
@ -905,13 +457,9 @@ main (int argc, char *argv[])
goto done;
}
/* If Hal is around, grab a device list from it */
if (nm_dbus_manager_name_has_owner (dbus_mgr, "org.freedesktop.Hal")) {
if (!nm_hal_init (nm_data, dbus_connection)) {
nm_error (NO_HAL_MSG);
goto done;
}
}
hal_manager = nm_hal_manager_new (manager, nm_data);
if (!hal_manager)
goto done;
/* If NMI is running, grab allowed wireless network lists from it ASAP */
if (nm_dbus_manager_name_has_owner (dbus_mgr, NMI_DBUS_SERVICE)) {
@ -941,6 +489,12 @@ done:
nm_dbus_manager_remove_signal_handler (dbus_mgr, nm_data->nmi_sig_handler_id);
nm_hal_manager_destroy (hal_manager);
nm_policy_destroy (policy);
if (manager)
g_object_unref (manager);
nm_data_free (nm_data);
if (sup_mgr)

View file

@ -304,45 +304,17 @@ void nm_dbus_schedule_device_status_change_signal (NMData *data, NMDevice *dev,
}
/*
* nm_get_app_state_from_data
*
* Return the state of the network connection
*
*/
NMState nm_get_app_state_from_data (NMData *data)
{
NMDevice * act_dev = NULL;
g_return_val_if_fail (data != NULL, NM_STATE_DISCONNECTED);
if (data->asleep == TRUE)
return NM_STATE_ASLEEP;
act_dev = nm_get_active_device (data);
if (!act_dev && !data->modem_active)
return NM_STATE_DISCONNECTED;
if (nm_device_is_activating (act_dev))
return NM_STATE_CONNECTING;
else
return NM_STATE_CONNECTED;
}
/*
* nm_dbus_signal_state_change
*
* Signal a change in state
*
*/
void nm_dbus_signal_state_change (DBusConnection *connection, NMData *data)
void nm_dbus_signal_state_change (DBusConnection *connection, NMState state)
{
DBusMessage * message;
NMState state;
g_return_if_fail (connection != NULL);
g_return_if_fail (data != NULL);
if (!(message = dbus_message_new_signal (NM_DBUS_PATH, NM_DBUS_INTERFACE, NM_DBUS_SIGNAL_STATE_CHANGE)))
{
@ -350,7 +322,6 @@ void nm_dbus_signal_state_change (DBusConnection *connection, NMData *data)
return;
}
state = nm_get_app_state_from_data (data);
dbus_message_append_args (message, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID);
if (!dbus_connection_send (connection, message, NULL))
nm_warning ("nm_dbus_signal_state_change(): Could not raise the signal!");

View file

@ -59,15 +59,13 @@ char * nm_dbus_get_object_path_for_network (NMDevice *dev, NMAccessPoint *ap);
void nm_dbus_schedule_device_status_change_signal (NMData *data, NMDevice *dev, NMAccessPoint *ap, DeviceStatus status);
void nm_dbus_signal_state_change (DBusConnection *connection, NMData *data);
void nm_dbus_signal_state_change (DBusConnection *connection, NMState state);
void nm_dbus_signal_wireless_network_change (NMDevice80211Wireless *dev, NMAccessPoint *ap, NMNetworkStatus status, gint strength);
void nm_dbus_signal_device_strength_change (NMDevice80211Wireless *dev, gint strength);
NMDevice * nm_dbus_get_device_from_escaped_object_path (NMData *data, const char *path);
NMState nm_get_app_state_from_data (NMData *data);
DBusMessage * nm_dbus_create_error_message (DBusMessage *message, const char *exception_namespace, const char *exception, const char *format, ...);
DBusMessage * nm_dbus_new_invalid_args_error (DBusMessage *replyto, const char *namespace);

View file

@ -25,7 +25,6 @@
#include <glib.h>
#include <glib/gthread.h>
#include <dbus/dbus.h>
#include <libhal.h>
#include "NetworkManager.h"
#include "NetworkManagerAP.h"
#include "nm-netlink-monitor.h"
@ -34,18 +33,6 @@
#include "NetworkManagerDbusUtils.h"
typedef enum NMIntState
{
NM_INT_STATE_UNKNOWN = 0,
NM_INT_STATE_ASLEEP,
NM_INT_STATE_CONFIGURE_AP,
NM_INT_STATE_CONFIGURE_DEV,
NM_INT_STATE_CONFIGURE_IP,
NM_INT_STATE_CONNECTED,
NM_INT_STATE_DISCONNECTED
} NMIntState;
typedef struct NMActRequest NMActRequest;
typedef struct NMVPNActRequest NMVPNActRequest;
typedef struct NMVPNManager NMVPNManager;
@ -55,8 +42,6 @@ typedef struct NMData
GIOChannel * sigterm_iochannel;
int sigterm_pipe[2];
LibHalContext * hal_ctx;
NmNetlinkMonitor * netlink_monitor;
NMNamedManager * named_manager;
@ -85,15 +70,6 @@ typedef struct NMData
} NMData;
NMDevice * nm_get_active_device (NMData *data);
NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, const char *iface,
gboolean test_device, NMDeviceType test_device_type);
void nm_add_initial_devices (NMData *data);
void nm_remove_device (NMData *data, NMDevice *dev);
void nm_schedule_state_change_signal_broadcast (NMData *data);
int nm_get_sigterm_pipe (void);

View file

@ -40,6 +40,20 @@
#include "nm-device-802-3-ethernet.h"
#include "nm-dbus-manager.h"
struct NMPolicy {
NMManager *manager;
guint device_state_changed_idle_id;
};
/* NMPolicy is supposed to be one of the highest classes of the
NM class hierarchy and the only public API it needs is:
NMPolicy *nm_policy_new (NMManager *manager);
void nm_policy_destroy (NMPolicy *policy);
Until this hasn't fixed, keep the global policy around.
*/
static NMPolicy *global_policy;
/*
* nm_policy_activation_finish
@ -286,15 +300,16 @@ nm_policy_device_change_check (gpointer user_data)
{
NMData * data = (NMData *) user_data;
NMAccessPoint * ap = NULL;
NMDevice * new_dev = NULL;
NMDevice * old_dev = NULL;
NMDevice * new_dev;
NMDevice * old_dev;
gboolean do_switch = FALSE;
g_return_val_if_fail (data != NULL, FALSE);
data->dev_change_check_idle_id = 0;
old_dev = nm_get_active_device (data);
g_assert (global_policy != NULL);
old_dev = nm_manager_get_active_device (global_policy->manager);
if (old_dev) {
guint32 caps = nm_device_get_capabilities (old_dev);
@ -455,16 +470,13 @@ static gboolean
nm_policy_device_activation (gpointer user_data)
{
NMActRequest * req = (NMActRequest *) user_data;
NMData * data;
NMDevice * new_dev = NULL;
NMDevice * old_dev = NULL;
NMDevice * new_dev;
NMDevice * old_dev;
g_return_val_if_fail (req != NULL, FALSE);
data = nm_act_request_get_data (req);
g_assert (data);
if ((old_dev = nm_get_active_device (data)))
g_assert (global_policy != NULL);
if ((old_dev = nm_manager_get_active_device (global_policy->manager)))
nm_device_deactivate (old_dev);
new_dev = nm_act_request_get_dev (req);
@ -634,3 +646,136 @@ nm_policy_schedule_device_ap_lists_update_from_allowed (NMData *app_data)
g_source_set_priority (source, G_PRIORITY_HIGH_IDLE);
}
}
/*****************************************************************************/
static void
device_change_check_done (gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
policy->device_state_changed_idle_id = 0;
}
static void
schedule_change_check (NMPolicy *policy)
{
if (policy->device_state_changed_idle_id > 0)
return;
/* FIXME: Uncomment this when nm_policy_schedule_device_change_check and
all it's callers have been removed. */
#if 0
policy->device_state_changed_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
nm_policy_device_change_check,
policy,
device_change_check_done);
#endif
}
static void
device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
if (state == NM_DEVICE_STATE_FAILED || state == NM_DEVICE_STATE_CANCELLED)
schedule_change_check (policy);
}
static void
device_carrier_changed (NMDevice *device, gboolean carrier_on, gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
schedule_change_check (policy);
}
static void
device_added (NMManager *manager, NMDevice *device, gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
g_signal_connect (device, "state-changed",
G_CALLBACK (device_state_changed),
policy);
g_signal_connect (device, "carrier-changed",
G_CALLBACK (device_carrier_changed),
policy);
/* FIXME: */
{
NMData *nm_data = nm_device_get_app_data (device);
nm_data->dev_list = g_slist_append (nm_data->dev_list, device);
}
/* FIXME: Uncomment once the patch to add these signals to wireless devices is committed */
#if 0
if (NM_IS_DEVICE_802_11_WIRELESS (device)) {
g_signal_connect (device, "network-added",
G_CALLBACK (wireless_networks_changed),
policy);
g_signal_connect (device, "network-removed",
G_CALLBACK (wireless_networks_changed),
policy);
}
#endif
schedule_change_check (policy);
}
static void
device_removed (NMManager *manager, NMDevice *device, gpointer user_data)
{
NMPolicy *policy = (NMPolicy *) user_data;
/* FIXME: */
{
NMData *nm_data = nm_device_get_app_data (device);
nm_data->dev_list = g_slist_remove (nm_data->dev_list, device);
}
schedule_change_check (policy);
}
static void
state_changed (NMManager *manager, NMState state, gpointer user_data)
{
/* FIXME: Do cool stuff here */
}
NMPolicy *
nm_policy_new (NMManager *manager)
{
NMPolicy *policy;
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
g_assert (global_policy == NULL);
policy = g_slice_new (NMPolicy);
policy->manager = g_object_ref (manager);
g_signal_connect (manager, "device-added",
G_CALLBACK (device_added), policy);
g_signal_connect (manager, "device-removed",
G_CALLBACK (device_removed), policy);
g_signal_connect (manager, "state-change",
G_CALLBACK (state_changed), policy);
global_policy = policy;
return policy;
}
void
nm_policy_destroy (NMPolicy *policy)
{
if (policy) {
g_object_unref (policy->manager);
g_slice_free (NMPolicy, policy);
}
global_policy = NULL;
}

View file

@ -23,10 +23,17 @@
#define NETWORK_MANAGER_POLICY_H
#include "NetworkManager.h"
#include "nm-manager.h"
#include "nm-device.h"
#include "NetworkManagerDbus.h"
#include "nm-activation-request.h"
typedef struct NMPolicy NMPolicy;
NMPolicy *nm_policy_new (NMManager *manager);
void nm_policy_destroy (NMPolicy *policy);
void nm_policy_schedule_device_change_check (NMData *data);
void nm_policy_schedule_device_activation (NMActRequest *req);

View file

@ -419,7 +419,7 @@ out:
return reply;
}
#if 0
static DBusMessage *
nm_dbus_nm_create_test_device (DBusConnection *connection,
DBusMessage *message,
@ -521,6 +521,7 @@ out:
g_object_unref (G_OBJECT (dev));
return reply;
}
#endif
static DBusMessage *
nm_dbus_nm_set_wireless_enabled (DBusConnection *connection,
@ -606,7 +607,7 @@ nm_dbus_nm_sleep (DBusConnection *connection,
/* Not using nm_schedule_state_change_signal_broadcast() here
* because we want the signal to go out ASAP.
*/
nm_dbus_signal_state_change (connection, data);
nm_dbus_signal_state_change (connection, NM_STATE_ASLEEP);
/* Just deactivate and down all devices from the device list,
* we'll remove them in 'wake' for speed's sake.
@ -642,12 +643,15 @@ nm_dbus_nm_wake (DBusConnection *connection,
data->asleep = FALSE;
/* Remove all devices from the device list */
/* FIXME: Well, not really. This whole file will be gone soon. */
#if 0
while (g_slist_length (data->dev_list))
nm_remove_device (data, NM_DEVICE (data->dev_list->data));
g_slist_free (data->dev_list);
data->dev_list = NULL;
nm_add_initial_devices (data);
#endif
nm_schedule_state_change_signal_broadcast (data);
nm_policy_schedule_device_change_check (data);
@ -655,6 +659,8 @@ nm_dbus_nm_wake (DBusConnection *connection,
return NULL;
}
static DBusMessage *
nm_dbus_nm_get_state (DBusConnection *connection,
DBusMessage *message,
@ -673,7 +679,8 @@ nm_dbus_nm_get_state (DBusConnection *connection,
goto out;
}
state = nm_get_app_state_from_data (data);
/* FIXME: This function is deprecated and doesn't work anymore */
state = NM_STATE_UNKNOWN;
dbus_message_append_args (reply, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID);
out:
@ -706,8 +713,10 @@ NMDbusMethodList *nm_dbus_nm_methods_setup (NMData *data)
nm_dbus_method_list_add_method (list, "sleep", nm_dbus_nm_sleep);
nm_dbus_method_list_add_method (list, "wake", nm_dbus_nm_wake);
nm_dbus_method_list_add_method (list, "state", nm_dbus_nm_get_state);
#if 0
nm_dbus_method_list_add_method (list, "createTestDevice", nm_dbus_nm_create_test_device);
nm_dbus_method_list_add_method (list, "removeTestDevice", nm_dbus_nm_remove_test_device);
#endif
return list;
}

View file

@ -42,6 +42,14 @@ G_BEGIN_DECLS
#define NM_IS_DEVICE_802_11_WIRELESS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_DEVICE_802_11_WIRELESS))
#define NM_DEVICE_802_11_WIRELESS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_802_11_WIRELESS, NMDevice80211WirelessClass))
typedef enum NMWirelessScanInterval
{
NM_WIRELESS_SCAN_INTERVAL_INIT = 0,
NM_WIRELESS_SCAN_INTERVAL_ACTIVE,
NM_WIRELESS_SCAN_INTERVAL_INACTIVE
} NMWirelessScanInterval;
#ifndef NM_DEVICE_802_11_WIRELESS_DEFINED
#define NM_DEVICE_802_11_WIRELESS_DEFINED
typedef struct _NMDevice80211Wireless NMDevice80211Wireless;

View file

@ -284,24 +284,11 @@ real_get_generic_capabilities (NMDevice *dev)
{
NMDevice8023Ethernet * self = NM_DEVICE_802_3_ETHERNET (dev);
guint32 caps = NM_DEVICE_CAP_NONE;
const char * udi = NULL;
char * usb_test = NULL;
NMData * app_data;
/* cipsec devices are also explicitly unsupported at this time */
if (strstr (nm_device_get_iface (dev), "cipsec"))
return NM_DEVICE_CAP_NONE;
/* Ignore Ethernet-over-USB devices too for the moment (Red Hat #135722) */
app_data = nm_device_get_app_data (dev);
udi = nm_device_get_udi (dev);
if ( libhal_device_property_exists (app_data->hal_ctx, udi, "usb.interface.class", NULL)
&& (usb_test = libhal_device_get_property_string (app_data->hal_ctx, udi, "usb.interface.class", NULL)))
{
libhal_free_string (usb_test);
return NM_DEVICE_CAP_NONE;
}
if (supports_ethtool_carrier_detect (self) || supports_mii_carrier_detect (self))
caps |= NM_DEVICE_CAP_CARRIER_DETECT;

View file

@ -83,7 +83,7 @@ nm_device_interface_init (gpointer g_iface)
G_PARAM_READABLE));
/* Signals */
g_signal_new ("state_changed",
g_signal_new ("state-changed",
iface_type,
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMDeviceInterface, state_changed),
@ -92,7 +92,7 @@ nm_device_interface_init (gpointer g_iface)
G_TYPE_NONE, 1,
G_TYPE_UINT);
g_signal_new ("carrier_changed",
g_signal_new ("carrier-changed",
iface_type,
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMDeviceInterface, carrier_changed),

View file

@ -6,7 +6,7 @@
#include "NetworkManager.h"
#define NM_TYPE_DEVICE_INTERFACE (nm_device_interface_get_type ())
#define NM_DEVICE_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_INTERFACE, NmDeviceInterface))
#define NM_DEVICE_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_INTERFACE, NMDeviceInterface))
#define NM_IS_DEVICE_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_INTERFACE))
#define NM_DEVICE_INTERFACE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_DEVICE_INTERFACE, NMDeviceInterface))

View file

@ -419,55 +419,15 @@ void
nm_device_set_active_link (NMDevice *self,
const gboolean link_active)
{
NMData * app_data;
NMActRequest * req;
NMDevicePrivate *priv;
g_return_if_fail (self != NULL);
g_return_if_fail (self->priv->app_data != NULL);
g_return_if_fail (NM_IS_DEVICE (self));
app_data = self->priv->app_data;
req = nm_device_get_act_request (self);
if (self->priv->link_active == link_active)
return;
self->priv->link_active = link_active;
/* Deactivate a currently active device */
if (!link_active && req) {
nm_policy_schedule_device_change_check (app_data);
} else if (link_active && !req) {
NMDevice * act_dev = nm_get_active_device (app_data);
NMActRequest * act_dev_req = act_dev ? nm_device_get_act_request (act_dev) : NULL;
/* Should we switch to this device now that it has a link?
*
* Only auto-switch for wired devices, AND...
*
* only switch to fully-supported devices, since ones that don't have carrier detection
* capability usually report the carrier as "always on" even if its not really on. User
* must manually choose semi-supported devices.
*
*/
if (NM_IS_DEVICE_802_3_ETHERNET (self) && (nm_device_get_capabilities (self) & NM_DEVICE_CAP_CARRIER_DETECT))
{
gboolean do_switch = act_dev ? FALSE : TRUE; /* If no currently active device, switch to this one */
NMActRequest * act_req;
/* If active device is wireless, switch to this one */
if (act_dev && NM_IS_DEVICE_802_11_WIRELESS (act_dev) && act_dev_req && !nm_act_request_get_user_requested (act_dev_req))
do_switch = TRUE;
if (do_switch && (act_req = nm_act_request_new (app_data, self, NULL, TRUE)))
{
nm_info ("Will activate wired connection '%s' because it now has a link.", nm_device_get_iface (self));
nm_policy_schedule_device_change_check (app_data);
}
}
priv = NM_DEVICE_GET_PRIVATE (self);
if (priv->link_active != link_active) {
priv->link_active = link_active;
g_signal_emit_by_name (self, "carrier-changed", link_active);
}
g_signal_emit_by_name (self, "carrier_changed", link_active);
nm_dbus_schedule_device_status_change_signal (app_data, self, NULL, link_active ? DEVICE_CARRIER_ON : DEVICE_CARRIER_OFF);
}
@ -1862,7 +1822,7 @@ nm_device_state_changed (NMDevice *device, NMDeviceState state)
break;
}
g_signal_emit_by_name (device, "state_changed", state);
g_signal_emit_by_name (device, "state-changed", state);
}

View file

@ -42,13 +42,6 @@
# define nm_ioctl_info(fmt, args...) do { } while(0)
#endif
typedef enum NMWirelessScanInterval
{
NM_WIRELESS_SCAN_INTERVAL_INIT = 0,
NM_WIRELESS_SCAN_INTERVAL_ACTIVE,
NM_WIRELESS_SCAN_INTERVAL_INACTIVE
} NMWirelessScanInterval;
typedef enum NMActStageReturn
{
NM_ACT_STAGE_RETURN_FAILURE = 0,

396
src/nm-hal-manager.c Normal file
View file

@ -0,0 +1,396 @@
#include <string.h>
#include <stdlib.h>
#include <libhal.h>
#include "nm-hal-manager.h"
#include "nm-dbus-manager.h"
#include "nm-utils.h"
#include "nm-device-802-11-wireless.h"
#include "nm-device-802-3-ethernet.h"
struct _NMHalManager {
LibHalContext *hal_ctx;
NMDBusManager *dbus_mgr;
NMManager *nm_manager;
NMData *nm_data;
gboolean nm_sleeping;
};
static char *
get_device_interface_from_hal (LibHalContext *ctx, const char *udi)
{
char *iface = NULL;
if (libhal_device_property_exists (ctx, udi, "net.interface", NULL)) {
/* Only use Ethernet and Wireless devices at the moment */
if (libhal_device_property_exists (ctx, udi, "info.category", NULL)) {
char *category = libhal_device_get_property_string (ctx, udi, "info.category", NULL);
if (category && (!strcmp (category, "net.80203") || !strcmp (category, "net.80211"))) {
char *temp = libhal_device_get_property_string (ctx, udi, "net.interface", NULL);
iface = g_strdup (temp);
libhal_free_string (temp);
}
libhal_free_string (category);
}
}
return iface;
}
static NMDeviceType
discover_device_type (LibHalContext *ctx, const char *udi)
{
char *category = NULL;
if (libhal_device_property_exists (ctx, udi, "info.category", NULL))
category = libhal_device_get_property_string (ctx, udi, "info.category", NULL);
if (category && (!strcmp (category, "net.80211")))
return DEVICE_TYPE_802_11_WIRELESS;
else if (category && (!strcmp (category, "net.80203")))
return DEVICE_TYPE_802_3_ETHERNET;
return DEVICE_TYPE_UNKNOWN;
}
/*
* nm_get_device_driver_name
*
* Get the device's driver name from HAL.
*
*/
static char *
nm_get_device_driver_name (LibHalContext *ctx, const char *udi)
{
char *physdev_udi;
char *driver_name = NULL;
physdev_udi = libhal_device_get_property_string (ctx, udi, "net.physical_device", NULL);
if (physdev_udi && libhal_device_property_exists (ctx, physdev_udi, "info.linux.driver", NULL)) {
char *drv = libhal_device_get_property_string (ctx, physdev_udi, "info.linux.driver", NULL);
driver_name = g_strdup (drv);
g_free (drv);
}
libhal_free_string (physdev_udi);
return driver_name;
}
static NMDevice *
create_nm_device (LibHalContext *ctx,
NMData *nm_data,
const char *iface,
const char *udi)
{
NMDevice *dev;
char *driver;
NMDeviceType type;
type = discover_device_type (ctx, udi);
driver = nm_get_device_driver_name (ctx, udi);
switch (type) {
case DEVICE_TYPE_802_11_WIRELESS:
dev = (NMDevice *) nm_device_802_11_wireless_new (iface, udi, driver, FALSE, nm_data);
break;
case DEVICE_TYPE_802_3_ETHERNET:
dev = (NMDevice *) nm_device_802_3_ethernet_new (iface, udi, driver, FALSE, nm_data);
break;
default:
g_assert_not_reached ();
}
g_free (driver);
return dev;
}
static NMDevice *
create_device_and_add_to_list (NMHalManager *manager, const char *udi, const char *iface,
gboolean test_device, NMDeviceType test_device_type)
{
NMDevice *dev = NULL;
char *usb_test = NULL;
/* Make sure the device is not already in the device list */
if ((dev = nm_manager_get_device_by_iface (manager->nm_manager, iface)))
return NULL;
/* Ignore Ethernet-over-USB devices too for the moment (Red Hat #135722) */
if (libhal_device_property_exists (manager->hal_ctx, udi, "usb.interface.class", NULL)
&& (usb_test = libhal_device_get_property_string (manager->hal_ctx, udi, "usb.interface.class", NULL))) {
libhal_free_string (usb_test);
return NULL;
}
if ((dev = create_nm_device (manager->hal_ctx, manager->nm_data, iface, udi))) {
nm_info ("Now managing %s device '%s'.",
NM_IS_DEVICE_802_11_WIRELESS (dev) ? "wireless (802.11)" : "wired Ethernet (802.3)",
nm_device_get_iface (dev));
nm_manager_add_device (manager->nm_manager, dev);
}
return dev;
}
static void
device_added (LibHalContext *ctx, const char *udi)
{
NMHalManager *manager = (NMHalManager *) libhal_ctx_get_user_data (ctx);
char *iface;
nm_debug ("New device added (hal udi is '%s').", udi );
/* Sometimes the device's properties (like net.interface) are not set up yet,
* so this call will fail, and it will actually be added when hal sets the device's
* capabilities a bit later on.
*/
if ((iface = get_device_interface_from_hal (manager->hal_ctx, udi))) {
create_device_and_add_to_list (manager, udi, iface, FALSE, DEVICE_TYPE_UNKNOWN);
g_free (iface);
}
}
static void
device_removed (LibHalContext *ctx, const char *udi)
{
NMHalManager *manager = (NMHalManager *) libhal_ctx_get_user_data (ctx);
NMDevice *dev;
nm_debug ("Device removed (hal udi is '%s').", udi );
if ((dev = nm_manager_get_device_by_udi (manager->nm_manager, udi)))
nm_manager_remove_device (manager->nm_manager, dev);
}
static void
device_new_capability (LibHalContext *ctx, const char *udi, const char *capability)
{
NMHalManager *manager = (NMHalManager *) libhal_ctx_get_user_data (ctx);
/*nm_debug ("nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );*/
if (capability && ((strcmp (capability, "net.80203") == 0) || (strcmp (capability, "net.80211") == 0))) {
char *iface;
if ((iface = get_device_interface_from_hal (manager->hal_ctx, udi))) {
create_device_and_add_to_list (manager, udi, iface, FALSE, DEVICE_TYPE_UNKNOWN);
g_free (iface);
}
}
}
static void
add_initial_devices (NMHalManager *manager)
{
char **net_devices;
int num_net_devices;
int i;
DBusError error;
dbus_error_init (&error);
/* Grab a list of network devices */
net_devices = libhal_find_device_by_capability (manager->hal_ctx, "net", &num_net_devices, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("could not find existing networking devices: %s", error.message);
dbus_error_free (&error);
}
if (net_devices) {
for (i = 0; i < num_net_devices; i++) {
char *iface;
if ((iface = get_device_interface_from_hal (manager->hal_ctx, net_devices[i]))) {
create_device_and_add_to_list (manager, net_devices[i], iface, FALSE, DEVICE_TYPE_UNKNOWN);
g_free (iface);
}
}
}
libhal_free_string_array (net_devices);
}
static gboolean
hal_init (NMHalManager *manager)
{
DBusError error;
DBusGConnection *connection;
gboolean success = FALSE;
manager->hal_ctx = libhal_ctx_new ();
if (!manager->hal_ctx) {
nm_warning ("Could not get connection to the HAL service.");
return FALSE;
}
connection = nm_dbus_manager_get_connection (manager->dbus_mgr);
libhal_ctx_set_dbus_connection (manager->hal_ctx,
dbus_g_connection_get_connection (connection));
dbus_error_init (&error);
if (!libhal_ctx_init (manager->hal_ctx, &error)) {
nm_error ("libhal_ctx_init() failed: %s\n"
"Make sure the hal daemon is running?",
error.message);
goto out;
}
libhal_ctx_set_user_data (manager->hal_ctx, manager);
libhal_ctx_set_device_added (manager->hal_ctx, device_added);
libhal_ctx_set_device_removed (manager->hal_ctx, device_removed);
libhal_ctx_set_device_new_capability (manager->hal_ctx, device_new_capability);
libhal_device_property_watch_all (manager->hal_ctx, &error);
if (dbus_error_is_set (&error)) {
nm_error ("libhal_device_property_watch_all(): %s", error.message);
libhal_ctx_shutdown (manager->hal_ctx, NULL);
goto out;
}
/* Add any devices we know about */
add_initial_devices (manager);
success = TRUE;
out:
if (!success) {
if (dbus_error_is_set (&error))
dbus_error_free (&error);
if (manager->hal_ctx) {
libhal_ctx_free (manager->hal_ctx);
manager->hal_ctx = NULL;
}
}
return success;
}
static void
hal_deinit (NMHalManager *manager)
{
DBusError error;
if (!manager->hal_ctx)
return;
dbus_error_init (&error);
libhal_ctx_shutdown (manager->hal_ctx, &error);
if (dbus_error_is_set (&error)) {
nm_warning ("libhal shutdown failed - %s", error.message);
dbus_error_free (&error);
}
libhal_ctx_free (manager->hal_ctx);
manager->hal_ctx = NULL;
}
static void
name_owner_changed (NMDBusManager *dbus_mgr,
DBusGConnection *connection,
const char *name,
const char *old,
const char *new,
gpointer user_data)
{
NMHalManager *manager = (NMHalManager *) user_data;
gboolean old_owner_good = (old && (strlen (old) > 0));
gboolean new_owner_good = (new && (strlen (new) > 0));
/* Only care about signals from HAL */
if (strcmp (name, "org.freedesktop.Hal"))
return;
if (!old_owner_good && new_owner_good) {
/* HAL just appeared */
if (!hal_init (manager))
exit (EXIT_FAILURE);
} else if (old_owner_good && !new_owner_good) {
/* HAL went away. Bad HAL. */
hal_deinit (manager);
}
}
static void
connection_changed (NMDBusManager *dbus_mgr,
DBusGConnection *connection,
gpointer user_data)
{
NMHalManager *manager = (NMHalManager *) user_data;
char *owner;
if (!connection) {
hal_deinit (manager);
return;
}
if ((owner = nm_dbus_manager_get_name_owner (dbus_mgr, "org.freedesktop.Hal"))) {
if (!hal_init (manager))
exit (EXIT_FAILURE);
g_free (owner);
}
}
static void
nm_manager_state_changed (NMManager *nm_manager, NMState state, gpointer user_data)
{
NMHalManager *manager = (NMHalManager *) user_data;
if (state == NM_STATE_ASLEEP) {
/* Save the sleep state */
manager->nm_sleeping = TRUE;
} else if (manager->nm_sleeping) {
/* If the previous state was sleep, the next one means we just woke up */
manager->nm_sleeping = FALSE;
add_initial_devices (manager);
}
}
NMHalManager *
nm_hal_manager_new (NMManager *nm_manager, NMData *nm_data)
{
NMHalManager *manager;
NMDBusManager *dbus_mgr;
g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
dbus_mgr = nm_dbus_manager_get ();
if (!nm_dbus_manager_name_has_owner (dbus_mgr, "org.freedesktop.Hal")) {
nm_warning ("Could not initialize connection to the HAL daemon.");
return NULL;
}
manager = g_slice_new0 (NMHalManager);
manager->nm_manager = g_object_ref (nm_manager);
manager->dbus_mgr = dbus_mgr;
manager->nm_data = nm_data;
g_signal_connect (manager->dbus_mgr,
"name-owner-changed",
G_CALLBACK (name_owner_changed),
manager);
g_signal_connect (manager->dbus_mgr,
"dbus-connection-changed",
G_CALLBACK (connection_changed),
manager);
g_signal_connect (nm_manager,
"state-change",
G_CALLBACK (nm_manager_state_changed),
manager);
hal_init (manager);
add_initial_devices (manager);
return manager;
}
void
nm_hal_manager_destroy (NMHalManager *manager)
{
if (manager) {
hal_deinit (manager);
g_object_unref (manager->nm_manager);
g_slice_free (NMHalManager, manager);
}
}

12
src/nm-hal-manager.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef NM_HAL_MANAGER_H
#define NM_HAL_MANAGER_H
#include "nm-manager.h"
#include "NetworkManagerMain.h"
typedef struct _NMHalManager NMHalManager;
NMHalManager *nm_hal_manager_new (NMManager *nm_manager, NMData *nm_data);
void nm_hal_manager_destroy (NMHalManager *manager);
#endif /* NM_HAL_MANAGER_H */

417
src/nm-manager.c Normal file
View file

@ -0,0 +1,417 @@
#include <string.h>
#include "nm-manager.h"
#include "nm-utils.h"
#include "nm-dbus-manager.h"
#include "nm-device-802-11-wireless.h"
#include "NetworkManagerSystem.h"
// #include "NetworkManagerDbus.h"
static void manager_state_changed (NMManager *manager);
static void manager_set_wireless_enabled (NMManager *manager, gboolean enabled);
typedef struct {
GSList *devices;
gboolean wireless_enabled;
gboolean sleeping;
} NMManagerPrivate;
#define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate))
G_DEFINE_TYPE (NMManager, nm_manager, G_TYPE_OBJECT)
enum {
DEVICE_ADDED,
DEVICE_REMOVED,
STATE_CHANGE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
enum {
PROP_0,
PROP_STATE,
PROP_WIRELESS_ENABLED,
LAST_PROP
};
static void
nm_manager_init (NMManager *msg)
{
}
static void
device_stop_and_free (gpointer data, gpointer user_data)
{
NMDevice *device = NM_DEVICE (data);
nm_device_set_removed (device, TRUE);
nm_device_deactivate (device);
g_object_unref (device);
}
static void
finalize (GObject *object)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
g_slist_foreach (priv->devices,
device_stop_and_free,
NULL);
g_slist_free (priv->devices);
G_OBJECT_CLASS (nm_manager_parent_class)->finalize (object);
}
static void
set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case PROP_WIRELESS_ENABLED:
manager_set_wireless_enabled (NM_MANAGER (object), g_value_get_boolean (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object);
switch (prop_id) {
case PROP_STATE:
g_value_set_uint (value, nm_manager_get_state (NM_MANAGER (object)));
break;
case PROP_WIRELESS_ENABLED:
g_value_set_boolean (value, priv->wireless_enabled);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_manager_class_init (NMManagerClass *manager_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
g_type_class_add_private (manager_class, sizeof (NMManagerPrivate));
/* virtual methods */
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->finalize = finalize;
/* properties */
g_object_class_install_property
(object_class, PROP_STATE,
g_param_spec_uint (NM_MANAGER_STATE,
"State",
"Current state",
0, 5, 0, /* FIXME */
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_WIRELESS_ENABLED,
g_param_spec_boolean (NM_MANAGER_WIRELESS_ENABLED,
"WirelessEnabled",
"Is wireless enabled",
TRUE,
G_PARAM_READWRITE));
/* signals */
signals[DEVICE_ADDED] =
g_signal_new ("device-added",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMManagerClass, device_added),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
signals[DEVICE_REMOVED] =
g_signal_new ("device-removed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMManagerClass, device_removed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1,
G_TYPE_OBJECT);
signals[STATE_CHANGE] =
g_signal_new ("state-change",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMManagerClass, state_change),
NULL, NULL,
g_cclosure_marshal_VOID__UCHAR,
G_TYPE_NONE, 1,
G_TYPE_UCHAR);
}
NMManager *
nm_manager_new (void)
{
GObject *object;
DBusGConnection *connection;
object = g_object_new (NM_TYPE_MANAGER, NULL);
connection = nm_dbus_manager_get_connection (nm_dbus_manager_get ());
dbus_g_connection_register_g_object (connection,
NM_DBUS_PATH,
object);
return (NMManager *) object;
}
static void
manager_state_changed (NMManager *manager)
{
g_signal_emit (manager, signals[STATE_CHANGE], 0, nm_manager_get_state (manager));
}
static void
manager_set_wireless_enabled (NMManager *manager, gboolean enabled)
{
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
GSList *iter;
if (priv->wireless_enabled == enabled)
return;
priv->wireless_enabled = enabled;
/* Tear down all wireless devices */
for (iter = priv->devices; iter; iter = iter->next) {
if (NM_IS_DEVICE_802_11_WIRELESS (iter->data)) {
NMDevice *dev = NM_DEVICE (iter->data);
if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) {
nm_device_deactivate (dev);
nm_device_bring_down (dev);
}
}
}
}
static void
manager_device_added (NMManager *manager, NMDevice *device)
{
g_signal_emit (manager, signals[DEVICE_ADDED], 0, device);
}
static void
manager_device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
{
NMManager *manager = NM_MANAGER (user_data);
/* Only these state changes can modify the manager state */
if (state == NM_DEVICE_STATE_ACTIVATED || state == NM_DEVICE_STATE_FAILED ||
state == NM_DEVICE_STATE_CANCELLED || state == NM_DEVICE_STATE_DISCONNECTED)
manager_state_changed (manager);
}
void
nm_manager_add_device (NMManager *manager, NMDevice *device)
{
NMManagerPrivate *priv;
g_return_if_fail (NM_IS_MANAGER (manager));
g_return_if_fail (NM_IS_DEVICE (device));
priv = NM_MANAGER_GET_PRIVATE (manager);
priv->devices = g_slist_append (priv->devices, g_object_ref (device));
g_signal_connect (device, "state-changed",
G_CALLBACK (manager_device_state_changed),
manager);
nm_device_deactivate (device);
manager_device_added (manager, device);
}
static void
manager_device_removed (NMManager *manager, NMDevice *device)
{
g_signal_emit (manager, signals[DEVICE_REMOVED], 0, device);
}
void
nm_manager_remove_device (NMManager *manager, NMDevice *device)
{
NMManagerPrivate *priv;
GSList *iter;
g_return_if_fail (NM_IS_MANAGER (manager));
g_return_if_fail (NM_IS_DEVICE (device));
priv = NM_MANAGER_GET_PRIVATE (manager);
for (iter = priv->devices; iter; iter = iter->next) {
if (iter->data == device) {
priv->devices = g_slist_delete_link (priv->devices, iter);
g_signal_handlers_disconnect_by_func (device, manager_device_state_changed, manager);
nm_device_set_removed (device, TRUE);
nm_device_stop (device);
manager_device_removed (manager, device);
g_object_unref (device);
break;
}
}
}
GSList *
nm_manager_get_devices (NMManager *manager)
{
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
return NM_MANAGER_GET_PRIVATE (manager)->devices;
}
NMDevice *
nm_manager_get_device_by_iface (NMManager *manager, const char *iface)
{
GSList *iter;
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
NMDevice *device = NM_DEVICE (iter->data);
if (!strcmp (nm_device_get_iface (device), iface))
return device;
}
return NULL;
}
NMDevice *
nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
{
GSList *iter;
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
NMDevice *device = NM_DEVICE (iter->data);
if (!strcmp (nm_device_get_udi (device), udi))
return device;
}
return NULL;
}
NMState
nm_manager_get_state (NMManager *manager)
{
NMManagerPrivate *priv;
GSList *iter;
NMState state = NM_STATE_DISCONNECTED;
g_return_val_if_fail (NM_IS_MANAGER (manager), NM_STATE_UNKNOWN);
priv = NM_MANAGER_GET_PRIVATE (manager);
if (priv->sleeping)
return NM_STATE_ASLEEP;
for (iter = priv->devices; iter; iter = iter->next) {
NMDevice *dev = NM_DEVICE (iter->data);
if (nm_device_has_active_link (dev))
return NM_STATE_CONNECTED;
if (nm_device_is_activating (dev))
state = NM_STATE_CONNECTING;
}
return state;
}
gboolean
nm_manager_wireless_enabled (NMManager *manager)
{
gboolean enabled;
g_return_val_if_fail (NM_IS_MANAGER (manager), FALSE);
g_object_get (manager, NM_MANAGER_WIRELESS_ENABLED, &enabled, NULL);
return enabled;
}
void
nm_manager_sleep (NMManager *manager, gboolean sleep)
{
NMManagerPrivate *priv;
g_return_if_fail (NM_IS_MANAGER (manager));
priv = NM_MANAGER_GET_PRIVATE (manager);
if (priv->sleeping == sleep)
return;
priv->sleeping = sleep;
if (sleep) {
GSList *iter;
nm_info ("Going to sleep.");
/* Just deactivate and down all devices from the device list,
* we'll remove them in 'wake' for speed's sake.
*/
for (iter = priv->devices; iter; iter = iter->next) {
NMDevice *dev = NM_DEVICE (iter->data);
nm_device_set_removed (dev, TRUE);
nm_device_deactivate_quickly (dev);
nm_system_device_set_up_down (dev, FALSE);
}
} else {
nm_info ("Waking up from sleep.");
while (g_slist_length (priv->devices))
nm_manager_remove_device (manager, NM_DEVICE (priv->devices->data));
priv->devices = NULL;
}
manager_state_changed (manager);
}
NMDevice *
nm_manager_get_active_device (NMManager *manager)
{
GSList *iter;
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
for (iter = nm_manager_get_devices (manager); iter; iter = iter->next) {
NMDevice *dev = NM_DEVICE (iter->data);
if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED)
return dev;
}
return NULL;
}

48
src/nm-manager.h Normal file
View file

@ -0,0 +1,48 @@
#ifndef NM_MANAGER_H
#define NM_MANAGER_H 1
#include <glib/gtypes.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include "nm-device.h"
#define NM_TYPE_MANAGER (nm_manager_get_type ())
#define NM_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_MANAGER, NMManager))
#define NM_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_MANAGER, NMManagerClass))
#define NM_IS_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_MANAGER))
#define NM_IS_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_MANAGER))
#define NM_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_MANAGER, NMManagerClass))
#define NM_MANAGER_STATE "state"
#define NM_MANAGER_WIRELESS_ENABLED "wireless-enabled"
typedef struct {
GObject parent;
} NMManager;
typedef struct {
GObjectClass parent;
/* Signals */
void (*device_added) (NMManager *manager, NMDevice *device);
void (*device_removed) (NMManager *manager, NMDevice *device);
void (*state_change) (NMManager *manager, guint state);
} NMManagerClass;
GType nm_manager_get_type (void);
NMManager *nm_manager_new (void);
void nm_manager_add_device (NMManager *manager, NMDevice *device);
void nm_manager_remove_device (NMManager *manager, NMDevice *device);
GSList *nm_manager_get_devices (NMManager *manager);
NMDevice *nm_manager_get_device_by_iface (NMManager *manager, const char *iface);
NMDevice *nm_manager_get_device_by_udi (NMManager *manager, const char *udi);
NMState nm_manager_get_state (NMManager *manager);
gboolean nm_manager_wireless_enabled (NMManager *manager);
void nm_manager_sleep (NMManager *manager, gboolean sleep);
NMDevice *nm_manager_get_active_device (NMManager *manager);
#endif /* NM_MANAGER_H */

View file

@ -38,6 +38,7 @@
struct NMVPNManager
{
NMManager * nm_manager;
NMData * app_data;
GHashTable * service_table;
GSList * connections;
@ -54,14 +55,16 @@ static void load_services (NMVPNManager *manager, GHashTable *table);
* Create a new VPN manager instance.
*
*/
NMVPNManager *nm_vpn_manager_new (NMData *app_data)
NMVPNManager *nm_vpn_manager_new (NMManager *nm_manager, NMData *app_data)
{
NMVPNManager * manager;
NMDBusManager * dbus_mgr;
g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
g_return_val_if_fail (app_data != NULL, NULL);
manager = g_slice_new0 (NMVPNManager);
manager->nm_manager = g_object_ref (nm_manager);
manager->app_data = app_data;
manager->service_table = g_hash_table_new_full (g_str_hash,
@ -98,6 +101,7 @@ void nm_vpn_manager_dispose (NMVPNManager *manager)
g_hash_table_destroy (manager->service_table);
nm_dbus_method_list_unref (manager->dbus_methods);
g_object_unref (manager->nm_manager);
memset (manager, 0, sizeof (NMVPNManager));
g_slice_free (NMVPNManager, manager);
@ -330,7 +334,7 @@ void nm_vpn_manager_activate_vpn_connection (NMVPNManager *manager, NMVPNConnect
if (!(service = nm_vpn_manager_find_service_by_name (manager, service_name)))
return;
if (!(parent_dev = nm_get_active_device (manager->app_data)))
if (!(parent_dev = nm_manager_get_active_device (manager->nm_manager)))
{
nm_warning ("nm_vpn_manager_activate_vpn_connection(): no currently active network device, won't activate VPN.");
return;

View file

@ -21,12 +21,13 @@
#define NM_VPN_MANAGER_H
#include <dbus/dbus.h>
#include "nm-manager.h"
#include "NetworkManagerMain.h"
#include "nm-vpn-connection.h"
#include "nm-vpn-service.h"
NMVPNManager * nm_vpn_manager_new (NMData *app_data);
NMVPNManager * nm_vpn_manager_new (NMManager *nm_manager, NMData *app_data);
NMVPNConnection * nm_vpn_manager_add_connection (NMVPNManager *manager, const char *name, const char *service_name, const char *user_name);
void nm_vpn_manager_remove_connection (NMVPNManager *manager, NMVPNConnection *vpn);
char ** nm_vpn_manager_get_connection_names (NMVPNManager *manager);