aboutsummaryrefslogtreecommitdiff
path: root/src/mm-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-manager.c')
-rw-r--r--src/mm-manager.c561
1 files changed, 359 insertions, 202 deletions
diff --git a/src/mm-manager.c b/src/mm-manager.c
index a19c9446..aa109a99 100644
--- a/src/mm-manager.c
+++ b/src/mm-manager.c
@@ -2,12 +2,12 @@
#include <string.h>
#include <gmodule.h>
+#define G_UDEV_API_IS_SUBJECT_TO_CHANGE
+#include <gudev/gudev.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include "mm-manager.h"
#include "mm-errors.h"
-#include "mm-generic-gsm.h"
-#include "mm-generic-cdma.h"
#include "mm-plugin.h"
static gboolean impl_manager_enumerate_devices (MMManager *manager,
@@ -29,11 +29,15 @@ static guint signals[LAST_SIGNAL] = { 0 };
#define MM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), MM_TYPE_MANAGER, MMManagerPrivate))
+#define DBUS_PATH_TAG "dbus-path"
+
typedef struct {
DBusGConnection *connection;
- LibHalContext *hal_ctx;
+ GUdevClient *udev;
GSList *plugins;
GHashTable *modems;
+
+ GHashTable *supports;
} MMManagerPrivate;
static MMPlugin *
@@ -97,6 +101,7 @@ load_plugins (MMManager *manager)
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
GDir *dir;
const char *fname;
+ MMPlugin *generic_plugin = NULL;
if (!g_module_supported ()) {
g_warning ("GModules are not supported on your platform!");
@@ -120,10 +125,18 @@ load_plugins (MMManager *manager)
plugin = load_plugin (path);
g_free (path);
- if (plugin)
- priv->plugins = g_slist_append (priv->plugins, plugin);
+ if (plugin) {
+ if (!strcmp (mm_plugin_get_name (plugin), MM_PLUGIN_GENERIC_NAME))
+ generic_plugin = plugin;
+ else
+ priv->plugins = g_slist_append (priv->plugins, plugin);
+ }
}
+ /* Make sure the generic plugin is last */
+ if (generic_plugin)
+ priv->plugins = g_slist_append (priv->plugins, generic_plugin);
+
g_dir_close (dir);
}
@@ -138,7 +151,7 @@ mm_manager_new (DBusGConnection *bus)
if (manager) {
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
- priv->connection = bus;
+ priv->connection = dbus_g_connection_ref (bus);
dbus_g_connection_register_g_object (priv->connection,
MM_DBUS_PATH,
G_OBJECT (manager));
@@ -147,296 +160,441 @@ mm_manager_new (DBusGConnection *bus)
return manager;
}
-static char *
-get_driver_name (LibHalContext *ctx, const char *udi)
+static void
+remove_modem (MMManager *manager, MMModem *modem)
{
- char *parent_udi;
- char *driver = NULL;
+ MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
+ char *device;
- parent_udi = libhal_device_get_property_string (ctx, udi, "info.parent", NULL);
- if (parent_udi) {
- driver = libhal_device_get_property_string (ctx, parent_udi, "info.linux.driver", NULL);
- libhal_free_string (parent_udi);
- }
+ device = mm_modem_get_device (modem);
+ g_assert (device);
+ g_debug ("Removed modem %s", device);
- return driver;
+ g_signal_emit (manager, signals[DEVICE_REMOVED], 0, modem);
+ g_hash_table_remove (priv->modems, device);
+ g_free (device);
}
-static MMModem *
-create_generic_modem (MMManager *manager, const char *udi)
+static void
+modem_valid (MMModem *modem, GParamSpec *pspec, gpointer user_data)
{
+ MMManager *manager = MM_MANAGER (user_data);
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
- MMModem *modem;
- char **capabilities;
- char **iter;
- char *serial_device;
- char *driver;
- gboolean type_gsm = FALSE;
- gboolean type_cdma = FALSE;
-
- capabilities = libhal_device_get_property_strlist (priv->hal_ctx, udi, "modem.command_sets", NULL);
- for (iter = capabilities; iter && *iter; iter++) {
- if (!strcmp (*iter, "GSM-07.07")) {
- type_gsm = TRUE;
- break;
- }
- if (!strcmp (*iter, "IS-707-A")) {
- type_cdma = TRUE;
- break;
- }
- }
- g_strfreev (capabilities);
-
- if (!type_gsm && !type_cdma)
- return NULL;
+ static guint32 id = 0;
+ char *path, *device;
- serial_device = libhal_device_get_property_string (priv->hal_ctx, udi, "serial.device", NULL);
- g_return_val_if_fail (serial_device != NULL, NULL);
+ if (mm_modem_get_valid (modem)) {
+ path = g_strdup_printf (MM_DBUS_PATH"/Modems/%d", id++);
+ dbus_g_connection_register_g_object (priv->connection, path, G_OBJECT (modem));
+ g_object_set_data_full (G_OBJECT (modem), DBUS_PATH_TAG, path, (GDestroyNotify) g_free);
- driver = get_driver_name (priv->hal_ctx, udi);
- g_return_val_if_fail (driver != NULL, NULL);
+ device = mm_modem_get_device (modem);
+ g_assert (device);
+ g_debug ("Exported modem %s as %s", device, path);
+ g_free (device);
- if (type_gsm)
- modem = mm_generic_gsm_new (serial_device, driver);
- else
- modem = mm_generic_cdma_new (serial_device, driver);
-
- g_free (serial_device);
- g_free (driver);
-
- if (modem)
- g_debug ("Created new generic modem (%s)", udi);
- else
- g_warning ("Failed to create generic modem (%s)", udi);
-
- return modem;
+ g_signal_emit (manager, signals[DEVICE_ADDED], 0, modem);
+ } else
+ remove_modem (manager, modem);
}
static void
-add_modem (MMManager *manager, const char *udi, MMModem *modem)
+add_modem (MMManager *manager, MMModem *modem)
{
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
+ char *device;
+ gboolean valid = FALSE;
+
+ device = mm_modem_get_device (modem);
+ g_assert (device);
+ if (!g_hash_table_lookup (priv->modems, device)) {
+ g_hash_table_insert (priv->modems, g_strdup (device), modem);
+ g_debug ("Added modem %s", device);
+ g_signal_connect (modem, "notify::valid", G_CALLBACK (modem_valid), manager);
+ g_object_get (modem, MM_MODEM_VALID, &valid, NULL);
+ if (valid)
+ modem_valid (modem, NULL, manager);
+ }
+ g_free (device);
+}
- g_hash_table_insert (priv->modems, g_strdup (udi), modem);
- dbus_g_connection_register_g_object (priv->connection, udi, G_OBJECT (modem));
-
- g_signal_emit (manager, signals[DEVICE_ADDED], 0, modem);
+static void
+enumerate_devices_cb (gpointer key, gpointer val, gpointer user_data)
+{
+ MMModem *modem = MM_MODEM (val);
+ GPtrArray **devices = (GPtrArray **) user_data;
+ const char *path;
+ gboolean valid = FALSE;
+
+ g_object_get (G_OBJECT (modem), MM_MODEM_VALID, &valid, NULL);
+ if (valid) {
+ path = g_object_get_data (G_OBJECT (modem), DBUS_PATH_TAG);
+ g_return_if_fail (path != NULL);
+ g_ptr_array_add (*devices, g_strdup (path));
+ }
}
-static MMModem *
-modem_exists (MMManager *manager, const char *udi)
+static gboolean
+impl_manager_enumerate_devices (MMManager *manager,
+ GPtrArray **devices,
+ GError **err)
{
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
- return (MMModem *) g_hash_table_lookup (priv->modems, udi);
+ *devices = g_ptr_array_sized_new (g_hash_table_size (priv->modems));
+ g_hash_table_foreach (priv->modems, enumerate_devices_cb, devices);
+
+ return TRUE;
}
-static void
-create_initial_modems_from_plugins (MMManager *manager)
+static MMModem *
+find_modem_for_port (MMManager *manager, const char *subsys, const char *name)
{
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
- GSList *iter;
+ GHashTableIter iter;
+ gpointer key, value;
- for (iter = priv->plugins; iter; iter = iter->next) {
- MMPlugin *plugin = MM_PLUGIN (iter->data);
- char **udis;
- int i;
+ g_hash_table_iter_init (&iter, priv->modems);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ MMModem *modem = MM_MODEM (value);
- udis = mm_plugin_list_supported_udis (plugin, priv->hal_ctx);
- if (udis) {
- for (i = 0; udis[i]; i++) {
- char *udi = udis[i];
- MMModem *modem;
+ if (mm_modem_owns_port (modem, subsys, name))
+ return modem;
+ }
+ return NULL;
+}
- if (modem_exists (manager, udi)) {
- g_warning ("Modem for UDI %s already exists, ignoring", udi);
- continue;
- }
+typedef struct {
+ MMManager *manager;
+ char *subsys;
+ char *name;
+ GSList *plugins;
+ GSList *cur_plugin;
+ guint defer_id;
+ guint done_id;
- modem = mm_plugin_create_modem (plugin, priv->hal_ctx, udi);
- if (modem)
- add_modem (manager, udi, modem);
- }
+ guint32 best_level;
+ MMPlugin *best_plugin;
+} SupportsInfo;
- g_strfreev (udis);
- }
- }
+static SupportsInfo *
+supports_info_new (MMManager *self, const char *subsys, const char *name)
+{
+ MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (self);
+ SupportsInfo *info;
+
+ info = g_malloc0 (sizeof (SupportsInfo));
+ info->manager = self;
+ info->subsys = g_strdup (subsys);
+ info->name = g_strdup (name);
+ info->plugins = g_slist_copy (priv->plugins);
+ info->cur_plugin = info->plugins;
+ return info;
}
static void
-create_initial_modems_generic (MMManager *manager)
+supports_info_free (SupportsInfo *info)
{
- MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
- char **devices;
- int num_devices;
- int i;
- DBusError err;
-
- dbus_error_init (&err);
- devices = libhal_find_device_by_capability (priv->hal_ctx, "modem", &num_devices, &err);
- if (dbus_error_is_set (&err)) {
- g_warning ("Could not list HAL devices: %s", err.message);
- dbus_error_free (&err);
- }
+ /* Cancel any in-process operation on the first plugin */
+ if (info->cur_plugin)
+ mm_plugin_cancel_supports_port (MM_PLUGIN (info->cur_plugin->data), info->subsys, info->name);
- if (devices) {
- for (i = 0; i < num_devices; i++) {
- char *udi = devices[i];
- MMModem *modem;
+ if (info->defer_id)
+ g_source_remove (info->defer_id);
- if (modem_exists (manager, udi))
- /* Already exists, most likely handled by a plugin */
- continue;
+ if (info->done_id)
+ g_source_remove (info->done_id);
- modem = create_generic_modem (manager, udi);
- if (modem)
- add_modem (manager, g_strdup (udi), modem);
- }
- }
+ g_free (info->subsys);
+ g_free (info->name);
+ g_slist_free (info->plugins);
+ memset (info, 0, sizeof (SupportsInfo));
+ g_free (info);
+}
- g_strfreev (devices);
+static char *
+get_key (const char *subsys, const char *name)
+{
+ return g_strdup_printf ("%s%s", subsys, name);
}
-static void
-create_initial_modems (MMManager *manager)
+
+static void supports_callback (MMPlugin *plugin,
+ const char *subsys,
+ const char *name,
+ guint32 level,
+ gpointer user_data);
+
+static void try_supports_port (MMManager *manager,
+ MMPlugin *plugin,
+ const char *subsys,
+ const char *name,
+ SupportsInfo *info);
+
+static gboolean
+supports_defer_timeout (gpointer user_data)
{
- create_initial_modems_from_plugins (manager);
- create_initial_modems_generic (manager);
+ SupportsInfo *info = user_data;
+
+ g_debug ("(%s): re-checking support...", info->name);
+ try_supports_port (info->manager,
+ MM_PLUGIN (info->cur_plugin->data),
+ info->subsys,
+ info->name,
+ info);
+ return FALSE;
}
static void
-enumerate_devices_cb (gpointer key, gpointer val, gpointer user_data)
+try_supports_port (MMManager *manager,
+ MMPlugin *plugin,
+ const char *subsys,
+ const char *name,
+ SupportsInfo *info)
{
- GPtrArray **devices = (GPtrArray **) user_data;
-
- g_ptr_array_add (*devices, g_strdup ((char *) key));
+ MMPluginSupportsResult result;
+
+ result = mm_plugin_supports_port (plugin, subsys, name, supports_callback, info);
+
+ switch (result) {
+ case MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED:
+ /* If the plugin knows it doesn't support the modem, just call the
+ * callback and indicate 0 support.
+ */
+ supports_callback (plugin, subsys, name, 0, info);
+ break;
+ case MM_PLUGIN_SUPPORTS_PORT_DEFER:
+ g_debug ("(%s): (%s) deferring support check", mm_plugin_get_name (plugin), name);
+ if (info->defer_id)
+ g_source_remove (info->defer_id);
+
+ /* defer port detection for a bit as requested by the plugin */
+ info->defer_id = g_timeout_add (3000, supports_defer_timeout, info);
+ break;
+ case MM_PLUGIN_SUPPORTS_PORT_IN_PROGRESS:
+ default:
+ break;
+ }
}
static gboolean
-impl_manager_enumerate_devices (MMManager *manager,
- GPtrArray **devices,
- GError **err)
+do_grab_port (gpointer user_data)
{
- MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
+ SupportsInfo *info = user_data;
+ MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (info->manager);
+ MMModem *modem;
+ GError *error = NULL;
+ char *key;
+ GSList *iter;
- *devices = g_ptr_array_sized_new (g_hash_table_size (priv->modems));
- g_hash_table_foreach (priv->modems, enumerate_devices_cb, devices);
+ /* No more plugins to try */
+ if (info->best_plugin) {
+ /* Create the modem */
+ modem = mm_plugin_grab_port (info->best_plugin, info->subsys, info->name, &error);
+ if (modem) {
+ guint32 modem_type = MM_MODEM_TYPE_UNKNOWN;
+ const char *type_name = "UNKNOWN";
+
+ g_object_get (G_OBJECT (modem), MM_MODEM_TYPE, &modem_type, NULL);
+ if (modem_type == MM_MODEM_TYPE_GSM)
+ type_name = "GSM";
+ else if (modem_type == MM_MODEM_TYPE_CDMA)
+ type_name = "CDMA";
+
+ g_message ("(%s): %s modem %s claimed port %s",
+ mm_plugin_get_name (info->best_plugin),
+ type_name,
+ mm_modem_get_device (modem),
+ info->name);
+
+ add_modem (info->manager, modem);
+ } else {
+ g_warning ("%s: plugin '%s' claimed to support %s/%s but couldn't: (%d) %s",
+ __func__,
+ mm_plugin_get_name (info->best_plugin),
+ info->subsys,
+ info->name,
+ error ? error->code : -1,
+ (error && error->message) ? error->message : "(unknown)");
+ }
+ }
- return TRUE;
+ /* Tell each plugin to clean up any outstanding supports task */
+ for (iter = info->plugins; iter; iter = g_slist_next (iter))
+ mm_plugin_cancel_supports_port (MM_PLUGIN (iter->data), info->subsys, info->name);
+ g_slist_free (info->plugins);
+ info->cur_plugin = info->plugins = NULL;
+
+ key = get_key (info->subsys, info->name);
+ g_hash_table_remove (priv->supports, key);
+ g_free (key);
+
+ return FALSE;
}
static void
-device_added (LibHalContext *ctx, const char *udi)
+supports_callback (MMPlugin *plugin,
+ const char *subsys,
+ const char *name,
+ guint32 level,
+ gpointer user_data)
+{
+ SupportsInfo *info = user_data;
+ MMPlugin *next_plugin = NULL;
+
+ info->cur_plugin = info->cur_plugin->next;
+ if (info->cur_plugin)
+ next_plugin = MM_PLUGIN (info->cur_plugin->data);
+
+ /* Is this plugin's result better than any one we've tried before? */
+ if (level > info->best_level) {
+ info->best_level = level;
+ info->best_plugin = plugin;
+ }
+
+ /* Prevent the generic plugin from probing devices that are already supported
+ * by other plugins. For Huawei for example, secondary ports shouldn't
+ * be probed, but the generic plugin would happily do so if allowed to.
+ */
+ if ( next_plugin
+ && !strcmp (mm_plugin_get_name (next_plugin), MM_PLUGIN_GENERIC_NAME)
+ && info->best_plugin)
+ next_plugin = NULL;
+
+ if (next_plugin) {
+ /* Try the next plugin */
+ try_supports_port (info->manager, next_plugin, info->subsys, info->name, info);
+ } else {
+ /* All done; let the best modem grab the port */
+ info->done_id = g_idle_add (do_grab_port, info);
+ }
+}
+
+static void
+device_added (MMManager *manager, GUdevDevice *device)
{
- MMManager *manager = MM_MANAGER (libhal_ctx_get_user_data (ctx));
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
- GSList *iter;
- MMModem *modem = NULL;
+ const char *subsys, *name;
+ SupportsInfo *info;
+ char *key;
+ gboolean found;
+
+ g_return_if_fail (device != NULL);
- if (modem_exists (manager, udi))
- /* Shouldn't happen */
+ if (!g_slist_length (priv->plugins))
return;
- for (iter = priv->plugins; iter && modem == NULL; iter = iter->next) {
- MMPlugin *plugin = MM_PLUGIN (iter->data);
+ subsys = g_udev_device_get_subsystem (device);
+ name = g_udev_device_get_name (device);
- if (mm_plugin_supports_udi (plugin, ctx, udi)) {
- modem = mm_plugin_create_modem (plugin, ctx, udi);
- if (modem)
- break;
- }
+ if (find_modem_for_port (manager, subsys, name))
+ return;
+
+ key = get_key (subsys, name);
+ found = !!g_hash_table_lookup (priv->supports, key);
+ if (found) {
+ g_free (key);
+ return;
}
- if (!modem)
- /* None of the plugins supported the udi, try generic devices */
- modem = create_generic_modem (manager, udi);
+ info = supports_info_new (manager, subsys, name);
+ g_hash_table_insert (priv->supports, key, info);
- if (modem)
- add_modem (manager, udi, modem);
+ try_supports_port (manager, MM_PLUGIN (info->cur_plugin->data), subsys, name, info);
}
static void
-device_removed (LibHalContext *ctx, const char *udi)
+device_removed (MMManager *manager, GUdevDevice *device)
{
- MMManager *manager = MM_MANAGER (libhal_ctx_get_user_data (ctx));
+ MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
MMModem *modem;
+ const char *subsys, *name;
+ char *key;
+ SupportsInfo *info;
+
+ g_return_if_fail (device != NULL);
+
+ if (!g_slist_length (priv->plugins))
+ return;
- modem = modem_exists (manager, udi);
+ subsys = g_udev_device_get_subsystem (device);
+ name = g_udev_device_get_name (device);
+ modem = find_modem_for_port (manager, subsys, name);
if (modem) {
- g_debug ("Removed modem %s", udi);
- g_signal_emit (manager, signals[DEVICE_REMOVED], 0, modem);
- g_hash_table_remove (MM_MANAGER_GET_PRIVATE (manager)->modems, udi);
+ mm_modem_release_port (modem, subsys, name);
+ return;
}
-}
-static void
-device_new_capability (LibHalContext *ctx, const char *udi, const char *capability)
-{
- device_added (ctx, udi);
-}
+ /* Maybe a plugin is checking whether or not the port is supported */
+ key = get_key (subsys, name);
+ info = g_hash_table_lookup (priv->supports, key);
+ if (info) {
+ if (info->plugins)
+ mm_plugin_cancel_supports_port (MM_PLUGIN (info->plugins->data), subsys, name);
+ g_hash_table_remove (priv->supports, key);
+ }
-DBusGConnection *
-mm_manager_get_bus (MMManager *manager)
-{
- g_return_val_if_fail (MM_IS_MANAGER (manager), NULL);
-
- return MM_MANAGER_GET_PRIVATE (manager)->connection;
+ g_free (key);
}
-static gboolean
-remove_one (gpointer key,
- gpointer value,
- gpointer user_data)
+static void
+handle_uevent (GUdevClient *client,
+ const char *action,
+ GUdevDevice *device,
+ gpointer user_data)
{
- const char *udi = (char *) key;
- MMModem *modem = MM_MODEM (value);
- MMManager *manager = MM_MANAGER (user_data);
+ MMManager *self = MM_MANAGER (user_data);
+ const char *subsys;
- g_debug ("Removed modem %s", udi);
- g_signal_emit (manager, signals[DEVICE_REMOVED], 0, modem);
+ g_return_if_fail (action != NULL);
- return TRUE;
+ /* A bit paranoid */
+ subsys = g_udev_device_get_subsystem (device);
+ g_return_if_fail (subsys != NULL);
+
+ g_return_if_fail (!strcmp (subsys, "tty") || !strcmp (subsys, "net"));
+
+ if (!strcmp (action, "add"))
+ device_added (self, device);
+ else if (!strcmp (action, "remove"))
+ device_removed (self, device);
}
void
-mm_manager_set_hal_ctx (MMManager *manager,
- LibHalContext *hal_ctx)
+mm_manager_start (MMManager *manager)
{
MMManagerPrivate *priv;
+ GList *devices, *iter;
+ g_return_if_fail (manager != NULL);
g_return_if_fail (MM_IS_MANAGER (manager));
priv = MM_MANAGER_GET_PRIVATE (manager);
- priv->hal_ctx = hal_ctx;
- if (hal_ctx) {
- libhal_ctx_set_user_data (hal_ctx, manager);
- libhal_ctx_set_device_added (hal_ctx, device_added);
- libhal_ctx_set_device_removed (hal_ctx, device_removed);
- libhal_ctx_set_device_new_capability (hal_ctx, device_new_capability);
+ devices = g_udev_client_query_by_subsystem (priv->udev, "tty");
+ for (iter = devices; iter; iter = g_list_next (iter))
+ device_added (manager, G_UDEV_DEVICE (iter->data));
- create_initial_modems (manager);
- } else {
- g_hash_table_foreach_remove (priv->modems, remove_one, manager);
- }
-}
-
-LibHalContext *
-mm_manager_get_hal_ctx (MMManager *manager)
-{
- g_return_val_if_fail (MM_IS_MANAGER (manager), NULL);
-
- return MM_MANAGER_GET_PRIVATE (manager)->hal_ctx;
+ devices = g_udev_client_query_by_subsystem (priv->udev, "net");
+ for (iter = devices; iter; iter = g_list_next (iter))
+ device_added (manager, G_UDEV_DEVICE (iter->data));
}
static void
mm_manager_init (MMManager *manager)
{
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (manager);
+ const char *subsys[3] = { "tty", "net", NULL };
priv->modems = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
load_plugins (manager);
+
+ priv->supports = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) supports_info_free);
+
+ priv->udev = g_udev_client_new (subsys);
+ g_assert (priv->udev);
+ g_signal_connect (priv->udev, "uevent", G_CALLBACK (handle_uevent), manager);
}
static void
@@ -444,16 +602,14 @@ finalize (GObject *object)
{
MMManagerPrivate *priv = MM_MANAGER_GET_PRIVATE (object);
+ g_hash_table_destroy (priv->supports);
g_hash_table_destroy (priv->modems);
g_slist_foreach (priv->plugins, (GFunc) g_object_unref, NULL);
g_slist_free (priv->plugins);
- if (priv->hal_ctx) {
- mm_manager_set_hal_ctx (MM_MANAGER (object), NULL);
- libhal_ctx_shutdown (priv->hal_ctx, NULL);
- libhal_ctx_free (priv->hal_ctx);
- }
+ if (priv->udev)
+ g_object_unref (priv->udev);
if (priv->connection)
dbus_g_connection_unref (priv->connection);
@@ -500,3 +656,4 @@ mm_manager_class_init (MMManagerClass *manager_class)
dbus_g_error_domain_register (MM_MODEM_CONNECT_ERROR, "org.freedesktop.ModemManager.Modem", MM_TYPE_MODEM_CONNECT_ERROR);
dbus_g_error_domain_register (MM_MOBILE_ERROR, "org.freedesktop.ModemManager.Modem.Gsm", MM_TYPE_MOBILE_ERROR);
}
+