diff options
author | mank.wang <mank.wang@quectel.com> | 2024-07-25 09:37:30 +0800 |
---|---|---|
committer | Aleksander Morgado <aleksandermj@chromium.org> | 2024-07-31 13:58:16 +0000 |
commit | 8cbd12a6037e69457f6f56efc5631e6f9b2cf1b8 (patch) | |
tree | 61f5470b304a51031b9463d0a516677d7acc7c74 | |
parent | 14192af87e26822973e4da971bbc60fe6d6280c2 (diff) |
quectel: support at over mbim in quectel modems
-rw-r--r-- | src/plugins/meson.build | 5 | ||||
-rw-r--r-- | src/plugins/quectel/mm-broadband-modem-mbim-quectel.c | 11 | ||||
-rw-r--r-- | src/plugins/quectel/mm-broadband-modem-qmi-quectel.c | 8 | ||||
-rw-r--r-- | src/plugins/quectel/mm-broadband-modem-quectel.c | 8 | ||||
-rw-r--r-- | src/plugins/quectel/mm-port-mbim-quectel.c | 291 | ||||
-rw-r--r-- | src/plugins/quectel/mm-port-mbim-quectel.h | 59 | ||||
-rw-r--r-- | src/plugins/quectel/mm-shared-quectel.c | 106 | ||||
-rw-r--r-- | src/plugins/quectel/mm-shared-quectel.h | 10 |
8 files changed, 422 insertions, 76 deletions
diff --git a/src/plugins/meson.build b/src/plugins/meson.build index 7cc6ef92..d7f78a4a 100644 --- a/src/plugins/meson.build +++ b/src/plugins/meson.build @@ -790,7 +790,10 @@ if plugins_options['quectel'] endif if enable_mbim - sources += files('quectel/mm-broadband-modem-mbim-quectel.c') + sources += files( + 'quectel/mm-broadband-modem-mbim-quectel.c', + 'quectel/mm-port-mbim-quectel.c' + ) endif plugins += {'plugin-quectel': { diff --git a/src/plugins/quectel/mm-broadband-modem-mbim-quectel.c b/src/plugins/quectel/mm-broadband-modem-mbim-quectel.c index 9f2dc7d3..82fa8c47 100644 --- a/src/plugins/quectel/mm-broadband-modem-mbim-quectel.c +++ b/src/plugins/quectel/mm-broadband-modem-mbim-quectel.c @@ -119,10 +119,10 @@ peek_parent_modem_location_interface (MMSharedQuectel *self) return iface_modem_location_parent; } -static MMBroadbandModemClass * -peek_parent_broadband_modem_class (MMSharedQuectel *self) +static MMBaseModemClass * +peek_parent_class (MMSharedQuectel *self) { - return MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_mbim_quectel_parent_class); + return MM_BASE_MODEM_CLASS (mm_broadband_modem_mbim_quectel_parent_class); } static void @@ -130,13 +130,16 @@ shared_quectel_init (MMSharedQuectelInterface *iface) { iface->peek_parent_modem_interface = peek_parent_modem_interface; iface->peek_parent_modem_location_interface = peek_parent_modem_location_interface; - iface->peek_parent_broadband_modem_class = peek_parent_broadband_modem_class; + iface->peek_parent_class = peek_parent_class; } static void mm_broadband_modem_mbim_quectel_class_init (MMBroadbandModemMbimQuectelClass *klass) { + MMBaseModemClass *base_modem_class = MM_BASE_MODEM_CLASS (klass); MMBroadbandModemClass *broadband_modem_class = MM_BROADBAND_MODEM_CLASS (klass); + base_modem_class->create_usbmisc_port = mm_shared_quectel_create_usbmisc_port; + base_modem_class->create_wwan_port = mm_shared_quectel_create_wwan_port; broadband_modem_class->setup_ports = mm_shared_quectel_setup_ports; } diff --git a/src/plugins/quectel/mm-broadband-modem-qmi-quectel.c b/src/plugins/quectel/mm-broadband-modem-qmi-quectel.c index eef3438b..a4e536a7 100644 --- a/src/plugins/quectel/mm-broadband-modem-qmi-quectel.c +++ b/src/plugins/quectel/mm-broadband-modem-qmi-quectel.c @@ -189,10 +189,10 @@ iface_modem_time_init (MMIfaceModemTimeInterface *iface) iface->check_support_finish = mm_shared_quectel_time_check_support_finish; } -static MMBroadbandModemClass * -peek_parent_broadband_modem_class (MMSharedQuectel *self) +static MMBaseModemClass * +peek_parent_class (MMSharedQuectel *self) { - return MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_qmi_quectel_parent_class); + return MM_BASE_MODEM_CLASS (mm_broadband_modem_qmi_quectel_parent_class); } static MMIfaceModemInterface * @@ -221,7 +221,7 @@ shared_quectel_init (MMSharedQuectelInterface *iface) { iface->peek_parent_modem_interface = peek_parent_modem_interface; iface->peek_parent_modem_location_interface = peek_parent_modem_location_interface; - iface->peek_parent_broadband_modem_class = peek_parent_broadband_modem_class; + iface->peek_parent_class = peek_parent_class; } static void diff --git a/src/plugins/quectel/mm-broadband-modem-quectel.c b/src/plugins/quectel/mm-broadband-modem-quectel.c index ef11196a..ff5a22e1 100644 --- a/src/plugins/quectel/mm-broadband-modem-quectel.c +++ b/src/plugins/quectel/mm-broadband-modem-quectel.c @@ -104,10 +104,10 @@ iface_modem_time_init (MMIfaceModemTimeInterface *iface) iface->check_support_finish = mm_shared_quectel_time_check_support_finish; } -static MMBroadbandModemClass * -peek_parent_broadband_modem_class (MMSharedQuectel *self) +static MMBaseModemClass * +peek_parent_class (MMSharedQuectel *self) { - return MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_quectel_parent_class); + return MM_BASE_MODEM_CLASS (mm_broadband_modem_quectel_parent_class); } static MMIfaceModemInterface * @@ -127,7 +127,7 @@ shared_quectel_init (MMSharedQuectelInterface *iface) { iface->peek_parent_modem_interface = peek_parent_modem_interface; iface->peek_parent_modem_location_interface = peek_parent_modem_location_interface; - iface->peek_parent_broadband_modem_class = peek_parent_broadband_modem_class; + iface->peek_parent_class = peek_parent_class; } static void diff --git a/src/plugins/quectel/mm-port-mbim-quectel.c b/src/plugins/quectel/mm-port-mbim-quectel.c new file mode 100644 index 00000000..617b681a --- /dev/null +++ b/src/plugins/quectel/mm-port-mbim-quectel.c @@ -0,0 +1,291 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2024 Quectel Wireless Solution,Co.,Ltd. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#include <ModemManager.h> +#include <mm-errors-types.h> + +#include "mm-serial-parsers.h" +#include "mm-iface-port-at.h" +#include "mm-port-mbim-quectel.h" +#include "mm-log-object.h" + +static void iface_port_at_init (MMIfacePortAtInterface *iface); + +G_DEFINE_TYPE_EXTENDED (MMPortMbimQuectel, mm_port_mbim_quectel, MM_TYPE_PORT_MBIM, 0, + G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_PORT_AT, iface_port_at_init)) + +typedef enum { + FEATURE_SUPPORT_UNKNOWN, + FEATURE_NOT_SUPPORTED, + FEATURE_SUPPORTED +} FeatureSupport; + +struct _MMPortMbimQuectelPrivate { + FeatureSupport at_over_mbim; + gpointer parser; +}; + +/*****************************************************************************/ + +static gboolean +iface_port_at_check_support (MMIfacePortAt *_self, + gboolean *out_supported, + GError **error) +{ + MMPortMbimQuectel *self = MM_PORT_MBIM_QUECTEL (_self); + + g_assert (out_supported); + + if (self->priv->at_over_mbim == FEATURE_SUPPORT_UNKNOWN) { + /* First time check */ + if (!mm_port_mbim_is_open (MM_PORT_MBIM (self))) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_WRONG_STATE, + "Couldn't check AT support: MBIM port is closed"); + return FALSE; + } + + if (!mm_port_mbim_supports_command (MM_PORT_MBIM (self), MBIM_SERVICE_QDU, MBIM_CID_QDU_COMMAND)) { + mm_obj_msg (self, "MBIM device is not AT capable"); + self->priv->at_over_mbim = FEATURE_NOT_SUPPORTED; + } else { + mm_obj_msg (self, "MBIM device is AT capable"); + self->priv->at_over_mbim = FEATURE_SUPPORTED; + } + } + + *out_supported = (self->priv->at_over_mbim == FEATURE_SUPPORTED); + return TRUE; +} + +/*****************************************************************************/ +/* AT command */ +static gchar * +iface_port_at_command_finish (MMIfacePortAt *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +debug_log (MMPortMbimQuectel *self, + const gchar *prefix, + const guint8 *buf, + gsize len) +{ + g_autoptr(GString) debug = NULL; + const guint8 *s; + + debug = g_string_new (prefix); + g_string_append (debug, " '"); + + s = buf; + while (len--) { + if (g_ascii_isprint ((gchar)*s)) + g_string_append_c (debug, (gchar)*s); + else if (*s == '\r') + g_string_append (debug, "<CR>"); + else if (*s == '\n') + g_string_append (debug, "<LF>"); + else + g_string_append_printf (debug, "\\%u", (guint8) (*s & 0xFF)); + s++; + } + + g_string_append_c (debug, '\''); + mm_obj_dbg (self, "%s", debug->str); +} + +static void +at_command_ready (MbimDevice *device, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + MMPortMbimQuectel *self; + guint32 ret_size = 0; + const gchar *ret_str = NULL; + const gchar *resp_str = NULL; + g_autoptr(MbimMessage) response = NULL; + guint32 ret_status = 0; + GString *string; + + self = g_task_get_source_object (task); + + response = mbim_device_command_finish (device, res, &error); + if (!response || + !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) || + !mbim_message_qdu_command_response_parse ( + response, + &ret_status, + &ret_size, + (const guint8 **)&ret_str, + &error)) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + /* The first line in the response information of the AT command sent via + * mbim is the original AT command information, skip it. */ + resp_str = strchr (ret_str, '\n'); + resp_str = resp_str ? &resp_str[1] : ret_str; + ret_size -= resp_str - ret_str; + + debug_log (self, "<--", (const guint8 *)resp_str, ret_size); + + if (G_UNLIKELY (!self->priv->parser)) + self->priv->parser = mm_serial_parser_v1_new (); + + /* Prepare the GString to pass to the parser. We add an explicit leading CRLF + * sequence only because it is what the parser expects, so that we don't need + * to do major changes to handle that case. */ + string = g_string_sized_new (ret_size + 3); + g_string_append (string, "\r\n"); + g_string_append_len (string, resp_str, ret_size); + + if (!mm_serial_parser_v1_parse (self->priv->parser, string, self, &error)) { + if (error) + g_task_return_error (task, error); + else + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "Incomplete response"); + g_string_free (string, TRUE); + g_object_unref (task); + return; + } + + g_task_return_pointer (task, g_string_free (string, FALSE), g_free); + g_object_unref (task); +} + +static GByteArray * +at_command_to_byte_array (const gchar *command, + gboolean is_raw) +{ + GByteArray *buf; + int cmdlen; + g_autofree gchar *lower = NULL; + + cmdlen = strlen (command); + buf = g_byte_array_sized_new (cmdlen + 4); + + if (!is_raw) { + /* Make sure there's an AT in the front */ + lower = g_ascii_strdown (command, -1); + if (!g_str_has_prefix (lower, "at")) + g_byte_array_append (buf, (const guint8 *) "AT", 2); + } + + g_byte_array_append (buf, (const guint8 *) command, cmdlen); + + if (!is_raw) { + /* Make sure there's a trailing carriage return */ + if ((cmdlen == 0) || + (command[cmdlen - 1] != '\r' && (cmdlen == 1 || command[cmdlen - 2] != '\r'))) + g_byte_array_append (buf, (const guint8 *) "\r", 1); + /* Make sure there's a trailing line-feed */ + if ((cmdlen == 0) || + (command[cmdlen - 1] != '\n' && (cmdlen == 1 || command[cmdlen - 2] != '\n'))) + g_byte_array_append (buf, (const guint8 *) "\n", 1); + } + + return buf; +} + +static void +iface_port_at_command (MMIfacePortAt *self, + const gchar *command, + guint32 timeout_seconds, + gboolean is_raw, + gboolean allow_cached, /* ignored */ + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + g_autoptr(MbimMessage) request = NULL; + g_autoptr(GByteArray) buffer = NULL; + GTask *task; + + task = g_task_new (self, cancellable, callback, user_data); + + buffer = at_command_to_byte_array (command, is_raw); + + debug_log (MM_PORT_MBIM_QUECTEL (self), "-->", buffer->data, buffer->len); + + request = mbim_message_qdu_command_set_new (MBIM_QUECTEL_COMMAND_TYPE_AT, + buffer->len, + (const guint8 *)buffer->data, + NULL); + mbim_device_command (mm_port_mbim_peek_device (MM_PORT_MBIM (self)), + request, + timeout_seconds, + cancellable, + (GAsyncReadyCallback)at_command_ready, + task); +} + +/*****************************************************************************/ + +MMPortMbimQuectel * +mm_port_mbim_quectel_new (const gchar *name, + MMPortSubsys subsys) +{ + return MM_PORT_MBIM_QUECTEL (g_object_new (MM_TYPE_PORT_MBIM_QUECTEL, + MM_PORT_DEVICE, name, + MM_PORT_SUBSYS, subsys, + MM_PORT_TYPE, MM_PORT_TYPE_MBIM, + NULL)); +} + +static void +mm_port_mbim_quectel_init (MMPortMbimQuectel *self) +{ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_PORT_MBIM_QUECTEL, MMPortMbimQuectelPrivate); + self->priv->at_over_mbim = FEATURE_SUPPORT_UNKNOWN; +} + +static void +finalize (GObject *object) +{ + MMPortMbimQuectel *self = MM_PORT_MBIM_QUECTEL (object); + + if (self->priv->parser) + mm_serial_parser_v1_destroy (self->priv->parser); + + G_OBJECT_CLASS (mm_port_mbim_quectel_parent_class)->finalize (object); +} + +static void +iface_port_at_init (MMIfacePortAtInterface *iface) +{ + iface->check_support = iface_port_at_check_support; + iface->command = iface_port_at_command; + iface->command_finish = iface_port_at_command_finish; +} + +static void +mm_port_mbim_quectel_class_init (MMPortMbimQuectelClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMPortMbimQuectelPrivate)); + + object_class->finalize = finalize; +} diff --git a/src/plugins/quectel/mm-port-mbim-quectel.h b/src/plugins/quectel/mm-port-mbim-quectel.h new file mode 100644 index 00000000..883bada5 --- /dev/null +++ b/src/plugins/quectel/mm-port-mbim-quectel.h @@ -0,0 +1,59 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2024 Quectel Wireless Solution,Co.,Ltd. + */ + +#ifndef MM_PORT_MBIM_QUECTEL_H +#define MM_PORT_MBIM_QUECTEL_H + +#include <config.h> + +#include <glib.h> +#include <glib-object.h> +#include <gio/gio.h> + +#include <libmbim-glib.h> + +#if defined WITH_QMI +# include <libqmi-glib.h> +#endif + +#include "mm-port-mbim.h" + +#define MM_TYPE_PORT_MBIM_QUECTEL (mm_port_mbim_quectel_get_type ()) +#define MM_PORT_MBIM_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PORT_MBIM_QUECTEL, MMPortMbimQuectel)) +#define MM_PORT_MBIM_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_PORT_MBIM_QUECTEL, MMPortMbimQuectelClass)) +#define MM_IS_PORT_MBIM_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_PORT_MBIM_QUECTEL)) +#define MM_IS_PORT_MBIM_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PORT_MBIM_QUECTEL)) +#define MM_PORT_MBIM_QUECTEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PORT_MBIM_QUECTEL, MMPortMbimQuectelClass)) + +typedef struct _MMPortMbimQuectel MMPortMbimQuectel; +typedef struct _MMPortMbimQuectelClass MMPortMbimQuectelClass; +typedef struct _MMPortMbimQuectelPrivate MMPortMbimQuectelPrivate; + +struct _MMPortMbimQuectel { + MMPortMbim parent; + MMPortMbimQuectelPrivate *priv; +}; + +struct _MMPortMbimQuectelClass { + MMPortMbimClass parent; +}; + +GType mm_port_mbim_quectel_get_type (void); +G_DEFINE_AUTOPTR_CLEANUP_FUNC (MMPortMbimQuectel, g_object_unref) + +MMPortMbimQuectel *mm_port_mbim_quectel_new (const gchar *name, + MMPortSubsys subsys); + +#endif /* MM_PORT_MBIM_QUECTEL_H */ diff --git a/src/plugins/quectel/mm-shared-quectel.c b/src/plugins/quectel/mm-shared-quectel.c index e3fa87c3..77d4d5ff 100644 --- a/src/plugins/quectel/mm-shared-quectel.c +++ b/src/plugins/quectel/mm-shared-quectel.c @@ -32,7 +32,7 @@ #include "mm-modem-helpers-quectel.h" #if defined WITH_MBIM -#include "mm-broadband-modem-mbim.h" +#include "mm-port-mbim-quectel.h" #endif G_DEFINE_INTERFACE (MMSharedQuectel, mm_shared_quectel, MM_TYPE_IFACE_MODEM) @@ -50,7 +50,7 @@ typedef enum { } FeatureSupport; typedef struct { - MMBroadbandModemClass *broadband_modem_class_parent; + MMBaseModemClass *class_parent; MMIfaceModemInterface *iface_modem_parent; MMIfaceModemLocationInterface *iface_modem_location_parent; MMModemLocationSource provided_sources; @@ -93,8 +93,8 @@ get_private (MMSharedQuectel *self) g_assert (priv->qlwurc_regex); g_assert (priv->rdy_regex); - g_assert (MM_SHARED_QUECTEL_GET_IFACE (self)->peek_parent_broadband_modem_class); - priv->broadband_modem_class_parent = MM_SHARED_QUECTEL_GET_IFACE (self)->peek_parent_broadband_modem_class (self); + g_assert (MM_SHARED_QUECTEL_GET_IFACE (self)->peek_parent_class); + priv->class_parent = MM_SHARED_QUECTEL_GET_IFACE (self)->peek_parent_class (self); g_assert (MM_SHARED_QUECTEL_GET_IFACE (self)->peek_parent_modem_location_interface); priv->iface_modem_location_parent = MM_SHARED_QUECTEL_GET_IFACE (self)->peek_parent_modem_location_interface (self); @@ -107,6 +107,39 @@ get_private (MMSharedQuectel *self) return priv; } +#if defined WITH_MBIM +MMPort * +mm_shared_quectel_create_usbmisc_port (MMBaseModem *self, + const gchar *name, + MMPortType ptype) +{ + Private *priv; + + priv = get_private (MM_SHARED_QUECTEL (self)); + if (ptype == MM_PORT_TYPE_MBIM) { + mm_obj_dbg (self, "creating quectel-specific MBIM port"); + return MM_PORT (mm_port_mbim_quectel_new (name, MM_PORT_SUBSYS_USBMISC)); + } + + return priv->class_parent->create_usbmisc_port (self, name, ptype); +} + +MMPort * +mm_shared_quectel_create_wwan_port (MMBaseModem *self, + const gchar *name, + MMPortType ptype) +{ + Private *priv; + + priv = get_private (MM_SHARED_QUECTEL (self)); + if (ptype == MM_PORT_TYPE_MBIM) { + mm_obj_dbg (self, "creating quectel-specific MBIM port"); + return MM_PORT (mm_port_mbim_quectel_new (name, MM_PORT_SUBSYS_WWAN)); + } + + return priv->class_parent->create_wwan_port (self, name, ptype); +} +#endif /*****************************************************************************/ /* RDY unsolicited event handler */ @@ -137,11 +170,11 @@ mm_shared_quectel_setup_ports (MMBroadbandModem *self) mm_obj_dbg (self, "setting up ports in quectel modem..."); priv = get_private (MM_SHARED_QUECTEL (self)); - g_assert (priv->broadband_modem_class_parent); - g_assert (priv->broadband_modem_class_parent->setup_ports); + g_assert (priv->class_parent); + g_assert (MM_BROADBAND_MODEM_CLASS (priv->class_parent)->setup_ports); /* Parent setup always first */ - priv->broadband_modem_class_parent->setup_ports (self); + MM_BROADBAND_MODEM_CLASS (priv->class_parent)->setup_ports (self); ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); @@ -315,30 +348,6 @@ quectel_at_port_get_firmware_version_ready (MMBaseModem *modem, g_timeout_add_seconds (1, (GSourceFunc) quectel_at_port_get_firmware_version_retry, task); } -#if defined WITH_MBIM -static void -quectel_mbim_port_get_firmware_version_ready (MbimDevice *device, - GAsyncResult *res, - GTask *task) -{ - g_autoptr(MbimMessage) response = NULL; - guint32 version_id; - g_autofree gchar *version_str = NULL; - LoadUpdateSettingsContext *ctx; - - ctx = g_task_get_task_data (task); - - response = mbim_device_command_finish (device, res, NULL); - if (response && mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, NULL) && - mbim_message_qdu_quectel_read_version_response_parse (response, &version_id, &version_str, NULL)) { - mm_firmware_update_settings_set_version (ctx->update_settings, version_str); - } - - g_task_return_pointer (task, g_object_ref (ctx->update_settings), g_object_unref); - g_object_unref (task); -} -#endif - static void qfastboot_test_ready (MMBaseModem *self, GAsyncResult *res, @@ -426,8 +435,8 @@ mm_shared_quectel_firmware_load_update_settings (MMIfaceModemFirmware *self, GAsyncReadyCallback callback, gpointer user_data) { - GTask *task; - MMPortSerialAt *at_port; + GTask *task; + MMIfacePortAt *at_port; MMModemFirmwareUpdateMethod update_methods; LoadUpdateSettingsContext *ctx; @@ -435,8 +444,8 @@ mm_shared_quectel_firmware_load_update_settings (MMIfaceModemFirmware *self, ctx = g_new0 (LoadUpdateSettingsContext, 1); g_task_set_task_data (task, ctx, (GDestroyNotify)load_update_settings_context_free); - /* We always report the primary port as the one to be used for FW upgrade */ - at_port = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); + /* Get the best at port to be used for FW vision update */ + at_port = mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL); if (at_port) { update_methods = quectel_get_firmware_update_methods (MM_BASE_MODEM (self), MM_PORT (at_port)); ctx->update_settings = mm_firmware_update_settings_new (update_methods); @@ -453,33 +462,6 @@ mm_shared_quectel_firmware_load_update_settings (MMIfaceModemFirmware *self, return; } -#if defined WITH_MBIM - { - MMPortMbim *mbim = NULL; - - if (MM_IS_BROADBAND_MODEM_MBIM (self)) - mbim = mm_broadband_modem_mbim_peek_port_mbim (MM_BROADBAND_MODEM_MBIM (self)); - - if (mbim) { - g_autoptr(MbimMessage) message = NULL; - - update_methods = quectel_get_firmware_update_methods (MM_BASE_MODEM (self), MM_PORT (mbim)); - ctx->update_settings = mm_firmware_update_settings_new (update_methods); - ctx->get_firmware_maximum_retry_int = QUECTEL_STD_AP_FIRMWARE_INVALID_MAXIMUM_RETRY; - - /* Fetch firmware info */ - message = mbim_message_qdu_quectel_read_version_set_new (MBIM_QDU_QUECTEL_VERSION_TYPE_FW_BUILD_ID, NULL); - mbim_device_command (mm_port_mbim_peek_device (mbim), - message, - 5, - NULL, - (GAsyncReadyCallback) quectel_mbim_port_get_firmware_version_ready, - task); - return; - } - } -#endif - g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, diff --git a/src/plugins/quectel/mm-shared-quectel.h b/src/plugins/quectel/mm-shared-quectel.h index 20180515..660d9314 100644 --- a/src/plugins/quectel/mm-shared-quectel.h +++ b/src/plugins/quectel/mm-shared-quectel.h @@ -33,7 +33,7 @@ G_DECLARE_INTERFACE (MMSharedQuectel, mm_shared_quectel, MM, SHARED_QUECTEL, MMI struct _MMSharedQuectelInterface { GTypeInterface g_iface; - MMBroadbandModemClass * (* peek_parent_broadband_modem_class) (MMSharedQuectel *self); + MMBaseModemClass * (* peek_parent_class) (MMSharedQuectel *self); MMIfaceModemInterface * (* peek_parent_modem_interface) (MMSharedQuectel *self); MMIfaceModemLocationInterface * (* peek_parent_modem_location_interface) (MMSharedQuectel *self); }; @@ -83,5 +83,13 @@ void mm_shared_quectel_time_check_support (MMIfa gboolean mm_shared_quectel_time_check_support_finish (MMIfaceModemTime *self, GAsyncResult *res, GError **error); +#if defined WITH_MBIM +MMPort *mm_shared_quectel_create_usbmisc_port (MMBaseModem *self, + const gchar *name, + MMPortType ptype); +MMPort *mm_shared_quectel_create_wwan_port (MMBaseModem *self, + const gchar *name, + MMPortType ptype); +#endif #endif /* MM_SHARED_QUECTEL_H */ |