diff --git a/src/plugins/cinterion/mm-broadband-modem-mbim-cinterion.c b/src/plugins/cinterion/mm-broadband-modem-mbim-cinterion.c index ec4cc91d..a23c55d5 100644 --- a/src/plugins/cinterion/mm-broadband-modem-mbim-cinterion.c +++ b/src/plugins/cinterion/mm-broadband-modem-mbim-cinterion.c @@ -183,6 +183,125 @@ load_revision (MMIfaceModem *self, iface_modem_parent->load_revision (self, (GAsyncReadyCallback)mbim_load_revision_ready, task); } +/*****************************************************************************/ +/* Load hardware revision (Modem interface) */ + +static gchar * +load_hardware_revision_finish (MMIfaceModem *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +at_load_hardware_revision_ready (MMBaseModem *self, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + const gchar *output = NULL; + g_autofree gchar *revision = NULL; + g_autoptr(GMatchInfo) match_info = NULL; + g_autoptr(GRegex) r = NULL; + + output = mm_base_modem_at_command_finish (self, res, &error); + if (error) { + mm_obj_dbg (self, "unable to get AT hardware revision output"); + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + r = g_regex_new ("HW Revision:\\s*(.*)\\s*", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + if (!g_regex_match_full (r, output, strlen(output), 0, 0, &match_info, &error)) { + if (error) + g_task_return_error (task, error); + else + g_task_return_new_error (task, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Couldn't match 'HW Revision:' in reply: '%s'", + output); + g_object_unref (task); + return; + } + + if (!g_match_info_matches (match_info)) { + g_task_return_new_error ( + task, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Failed to parse 'AT+SKUID' reply: '%s'", + output); + g_object_unref (task); + return; + } + + revision = mm_get_string_unquoted_from_match_info (match_info, 1); + if (revision == NULL) { + g_task_return_new_error ( + task, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Could not find hardware revision in reply: '%s'", + output); + g_object_unref (task); + return; + } + + mm_obj_dbg (self, "got AT hardware revision '%s'", revision); + g_task_return_pointer (task, g_strdup (revision), g_free); + g_object_unref (task); +} + +static void +mbim_load_hardware_revision_ready (MMIfaceModem *self, + GAsyncResult *res, + GTask *task) +{ + gchar *revision = NULL; + + revision = iface_modem_parent->load_revision_finish (self, res, NULL); + + mm_obj_dbg (self, "got mbim hardware revision '%s'", revision); + g_task_return_pointer (task, revision, g_free); + g_object_unref (task); +} + +static void +load_hardware_revision (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + MMPortSerialAt *at_port = NULL; + guint product_id; + + task = g_task_new (self, NULL, callback, user_data); + at_port = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); + product_id = mm_base_modem_get_product_id (MM_BASE_MODEM(self)); + + if (at_port) { + /* MV31 or MV32 */ + if ((product_id == 0x00f1) || (product_id == 0x00b3)) { + mm_base_modem_at_command (MM_BASE_MODEM(self), + "AT+SKUID", + 3, + TRUE, + (GAsyncReadyCallback) at_load_hardware_revision_ready, + task); + return; + } + } + + /* + * Only call parent function, if no AT port is available + * or the product ID does not match + */ + iface_modem_parent->load_revision (self, (GAsyncReadyCallback)mbim_load_hardware_revision_ready, task); +} + /*****************************************************************************/ MMBroadbandModemMbimCinterion * @@ -219,10 +338,12 @@ iface_modem_init (MMIfaceModemInterface *iface) { iface_modem_parent = g_type_interface_peek_parent (iface); - iface->reset = mm_shared_cinterion_modem_reset; - iface->reset_finish = mm_shared_cinterion_modem_reset_finish; - iface->load_revision_finish = load_revision_finish; - iface->load_revision = load_revision; + iface->reset = mm_shared_cinterion_modem_reset; + iface->reset_finish = mm_shared_cinterion_modem_reset_finish; + iface->load_revision_finish = load_revision_finish; + iface->load_revision = load_revision; + iface->load_hardware_revision_finish = load_hardware_revision_finish; + iface->load_hardware_revision = load_hardware_revision; } static MMIfaceModemInterface *