diff options
-rw-r--r-- | src/mm-plugin.c | 22 | ||||
-rw-r--r-- | src/mm-plugin.h | 1 | ||||
-rw-r--r-- | src/mm-port-probe.c | 153 | ||||
-rw-r--r-- | src/mm-port-probe.h | 1 |
4 files changed, 107 insertions, 70 deletions
diff --git a/src/mm-plugin.c b/src/mm-plugin.c index f4d84ad4..97dcbc44 100644 --- a/src/mm-plugin.c +++ b/src/mm-plugin.c @@ -91,6 +91,7 @@ struct _MMPluginPrivate { gboolean at; gboolean single_at; gboolean qcdm; + gboolean qcdm_required; gboolean qmi; gboolean mbim; gboolean icera_probe; @@ -124,6 +125,7 @@ enum { PROP_ALLOWED_AT, PROP_ALLOWED_SINGLE_AT, PROP_ALLOWED_QCDM, + PROP_REQUIRED_QCDM, PROP_ALLOWED_QMI, PROP_ALLOWED_MBIM, PROP_ICERA_PROBE, @@ -802,7 +804,7 @@ mm_plugin_supports_port (MMPlugin *self, probe_run_flags |= MM_PORT_PROBE_AT; else if (self->priv->single_at) probe_run_flags |= MM_PORT_PROBE_AT; - if (self->priv->qcdm) + if (self->priv->qcdm || self->priv->qcdm_required) probe_run_flags |= MM_PORT_PROBE_QCDM; } else if (g_str_equal (mm_kernel_device_get_subsystem (port), "usbmisc")) { if (self->priv->qmi && !g_strcmp0 (mm_kernel_device_get_driver (port), "qmi_wwan")) @@ -821,7 +823,7 @@ mm_plugin_supports_port (MMPlugin *self, probe_run_flags |= MM_PORT_PROBE_MBIM; if (self->priv->qmi) probe_run_flags |= MM_PORT_PROBE_QMI; - if (self->priv->qcdm) + if (self->priv->qcdm || self->priv->qcdm_required) probe_run_flags |= MM_PORT_PROBE_QCDM; if (self->priv->at) probe_run_flags |= MM_PORT_PROBE_AT; @@ -893,6 +895,7 @@ mm_plugin_supports_port (MMPlugin *self, self->priv->send_lf, self->priv->custom_at_probe, self->priv->custom_init, + self->priv->qcdm_required, cancellable, (GAsyncReadyCallback) port_probe_run_ready, task); @@ -1238,6 +1241,10 @@ set_property (GObject *object, /* Construct only */ self->priv->qcdm = g_value_get_boolean (value); break; + case PROP_REQUIRED_QCDM: + /* Construct only */ + self->priv->qcdm_required = g_value_get_boolean (value); + break; case PROP_ALLOWED_QMI: /* Construct only */ self->priv->qmi = g_value_get_boolean (value); @@ -1350,6 +1357,9 @@ get_property (GObject *object, case PROP_ALLOWED_QCDM: g_value_set_boolean (value, self->priv->qcdm); break; + case PROP_REQUIRED_QCDM: + g_value_set_boolean (value, self->priv->qcdm_required); + break; case PROP_ALLOWED_QMI: g_value_set_boolean (value, self->priv->qmi); break; @@ -1584,6 +1594,14 @@ mm_plugin_class_init (MMPluginClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property + (object_class, PROP_REQUIRED_QCDM, + g_param_spec_boolean (MM_PLUGIN_REQUIRED_QCDM, + "Required QCDM", + "Whether QCDM ports are required in this plugin", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_class, PROP_ALLOWED_QMI, g_param_spec_boolean (MM_PLUGIN_ALLOWED_QMI, "Allowed QMI", diff --git a/src/mm-plugin.h b/src/mm-plugin.h index 3c00ed1a..1c071383 100644 --- a/src/mm-plugin.h +++ b/src/mm-plugin.h @@ -62,6 +62,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_REQUIRED_QCDM "required-qcdm" #define MM_PLUGIN_ALLOWED_QMI "allowed-qmi" #define MM_PLUGIN_ALLOWED_MBIM "allowed-mbim" #define MM_PLUGIN_ICERA_PROBE "icera-probe" diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index ed7d36ab..650a05c5 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -380,6 +380,9 @@ typedef struct { /* ---- MBIM probing specific context ---- */ MMPortMbim *mbim_port; #endif + + /* ---- QCDM probing specific context ---- */ + gboolean qcdm_required; } PortProbeRunContext; static gboolean serial_probe_at (MMPortProbe *self); @@ -756,84 +759,96 @@ serial_probe_qcdm (MMPortProbe *self) if (port_probe_task_return_error_if_cancelled (self)) return G_SOURCE_REMOVE; - mm_obj_dbg (self, "probing QCDM..."); + /* Check if port requires QCDM probing */ + if (!ctx->qcdm_required) { + /* Ok, this is probably a QCDM port */ + mm_obj_dbg (self, "Likely a QCDM port, but plugin does not require probing and grabbing..."); + mm_port_probe_set_result_qcdm (self, TRUE); + self->priv->is_ignored = TRUE; + /* Reschedule probing */ + serial_probe_schedule (self); - /* If open, close the AT port */ - if (ctx->serial) { - /* Explicitly clear the buffer full signal handler */ - if (ctx->buffer_full_id) { - g_signal_handler_disconnect (ctx->serial, ctx->buffer_full_id); - ctx->buffer_full_id = 0; + return G_SOURCE_REMOVE; + } else { + mm_obj_dbg (self, "probing QCDM..."); + + /* If open, close the AT port */ + if (ctx->serial) { + /* Explicitly clear the buffer full signal handler */ + if (ctx->buffer_full_id) { + g_signal_handler_disconnect (ctx->serial, ctx->buffer_full_id); + ctx->buffer_full_id = 0; + } + mm_port_serial_close (ctx->serial); + g_object_unref (ctx->serial); } - mm_port_serial_close (ctx->serial); - g_object_unref (ctx->serial); - } - if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "wwan")) - subsys = MM_PORT_SUBSYS_WWAN; + if (g_str_equal (mm_kernel_device_get_subsystem (self->priv->port), "wwan")) + subsys = MM_PORT_SUBSYS_WWAN; - /* Open the QCDM port */ - ctx->serial = MM_PORT_SERIAL (mm_port_serial_qcdm_new (mm_kernel_device_get_name (self->priv->port), subsys)); - if (!ctx->serial) { - port_probe_task_return_error (self, - g_error_new (MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "(%s/%s) Couldn't create QCDM port", - mm_kernel_device_get_subsystem (self->priv->port), - mm_kernel_device_get_name (self->priv->port))); - return G_SOURCE_REMOVE; - } + /* Open the QCDM port */ + ctx->serial = MM_PORT_SERIAL (mm_port_serial_qcdm_new (mm_kernel_device_get_name (self->priv->port), subsys)); + if (!ctx->serial) { + port_probe_task_return_error (self, + g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "(%s/%s) Couldn't create QCDM port", + mm_kernel_device_get_subsystem (self->priv->port), + mm_kernel_device_get_name (self->priv->port))); + return G_SOURCE_REMOVE; + } - /* Setup port if needed */ - common_serial_port_setup (self, ctx->serial); + /* Setup port if needed */ + common_serial_port_setup (self, ctx->serial); - /* Try to open the port */ - if (!mm_port_serial_open (ctx->serial, &error)) { - port_probe_task_return_error (self, - g_error_new (MM_SERIAL_ERROR, - MM_SERIAL_ERROR_OPEN_FAILED, - "(%s/%s) Failed to open QCDM port: %s", - mm_kernel_device_get_subsystem (self->priv->port), - mm_kernel_device_get_name (self->priv->port), - (error ? error->message : "unknown error"))); - g_clear_error (&error); - return G_SOURCE_REMOVE; - } + /* Try to open the port */ + if (!mm_port_serial_open (ctx->serial, &error)) { + port_probe_task_return_error (self, + g_error_new (MM_SERIAL_ERROR, + MM_SERIAL_ERROR_OPEN_FAILED, + "(%s/%s) Failed to open QCDM port: %s", + mm_kernel_device_get_subsystem (self->priv->port), + mm_kernel_device_get_name (self->priv->port), + (error ? error->message : "unknown error"))); + g_clear_error (&error); + return G_SOURCE_REMOVE; + } - /* Build up the probe command; 0x7E is the frame marker, so put one at the - * beginning of the buffer to ensure that the device discards any AT - * commands that probing might have sent earlier. Should help devices - * respond more quickly and speed up QCDM probing. - */ - verinfo = g_byte_array_sized_new (10); - g_byte_array_append (verinfo, &marker, 1); - len = qcdm_cmd_version_info_new ((char *) (verinfo->data + 1), 9); - if (len <= 0) { + /* Build up the probe command; 0x7E is the frame marker, so put one at the + * beginning of the buffer to ensure that the device discards any AT + * commands that probing might have sent earlier. Should help devices + * respond more quickly and speed up QCDM probing. + */ + verinfo = g_byte_array_sized_new (10); + g_byte_array_append (verinfo, &marker, 1); + len = qcdm_cmd_version_info_new ((char *) (verinfo->data + 1), 9); + if (len <= 0) { + g_byte_array_unref (verinfo); + port_probe_task_return_error (self, + g_error_new (MM_SERIAL_ERROR, + MM_SERIAL_ERROR_OPEN_FAILED, + "(%s/%s) Failed to create QCDM version info command", + mm_kernel_device_get_subsystem (self->priv->port), + mm_kernel_device_get_name (self->priv->port))); + return G_SOURCE_REMOVE; + } + verinfo->len = len + 1; + + /* Queuing the command takes ownership over it; save it for the second try */ + verinfo2 = g_byte_array_sized_new (verinfo->len); + g_byte_array_append (verinfo2, verinfo->data, verinfo->len); + g_object_set_data_full (G_OBJECT (self), "cmd2", verinfo2, (GDestroyNotify) g_byte_array_unref); + + mm_port_serial_qcdm_command (MM_PORT_SERIAL_QCDM (ctx->serial), + verinfo, + 3, + NULL, + (GAsyncReadyCallback) serial_probe_qcdm_parse_response, + self); g_byte_array_unref (verinfo); - port_probe_task_return_error (self, - g_error_new (MM_SERIAL_ERROR, - MM_SERIAL_ERROR_OPEN_FAILED, - "(%s/%s) Failed to create QCDM version info command", - mm_kernel_device_get_subsystem (self->priv->port), - mm_kernel_device_get_name (self->priv->port))); + return G_SOURCE_REMOVE; } - verinfo->len = len + 1; - - /* Queuing the command takes ownership over it; save it for the second try */ - verinfo2 = g_byte_array_sized_new (verinfo->len); - g_byte_array_append (verinfo2, verinfo->data, verinfo->len); - g_object_set_data_full (G_OBJECT (self), "cmd2", verinfo2, (GDestroyNotify) g_byte_array_unref); - - mm_port_serial_qcdm_command (MM_PORT_SERIAL_QCDM (ctx->serial), - verinfo, - 3, - NULL, - (GAsyncReadyCallback) serial_probe_qcdm_parse_response, - self); - g_byte_array_unref (verinfo); - - return G_SOURCE_REMOVE; } /***************************************************************/ @@ -1428,6 +1443,7 @@ mm_port_probe_run (MMPortProbe *self, gboolean at_send_lf, const MMPortProbeAtCommand *at_custom_probe, const MMAsyncMethod *at_custom_init, + gboolean qcdm_required, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) @@ -1453,6 +1469,7 @@ mm_port_probe_run (MMPortProbe *self, ctx->at_custom_probe = at_custom_probe; ctx->at_custom_init = at_custom_init ? (MMPortProbeAtCustomInit)at_custom_init->async : NULL; ctx->at_custom_init_finish = at_custom_init ? (MMPortProbeAtCustomInitFinish)at_custom_init->finish : NULL; + ctx->qcdm_required = qcdm_required; ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; /* The context will be owned by the task */ diff --git a/src/mm-port-probe.h b/src/mm-port-probe.h index 9c2fd893..5dd56a8f 100644 --- a/src/mm-port-probe.h +++ b/src/mm-port-probe.h @@ -117,6 +117,7 @@ void mm_port_probe_run (MMPortProbe *self, gboolean at_send_lf, const MMPortProbeAtCommand *at_custom_probe, const MMAsyncMethod *at_custom_init, + gboolean qcdm_required, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); |