diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-07-11 10:20:11 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-08-06 20:06:46 +0200 |
commit | 6e3d90e2a4cd0a5b863748b88ab67e959f47f0f6 (patch) | |
tree | eb436b6c705b1657a1c7b3d6facc0be880b98e58 | |
parent | d63570838be002b4e82d4753e3b137aced1bcfe0 (diff) |
plugin: new `MM_PLUGIN_CUSTOM_INIT' property
We let plugins execute some custom initialization in the ports, specified by
a `MMAsyncMethod'.
-rw-r--r-- | docs/reference/api/ModemManager-overview.xml | 14 | ||||
-rw-r--r-- | src/mm-plugin.c | 38 | ||||
-rw-r--r-- | src/mm-plugin.h | 1 | ||||
-rw-r--r-- | src/mm-port-probe.c | 40 | ||||
-rw-r--r-- | src/mm-port-probe.h | 15 |
5 files changed, 104 insertions, 4 deletions
diff --git a/docs/reference/api/ModemManager-overview.xml b/docs/reference/api/ModemManager-overview.xml index 79147e13..ebb81585 100644 --- a/docs/reference/api/ModemManager-overview.xml +++ b/docs/reference/api/ModemManager-overview.xml @@ -176,6 +176,20 @@ </para> <itemizedlist> <listitem> + <para><emphasis>Custom initialization</emphasis></para> + <para> + This property allows plugins to provide an asynchronous method which will get + executed as soon as the AT port gets opened. This method may be used for any + purpose, like running an early command in the ports as soon as possible, or + querying the modem for info about the port layout. + </para> + <para> + This configuration is specified by the <type>MM_PLUGIN_CUSTOM_INIT</type> + property in the <structname>MMPlugin</structname> object provided + by the plugin. + </para> + </listitem> + <listitem> <para><emphasis>AT allowed</emphasis></para> <para> This boolean property allows plugins to specify that they expect and support diff --git a/src/mm-plugin.c b/src/mm-plugin.c index 9a9faa93..7a1f49c2 100644 --- a/src/mm-plugin.c +++ b/src/mm-plugin.c @@ -62,6 +62,7 @@ struct _MMPluginPrivate { gboolean single_at; gboolean qcdm; MMPortProbeAtCommand *custom_at_probe; + MMAsyncMethod *custom_init; guint64 send_delay; }; @@ -80,6 +81,7 @@ enum { PROP_ALLOWED_SINGLE_AT, PROP_ALLOWED_QCDM, PROP_CUSTOM_AT_PROBE, + PROP_CUSTOM_INIT, PROP_SEND_DELAY, LAST_PROP }; @@ -372,8 +374,20 @@ port_probe_run_ready (MMPortProbe *probe, GError *error = NULL; if (!mm_port_probe_run_finish (probe, probe_result, &error)) { - /* Probing failed */ - g_simple_async_result_take_error (ctx->result, error); + /* Probing failed saying the port is unsupported. This is not to be + * treated as a generic error, the plugin is just telling us as nicely + * as it can that the port is not supported, so don't warn these cases. + */ + if (g_error_matches (error, + MM_CORE_ERROR, + MM_CORE_ERROR_UNSUPPORTED)) { + g_simple_async_result_set_op_res_gpointer (ctx->result, + GUINT_TO_POINTER (MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED), + NULL); + } else { + /* For remaining errors, just propagate them */ + g_simple_async_result_take_error (ctx->result, error); + } } else { /* Probing succeeded */ MMPluginSupportsResult supports_result; @@ -427,8 +441,7 @@ mm_plugin_supports_port_finish (MMPlugin *self, MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED); /* Propagate error, if any */ - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), - error)) { + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error)) { return MM_PLUGIN_SUPPORTS_PORT_UNSUPPORTED; } @@ -539,6 +552,7 @@ mm_plugin_supports_port (MMPlugin *self, ctx->flags, self->priv->send_delay, self->priv->custom_at_probe, + self->priv->custom_init, (GAsyncReadyCallback)port_probe_run_ready, ctx); @@ -668,6 +682,10 @@ set_property (GObject *object, /* Construct only */ self->priv->custom_at_probe = g_value_dup_boxed (value); break; + case PROP_CUSTOM_INIT: + /* Construct only */ + self->priv->custom_init = g_value_dup_boxed (value); + break; case PROP_SEND_DELAY: /* Construct only */ self->priv->send_delay = (guint64)g_value_get_uint64 (value); @@ -726,6 +744,9 @@ get_property (GObject *object, case PROP_CUSTOM_AT_PROBE: g_value_set_boxed (value, self->priv->custom_at_probe); break; + case PROP_CUSTOM_INIT: + g_value_set_boxed (value, self->priv->custom_init); + break; case PROP_SEND_DELAY: g_value_set_uint64 (value, self->priv->send_delay); break; @@ -873,6 +894,15 @@ mm_plugin_class_init (MMPluginClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property + (object_class, PROP_CUSTOM_INIT, + g_param_spec_boxed (MM_PLUGIN_CUSTOM_INIT, + "Custom initialization", + "Asynchronous method setup which contains the " + "custom initializations this plugin needs.", + MM_TYPE_ASYNC_METHOD, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_SEND_DELAY, g_param_spec_uint64 (MM_PLUGIN_SEND_DELAY, "Send delay", diff --git a/src/mm-plugin.h b/src/mm-plugin.h index d63a734f..d9efa69b 100644 --- a/src/mm-plugin.h +++ b/src/mm-plugin.h @@ -49,6 +49,7 @@ #define MM_PLUGIN_ALLOWED_AT "allowed-at" #define MM_PLUGIN_ALLOWED_SINGLE_AT "allowed-single-at" #define MM_PLUGIN_ALLOWED_QCDM "allowed-qcdm" +#define MM_PLUGIN_CUSTOM_INIT "custom-init" #define MM_PLUGIN_CUSTOM_AT_PROBE "custom-at-probe" #define MM_PLUGIN_SEND_DELAY "send-delay" diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index adcf8b87..55a328e7 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -37,6 +37,7 @@ /* * Steps and flow of the Probing process: * ----> AT Serial Open + * |----> Custom Init * |----> AT? * |----> Vendor * |----> Product @@ -68,6 +69,10 @@ typedef struct { guint64 at_send_delay; /* Number of times we tried to open the AT port */ guint at_open_tries; + /* Custom initialization setup */ + gboolean at_custom_init_run; + MMPortProbeAtCustomInit at_custom_init; + MMPortProbeAtCustomInitFinish at_custom_init_finish; /* Custom commands to look for AT support */ const MMPortProbeAtCommand *at_custom_probe; /* Current group of AT commands to be sent */ @@ -561,6 +566,24 @@ static const MMPortProbeAtCommand product_probing[] = { }; static void +at_custom_init_ready (MMPortProbe *self, + GAsyncResult *res) +{ + PortProbeRunTask *task = self->priv->task; + GError *error = NULL; + + if (!task->at_custom_init_finish (self, res, &error)) { + /* All errors propagated up end up forcing an UNSUPPORTED result */ + port_probe_run_task_complete (task, FALSE, error); + return; + } + + /* Keep on with remaining probings */ + task->at_custom_init_run = TRUE; + serial_probe_schedule (self); +} + +static void serial_probe_schedule (MMPortProbe *self) { PortProbeRunTask *task = self->priv->task; @@ -569,6 +592,19 @@ serial_probe_schedule (MMPortProbe *self) if (port_probe_run_is_cancelled (self)) return; + /* If we got some custom initialization setup requested, go on with it + * first. */ + if (!task->at_custom_init_run && + task->at_custom_init && + task->at_custom_init_finish) { + task->at_custom_init (self, + MM_AT_SERIAL_PORT (task->serial), + task->at_probing_cancellable, + (GAsyncReadyCallback)at_custom_init_ready, + NULL); + return; + } + /* Cleanup */ task->at_result_processor = NULL; task->at_commands = NULL; @@ -833,6 +869,7 @@ mm_port_probe_run (MMPortProbe *self, MMPortProbeFlag flags, guint64 at_send_delay, const MMPortProbeAtCommand *at_custom_probe, + const MMAsyncMethod *at_custom_init, GAsyncReadyCallback callback, gpointer user_data) { @@ -851,6 +888,9 @@ mm_port_probe_run (MMPortProbe *self, task->at_send_delay = at_send_delay; task->flags = MM_PORT_PROBE_NONE; task->at_custom_probe = at_custom_probe; + task->at_custom_init = at_custom_init ? (MMPortProbeAtCustomInit)at_custom_init->async : NULL; + task->at_custom_init_finish = at_custom_init ? (MMPortProbeAtCustomInitFinish)at_custom_init->finish : NULL; + task->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, diff --git a/src/mm-port-probe.h b/src/mm-port-probe.h index cd139784..820a7eb4 100644 --- a/src/mm-port-probe.h +++ b/src/mm-port-probe.h @@ -21,6 +21,7 @@ #include <gio/gio.h> #include <gudev/gudev.h> +#include "mm-private-boxed-types.h" #include "mm-port-probe-at.h" #include "mm-at-serial-port.h" @@ -55,6 +56,19 @@ struct _MMPortProbeClass { GObjectClass parent; }; +/* Custom AT probing initialization setup. + * Plugins can use this to configure how AT ports need to get initialized. + * It also helps to implement plugin-specific checks, as plugins can set + * their own probing results on the 'probe' object. */ +typedef void (* MMPortProbeAtCustomInit) (MMPortProbe *probe, + MMAtSerialPort *port, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +typedef gboolean (* MMPortProbeAtCustomInitFinish) (MMPortProbe *probe, + GAsyncResult *result, + GError **error); + GType mm_port_probe_get_type (void); MMPortProbe *mm_port_probe_new (GUdevDevice *port); @@ -79,6 +93,7 @@ void mm_port_probe_run (MMPortProbe *self, MMPortProbeFlag flags, guint64 at_send_delay, const MMPortProbeAtCommand *at_custom_probe, + const MMAsyncMethod *at_custom_init, GAsyncReadyCallback callback, gpointer user_data); gboolean mm_port_probe_run_finish (MMPortProbe *self, |