diff options
author | Dan Williams <dcbw@redhat.com> | 2009-06-18 14:25:30 -0400 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2009-06-18 14:25:30 -0400 |
commit | 924814c101da42fcb53005691d136852653f0eae (patch) | |
tree | 0ddc83d1c16b323f2962125640fd8ef0d6a0ed55 /src/mm-generic-cdma.c | |
parent | 0555cc1824aabbdda77cf1440c4e7be4ef8cc69e (diff) |
udev: move device probing and detection to udev
Get rid of dependency on HAL, using libgudev instead. Fix up the plugin API
to no longer use either HAL or udev defines, but let plugins use whatever
mechanism they want for getting more information out of the device given the
subsystem and device node name.
Modems are now defined as "master" devices which "own" a one or more ports.
A port could be a serial tty device or a network device or whatever. The
plugin figures out whether it supports a given port or not and then assigns
it to a new or existing modem. Modems now have a 'valid' property that
should be set to TRUE when the modem has enough ports to operate correctly.
For devices (ex. 'hso') that use a network device for data transfer, the
modem would need to grab at least one TTY and the network device associated
with that physical device to be 'valid'.
Also move the generic modem support code to a plugin like other modem plugins,
and change the I-support-this-device mechanism to return a number indicating
the level of support. For example, the generic plugin would return a quite
low number if the device indicates via probing that it can do GSM or CDMA, but
a more specific plugin can indicate better support for the device, and thus
the more specific plugin would win control.
Diffstat (limited to 'src/mm-generic-cdma.c')
-rw-r--r-- | src/mm-generic-cdma.c | 217 |
1 files changed, 182 insertions, 35 deletions
diff --git a/src/mm-generic-cdma.c b/src/mm-generic-cdma.c index de8c916a..984b8aa8 100644 --- a/src/mm-generic-cdma.c +++ b/src/mm-generic-cdma.c @@ -16,25 +16,124 @@ static gpointer mm_generic_cdma_parent_class = NULL; typedef struct { char *driver; + char *plugin; + char *device; + + guint32 ip_method; + gboolean valid; + + MMSerialPort *primary; + MMSerialPort *secondary; } MMGenericCdmaPrivate; MMModem * -mm_generic_cdma_new (const char *serial_device, const char *driver) +mm_generic_cdma_new (const char *device, + const char *driver, + const char *plugin) { - g_return_val_if_fail (serial_device != NULL, NULL); + g_return_val_if_fail (device != NULL, NULL); g_return_val_if_fail (driver != NULL, NULL); + g_return_val_if_fail (plugin != NULL, NULL); return MM_MODEM (g_object_new (MM_TYPE_GENERIC_CDMA, - MM_SERIAL_DEVICE, serial_device, + MM_MODEM_MASTER_DEVICE, device, MM_MODEM_DRIVER, driver, - MM_MODEM_TYPE, MM_MODEM_TYPE_CDMA, + MM_MODEM_PLUGIN, plugin, NULL)); } /*****************************************************************************/ static void -enable_error_reporting_done (MMSerial *serial, +check_valid (MMGenericCdma *self) +{ + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self); + gboolean new_valid = FALSE; + + if (priv->primary) + new_valid = TRUE; + + if (priv->valid != new_valid) { + priv->valid = new_valid; + g_object_notify (G_OBJECT (self), MM_MODEM_VALID); + } +} + +static gboolean +owns_port (MMModem *modem, const char *subsys, const char *name) +{ + MMGenericCdma *self = MM_GENERIC_CDMA (modem); + + if (strcmp (subsys, "tty")) + return FALSE; + + return !!mm_serial_get_port (MM_SERIAL (self), name); +} + +static gboolean +grab_port (MMModem *modem, + const char *subsys, + const char *name, + GError **error) +{ + MMGenericCdma *self = MM_GENERIC_CDMA (modem); + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (self); + MMSerialPortType ptype = MM_SERIAL_PORT_TYPE_IGNORED; + MMSerialPort *port; + + if (strcmp (subsys, "tty")) + return FALSE; + + if (!priv->primary) + ptype = MM_SERIAL_PORT_TYPE_PRIMARY; + else if (!priv->secondary) + ptype = MM_SERIAL_PORT_TYPE_SECONDARY; + + port = mm_serial_add_port (MM_SERIAL (self), name, ptype); + g_object_set (G_OBJECT (port), MM_SERIAL_PORT_CARRIER_DETECT, FALSE, NULL); + mm_serial_port_set_response_parser (port, + mm_serial_parser_v1_parse, + mm_serial_parser_v1_new (), + mm_serial_parser_v1_destroy); + + if (ptype == MM_SERIAL_PORT_TYPE_PRIMARY) { + priv->primary = port; + g_object_notify (G_OBJECT (self), MM_MODEM_DATA_DEVICE); + check_valid (self); + } else if (ptype == MM_SERIAL_PORT_TYPE_SECONDARY) + priv->secondary = port; + + return TRUE; +} + +static void +release_port (MMModem *modem, const char *subsys, const char *name) +{ + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); + MMSerialPort *port; + + if (strcmp (subsys, "tty")) + return; + + port = mm_serial_get_port (MM_SERIAL (modem), name); + if (!port) + return; + + if (port == priv->primary) { + mm_serial_remove_port (MM_SERIAL (modem), port); + priv->primary = NULL; + } + + if (port == priv->secondary) { + mm_serial_remove_port (MM_SERIAL (modem), port); + priv->secondary = NULL; + } + + check_valid (MM_GENERIC_CDMA (modem)); +} + +static void +enable_error_reporting_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -49,7 +148,7 @@ enable_error_reporting_done (MMSerial *serial, } static void -init_done (MMSerial *serial, +init_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -65,14 +164,14 @@ init_done (MMSerial *serial, FIXME: It's mandatory by spec, so it really shouldn't be optional. Figure out which CDMA modems have problems with it and implement plugin for them. */ - mm_serial_queue_command (serial, "+CMEE=1", 3, enable_error_reporting_done, user_data); + mm_serial_port_queue_command (port, "+CMEE=1", 3, enable_error_reporting_done, user_data); } } static void -flash_done (MMSerial *serial, gpointer user_data) +flash_done (MMSerialPort *port, gpointer user_data) { - mm_serial_queue_command (serial, "Z E0 V1 X4 &C1", 3, init_done, user_data); + mm_serial_port_queue_command (port, "Z E0 V1 X4 &C1", 3, init_done, user_data); } static void @@ -81,25 +180,26 @@ enable (MMModem *modem, MMModemFn callback, gpointer user_data) { + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); MMCallbackInfo *info; info = mm_callback_info_new (modem, callback, user_data); if (!do_enable) { - mm_serial_close (MM_SERIAL (modem)); + mm_serial_port_close (priv->primary); mm_callback_info_schedule (info); return; } - if (mm_serial_open (MM_SERIAL (modem), &info->error)) - mm_serial_flash (MM_SERIAL (modem), 100, flash_done, info); + if (mm_serial_port_open (priv->primary, &info->error)) + mm_serial_port_flash (priv->primary, 100, flash_done, info); if (info->error) mm_callback_info_schedule (info); } static void -dial_done (MMSerial *serial, +dial_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -118,17 +218,18 @@ connect (MMModem *modem, MMModemFn callback, gpointer user_data) { + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); MMCallbackInfo *info; char *command; info = mm_callback_info_new (modem, callback, user_data); command = g_strconcat ("DT", number, NULL); - mm_serial_queue_command (MM_SERIAL (modem), command, 60, dial_done, info); + mm_serial_port_queue_command (priv->primary, command, 60, dial_done, info); g_free (command); } static void -disconnect_flash_done (MMSerial *serial, gpointer user_data) +disconnect_flash_done (MMSerialPort *port, gpointer user_data) { mm_callback_info_schedule ((MMCallbackInfo *) user_data); } @@ -138,14 +239,17 @@ disconnect (MMModem *modem, MMModemFn callback, gpointer user_data) { + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); MMCallbackInfo *info; + g_return_if_fail (priv->primary != NULL); + info = mm_callback_info_new (modem, callback, user_data); - mm_serial_flash (MM_SERIAL (modem), 1000, disconnect_flash_done, info); + mm_serial_port_flash (priv->primary, 1000, disconnect_flash_done, info); } static void -get_signal_quality_done (MMSerial *serial, +get_signal_quality_done (MMSerialPort *port, GString *response, GError *error, gpointer user_data) @@ -182,10 +286,15 @@ get_signal_quality (MMModemCdma *modem, MMModemUIntFn callback, gpointer user_data) { + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (modem); MMCallbackInfo *info; info = mm_callback_info_uint_new (MM_MODEM (modem), callback, user_data); - mm_serial_queue_command (MM_SERIAL (modem), "+CSQ", 3, get_signal_quality_done, info); + /* Prefer secondary port for signal strength */ + mm_serial_port_queue_command (priv->secondary ? priv->secondary : priv->primary, + "+CSQ", + 3, + get_signal_quality_done, info); } /*****************************************************************************/ @@ -261,6 +370,7 @@ simple_connect (MMModemSimple *simple, gpointer user_data) { MMCallbackInfo *info; + GError *error = NULL; info = mm_callback_info_new (MM_MODEM (simple), callback, user_data); mm_callback_info_set_data (info, "simple-connect-properties", @@ -268,12 +378,12 @@ simple_connect (MMModemSimple *simple, (GDestroyNotify) g_hash_table_unref); /* At least number must be present */ - if (!simple_get_string_property (info, "number", &info->error)) { - if (!info->error) - info->error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Missing number property"); + if (!simple_get_string_property (info, "number", &error)) { + if (!error) + error = g_error_new_literal (MM_MODEM_ERROR, MM_MODEM_ERROR_GENERAL, "Missing number property"); } - simple_state_machine (MM_MODEM (simple), NULL, info); + simple_state_machine (MM_MODEM (simple), error, info); } static void @@ -340,6 +450,9 @@ simple_get_status (MMModemSimple *simple, static void modem_init (MMModem *modem_class) { + modem_class->owns_port = owns_port; + modem_class->grab_port = grab_port; + modem_class->release_port = release_port; modem_class->enable = enable; modem_class->connect = connect; modem_class->disconnect = disconnect; @@ -361,24 +474,32 @@ modem_simple_init (MMModemSimple *class) static void mm_generic_cdma_init (MMGenericCdma *self) { - mm_serial_set_response_parser (MM_SERIAL (self), - mm_serial_parser_v1_parse, - mm_serial_parser_v1_new (), - mm_serial_parser_v1_destroy); } static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (object); + switch (prop_id) { case MM_MODEM_PROP_DRIVER: /* Construct only */ - MM_GENERIC_CDMA_GET_PRIVATE (object)->driver = g_value_dup_string (value); + priv->driver = g_value_dup_string (value); + break; + case MM_MODEM_PROP_PLUGIN: + /* Construct only */ + priv->plugin = g_value_dup_string (value); + break; + case MM_MODEM_PROP_MASTER_DEVICE: + /* Constrcut only */ + priv->device = g_value_dup_string (value); break; - case MM_MODEM_PROP_DEVICE: - case MM_MODEM_PROP_TYPE: case MM_MODEM_PROP_IP_METHOD: + priv->ip_method = g_value_get_uint (value); + break; + case MM_MODEM_PROP_TYPE: + case MM_MODEM_PROP_VALID: break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -390,18 +511,32 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { + MMGenericCdmaPrivate *priv = MM_GENERIC_CDMA_GET_PRIVATE (object); + switch (prop_id) { - case MM_MODEM_PROP_DEVICE: - g_value_set_string (value, mm_serial_get_device (MM_SERIAL (object))); + case MM_MODEM_PROP_DATA_DEVICE: + if (priv->primary) + g_value_set_string (value, mm_serial_port_get_device (priv->primary)); + else + g_value_set_string (value, NULL); + break; + case MM_MODEM_PROP_MASTER_DEVICE: + g_value_set_string (value, priv->device); break; case MM_MODEM_PROP_DRIVER: - g_value_set_string (value, MM_GENERIC_CDMA_GET_PRIVATE (object)->driver); + g_value_set_string (value, priv->driver); + break; + case MM_MODEM_PROP_PLUGIN: + g_value_set_string (value, priv->plugin); break; case MM_MODEM_PROP_TYPE: g_value_set_uint (value, MM_MODEM_TYPE_CDMA); break; case MM_MODEM_PROP_IP_METHOD: - g_value_set_uint (value, MM_MODEM_IP_METHOD_PPP); + g_value_set_uint (value, priv->ip_method); + break; + case MM_MODEM_PROP_VALID: + g_value_set_boolean (value, priv->valid); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -434,20 +569,32 @@ mm_generic_cdma_class_init (MMGenericCdmaClass *klass) /* Properties */ g_object_class_override_property (object_class, - MM_MODEM_PROP_DEVICE, - MM_MODEM_DEVICE); + MM_MODEM_PROP_DATA_DEVICE, + MM_MODEM_DATA_DEVICE); + + g_object_class_override_property (object_class, + MM_MODEM_PROP_MASTER_DEVICE, + MM_MODEM_MASTER_DEVICE); g_object_class_override_property (object_class, MM_MODEM_PROP_DRIVER, MM_MODEM_DRIVER); g_object_class_override_property (object_class, + MM_MODEM_PROP_PLUGIN, + MM_MODEM_PLUGIN); + + g_object_class_override_property (object_class, MM_MODEM_PROP_TYPE, MM_MODEM_TYPE); g_object_class_override_property (object_class, MM_MODEM_PROP_IP_METHOD, MM_MODEM_IP_METHOD); + + g_object_class_override_property (object_class, + MM_MODEM_PROP_VALID, + MM_MODEM_VALID); } GType |