core: start using MMBroadbandModem objects

We chain up the Generic plugin created MMBroadbandModem objects within the
GDBusObjectManagerServer in MMManager, so that they get properly exported in
DBus.
This commit is contained in:
Aleksander Morgado
2011-11-23 11:58:54 +01:00
parent 4ad9374159
commit 86aa9df849
8 changed files with 215 additions and 221 deletions

View File

@@ -27,8 +27,7 @@
#include <gmodule.h>
#include "mm-plugin-generic.h"
#include "mm-generic-gsm.h"
#include "mm-generic-cdma.h"
#include "mm-broadband-modem.h"
#include "mm-errors.h"
#include "mm-serial-parsers.h"
#include "mm-log.h"
@@ -40,27 +39,33 @@ int mm_plugin_minor_version = MM_PLUGIN_MINOR_VERSION;
/*****************************************************************************/
static MMModem *
static MMBaseModem *
grab_port (MMPluginBase *base,
MMModem *existing,
MMBaseModem *existing,
MMPortProbe *probe,
GError **error)
{
GUdevDevice *port;
MMModem *modem = NULL;
const gchar *name, *subsys, *devfile, *physdev, *driver;
guint32 caps;
MMBaseModem *modem = NULL;
const gchar *name, *subsys, *devfile, *driver;
guint16 vendor = 0, product = 0;
subsys = mm_port_probe_get_port_subsys (probe);
name = mm_port_probe_get_port_name (probe);
/* The generic plugin cannot do anything with non-AT ports */
if (!mm_port_probe_is_at (probe)) {
g_set_error (error, 0, 0, "Ignoring non-AT port");
return NULL;
}
driver = mm_port_probe_get_port_driver (probe);
port = mm_port_probe_get_port (probe);
g_assert (port);
/* Check device file of the port, we expect one */
devfile = g_udev_device_get_device_file (port);
if (!devfile) {
if (!driver || strcmp (driver, "bluetooth")) {
if (!driver || !g_str_equal (driver, "bluetooth")) {
g_set_error (error, 0, 0, "Could not get port's sysfs file.");
return NULL;
}
@@ -71,58 +76,29 @@ grab_port (MMPluginBase *base,
name);
}
if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product)) {
g_set_error (error, 0, 0, "Could not get modem product ID.");
return NULL;
}
/* Vendor and Product IDs are really optional, we'll just warn if they
* cannot get loaded */
if (!mm_plugin_base_get_device_ids (base, subsys, name, &vendor, &product))
mm_warn ("Could not get modem vendor/product ID");
caps = mm_port_probe_get_capabilities (probe);
physdev = mm_port_probe_get_port_physdev (probe);
if (!existing) {
if (caps & MM_PORT_PROBE_CAPABILITY_CDMA) {
modem = mm_generic_cdma_new (physdev,
driver,
mm_plugin_get_name (MM_PLUGIN (base)),
!!(caps & MM_PORT_PROBE_CAPABILITY_IS856),
!!(caps & MM_PORT_PROBE_CAPABILITY_IS856_A),
vendor,
product);
} else if (caps & MM_PORT_PROBE_CAPABILITY_GSM) {
modem = mm_generic_gsm_new (physdev,
/* If this is the first port being grabbed, create a new modem object */
if (!existing)
modem = MM_BASE_MODEM (mm_broadband_modem_new (mm_port_probe_get_port_physdev (probe),
driver,
mm_plugin_get_name (MM_PLUGIN (base)),
vendor,
product);
}
product));
if (modem) {
if (!mm_modem_grab_port (modem,
if (!mm_base_modem_grab_port (existing ? existing : modem,
subsys,
name,
MM_PORT_TYPE_UNKNOWN,
NULL,
error)) {
MM_PORT_TYPE_UNKNOWN)) {
if (modem)
g_object_unref (modem);
return NULL;
}
}
} else if (caps) {
MMPortType ptype = MM_PORT_TYPE_UNKNOWN;
if (mm_port_probe_is_qcdm (probe))
ptype = MM_PORT_TYPE_QCDM;
modem = existing;
if (!mm_modem_grab_port (modem,
subsys,
name,
ptype,
NULL,
error))
return NULL;
}
return modem;
return existing ? existing : modem;
}
/*****************************************************************************/
@@ -130,17 +106,13 @@ grab_port (MMPluginBase *base,
G_MODULE_EXPORT MMPlugin *
mm_plugin_create (void)
{
static const gchar *name = MM_PLUGIN_GENERIC_NAME;
static const gchar *subsystems[] = { "tty", NULL };
static const guint32 capabilities = MM_PORT_PROBE_CAPABILITY_GSM_OR_CDMA;
static const gboolean qcdm = TRUE;
return MM_PLUGIN (
g_object_new (MM_TYPE_PLUGIN_GENERIC,
MM_PLUGIN_BASE_NAME, name,
MM_PLUGIN_BASE_NAME, MM_PLUGIN_GENERIC_NAME,
MM_PLUGIN_BASE_ALLOWED_SUBSYSTEMS, subsystems,
MM_PLUGIN_BASE_ALLOWED_CAPABILITIES, capabilities,
MM_PLUGIN_BASE_ALLOWED_QCDM, qcdm,
MM_PLUGIN_BASE_ALLOWED_AT, TRUE,
NULL));
}

View File

@@ -98,24 +98,71 @@ find_port_support_context_free (FindPortSupportContext *ctx)
}
static void
remove_modem (MMManager *manager, MMModem *modem)
remove_modem (MMManager *manager,
MMBaseModem *modem)
{
char *device;
gchar *path;
gchar *device;
device = mm_modem_get_device (modem);
g_assert (device);
mm_dbg ("Removed modem %s", device);
device = g_strdup (mm_base_modem_get_device (modem));
path = g_strdup (g_dbus_object_get_object_path (G_DBUS_OBJECT (modem)));
/* GDBus TODO: Unexport object
* g_signal_emit (manager, signals[DEVICE_REMOVED], 0, modem); */
/* If we get DBus object path, modem was exported */
if (path) {
g_dbus_object_manager_server_unexport (manager->priv->object_manager, path);
g_object_set (modem,
MM_BASE_MODEM_CONNECTION, NULL,
NULL);
mm_dbg ("Unexported modem '%s' from path '%s'", device, path);
g_free (path);
}
/* Run dispose before unref-ing, in order to cleanup the SIM object,
* if any (which also holds a reference to the modem object) */
g_object_run_dispose (G_OBJECT (modem));
g_hash_table_remove (manager->priv->modems, device);
g_free (device);
}
static void
check_export_modem (MMManager *self, MMModem *modem)
debug_modem_info (MMManager *self,
MMBaseModem *modem)
{
char *modem_physdev;
/* guint32 vid = 0; */
/* guint32 pid = 0; */
/* GUdevDevice *physdev; */
/* const gchar *subsys; */
/* physdev = g_udev_client_query_by_sysfs_path ( */
/* self->priv->udev, */
/* mm_base_modem_get_device (modem)); */
/* subsys = (physdev ? */
/* g_udev_device_get_subsystem (physdev) : */
/* NULL); */
/* g_object_get (G_OBJECT (modem), */
/* MM_MODEM_DATA_DEVICE, &data_device, */
/* MM_MODEM_HW_VID, &vid, */
/* MM_MODEM_HW_PID, &pid, */
/* NULL); */
/* mm_dbg ("(%s): VID 0x%04X PID 0x%04X (%s)", */
/* path, */
/* (vid & 0xFFFF), */
/* (pid & 0xFFFF), */
/* subsys ? subsys : "unknown"); */
/* mm_dbg ("(%s): data port is %s", path, data_device); */
/* g_free (data_device); */
/* if (physdev) */
/* g_object_unref (physdev); */
}
static void
check_export_modem (MMManager *self,
MMBaseModem *modem)
{
const gchar *modem_physdev;
const gchar *name;
const gchar *subsys;
@@ -132,7 +179,8 @@ check_export_modem (MMManager *self, MMModem *modem)
* chance that a port could show up after the modem is already created and
* all other ports are already handled. That chance is very small though.
*/
modem_physdev = mm_modem_get_device (modem);
modem_physdev = mm_base_modem_get_device (modem);
g_assert (modem_physdev);
/* Check for ports that are in the process of being interrogated by plugins */
@@ -140,64 +188,42 @@ check_export_modem (MMManager *self, MMModem *modem)
modem_physdev,
&subsys,
&name)) {
mm_dbg ("(%s/%s): outstanding support task prevents export of %s",
mm_dbg ("(%s/%s): outstanding support task prevents export of '%s'",
subsys, name, modem_physdev);
goto out;
return;
}
/* Already exported? This can happen if the modem is exported and the kernel
* discovers another of the modem's ports.
*/
if (g_object_get_data (G_OBJECT (modem), DBUS_PATH_TAG))
goto out;
/* No outstanding port tasks, so if the modem is valid we can export it */
if (mm_modem_get_valid (modem)) {
static guint32 id = 0, vid = 0, pid = 0;
gchar *path, *data_device = NULL;
GUdevDevice *physdev;
subsys = NULL;
if (mm_base_modem_get_valid (modem)) {
gchar *path;
static guint32 id = 0;
path = g_strdup_printf (MM_DBUS_PATH"/Modems/%d", id++);
/* GDBus TODO:
* 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);
mm_dbg ("Exported modem %s as %s", modem_physdev, path);
physdev = g_udev_client_query_by_sysfs_path (self->priv->udev, modem_physdev);
if (physdev)
subsys = g_udev_device_get_subsystem (physdev);
g_object_get (G_OBJECT (modem),
MM_MODEM_DATA_DEVICE, &data_device,
MM_MODEM_HW_VID, &vid,
MM_MODEM_HW_PID, &pid,
g_object_set (modem,
"g-object-path", path,
MM_BASE_MODEM_CONNECTION, self->priv->connection,
NULL);
mm_dbg ("(%s): VID 0x%04X PID 0x%04X (%s)",
path, (vid & 0xFFFF), (pid & 0xFFFF),
subsys ? subsys : "unknown");
mm_dbg ("(%s): data port is %s", path, data_device);
g_free (data_device);
g_dbus_object_manager_server_export (self->priv->object_manager,
G_DBUS_OBJECT_SKELETON (modem));
mm_dbg ("Exported modem '%s' at path '%s'", modem_physdev, path);
g_free (path);
if (physdev)
g_object_unref (physdev);
/* GDBus TODO: export object
* g_signal_emit (self, signals[DEVICE_ADDED], 0, modem); */
/* Once connected, dump additional debug info about the modem */
debug_modem_info (self, modem);
return;
}
out:
g_free (modem_physdev);
mm_dbg ("Not exporting invalid modem '%s'", modem_physdev);
}
static void
modem_valid (MMModem *modem, GParamSpec *pspec, gpointer user_data)
modem_valid (MMBaseModem *modem,
GParamSpec *pspec,
gpointer user_data)
{
MMManager *manager = MM_MANAGER (user_data);
if (mm_modem_get_valid (modem))
if (mm_base_modem_get_valid (modem))
check_export_modem (manager, modem);
else
remove_modem (manager, modem);
@@ -206,54 +232,58 @@ modem_valid (MMModem *modem, GParamSpec *pspec, gpointer user_data)
#define MANAGER_PLUGIN_TAG "manager-plugin"
static void
add_modem (MMManager *manager, MMModem *modem, MMPlugin *plugin)
add_modem (MMManager *manager,
MMBaseModem *modem,
MMPlugin *plugin)
{
char *device;
const gchar *device;
device = mm_modem_get_device (modem);
g_assert (device);
device = mm_base_modem_get_device (modem);
if (!g_hash_table_lookup (manager->priv->modems, device)) {
g_hash_table_insert (manager->priv->modems, g_strdup (device), modem);
g_object_set_data (G_OBJECT (modem), MANAGER_PLUGIN_TAG, plugin);
mm_dbg ("Added modem %s", device);
g_signal_connect (modem, "notify::" MM_MODEM_VALID, G_CALLBACK (modem_valid), manager);
g_hash_table_insert (manager->priv->modems,
g_strdup (device),
modem);
g_object_set_data (G_OBJECT (modem), MANAGER_PLUGIN_TAG, plugin);
g_signal_connect (modem, "notify::" MM_BASE_MODEM_VALID, G_CALLBACK (modem_valid), manager);
}
check_export_modem (manager, modem);
}
g_free (device);
}
static MMModem *
find_modem_for_device (MMManager *manager, const char *device)
{
GHashTableIter iter;
gpointer key, value;
MMModem *found = NULL;
g_hash_table_iter_init (&iter, manager->priv->modems);
while (g_hash_table_iter_next (&iter, &key, &value) && !found) {
MMModem *candidate = MM_MODEM (value);
char *candidate_device = mm_modem_get_device (candidate);
if (!strcmp (device, candidate_device))
found = candidate;
g_free (candidate_device);
}
return found;
}
static MMModem *
find_modem_for_port (MMManager *manager, const char *subsys, const char *name)
static MMBaseModem *
find_modem_for_device (MMManager *manager,
const gchar *device)
{
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, manager->priv->modems);
while (g_hash_table_iter_next (&iter, &key, &value)) {
MMModem *modem = MM_MODEM (value);
MMBaseModem *candidate = MM_BASE_MODEM (value);
if (mm_modem_owns_port (modem, subsys, name))
return modem;
if (g_str_equal (device,
mm_base_modem_get_device (candidate)))
return candidate;
}
return NULL;
}
static MMBaseModem *
find_modem_for_port (MMManager *manager,
const gchar *subsys,
const gchar *name)
{
GHashTableIter iter;
gpointer key, value;
g_hash_table_iter_init (&iter, manager->priv->modems);
while (g_hash_table_iter_next (&iter, &key, &value)) {
MMBaseModem *candidate = MM_BASE_MODEM (value);
if (mm_base_modem_owns_port (candidate, subsys, name))
return candidate;
}
return NULL;
}
@@ -270,7 +300,7 @@ find_port_support_ready_cb (MMPluginManager *plugin_manager,
result,
&error);
if (!best_plugin) {
MMModem *existing;
MMBaseModem *existing;
if (error) {
mm_dbg ("(%s/%s): error checking support: '%s'",
@@ -313,51 +343,40 @@ grab_port (MMManager *manager,
GUdevDevice *device,
GUdevDevice *physical_device)
{
MMModem *modem = NULL;
GError *error = NULL;
/* GSList *iter; */
MMModem *existing;
MMBaseModem *modem;
MMBaseModem *existing;
existing = g_hash_table_lookup (manager->priv->modems,
g_udev_device_get_sysfs_path (physical_device));
/* Create the modem */
/* While grabbing the first port, modem will get created */
modem = mm_plugin_grab_port (plugin,
g_udev_device_get_subsystem (device),
g_udev_device_get_name (device),
existing,
&error);
if (modem) {
guint32 modem_type = MM_MODEM_TYPE_UNKNOWN;
const gchar *type_name = "UNKNOWN";
gchar *modem_device;
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";
modem_device = mm_modem_get_device (modem);
mm_info ("(%s): %s modem %s claimed port %s",
mm_plugin_get_name (plugin),
type_name,
modem_device,
g_udev_device_get_name (device));
g_free (modem_device);
add_modem (manager, modem, plugin);
} else {
if (!modem) {
mm_warn ("plugin '%s' claimed to support %s/%s but couldn't: (%d) %s",
mm_plugin_get_name (plugin),
g_udev_device_get_subsystem (device),
g_udev_device_get_name (device),
error ? error->code : -1,
(error && error->message) ? error->message : "(unknown)");
modem = existing;
if (existing)
check_export_modem (manager, existing);
return;
}
check_export_modem (manager, modem);
mm_info ("(%s): modem %s claimed port %s",
mm_plugin_get_name (plugin),
mm_base_modem_get_device (modem),
g_udev_device_get_name (device));
/* If the modem was just created, store it */
if (!existing)
add_modem (manager, modem, plugin);
}
static GUdevDevice *
@@ -423,13 +442,14 @@ find_physical_device (GUdevDevice *child)
}
static void
device_added (MMManager *manager, GUdevDevice *device)
device_added (MMManager *manager,
GUdevDevice *device)
{
const char *subsys, *name, *physdev_path, *physdev_subsys;
gboolean is_candidate;
GUdevDevice *physdev = NULL;
MMPlugin *plugin;
MMModem *existing;
MMBaseModem *existing;
g_return_if_fail (device != NULL);
@@ -531,11 +551,11 @@ out:
}
static void
device_removed (MMManager *manager, GUdevDevice *device)
device_removed (MMManager *manager,
GUdevDevice *device)
{
MMModem *modem;
MMBaseModem *modem;
const char *subsys, *name;
gchar *modem_device;
g_return_if_fail (device != NULL);
@@ -549,10 +569,11 @@ device_removed (MMManager *manager, GUdevDevice *device)
/* find_modem_for_port handles tty and net removal */
modem = find_modem_for_port (manager, subsys, name);
if (modem) {
modem_device = mm_modem_get_device (modem);
mm_info ("(%s/%s): released by modem %s", subsys, name, modem_device);
g_free (modem_device);
mm_modem_release_port (modem, subsys, name);
mm_info ("(%s/%s): released by modem %s",
subsys,
name,
mm_base_modem_get_device (modem));
mm_base_modem_release_port (modem, subsys, name);
return;
}
} else {
@@ -634,7 +655,7 @@ mm_manager_start (MMManager *manager)
typedef struct {
MMManager *manager;
MMModem *modem;
MMBaseModem *modem;
} RemoveInfo;
static gboolean
@@ -648,7 +669,7 @@ remove_disable_one (gpointer user_data)
}
static void
remove_disable_done (MMModem *modem,
remove_disable_done (MMBaseModem *modem,
GError *error,
gpointer user_data)
{
@@ -673,11 +694,12 @@ mm_manager_shutdown (MMManager *self)
modems = g_hash_table_get_values (self->priv->modems);
for (iter = modems; iter; iter = g_list_next (iter)) {
MMModem *modem = MM_MODEM (iter->data);
MMBaseModem *modem = MM_BASE_MODEM (iter->data);
if (mm_modem_get_state (modem) >= MM_MODEM_STATE_ENABLING)
mm_modem_disable (modem, remove_disable_done, self);
else
/* TODO */
/* if (mm_modem_get_state (modem) >= MM_MODEM_STATE_ENABLING) */
/* mm_modem_disable (modem, remove_disable_done, self); */
/* else */
remove_disable_done (modem, NULL, self);
}
g_list_free (modems);

View File

@@ -544,7 +544,7 @@ supports_port (MMPlugin *plugin,
const gchar *subsys,
const gchar *name,
const gchar *physdev_path,
MMModem *existing,
MMBaseModem *existing,
GAsyncReadyCallback callback,
gpointer user_data)
{
@@ -695,17 +695,17 @@ supports_port_cancel (MMPlugin *plugin,
g_free (key);
}
static MMModem *
static MMBaseModem *
grab_port (MMPlugin *plugin,
const char *subsys,
const char *name,
MMModem *existing,
MMBaseModem *existing,
GError **error)
{
MMPluginBase *self = MM_PLUGIN_BASE (plugin);
MMPluginBasePrivate *priv = MM_PLUGIN_BASE_GET_PRIVATE (self);
MMPortProbe *probe;
MMModem *modem = NULL;
MMBaseModem *modem = NULL;
char *key;
key = get_key (subsys, name);

View File

@@ -23,7 +23,7 @@
#include <gudev/gudev.h>
#include "mm-plugin.h"
#include "mm-modem.h"
#include "mm-base-modem.h"
#include "mm-port.h"
#include "mm-port-probe.h"
@@ -59,8 +59,8 @@ struct _MMPluginBaseClass {
GObjectClass parent;
/* Mandatory subclass functions */
MMModem *(*grab_port) (MMPluginBase *plugin,
MMModem *existing,
MMBaseModem *(*grab_port) (MMPluginBase *plugin,
MMBaseModem *existing,
MMPortProbe *probe,
GError **error);
};

View File

@@ -62,7 +62,7 @@ typedef struct {
gchar *subsys;
gchar *name;
gchar *physdev_path;
MMModem *existing;
MMBaseModem *existing;
/* Current context */
MMPlugin *suggested_plugin;
GSList *current;
@@ -341,7 +341,7 @@ mm_plugin_manager_find_port_support (MMPluginManager *self,
const gchar *name,
const gchar *physdev_path,
MMPlugin *suggested_plugin,
MMModem *existing,
MMBaseModem *existing,
GAsyncReadyCallback callback,
gpointer user_data)
{

View File

@@ -21,7 +21,7 @@
#include <glib-object.h>
#include "mm-plugin.h"
#include "mm-modem.h"
#include "mm-base-modem.h"
#define MM_TYPE_PLUGIN_MANAGER (mm_plugin_manager_get_type ())
#define MM_PLUGIN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PLUGIN_MANAGER, MMPluginManager))
@@ -52,7 +52,7 @@ void mm_plugin_manager_find_port_support (MMPluginManager *self,
const gchar *name,
const gchar *physdev_path,
MMPlugin *suggested_plugin,
MMModem *existing,
MMBaseModem *existing,
GAsyncReadyCallback callback,
gpointer user_data);
MMPlugin *mm_plugin_manager_find_port_support_finish (MMPluginManager *self,

View File

@@ -37,7 +37,7 @@ mm_plugin_supports_port (MMPlugin *self,
const gchar *subsys,
const gchar *name,
const gchar *physdev_path,
MMModem *existing,
MMBaseModem *existing,
GAsyncReadyCallback callback,
gpointer user_data)
{
@@ -83,11 +83,11 @@ mm_plugin_supports_port_cancel (MMPlugin *plugin,
MM_PLUGIN_GET_INTERFACE (plugin)->supports_port_cancel (plugin, subsys, name);
}
MMModem *
MMBaseModem *
mm_plugin_grab_port (MMPlugin *plugin,
const char *subsys,
const char *name,
MMModem *existing,
MMBaseModem *existing,
GError **error)
{
g_return_val_if_fail (MM_IS_PLUGIN (plugin), FALSE);

View File

@@ -20,7 +20,7 @@
#include <glib-object.h>
#include <gio/gio.h>
#include <mm-modem.h>
#include "mm-base-modem.h"
#define MM_PLUGIN_GENERIC_NAME "Generic"
@@ -74,7 +74,7 @@ struct _MMPlugin {
const gchar *subsys,
const gchar *name,
const gchar *physdev_path,
MMModem *existing,
MMBaseModem *existing,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -101,10 +101,10 @@ struct _MMPlugin {
* while claiming the port, the error information should be returned in the
* error argument, and the plugin should return NULL.
*/
MMModem * (*grab_port) (MMPlugin *self,
MMBaseModem * (*grab_port) (MMPlugin *self,
const char *subsys,
const char *name,
MMModem *existing,
MMBaseModem *existing,
GError **error);
};
@@ -118,7 +118,7 @@ void mm_plugin_supports_port (MMPlugin *plugin,
const gchar *subsys,
const gchar *name,
const gchar *physdev_path,
MMModem *existing,
MMBaseModem *existing,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -130,10 +130,10 @@ void mm_plugin_supports_port_cancel (MMPlugin *plugin,
const char *subsys,
const char *name);
MMModem *mm_plugin_grab_port (MMPlugin *plugin,
MMBaseModem *mm_plugin_grab_port (MMPlugin *plugin,
const char *subsys,
const char *name,
MMModem *existing,
MMBaseModem *existing,
GError **error);
#endif /* MM_PLUGIN_H */