aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-07-11 10:20:11 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-08-06 20:06:46 +0200
commit6e3d90e2a4cd0a5b863748b88ab67e959f47f0f6 (patch)
treeeb436b6c705b1657a1c7b3d6facc0be880b98e58
parentd63570838be002b4e82d4753e3b137aced1bcfe0 (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.xml14
-rw-r--r--src/mm-plugin.c38
-rw-r--r--src/mm-plugin.h1
-rw-r--r--src/mm-port-probe.c40
-rw-r--r--src/mm-port-probe.h15
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,