plugin: new `MM_PLUGIN_CUSTOM_INIT' property

We let plugins execute some custom initialization in the ports, specified by
a `MMAsyncMethod'.
This commit is contained in:
Aleksander Morgado
2012-07-11 10:20:11 +02:00
parent d63570838b
commit 6e3d90e2a4
5 changed files with 104 additions and 4 deletions

View File

@@ -175,6 +175,20 @@
prepare the information required in any expected post-probing filter.
</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>

View File

@@ -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 */
/* 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;
@@ -872,6 +893,15 @@ mm_plugin_class_init (MMPluginClass *klass)
MM_TYPE_POINTER_ARRAY,
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,

View File

@@ -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"

View File

@@ -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 */
@@ -560,6 +565,24 @@ static const MMPortProbeAtCommand product_probing[] = {
{ NULL }
};
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)
{
@@ -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,

View File

@@ -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,