diff options
Diffstat (limited to 'plugins/telit')
-rw-r--r-- | plugins/telit/77-mm-telit-port-types.rules | 146 | ||||
-rw-r--r-- | plugins/telit/mm-broadband-modem-mbim-telit.c | 242 | ||||
-rw-r--r-- | plugins/telit/mm-broadband-modem-mbim-telit.h | 48 | ||||
-rw-r--r-- | plugins/telit/mm-broadband-modem-telit.c | 1562 | ||||
-rw-r--r-- | plugins/telit/mm-broadband-modem-telit.h | 51 | ||||
-rw-r--r-- | plugins/telit/mm-common-telit.c | 373 | ||||
-rw-r--r-- | plugins/telit/mm-common-telit.h | 40 | ||||
-rw-r--r-- | plugins/telit/mm-modem-helpers-telit.c | 967 | ||||
-rw-r--r-- | plugins/telit/mm-modem-helpers-telit.h | 90 | ||||
-rw-r--r-- | plugins/telit/mm-plugin-telit.c | 132 | ||||
-rw-r--r-- | plugins/telit/mm-plugin-telit.h | 42 | ||||
-rw-r--r-- | plugins/telit/mm-shared-telit.c | 795 | ||||
-rw-r--r-- | plugins/telit/mm-shared-telit.h | 107 | ||||
-rw-r--r-- | plugins/telit/mm-shared.c | 20 | ||||
-rw-r--r-- | plugins/telit/tests/test-mm-modem-helpers-telit.c | 695 |
15 files changed, 0 insertions, 5310 deletions
diff --git a/plugins/telit/77-mm-telit-port-types.rules b/plugins/telit/77-mm-telit-port-types.rules deleted file mode 100644 index b9439ffc..00000000 --- a/plugins/telit/77-mm-telit-port-types.rules +++ /dev/null @@ -1,146 +0,0 @@ -# do not edit this file, it will be overwritten on update - -ACTION!="add|change|move|bind", GOTO="mm_telit_end" -SUBSYSTEMS=="usb", ATTRS{idVendor}=="1bc7", GOTO="mm_telit_generic" -SUBSYSTEMS=="usb", ATTRS{idVendor}=="8087", GOTO="mm_telit_intel" -GOTO="mm_telit_end" - -LABEL="mm_telit_generic" -SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="?*", ENV{.MM_USBIFNUM}="$attr{bInterfaceNumber}" - -# UC864-E, UC864-E-AUTO, UC864-K, UC864-WD, UC864-WDU -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1003", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1003", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# UC864-G -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1004", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1004", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1004", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# CC864-DUAL -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1005", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1005", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1005", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# CC864-SINGLE, CC864-KPS -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1006", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1006", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# DE910-DUAL -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1010", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1010", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1010", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" - -# CE910-DUAL -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1011", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" - -# LE910C1-EUX -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1031", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1031", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1031", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# LE910C1-EUX (ECM composition) -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1033", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1033", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1033", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# LE922, LM9x0 -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1040", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1040", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_IGNORE}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1040", ENV{.MM_USBIFNUM}=="04", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1040", ENV{.MM_USBIFNUM}=="05", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1040", ENV{.MM_USBIFNUM}=="06", ENV{ID_MM_PORT_IGNORE}="1" - -# LE922, LM9x0 (MBIM composition) -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1041", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1041", ENV{.MM_USBIFNUM}=="04", ENV{ID_MM_PORT_IGNORE}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1041", ENV{.MM_USBIFNUM}=="05", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1041", ENV{.MM_USBIFNUM}=="06", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1041", ENV{.MM_USBIFNUM}=="07", ENV{ID_MM_PORT_IGNORE}="1" - -# FN980 -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1050", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1050", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_IGNORE}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1050", ENV{.MM_USBIFNUM}=="04", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1050", ENV{.MM_USBIFNUM}=="05", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1050", ENV{.MM_USBIFNUM}=="06", ENV{ID_MM_PORT_IGNORE}="1" - -# FN980 (MBIM composition) -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1051", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1051", ENV{.MM_USBIFNUM}=="04", ENV{ID_MM_PORT_IGNORE}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1051", ENV{.MM_USBIFNUM}=="05", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1051", ENV{.MM_USBIFNUM}=="06", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1051", ENV{.MM_USBIFNUM}=="07", ENV{ID_MM_PORT_IGNORE}="1" - -# LN920 -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1060", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1060", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1060", ENV{.MM_USBIFNUM}=="04", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1060", ENV{.MM_USBIFNUM}=="05", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1060", ENV{.MM_USBIFNUM}=="06", ENV{ID_MM_PORT_IGNORE}="1" - -# LN920 (MBIM composition) -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1061", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1061", ENV{.MM_USBIFNUM}=="04", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1061", ENV{.MM_USBIFNUM}=="05", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1061", ENV{.MM_USBIFNUM}=="06", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1061", ENV{.MM_USBIFNUM}=="07", ENV{ID_MM_PORT_IGNORE}="1" - -# LE910C1 with default usb cfg -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1201", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1201", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1201", ENV{.MM_USBIFNUM}=="04", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1201", ENV{.MM_USBIFNUM}=="05", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1201", ENV{.MM_USBIFNUM}=="06", ENV{ID_MM_PORT_IGNORE}="1" - -# LE910C1 (MBIM) -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1204", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1204", ENV{.MM_USBIFNUM}=="04", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1204", ENV{.MM_USBIFNUM}=="05", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1204", ENV{.MM_USBIFNUM}=="06", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1204", ENV{.MM_USBIFNUM}=="07", ENV{ID_MM_PORT_IGNORE}="1" - -# ME910C1 -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1101", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1101", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1101", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# MEx10G1 -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="110a", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="110a", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="110a", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# LE910S1 (RNDIS) -# The following port is ignored since it's a diagnostic port for collecting proprietary modem traces (not QCDM) -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="7010", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_IGNORE}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="7010", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="7010", ENV{.MM_USBIFNUM}=="04", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" - -# LE910S1 (ECM) -# The following port is ignored since it's a diagnostic port for collecting proprietary modem traces (not QCDM) -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="7011", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_IGNORE}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="7011", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="7011", ENV{.MM_USBIFNUM}=="04", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" - -# LM940/960 initial port delay -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1040", ENV{ID_MM_TELIT_PORT_DELAY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1041", ENV{ID_MM_TELIT_PORT_DELAY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1042", ENV{ID_MM_TELIT_PORT_DELAY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1043", ENV{ID_MM_TELIT_PORT_DELAY}="1" - -# FN980 initial port delay -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1050", ENV{ID_MM_TELIT_PORT_DELAY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1051", ENV{ID_MM_TELIT_PORT_DELAY}="1" - -# LN920 initial port delay -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1060", ENV{ID_MM_TELIT_PORT_DELAY}="1" -ATTRS{idVendor}=="1bc7", ATTRS{idProduct}=="1061", ENV{ID_MM_TELIT_PORT_DELAY}="1" - -GOTO="mm_telit_end" - -LABEL="mm_telit_intel" - -# Telit LN930, generic Intel vid:pid in MBIM mode -ATTRS{idVendor}=="8087", ATTRS{idProduct}=="0911", ENV{ID_MM_PREFERRED_NETWORKS_CPOL_DISABLED}="1" - -LABEL="mm_telit_end" diff --git a/plugins/telit/mm-broadband-modem-mbim-telit.c b/plugins/telit/mm-broadband-modem-mbim-telit.c deleted file mode 100644 index 8437c841..00000000 --- a/plugins/telit/mm-broadband-modem-mbim-telit.c +++ /dev/null @@ -1,242 +0,0 @@ -/* -*- 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) 2019 Daniele Palmas <dnlplm@gmail.com> - */ - -#include <config.h> - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <ctype.h> - -#include "ModemManager.h" -#include "mm-log-object.h" -#include "mm-modem-helpers.h" -#include "mm-iface-modem.h" -#include "mm-base-modem-at.h" -#include "mm-broadband-modem-mbim-telit.h" -#include "mm-modem-helpers-telit.h" -#include "mm-shared-telit.h" - -static void iface_modem_init (MMIfaceModem *iface); -static void shared_telit_init (MMSharedTelit *iface); - -static MMIfaceModem *iface_modem_parent; - -G_DEFINE_TYPE_EXTENDED (MMBroadbandModemMbimTelit, mm_broadband_modem_mbim_telit, MM_TYPE_BROADBAND_MODEM_MBIM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_TELIT, shared_telit_init)) - -/*****************************************************************************/ -/* Load supported modes (Modem interface) */ - -static GArray * -load_supported_modes_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return (GArray *) g_task_propagate_pointer (G_TASK (res), error); -} - -static void -load_supported_modes_ready (MMIfaceModem *self, - GAsyncResult *res, - GTask *task) -{ - MMModemModeCombination modes_combination; - MMModemMode modes_mask = MM_MODEM_MODE_NONE; - const gchar *response; - GArray *modes; - GArray *all; - GArray *combinations; - GArray *filtered; - GError *error = NULL; - MMSharedTelit *shared = MM_SHARED_TELIT (self); - guint i; - - response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); - if (error) { - g_prefix_error (&error, "generic query of supported 3GPP networks with WS46=? failed: "); - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - modes = mm_3gpp_parse_ws46_test_response (response, self, &error); - if (!modes) { - g_prefix_error (&error, "parsing WS46=? response failed: "); - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - for (i = 0; i < modes->len; i++) { - MMModemMode mode; - g_autofree gchar *str = NULL; - - mode = g_array_index (modes, MMModemMode, i); - - modes_mask |= mode; - - str = mm_modem_mode_build_string_from_mask (mode); - mm_obj_dbg (self, "device allows (3GPP) mode combination: %s", str); - } - - g_array_unref (modes); - - /* Build a mask with all supported modes */ - all = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 1); - modes_combination.allowed = modes_mask; - modes_combination.preferred = MM_MODEM_MODE_NONE; - g_array_append_val (all, modes_combination); - - /* Filter out those unsupported modes */ - combinations = mm_telit_build_modes_list(); - filtered = mm_filter_supported_modes (all, combinations, self); - g_array_unref (all); - g_array_unref (combinations); - - mm_shared_telit_store_supported_modes (shared, filtered); - g_task_return_pointer (task, filtered, (GDestroyNotify) g_array_unref); - g_object_unref (task); -} - -static void -load_supported_modes (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - - task = g_task_new (self, NULL, callback, user_data); - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+WS46=?", - 3, - TRUE, /* allow caching, it's a test command */ - (GAsyncReadyCallback) load_supported_modes_ready, - task); -} - -/*****************************************************************************/ -/* Load revision (Modem interface) */ - -static gchar * -load_revision_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_pointer (G_TASK (res), error); -} - -static void -parent_load_revision_ready (MMIfaceModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - gchar *revision = NULL; - - revision = iface_modem_parent->load_revision_finish (self, res, &error); - if (!revision) { - g_task_return_error (task, error); - g_object_unref (task); - return; - } - mm_shared_telit_store_revision (MM_SHARED_TELIT (self), revision); - g_task_return_pointer (task, revision, g_free); - g_object_unref (task); -} - -static void -load_revision (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - /* Run parent's loading */ - /* Telit's custom revision loading (in telit/mm-shared) is AT-only and the - * MBIM modem might not have an AT port available, so we call the parent's - * load_revision and store the revision taken from the firmware info capabilities. */ - iface_modem_parent->load_revision ( - MM_IFACE_MODEM (self), - (GAsyncReadyCallback)parent_load_revision_ready, - g_task_new (self, NULL, callback, user_data)); -} - -/*****************************************************************************/ - -MMBroadbandModemMbimTelit * -mm_broadband_modem_mbim_telit_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id, - guint16 subsystem_vendor_id) -{ - return g_object_new (MM_TYPE_BROADBAND_MODEM_MBIM_TELIT, - MM_BASE_MODEM_DEVICE, device, - MM_BASE_MODEM_DRIVERS, drivers, - MM_BASE_MODEM_PLUGIN, plugin, - MM_BASE_MODEM_VENDOR_ID, vendor_id, - MM_BASE_MODEM_PRODUCT_ID, product_id, - MM_BASE_MODEM_SUBSYSTEM_VENDOR_ID, subsystem_vendor_id, - /* MBIM bearer supports NET only */ - MM_BASE_MODEM_DATA_NET_SUPPORTED, TRUE, - MM_BASE_MODEM_DATA_TTY_SUPPORTED, FALSE, - MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED, TRUE, - NULL); -} - -static void -mm_broadband_modem_mbim_telit_init (MMBroadbandModemMbimTelit *self) -{ -} - -static void -iface_modem_init (MMIfaceModem *iface) -{ - iface_modem_parent = g_type_interface_peek_parent (iface); - - iface->set_current_bands = mm_shared_telit_modem_set_current_bands; - iface->set_current_bands_finish = mm_shared_telit_modem_set_current_bands_finish; - iface->load_current_bands = mm_shared_telit_modem_load_current_bands; - iface->load_current_bands_finish = mm_shared_telit_modem_load_current_bands_finish; - iface->load_supported_bands = mm_shared_telit_modem_load_supported_bands; - iface->load_supported_bands_finish = mm_shared_telit_modem_load_supported_bands_finish; - iface->load_supported_modes = load_supported_modes; - iface->load_supported_modes_finish = load_supported_modes_finish; - iface->load_current_modes = mm_shared_telit_load_current_modes; - iface->load_current_modes_finish = mm_shared_telit_load_current_modes_finish; - iface->set_current_modes = mm_shared_telit_set_current_modes; - iface->set_current_modes_finish = mm_shared_telit_set_current_modes_finish; - iface->load_revision_finish = load_revision_finish; - iface->load_revision = load_revision; -} - -static MMIfaceModem * -peek_parent_modem_interface (MMSharedTelit *self) -{ - return iface_modem_parent; -} - -static void -shared_telit_init (MMSharedTelit *iface) -{ - iface->peek_parent_modem_interface = peek_parent_modem_interface; -} - -static void -mm_broadband_modem_mbim_telit_class_init (MMBroadbandModemMbimTelitClass *klass) -{ -} diff --git a/plugins/telit/mm-broadband-modem-mbim-telit.h b/plugins/telit/mm-broadband-modem-mbim-telit.h deleted file mode 100644 index 50c21e20..00000000 --- a/plugins/telit/mm-broadband-modem-mbim-telit.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- 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) 2019 Daniele Palmas <dnlplm@gmail.com> - */ - -#ifndef MM_BROADBAND_MODEM_MBIM_TELIT_H -#define MM_BROADBAND_MODEM_MBIM_TELIT_H - -#include "mm-broadband-modem-mbim.h" - -#define MM_TYPE_BROADBAND_MODEM_MBIM_TELIT (mm_broadband_modem_mbim_telit_get_type ()) -#define MM_BROADBAND_MODEM_MBIM_TELIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BROADBAND_MODEM_MBIM_TELIT, MMBroadbandModemMbimTelit)) -#define MM_BROADBAND_MODEM_MBIM_TELIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BROADBAND_MODEM_MBIM_TELIT, MMBroadbandModemMbimTelitClass)) -#define MM_IS_BROADBAND_MODEM_MBIM_TELIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BROADBAND_MODEM_MBIM_TELIT)) -#define MM_IS_BROADBAND_MODEM_MBIM_TELIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BROADBAND_MODEM_MBIM_TELIT)) -#define MM_BROADBAND_MODEM_MBIM_TELIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BROADBAND_MODEM_MBIM_TELIT, MMBroadbandModemMbimTelitClass)) - -typedef struct _MMBroadbandModemMbimTelit MMBroadbandModemMbimTelit; -typedef struct _MMBroadbandModemMbimTelitClass MMBroadbandModemMbimTelitClass; - -struct _MMBroadbandModemMbimTelit { - MMBroadbandModemMbim parent; -}; - -struct _MMBroadbandModemMbimTelitClass{ - MMBroadbandModemMbimClass parent; -}; - -GType mm_broadband_modem_mbim_telit_get_type (void); - -MMBroadbandModemMbimTelit *mm_broadband_modem_mbim_telit_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id, - guint16 subsystem_vendor_id); - -#endif /* MM_BROADBAND_MODEM_TELIT_H */ diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c deleted file mode 100644 index 1683d38a..00000000 --- a/plugins/telit/mm-broadband-modem-telit.c +++ /dev/null @@ -1,1562 +0,0 @@ -/* -*- 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) 2008 - 2009 Novell, Inc. - * Copyright (C) 2009 - 2012 Red Hat, Inc. - * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org> - */ - -#include <config.h> - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <ctype.h> - -#include "ModemManager.h" -#include "mm-log-object.h" -#include "mm-errors-types.h" -#include "mm-modem-helpers.h" -#include "mm-base-modem-at.h" -#include "mm-iface-modem.h" -#include "mm-iface-modem-3gpp.h" -#include "mm-iface-modem-location.h" -#include "mm-broadband-modem-telit.h" -#include "mm-modem-helpers-telit.h" -#include "mm-telit-enums-types.h" -#include "mm-shared-telit.h" - -static void iface_modem_init (MMIfaceModem *iface); -static void iface_modem_3gpp_init (MMIfaceModem3gpp *iface); -static void shared_telit_init (MMSharedTelit *iface); -static void iface_modem_location_init (MMIfaceModemLocation *iface); - -static MMIfaceModem *iface_modem_parent; -static MMIfaceModem3gpp *iface_modem_3gpp_parent; -static MMIfaceModemLocation *iface_modem_location_parent; - -G_DEFINE_TYPE_EXTENDED (MMBroadbandModemTelit, mm_broadband_modem_telit, MM_TYPE_BROADBAND_MODEM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_3GPP, iface_modem_3gpp_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_TELIT, shared_telit_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init)); - -#define CSIM_UNLOCK_MAX_TIMEOUT 3 - -typedef enum { - FEATURE_SUPPORT_UNKNOWN, - FEATURE_NOT_SUPPORTED, - FEATURE_SUPPORTED -} FeatureSupport; - -struct _MMBroadbandModemTelitPrivate { - FeatureSupport csim_lock_support; - MMTelitQssStatus qss_status; - MMTelitCsimLockState csim_lock_state; - GTask *csim_lock_task; - guint csim_lock_timeout_id; - gboolean parse_qss; - MMModemLocationSource enabled_sources; -}; - -typedef struct { - MMModemLocationSource source; - guint gps_enable_step; -} LocationGatheringContext; - -/* - * AT$GPSNMUN - * enable: 0 NMEA stream disabled (default) - * 1 NMEA stream enabled in the form $GPSNMUN: <nmea sentence><CR> - * 2 NMEA stream enabled in the form <nmea sentence><CR> - * 3 dedicated NMEA stream - * GGA: 0 disable (default), 1 enable - * GLL: 0 disable (default), 1 enable - * GSA: 0 disable (default), 1 enable - * GSV: 0 disable (default), 1 enable - * RMC: 0 disable (default), 1 enable - * VTG: 0 disable (default), 1 enable - */ -static const gchar *gps_enable[] = { - "$GPSP=1", - "$GPSNMUN=2,1,1,1,1,1,1" -}; - -static gboolean -disable_location_gathering_finish (MMIfaceModemLocation *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -gps_disabled_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - LocationGatheringContext *ctx; - MMPortSerialGps *gps_port; - GError *error = NULL; - - mm_base_modem_at_command_finish (self, res, &error); - ctx = g_task_get_task_data (task); - /* Only use the GPS port in NMEA/RAW setups */ - if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW)) { - /* Even if we get an error here, we try to close the GPS port */ - gps_port = mm_base_modem_peek_port_gps (self); - if (gps_port) - mm_port_serial_close (MM_PORT_SERIAL (gps_port)); - } - - if (error) - g_task_return_error (task, error); - else - g_task_return_boolean (task, TRUE); - - g_object_unref (task); -} - -static void -disable_location_gathering (MMIfaceModemLocation *self, - MMModemLocationSource source, - GAsyncReadyCallback callback, - gpointer user_data) -{ - MMBroadbandModemTelit *telit = MM_BROADBAND_MODEM_TELIT (self); - gboolean stop_gps = FALSE; - LocationGatheringContext *ctx; - GTask *task; - - ctx = g_new (LocationGatheringContext, 1); - ctx->source = source; - - task = g_task_new (self, NULL, callback, user_data); - g_task_set_task_data (task, ctx, g_free); - - /* Only stop GPS engine if no GPS-related sources enabled */ - if (source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) { - telit->priv->enabled_sources &= ~source; - - if (!(telit->priv->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED))) - stop_gps = TRUE; - } - - if (stop_gps) { - mm_base_modem_at_command (MM_BASE_MODEM (self), - "$GPSP=0", - 3, - FALSE, - (GAsyncReadyCallback)gps_disabled_ready, - task); - return; - } - /* For any other location (e.g. 3GPP), or if still some GPS needed, just return */ - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void -gps_enabled_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - LocationGatheringContext *ctx; - GError *error = NULL; - - ctx = g_task_get_task_data (task); - if (!mm_base_modem_at_command_finish (self, res, &error)) { - g_prefix_error (&error, "couldn't power up GNSS controller: "); - g_task_return_error (task, error); - g_object_unref (task); - return; - } - /* After Receiver was powered up we still have to enable unsolicited NMEA events */ - if (ctx->gps_enable_step < G_N_ELEMENTS (gps_enable)) { - mm_base_modem_at_command (MM_BASE_MODEM (self), - gps_enable[ctx->gps_enable_step++], - 3, - FALSE, - (GAsyncReadyCallback)gps_enabled_ready, - task); - return; - } - - mm_obj_dbg (self, "GNSS controller is powered up"); - - /* Only use the GPS port in NMEA/RAW setups */ - if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW)) { - MMPortSerialGps *gps_port; - - gps_port = mm_base_modem_peek_port_gps (self); - if (!gps_port || - !mm_port_serial_open (MM_PORT_SERIAL (gps_port), &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 open raw GPS serial port"); - } else - g_task_return_boolean (task, TRUE); - } else - g_task_return_boolean (task, TRUE); - - g_object_unref (task); -} - -static void -parent_enable_location_gathering_ready (MMIfaceModemLocation *_self, - GAsyncResult *res, - GTask *task) -{ - MMBroadbandModemTelit *self = MM_BROADBAND_MODEM_TELIT (_self); - LocationGatheringContext *ctx; - gboolean start_gps = FALSE; - GError *error = NULL; - - if (!iface_modem_location_parent->enable_location_gathering_finish (_self, res, &error)) { - g_task_return_error (task, error); - g_object_unref (task); - return; - } - /* Now our own enabling */ - ctx = g_task_get_task_data (task); - - /* NMEA, RAW and UNMANAGED are all enabled in the same way */ - if (ctx->source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) { - /* Only start GPS engine if not done already */ - if (!(self->priv->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED))) - start_gps = TRUE; - self->priv->enabled_sources |= ctx->source; - } - - if (start_gps && ctx->gps_enable_step < G_N_ELEMENTS (gps_enable)) { - mm_base_modem_at_command (MM_BASE_MODEM (self), - gps_enable[ctx->gps_enable_step++], - 3, - FALSE, - (GAsyncReadyCallback)gps_enabled_ready, - task); - return; - } - /* For any other location (e.g. 3GPP), or if GPS already running just return */ - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void -enable_location_gathering (MMIfaceModemLocation *self, - MMModemLocationSource source, - GAsyncReadyCallback callback, - gpointer user_data) -{ - LocationGatheringContext *ctx; - GTask *task; - - ctx = g_new (LocationGatheringContext, 1); - ctx->source = source; - ctx->gps_enable_step = 0; - task = g_task_new (self, NULL, callback, user_data); - g_task_set_task_data (task, ctx, g_free); - - /* Chain up parent's gathering enable */ - iface_modem_location_parent->enable_location_gathering ( - self, - source, - (GAsyncReadyCallback)parent_enable_location_gathering_ready, - task); -} - -static void -trace_received (MMPortSerialGps *port, - const gchar *trace, - MMIfaceModemLocation *self) -{ - mm_iface_modem_location_gps_update (self, trace); -} - -static gboolean -enable_location_gathering_finish (MMIfaceModemLocation *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -setup_ports (MMBroadbandModem *self) -{ - MMPortSerialGps *gps_data_port; - - /* Call parent's setup ports first always */ - MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_telit_parent_class)->setup_ports (self); - - gps_data_port = mm_base_modem_peek_port_gps (MM_BASE_MODEM (self)); - if (gps_data_port) { - /* It may happen that the modem was started with GPS already enabled, - * in this case GPSP AT command returns always error. Disable it for consistency - */ - mm_base_modem_at_command (MM_BASE_MODEM (self), - "$GPSP=0", 3, FALSE, FALSE, NULL); - - /* Add handler for the NMEA traces */ - mm_port_serial_gps_add_trace_handler (gps_data_port, - (MMPortSerialGpsTraceFn)trace_received, - self, - NULL); - } -} - -static MMModemLocationSource -location_load_capabilities_finish (MMIfaceModemLocation *self, - GAsyncResult *res, - GError **error) -{ - GError *inner_error = NULL; - gssize value; - - value = g_task_propagate_int (G_TASK (res), &inner_error); - if (inner_error) { - g_propagate_error (error, inner_error); - return MM_MODEM_LOCATION_SOURCE_NONE; - } - return (MMModemLocationSource)value; -} - -static void -gpsp_test_ready (MMIfaceModemLocation *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - MMModemLocationSource sources; - - sources = GPOINTER_TO_UINT (g_task_get_task_data (task)); - mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); - if (error) { - mm_obj_dbg (self, "GPS controller not supported: %s", error->message); - g_clear_error (&error); - } else if (mm_base_modem_peek_port_gps (MM_BASE_MODEM (self))) - sources |= (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED); - - g_task_return_int (task, sources); - g_object_unref (task); -} - -static void -parent_load_capabilities_ready (MMIfaceModemLocation *self, - GAsyncResult *res, - GTask *task) -{ - MMModemLocationSource sources; - GError *error = NULL; - - sources = iface_modem_location_parent->load_capabilities_finish (self, res, &error); - if (error) { - g_task_return_error (task, error); - g_object_unref (task); - return; - } - g_task_set_task_data (task, GUINT_TO_POINTER (sources), NULL); - mm_base_modem_at_command (MM_BASE_MODEM (self), - "$GPSP=?", - 3, - TRUE, - (GAsyncReadyCallback)gpsp_test_ready, - task); -} - -static void -location_load_capabilities (MMIfaceModemLocation *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - /* Chain up parent's setup */ - iface_modem_location_parent->load_capabilities ( - self, - (GAsyncReadyCallback)parent_load_capabilities_ready, - g_task_new (self, NULL, callback, user_data)); -} - -/*****************************************************************************/ -/* Setup SIM hot swap (Modem interface) */ - -typedef enum { - QSS_SETUP_STEP_FIRST, - QSS_SETUP_STEP_QUERY, - QSS_SETUP_STEP_ENABLE_PRIMARY_PORT, - QSS_SETUP_STEP_ENABLE_SECONDARY_PORT, - QSS_SETUP_STEP_LAST -} QssSetupStep; - -typedef struct { - QssSetupStep step; - MMPortSerialAt *primary; - MMPortSerialAt *secondary; - GError *primary_error; - GError *secondary_error; -} QssSetupContext; - -static void qss_setup_step (GTask *task); -static void pending_csim_unlock_complete (MMBroadbandModemTelit *self); - -static void -telit_qss_unsolicited_handler (MMPortSerialAt *port, - GMatchInfo *match_info, - MMBroadbandModemTelit *self) -{ - MMTelitQssStatus cur_qss_status; - MMTelitQssStatus prev_qss_status; - - if (!mm_get_int_from_match_info (match_info, 1, (gint*)&cur_qss_status)) - return; - - prev_qss_status = self->priv->qss_status; - self->priv->qss_status = cur_qss_status; - - if (self->priv->csim_lock_state >= CSIM_LOCK_STATE_LOCK_REQUESTED) { - - if (prev_qss_status > QSS_STATUS_SIM_REMOVED && cur_qss_status == QSS_STATUS_SIM_REMOVED) { - mm_obj_dbg (self, "QSS handler: #QSS=0 after +CSIM=1: CSIM locked!"); - self->priv->csim_lock_state = CSIM_LOCK_STATE_LOCKED; - } - - if (prev_qss_status == QSS_STATUS_SIM_REMOVED && cur_qss_status != QSS_STATUS_SIM_REMOVED) { - mm_obj_dbg (self, "QSS handler: #QSS>=1 after +CSIM=0: CSIM unlocked!"); - self->priv->csim_lock_state = CSIM_LOCK_STATE_UNLOCKED; - - if (self->priv->csim_lock_timeout_id) { - g_source_remove (self->priv->csim_lock_timeout_id); - self->priv->csim_lock_timeout_id = 0; - } - - pending_csim_unlock_complete (self); - } - - return; - } - - if (cur_qss_status != prev_qss_status) - mm_obj_dbg (self, "QSS handler: status changed %s -> %s", - mm_telit_qss_status_get_string (prev_qss_status), - mm_telit_qss_status_get_string (cur_qss_status)); - - if (self->priv->parse_qss == FALSE) { - mm_obj_dbg (self, "QSS handler: message ignored"); - return; - } - - if ((prev_qss_status == QSS_STATUS_SIM_REMOVED && cur_qss_status != QSS_STATUS_SIM_REMOVED) || - (prev_qss_status > QSS_STATUS_SIM_REMOVED && cur_qss_status == QSS_STATUS_SIM_REMOVED)) { - mm_obj_msg (self, "QSS handler: SIM swap detected"); - mm_iface_modem_process_sim_event (MM_IFACE_MODEM (self)); - } -} - -static void -qss_setup_context_free (QssSetupContext *ctx) -{ - g_clear_object (&(ctx->primary)); - g_clear_object (&(ctx->secondary)); - g_clear_error (&(ctx->primary_error)); - g_clear_error (&(ctx->secondary_error)); - g_slice_free (QssSetupContext, ctx); -} - -static gboolean -modem_setup_sim_hot_swap_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -telit_qss_enable_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - QssSetupContext *ctx; - MMPortSerialAt *port; - GError **error; - g_autoptr(GRegex) pattern = NULL; - - ctx = g_task_get_task_data (task); - - if (ctx->step == QSS_SETUP_STEP_ENABLE_PRIMARY_PORT) { - port = ctx->primary; - error = &ctx->primary_error; - } else if (ctx->step == QSS_SETUP_STEP_ENABLE_SECONDARY_PORT) { - port = ctx->secondary; - error = &ctx->secondary_error; - } else - g_assert_not_reached (); - - if (!mm_base_modem_at_command_full_finish (self, res, error)) { - mm_obj_warn (self, "QSS: error enabling unsolicited on port %s: %s", mm_port_get_device (MM_PORT (port)), (*error)->message); - goto next_step; - } - - pattern = g_regex_new ("#QSS:\\s*([0-3])\\r\\n", G_REGEX_RAW, 0, NULL); - g_assert (pattern); - mm_port_serial_at_add_unsolicited_msg_handler ( - port, - pattern, - (MMPortSerialAtUnsolicitedMsgFn)telit_qss_unsolicited_handler, - self, - NULL); - -next_step: - ctx->step++; - qss_setup_step (task); -} - -static void -telit_qss_query_ready (MMBaseModem *_self, - GAsyncResult *res, - GTask *task) -{ - MMBroadbandModemTelit *self; - GError *error = NULL; - const gchar *response; - MMTelitQssStatus qss_status; - QssSetupContext *ctx; - - self = MM_BROADBAND_MODEM_TELIT (_self); - ctx = g_task_get_task_data (task); - - response = mm_base_modem_at_command_finish (_self, res, &error); - if (error) { - mm_obj_warn (self, "could not get \"#QSS?\" reply: %s", error->message); - g_error_free (error); - goto next_step; - } - - qss_status = mm_telit_parse_qss_query (response, &error); - if (error) { - mm_obj_warn (self, "QSS query parse error: %s", error->message); - g_error_free (error); - goto next_step; - } - - mm_obj_dbg (self, "QSS: current status is '%s'", mm_telit_qss_status_get_string (qss_status)); - self->priv->qss_status = qss_status; - -next_step: - ctx->step++; - qss_setup_step (task); -} - -static void -telit_qss_support_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - QssSetupContext *ctx; - - ctx = g_task_get_task_data (task); - - if (!mm_base_modem_at_command_finish (self, res, &error)) { - mm_obj_dbg (self, "#QSS command unsupported: '%s'", error->message); - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - ctx->step++; - qss_setup_step (task); -} - -static void -qss_setup_step (GTask *task) -{ - QssSetupContext *ctx; - MMBroadbandModemTelit *self; - - self = MM_BROADBAND_MODEM_TELIT (g_task_get_source_object (task)); - ctx = g_task_get_task_data (task); - - switch (ctx->step) { - case QSS_SETUP_STEP_FIRST: - mm_base_modem_at_command (MM_BASE_MODEM (self), - "#QSS=?", - 3, - TRUE, - (GAsyncReadyCallback) telit_qss_support_ready, - task); - return; - case QSS_SETUP_STEP_QUERY: - mm_base_modem_at_command (MM_BASE_MODEM (self), - "#QSS?", - 3, - FALSE, - (GAsyncReadyCallback) telit_qss_query_ready, - task); - return; - case QSS_SETUP_STEP_ENABLE_PRIMARY_PORT: - mm_base_modem_at_command_full (MM_BASE_MODEM (self), - ctx->primary, - "#QSS=1", - 3, - FALSE, - FALSE, /* raw */ - NULL, /* cancellable */ - (GAsyncReadyCallback) telit_qss_enable_ready, - task); - return; - case QSS_SETUP_STEP_ENABLE_SECONDARY_PORT: - if (ctx->secondary) { - mm_base_modem_at_command_full (MM_BASE_MODEM (self), - ctx->secondary, - "#QSS=1", - 3, - FALSE, - FALSE, /* raw */ - NULL, /* cancellable */ - (GAsyncReadyCallback) telit_qss_enable_ready, - task); - return; - } - ctx->step++; - /* fall through */ - case QSS_SETUP_STEP_LAST: - /* If all enabling actions failed (either both, or only primary if - * there is no secondary), then we return an error */ - if (ctx->primary_error && (ctx->secondary_error || !ctx->secondary)) { - g_task_return_new_error (task, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "QSS: couldn't enable unsolicited"); - } else { - g_autoptr(GError) error = NULL; - - if (!mm_broadband_modem_sim_hot_swap_ports_context_init (MM_BROADBAND_MODEM (self), &error)) - mm_obj_warn (self, "failed to initialize SIM hot swap ports context: %s", error->message); - - g_task_return_boolean (task, TRUE); - } - g_object_unref (task); - break; - - default: - g_assert_not_reached (); - } -} - -static void -modem_setup_sim_hot_swap (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - QssSetupContext *ctx; - GTask *task; - - task = g_task_new (self, NULL, callback, user_data); - - ctx = g_slice_new0 (QssSetupContext); - ctx->step = QSS_SETUP_STEP_FIRST; - ctx->primary = mm_base_modem_get_port_primary (MM_BASE_MODEM (self)); - ctx->secondary = mm_base_modem_get_port_secondary (MM_BASE_MODEM (self)); - - g_task_set_task_data (task, ctx, (GDestroyNotify) qss_setup_context_free); - qss_setup_step (task); -} - -/*****************************************************************************/ -/* SIM hot swap cleanup (Modem interface) */ - -static void -modem_cleanup_sim_hot_swap (MMIfaceModem *self) -{ - mm_broadband_modem_sim_hot_swap_ports_context_reset (MM_BROADBAND_MODEM (self)); -} - -/*****************************************************************************/ -/* Load unlock retries (Modem interface) - * - * NOTE: the logic must make sure that LOAD_UNLOCK_RETRIES_STEP_UNLOCK is always - * run if LOAD_UNLOCK_RETRIES_STEP_LOCK has been run. Currently, the logic just - * runs all intermediate steps ignoring errors (i.e. not completing the - * operation if something fails), so the LOAD_UNLOCK_RETRIES_STEP_UNLOCK is - * always run. - */ - -#define CSIM_LOCK_STR "+CSIM=1" -#define CSIM_UNLOCK_STR "+CSIM=0" -#define CSIM_QUERY_TIMEOUT 3 - -typedef enum { - LOAD_UNLOCK_RETRIES_STEP_FIRST, - LOAD_UNLOCK_RETRIES_STEP_LOCK, - LOAD_UNLOCK_RETRIES_STEP_PARENT, - LOAD_UNLOCK_RETRIES_STEP_UNLOCK, - LOAD_UNLOCK_RETRIES_STEP_LAST -} LoadUnlockRetriesStep; - -typedef struct { - MMUnlockRetries *retries; - LoadUnlockRetriesStep step; -} LoadUnlockRetriesContext; - -static void load_unlock_retries_step (GTask *task); - -static void -load_unlock_retries_context_free (LoadUnlockRetriesContext *ctx) -{ - if (ctx->retries) - g_object_unref (ctx->retries); - g_slice_free (LoadUnlockRetriesContext, ctx); -} - -static MMUnlockRetries * -modem_load_unlock_retries_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return (MMUnlockRetries *) g_task_propagate_pointer (G_TASK (res), error); -} - -static void -csim_unlock_ready (MMBaseModem *_self, - GAsyncResult *res, - GTask *task) -{ - const gchar *response; - GError *error = NULL; - MMBroadbandModemTelit *self; - LoadUnlockRetriesContext *ctx; - - self = MM_BROADBAND_MODEM_TELIT (_self); - ctx = g_task_get_task_data (task); - - /* Ignore errors */ - response = mm_base_modem_at_command_finish (_self, res, &error); - if (!response) { - if (g_error_matches (error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED)) { - self->priv->csim_lock_support = FEATURE_NOT_SUPPORTED; - } - mm_obj_warn (self, "couldn't unlock SIM card: %s", error->message); - g_error_free (error); - } - - if (self->priv->csim_lock_support != FEATURE_NOT_SUPPORTED) - self->priv->csim_lock_support = FEATURE_SUPPORTED; - - ctx->step++; - load_unlock_retries_step (task); -} - -static void -parent_load_unlock_retries_ready (MMIfaceModem *self, - GAsyncResult *res, - GTask *task) -{ - LoadUnlockRetriesContext *ctx; - GError *error = NULL; - - ctx = g_task_get_task_data (task); - - if (!(ctx->retries = iface_modem_parent->load_unlock_retries_finish (self, res, &error))) { - mm_obj_warn (self, "couldn't load unlock retries with generic logic: %s", error->message); - g_error_free (error); - } - - ctx->step++; - load_unlock_retries_step (task); -} - -static void -csim_lock_ready (MMBaseModem *_self, - GAsyncResult *res, - GTask *task) -{ - const gchar *response; - GError *error = NULL; - MMBroadbandModemTelit *self; - LoadUnlockRetriesContext *ctx; - - self = MM_BROADBAND_MODEM_TELIT (_self); - ctx = g_task_get_task_data (task); - - response = mm_base_modem_at_command_finish (_self, res, &error); - if (!response) { - if (g_error_matches (error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_NOT_SUPPORTED) || - g_error_matches (error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN)) { - self->priv->csim_lock_support = FEATURE_NOT_SUPPORTED; - mm_obj_warn (self, "couldn't lock SIM card: %s; continuing without CSIM lock", error->message); - g_error_free (error); - } else { - g_prefix_error (&error, "Couldn't lock SIM card: "); - g_task_return_error (task, error); - g_object_unref (task); - return; - } - } else { - self->priv->csim_lock_state = CSIM_LOCK_STATE_LOCK_REQUESTED; - } - - if (self->priv->csim_lock_support != FEATURE_NOT_SUPPORTED) { - self->priv->csim_lock_support = FEATURE_SUPPORTED; - } - - ctx->step++; - load_unlock_retries_step (task); -} - -static void -handle_csim_locking (GTask *task, - gboolean is_lock) -{ - MMBroadbandModemTelit *self; - LoadUnlockRetriesContext *ctx; - - self = MM_BROADBAND_MODEM_TELIT (g_task_get_source_object (task)); - ctx = g_task_get_task_data (task); - - switch (self->priv->csim_lock_support) { - case FEATURE_SUPPORT_UNKNOWN: - case FEATURE_SUPPORTED: - if (is_lock) { - mm_base_modem_at_command (MM_BASE_MODEM (self), - CSIM_LOCK_STR, - CSIM_QUERY_TIMEOUT, - FALSE, - (GAsyncReadyCallback) csim_lock_ready, - task); - } else { - mm_base_modem_at_command (MM_BASE_MODEM (self), - CSIM_UNLOCK_STR, - CSIM_QUERY_TIMEOUT, - FALSE, - (GAsyncReadyCallback) csim_unlock_ready, - task); - } - break; - case FEATURE_NOT_SUPPORTED: - mm_obj_dbg (self, "CSIM lock not supported by this modem; skipping %s command", - is_lock ? "lock" : "unlock"); - ctx->step++; - load_unlock_retries_step (task); - break; - default: - g_assert_not_reached (); - break; - } -} - -static void -pending_csim_unlock_complete (MMBroadbandModemTelit *self) -{ - LoadUnlockRetriesContext *ctx; - - ctx = g_task_get_task_data (self->priv->csim_lock_task); - - if (!ctx->retries) { - g_task_return_new_error (self->priv->csim_lock_task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not get any of the SIM unlock retries values"); - } else { - g_task_return_pointer (self->priv->csim_lock_task, g_object_ref (ctx->retries), g_object_unref); - } - - g_clear_object (&self->priv->csim_lock_task); -} - -static gboolean -csim_unlock_periodic_check (MMBroadbandModemTelit *self) -{ - if (self->priv->csim_lock_state != CSIM_LOCK_STATE_UNLOCKED) - mm_obj_warn (self, "CSIM is still locked after %d seconds; trying to continue anyway", CSIM_UNLOCK_MAX_TIMEOUT); - - self->priv->csim_lock_timeout_id = 0; - pending_csim_unlock_complete (self); - g_object_unref (self); - - return G_SOURCE_REMOVE; -} - -static void -load_unlock_retries_step (GTask *task) -{ - MMBroadbandModemTelit *self; - LoadUnlockRetriesContext *ctx; - - self = MM_BROADBAND_MODEM_TELIT (g_task_get_source_object (task)); - ctx = g_task_get_task_data (task); - switch (ctx->step) { - case LOAD_UNLOCK_RETRIES_STEP_FIRST: - ctx->step++; - /* fall through */ - case LOAD_UNLOCK_RETRIES_STEP_LOCK: - handle_csim_locking (task, TRUE); - break; - case LOAD_UNLOCK_RETRIES_STEP_PARENT: - iface_modem_parent->load_unlock_retries ( - MM_IFACE_MODEM (self), - (GAsyncReadyCallback)parent_load_unlock_retries_ready, - task); - break; - case LOAD_UNLOCK_RETRIES_STEP_UNLOCK: - handle_csim_locking (task, FALSE); - break; - case LOAD_UNLOCK_RETRIES_STEP_LAST: - self->priv->csim_lock_task = task; - if (self->priv->csim_lock_state == CSIM_LOCK_STATE_LOCKED) { - mm_obj_dbg (self, "CSIM is locked, waiting for #QSS=1"); - self->priv->csim_lock_timeout_id = g_timeout_add_seconds (CSIM_UNLOCK_MAX_TIMEOUT, - (GSourceFunc) csim_unlock_periodic_check, - g_object_ref(self)); - } else { - self->priv->csim_lock_state = CSIM_LOCK_STATE_UNLOCKED; - pending_csim_unlock_complete (self); - } - break; - default: - break; - } -} - -static void -modem_load_unlock_retries (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - LoadUnlockRetriesContext *ctx; - - g_assert (iface_modem_parent->load_unlock_retries); - g_assert (iface_modem_parent->load_unlock_retries_finish); - - ctx = g_slice_new0 (LoadUnlockRetriesContext); - ctx->step = LOAD_UNLOCK_RETRIES_STEP_FIRST; - - task = g_task_new (self, NULL, callback, user_data); - g_task_set_task_data (task, ctx, (GDestroyNotify)load_unlock_retries_context_free); - - load_unlock_retries_step (task); -} - -/*****************************************************************************/ -/* Modem after power up (Modem interface) */ - -static gboolean -modem_after_power_up_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -modem_after_power_up (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - MMBroadbandModemTelit *modem = MM_BROADBAND_MODEM_TELIT (self); - - task = g_task_new (self, NULL, callback, user_data); - - mm_obj_dbg (self, "stop ignoring #QSS"); - modem->priv->parse_qss = TRUE; - - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -/*****************************************************************************/ -/* Modem power down (Modem interface) */ - -static gboolean -modem_power_down_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -telit_modem_power_down_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - - if (mm_base_modem_at_command_finish (self, res, &error)) { - mm_obj_dbg (self, "sgnore #QSS unsolicited during power down/low"); - MM_BROADBAND_MODEM_TELIT (self)->priv->parse_qss = FALSE; - } - - if (error) { - mm_obj_warn (self, "failed modem power down: %s", error->message); - g_clear_error (&error); - } - - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void -modem_power_down (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - - task = g_task_new (self, NULL, callback, user_data); - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+CFUN=4", - 20, - FALSE, - (GAsyncReadyCallback) telit_modem_power_down_ready, - task); -} - -/*****************************************************************************/ -/* Reset (Modem interface) */ - -static gboolean -modem_reset_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return !!mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error); -} - -static void -modem_reset (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - mm_base_modem_at_command (MM_BASE_MODEM (self), - "AT#REBOOT", - 8, - FALSE, - callback, - user_data); -} -/*****************************************************************************/ -/* Load access technologies (Modem interface) */ - -static gboolean -load_access_technologies_finish (MMIfaceModem *self, - GAsyncResult *res, - MMModemAccessTechnology *access_technologies, - guint *mask, - GError **error) -{ - GVariant *result; - - result = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, error); - if (!result) { - if (error) - g_assert (*error); - return FALSE; - } - - *access_technologies = (MMModemAccessTechnology) g_variant_get_uint32 (result); - *mask = MM_MODEM_ACCESS_TECHNOLOGY_ANY; - return TRUE; -} - -static MMBaseModemAtResponseProcessorResult -response_processor_cops_ignore_at_errors (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) -{ - g_autoptr(GMatchInfo) match_info = NULL; - g_autoptr(GRegex) r = NULL; - guint actval = 0; - guint mode = 0; - guint vid; - guint pid; - - *result = NULL; - *result_error = NULL; - - if (error) { - /* Ignore AT errors (ie, ERROR or CMx ERROR) */ - if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) { - *result_error = g_error_copy (error); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; - } - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; - } - - vid = mm_base_modem_get_vendor_id (self); - pid = mm_base_modem_get_product_id (self); - - if (!(vid == 0x1bc7 && (pid == 0x110a || pid == 0x110b))) { - /* AcT for non-LPWA modems would be checked by other command */ - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; - } - - r = g_regex_new ("\\+COPS:\\s*(\\d+),(\\d+),([^,]*)(?:,(\\d+))?(?:\\r\\n)?", - 0, - 0, - NULL); - g_assert (r != NULL); - - if (!g_regex_match (r, response, 0, &match_info)) { - g_set_error (result_error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Can't match +COPS? response: '%s'", - response); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; - } - - if (!mm_get_uint_from_match_info (match_info, 1, &mode)) { - g_set_error (result_error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Failed to parse mode in +COPS? response: '%s'", - response); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; - } - - if (mode == 2) { - g_set_error (result_error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Modem deregistered from the network: aborting AcT query"); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; - } - - if (!mm_get_uint_from_match_info (match_info, 4, &actval)) { - g_set_error (result_error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Failed to parse act in +COPS? response: '%s'", - response); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; - } - - switch (actval) { - case 0: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_GSM); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - case 8: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_LTE_CAT_M); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - case 9: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_LTE_NB_IOT); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - default: - break; - } - - g_set_error (result_error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Failed to map act in +COPS? response: '%s'", - response); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; -} - -static MMBaseModemAtResponseProcessorResult -response_processor_psnt_ignore_at_errors (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) -{ - const gchar *psnt; - const gchar *mode; - - *result = NULL; - *result_error = NULL; - - if (error) { - /* Ignore AT errors (ie, ERROR or CMx ERROR) */ - if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) { - *result_error = g_error_copy (error); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; - } - - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; - } - - psnt = mm_strip_tag (response, "#PSNT:"); - mode = strchr (psnt, ','); - if (mode) { - switch (atoi (++mode)) { - case 0: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_GPRS); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - case 1: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_EDGE); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - case 2: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_UMTS); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - case 3: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_HSDPA); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - case 4: - if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_LTE); - else - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - case 5: - if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) { - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - } - /* Fall-through since #PSNT: 5 is not supported in other than lte modems */ - default: - break; - } - } - - g_set_error (result_error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Failed to parse #PSNT response: '%s'", - response); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; -} - -static MMBaseModemAtResponseProcessorResult -response_processor_service_ignore_at_errors (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) -{ - const gchar *service; - - *result = NULL; - *result_error = NULL; - - if (error) { - /* Ignore AT errors (ie, ERROR or CMx ERROR) */ - if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) { - *result_error = g_error_copy (error); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; - } - - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; - } - - service = mm_strip_tag (response, "+SERVICE:"); - if (service) { - switch (atoi (service)) { - case 1: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_1XRTT); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - case 2: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_EVDO0); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - case 3: - *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_EVDOA); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; - default: - break; - } - } - - g_set_error (result_error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Failed to parse +SERVICE response: '%s'", - response); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; -} - -static const MMBaseModemAtCommand access_tech_commands[] = { - { "+COPS?", 3, FALSE, response_processor_cops_ignore_at_errors }, - { "#PSNT?", 3, FALSE, response_processor_psnt_ignore_at_errors }, - { "+SERVICE?", 3, FALSE, response_processor_service_ignore_at_errors }, - { NULL } -}; - -static void -load_access_technologies (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - mm_base_modem_at_sequence ( - MM_BASE_MODEM (self), - access_tech_commands, - NULL, /* response_processor_context */ - NULL, /* response_processor_context_free */ - callback, - user_data); -} - -/*****************************************************************************/ -/* Load supported modes (Modem interface) */ - -static GArray * -load_supported_modes_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return (GArray *) g_task_propagate_pointer (G_TASK (res), error); -} - -static void -parent_load_supported_modes_ready (MMIfaceModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - GArray *all; - GArray *combinations; - GArray *filtered; - MMSharedTelit *shared = MM_SHARED_TELIT (self); - - all = iface_modem_parent->load_supported_modes_finish (self, res, &error); - if (!all) { - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - /* CDMA-only modems don't support changing modes, default to parent's */ - if (!mm_iface_modem_is_3gpp (self)) { - g_task_return_pointer (task, all, (GDestroyNotify) g_array_unref); - g_object_unref (task); - return; - } - - /* Filter out those unsupported modes */ - combinations = mm_telit_build_modes_list(); - filtered = mm_filter_supported_modes (all, combinations, self); - g_array_unref (all); - g_array_unref (combinations); - - mm_shared_telit_store_supported_modes (shared, filtered); - g_task_return_pointer (task, filtered, (GDestroyNotify) g_array_unref); - g_object_unref (task); -} - -static void -load_supported_modes (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - /* Run parent's loading */ - iface_modem_parent->load_supported_modes ( - MM_IFACE_MODEM (self), - (GAsyncReadyCallback)parent_load_supported_modes_ready, - g_task_new (self, NULL, callback, user_data)); -} - -/*****************************************************************************/ -/* Enabling unsolicited events (3GPP interface) */ - -static gboolean -modem_3gpp_enable_unsolicited_events_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -cind_set_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - - if (!mm_base_modem_at_command_finish (self, res, &error)) { - mm_obj_warn (self, "couldn't enable custom +CIND settings: %s", error->message); - g_error_free (error); - } - - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void -parent_enable_unsolicited_events_ready (MMIfaceModem3gpp *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - - if (!iface_modem_3gpp_parent->enable_unsolicited_events_finish (self, res, &error)) { - mm_obj_warn (self, "couldn't enable parent 3GPP unsolicited events: %s", error->message); - g_error_free (error); - } - - /* Our own enable now */ - mm_base_modem_at_command_full ( - MM_BASE_MODEM (self), - mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)), - /* Enable +CIEV only for: signal, service, roam */ - "AT+CIND=0,1,1,0,0,0,1,0,0", - 5, - FALSE, - FALSE, - NULL, /* cancellable */ - (GAsyncReadyCallback)cind_set_ready, - task); -} - -static void -modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - - task = g_task_new (self, NULL, callback, user_data); - - /* Chain up parent's enable */ - iface_modem_3gpp_parent->enable_unsolicited_events ( - self, - (GAsyncReadyCallback)parent_enable_unsolicited_events_ready, - task); -} - -/*****************************************************************************/ - -MMBroadbandModemTelit * -mm_broadband_modem_telit_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id) -{ - return g_object_new (MM_TYPE_BROADBAND_MODEM_TELIT, - MM_BASE_MODEM_DEVICE, device, - MM_BASE_MODEM_DRIVERS, drivers, - MM_BASE_MODEM_PLUGIN, plugin, - MM_BASE_MODEM_VENDOR_ID, vendor_id, - MM_BASE_MODEM_PRODUCT_ID, product_id, - /* Generic bearer supports AT only */ - MM_BASE_MODEM_DATA_NET_SUPPORTED, FALSE, - MM_BASE_MODEM_DATA_TTY_SUPPORTED, TRUE, - MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED, TRUE, - NULL); -} - -static void -mm_broadband_modem_telit_init (MMBroadbandModemTelit *self) -{ - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - MM_TYPE_BROADBAND_MODEM_TELIT, - MMBroadbandModemTelitPrivate); - - self->priv->csim_lock_support = FEATURE_SUPPORT_UNKNOWN; - self->priv->csim_lock_state = CSIM_LOCK_STATE_UNKNOWN; - self->priv->qss_status = QSS_STATUS_UNKNOWN; - self->priv->parse_qss = TRUE; -} - -static void -iface_modem_init (MMIfaceModem *iface) -{ - iface_modem_parent = g_type_interface_peek_parent (iface); - - iface->set_current_bands = mm_shared_telit_modem_set_current_bands; - iface->set_current_bands_finish = mm_shared_telit_modem_set_current_bands_finish; - iface->load_current_bands = mm_shared_telit_modem_load_current_bands; - iface->load_current_bands_finish = mm_shared_telit_modem_load_current_bands_finish; - iface->load_revision = mm_shared_telit_modem_load_revision; - iface->load_revision_finish = mm_shared_telit_modem_load_revision_finish; - iface->load_supported_bands = mm_shared_telit_modem_load_supported_bands; - iface->load_supported_bands_finish = mm_shared_telit_modem_load_supported_bands_finish; - iface->load_unlock_retries_finish = modem_load_unlock_retries_finish; - iface->load_unlock_retries = modem_load_unlock_retries; - iface->reset = modem_reset; - iface->reset_finish = modem_reset_finish; - iface->modem_after_power_up = modem_after_power_up; - iface->modem_after_power_up_finish = modem_after_power_up_finish; - iface->modem_power_down = modem_power_down; - iface->modem_power_down_finish = modem_power_down_finish; - iface->load_access_technologies = load_access_technologies; - iface->load_access_technologies_finish = load_access_technologies_finish; - iface->load_supported_modes = load_supported_modes; - iface->load_supported_modes_finish = load_supported_modes_finish; - iface->load_current_modes = mm_shared_telit_load_current_modes; - iface->load_current_modes_finish = mm_shared_telit_load_current_modes_finish; - iface->set_current_modes = mm_shared_telit_set_current_modes; - iface->set_current_modes_finish = mm_shared_telit_set_current_modes_finish; - iface->setup_sim_hot_swap = modem_setup_sim_hot_swap; - iface->setup_sim_hot_swap_finish = modem_setup_sim_hot_swap_finish; - iface->cleanup_sim_hot_swap = modem_cleanup_sim_hot_swap; -} - -static void -iface_modem_3gpp_init (MMIfaceModem3gpp *iface) -{ - iface_modem_3gpp_parent = g_type_interface_peek_parent (iface); - - iface->enable_unsolicited_events = modem_3gpp_enable_unsolicited_events; - iface->enable_unsolicited_events_finish = modem_3gpp_enable_unsolicited_events_finish; -} - -static void -shared_telit_init (MMSharedTelit *iface) -{ -} - -static void -iface_modem_location_init (MMIfaceModemLocation *iface) -{ - iface_modem_location_parent = g_type_interface_peek_parent (iface); - - iface->load_capabilities = location_load_capabilities; - iface->load_capabilities_finish = location_load_capabilities_finish; - iface->enable_location_gathering = enable_location_gathering; - iface->enable_location_gathering_finish = enable_location_gathering_finish; - iface->disable_location_gathering = disable_location_gathering; - iface->disable_location_gathering_finish = disable_location_gathering_finish; -} - -static void -mm_broadband_modem_telit_class_init (MMBroadbandModemTelitClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - MMBroadbandModemClass *broadband_modem_class = MM_BROADBAND_MODEM_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (MMBroadbandModemTelitPrivate)); - broadband_modem_class->setup_ports = setup_ports; -} diff --git a/plugins/telit/mm-broadband-modem-telit.h b/plugins/telit/mm-broadband-modem-telit.h deleted file mode 100644 index f68465e7..00000000 --- a/plugins/telit/mm-broadband-modem-telit.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- 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) 2008 - 2009 Novell, Inc. - * Copyright (C) 2009 - 2013 Red Hat, Inc. - * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org> - */ - -#ifndef MM_BROADBAND_MODEM_TELIT_H -#define MM_BROADBAND_MODEM_TELIT_H - -#include "mm-broadband-modem.h" - -#define MM_TYPE_BROADBAND_MODEM_TELIT (mm_broadband_modem_telit_get_type ()) -#define MM_BROADBAND_MODEM_TELIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BROADBAND_MODEM_TELIT, MMBroadbandModemTelit)) -#define MM_BROADBAND_MODEM_TELIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BROADBAND_MODEM_TELIT, MMBroadbandModemTelitClass)) -#define MM_IS_BROADBAND_MODEM_TELIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BROADBAND_MODEM_TELIT)) -#define MM_IS_BROADBAND_MODEM_TELIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BROADBAND_MODEM_TELIT)) -#define MM_BROADBAND_MODEM_TELIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BROADBAND_MODEM_TELIT, MMBroadbandModemTelitClass)) - -typedef struct _MMBroadbandModemTelit MMBroadbandModemTelit; -typedef struct _MMBroadbandModemTelitClass MMBroadbandModemTelitClass; -typedef struct _MMBroadbandModemTelitPrivate MMBroadbandModemTelitPrivate; - -struct _MMBroadbandModemTelit { - MMBroadbandModem parent; - MMBroadbandModemTelitPrivate *priv; -}; - -struct _MMBroadbandModemTelitClass{ - MMBroadbandModemClass parent; -}; - -GType mm_broadband_modem_telit_get_type (void); - -MMBroadbandModemTelit *mm_broadband_modem_telit_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id); - -#endif /* MM_BROADBAND_MODEM_TELIT_H */ diff --git a/plugins/telit/mm-common-telit.c b/plugins/telit/mm-common-telit.c deleted file mode 100644 index 911c605b..00000000 --- a/plugins/telit/mm-common-telit.c +++ /dev/null @@ -1,373 +0,0 @@ -/* -*- 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) 2015 Aleksander Morgado <aleksander@aleksander.es> - */ - -#include <string.h> - -#include "mm-common-telit.h" -#include "mm-log-object.h" -#include "mm-serial-parsers.h" - -/*****************************************************************************/ - -#define TAG_GETPORTCFG_SUPPORTED "getportcfg-supported" - -#define TAG_TELIT_MODEM_PORT "ID_MM_TELIT_PORT_TYPE_MODEM" -#define TAG_TELIT_AUX_PORT "ID_MM_TELIT_PORT_TYPE_AUX" -#define TAG_TELIT_NMEA_PORT "ID_MM_TELIT_PORT_TYPE_NMEA" - -#define TELIT_GE910_FAMILY_PID 0x0022 - -/* The following number of retries of the port responsiveness - * check allows having up to 30 seconds of wait, that should - * be fine for most of the modems */ -#define TELIT_PORT_CHECK_RETRIES 6 - -gboolean -telit_grab_port (MMPlugin *self, - MMBaseModem *modem, - MMPortProbe *probe, - GError **error) -{ - MMKernelDevice *port; - MMDevice *device; - MMPortType ptype; - MMPortSerialAtFlag pflags = MM_PORT_SERIAL_AT_FLAG_NONE; - const gchar *subsys; - - port = mm_port_probe_peek_port (probe); - ptype = mm_port_probe_get_port_type (probe); - device = mm_port_probe_peek_device (probe); - subsys = mm_port_probe_get_port_subsys (probe); - - /* Just skip custom port identification for subsys different than tty */ - if (!g_str_equal (subsys, "tty")) - goto out; - - /* AT#PORTCFG (if supported) can be used for identifying the port layout */ - if (g_object_get_data (G_OBJECT (device), TAG_GETPORTCFG_SUPPORTED) != NULL) { - guint usbif; - - usbif = (guint) mm_kernel_device_get_interface_number (port); - if (usbif == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_TELIT_MODEM_PORT))) { - mm_obj_dbg (self, "AT port '%s/%s' flagged as primary", - mm_port_probe_get_port_subsys (probe), - mm_port_probe_get_port_name (probe)); - pflags = MM_PORT_SERIAL_AT_FLAG_PRIMARY; - } else if (usbif == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_TELIT_AUX_PORT))) { - mm_obj_dbg (self, "AT port '%s/%s' flagged as secondary", - mm_port_probe_get_port_subsys (probe), - mm_port_probe_get_port_name (probe)); - pflags = MM_PORT_SERIAL_AT_FLAG_SECONDARY; - } else if (usbif == GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (device), TAG_TELIT_NMEA_PORT))) { - mm_obj_dbg (self, "port '%s/%s' flagged as NMEA", - mm_port_probe_get_port_subsys (probe), - mm_port_probe_get_port_name (probe)); - ptype = MM_PORT_TYPE_GPS; - } else - ptype = MM_PORT_TYPE_IGNORED; - } - -out: - return mm_base_modem_grab_port (modem, - port, - ptype, - pflags, - error); -} - -/*****************************************************************************/ -/* Custom init */ - -typedef struct { - MMPortSerialAt *port; - gboolean getportcfg_done; - guint getportcfg_retries; - guint port_responsive_retries; -} TelitCustomInitContext; - -gboolean -telit_custom_init_finish (MMPortProbe *probe, - GAsyncResult *result, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (result), error); -} - -static void telit_custom_init_step (GTask *task); - -static gboolean -cache_port_mode (MMPortProbe *probe, - MMDevice *device, - const gchar *reply) -{ - g_autoptr(GRegex) r = NULL; - g_autoptr(GMatchInfo) match_info = NULL; - GRegexCompileFlags flags = G_REGEX_DOLLAR_ENDONLY | G_REGEX_RAW; - GError *error = NULL; - gboolean ret = FALSE; - guint portcfg_current; - - /* #PORTCFG: <requested>,<active> */ - r = g_regex_new ("#PORTCFG:\\s*(\\d+),(\\d+)", flags, 0, NULL); - g_assert (r != NULL); - - if (!g_regex_match_full (r, reply, strlen (reply), 0, 0, &match_info, &error)) - goto out; - - if (!mm_get_uint_from_match_info (match_info, 2, &portcfg_current)) { - mm_obj_dbg (probe, "unrecognized #PORTCFG <active> value"); - goto out; - } - - /* Reference for port configurations: - * HE910/UE910/UL865 Families Ports Arrangements User Guide - * GE910 Family Ports Arrangements User Guide - */ - switch (portcfg_current) { - case 0: - case 1: - case 4: - case 5: - case 7: - case 9: - case 10: - case 11: - g_object_set_data (G_OBJECT (device), TAG_TELIT_MODEM_PORT, GUINT_TO_POINTER (0x00)); - if (mm_device_get_product (device) == TELIT_GE910_FAMILY_PID) - g_object_set_data (G_OBJECT (device), TAG_TELIT_AUX_PORT, GUINT_TO_POINTER (0x02)); - else - g_object_set_data (G_OBJECT (device), TAG_TELIT_AUX_PORT, GUINT_TO_POINTER (0x06)); - break; - case 2: - case 3: - case 6: - g_object_set_data (G_OBJECT (device), TAG_TELIT_MODEM_PORT, GUINT_TO_POINTER (0x00)); - break; - case 8: - case 12: - g_object_set_data (G_OBJECT (device), TAG_TELIT_MODEM_PORT, GUINT_TO_POINTER (0x00)); - if (mm_device_get_product (device) == TELIT_GE910_FAMILY_PID) { - g_object_set_data (G_OBJECT (device), TAG_TELIT_AUX_PORT, GUINT_TO_POINTER (0x02)); - g_object_set_data (G_OBJECT (device), TAG_TELIT_NMEA_PORT, GUINT_TO_POINTER (0x04)); - } else { - g_object_set_data (G_OBJECT (device), TAG_TELIT_AUX_PORT, GUINT_TO_POINTER (0x06)); - g_object_set_data (G_OBJECT (device), TAG_TELIT_NMEA_PORT, GUINT_TO_POINTER (0x0a)); - } - break; - default: - /* portcfg value not supported */ - goto out; - } - ret = TRUE; - -out: - if (error) { - mm_obj_dbg (probe, "error while matching #PORTCFG: %s", error->message); - g_error_free (error); - } - return ret; -} - -static void -getportcfg_ready (MMPortSerialAt *port, - GAsyncResult *res, - GTask *task) -{ - const gchar *response; - GError *error = NULL; - MMPortProbe *probe; - TelitCustomInitContext *ctx; - - ctx = g_task_get_task_data (task); - probe = g_task_get_source_object (task); - - response = mm_port_serial_at_command_finish (port, res, &error); - if (error) { - mm_obj_dbg (probe, "couldn't get telit port mode: '%s'", error->message); - - /* If ERROR or COMMAND NOT SUPPORT occur then do not retry the - * command. - */ - if (g_error_matches (error, - MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN)) - ctx->getportcfg_done = TRUE; - } else { - MMDevice *device; - - device = mm_port_probe_peek_device (probe); - - /* Results are cached in the parent device object */ - if (g_object_get_data (G_OBJECT (device), TAG_GETPORTCFG_SUPPORTED) == NULL) { - mm_obj_dbg (probe, "retrieving telit port mode layout"); - if (cache_port_mode (probe, device, response)) { - g_object_set_data (G_OBJECT (device), TAG_GETPORTCFG_SUPPORTED, GUINT_TO_POINTER (TRUE)); - ctx->getportcfg_done = TRUE; - } - } - - /* Port answered to #PORTCFG, so mark it as being AT already */ - mm_port_probe_set_result_at (probe, TRUE); - } - - if (error) - g_error_free (error); - - telit_custom_init_step (task); -} - -static void -telit_custom_init_context_free (TelitCustomInitContext *ctx) -{ - g_object_unref (ctx->port); - g_slice_free (TelitCustomInitContext, ctx); -} - -static void -telit_custom_init_step (GTask *task) -{ - MMKernelDevice *port; - MMPortProbe *probe; - TelitCustomInitContext *ctx; - - ctx = g_task_get_task_data (task); - probe = g_task_get_source_object (task); - - /* If cancelled, end */ - if (g_cancellable_is_cancelled (g_task_get_cancellable (task))) { - mm_obj_dbg (probe, "no need to keep on running custom init"); - goto out; - } - - /* Try to get a port configuration from the modem: usb interface 00 - * is always linked to an AT port - */ - port = mm_port_probe_peek_port (probe); - if (!ctx->getportcfg_done && mm_kernel_device_get_interface_number (port) == 0) { - if (ctx->getportcfg_retries == 0) - goto out; - ctx->getportcfg_retries--; - - mm_port_serial_at_command ( - ctx->port, - "AT#PORTCFG?", - 2, - FALSE, /* raw */ - FALSE, /* allow_cached */ - g_task_get_cancellable (task), - (GAsyncReadyCallback)getportcfg_ready, - task); - return; - } - -out: - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void at_ready (MMPortSerialAt *port, - GAsyncResult *res, - GTask *task); - -static void -wait_for_ready (GTask *task) -{ - TelitCustomInitContext *ctx; - - ctx = g_task_get_task_data (task); - - if (ctx->port_responsive_retries == 0) { - telit_custom_init_step (task); - return; - } - ctx->port_responsive_retries--; - - mm_port_serial_at_command ( - ctx->port, - "AT", - 5, - FALSE, /* raw */ - FALSE, /* allow_cached */ - g_task_get_cancellable (task), - (GAsyncReadyCallback)at_ready, - task); -} - -static void -at_ready (MMPortSerialAt *port, - GAsyncResult *res, - GTask *task) -{ - MMPortProbe *probe; - g_autoptr(GError) error = NULL; - - probe = g_task_get_source_object (task); - - mm_port_serial_at_command_finish (port, res, &error); - if (error) { - /* On a timeout or send error, wait */ - if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT) || - g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_SEND_FAILED)) { - wait_for_ready (task); - return; - } - /* On an unknown error, make it fatal */ - if (!mm_serial_parser_v1_is_known_error (error)) { - mm_obj_warn (probe, "custom port initialization logic failed: %s", error->message); - g_task_return_boolean (task, TRUE); - g_object_unref (task); - return; - } - } - - /* When successful mark the port as AT and continue checking #PORTCFG */ - mm_obj_dbg (probe, "port is AT"); - mm_port_probe_set_result_at (probe, TRUE); - telit_custom_init_step (task); -} - -void -telit_custom_init (MMPortProbe *probe, - MMPortSerialAt *port, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - TelitCustomInitContext *ctx; - GTask *task; - gboolean wait_needed; - - ctx = g_slice_new (TelitCustomInitContext); - ctx->port = g_object_ref (port); - ctx->getportcfg_done = FALSE; - ctx->getportcfg_retries = 3; - ctx->port_responsive_retries = TELIT_PORT_CHECK_RETRIES; - task = g_task_new (probe, cancellable, callback, user_data); - g_task_set_check_cancellable (task, FALSE); - g_task_set_task_data (task, ctx, (GDestroyNotify)telit_custom_init_context_free); - - /* Some Telit modems require an initial delay for the ports to be responsive - * If no explicit tag is present, the modem does not need this step - * and can directly look for #PORTCFG support */ - wait_needed = mm_kernel_device_get_global_property_as_boolean (mm_port_probe_peek_port (probe), - "ID_MM_TELIT_PORT_DELAY"); - if (wait_needed) { - mm_obj_dbg (probe, "Start polling for port responsiveness"); - wait_for_ready (task); - return; - } - - telit_custom_init_step (task); -} diff --git a/plugins/telit/mm-common-telit.h b/plugins/telit/mm-common-telit.h deleted file mode 100644 index 0c5dbe7a..00000000 --- a/plugins/telit/mm-common-telit.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- 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) 2015 Aleksander Morgado <aleksander@aleksander.es> - */ - -#ifndef MM_COMMON_TELIT_H -#define MM_COMMON_TELIT_H - -#include "glib.h" -#include "mm-plugin.h" - -gboolean -telit_custom_init_finish (MMPortProbe *probe, - GAsyncResult *result, - GError **error); - -void -telit_custom_init (MMPortProbe *probe, - MMPortSerialAt *port, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data); - -gboolean -telit_grab_port (MMPlugin *self, - MMBaseModem *modem, - MMPortProbe *probe, - GError **error); - -#endif /* MM_COMMON_TELIT_H */ diff --git a/plugins/telit/mm-modem-helpers-telit.c b/plugins/telit/mm-modem-helpers-telit.c deleted file mode 100644 index c0df8093..00000000 --- a/plugins/telit/mm-modem-helpers-telit.c +++ /dev/null @@ -1,967 +0,0 @@ -/* -*- 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) 2015-2019 Telit. - * Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es> - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> - -#include <ModemManager.h> -#define _LIBMM_INSIDE_MMCLI -#include <libmm-glib.h> - -#include "mm-log-object.h" -#include "mm-modem-helpers.h" -#include "mm-modem-helpers-telit.h" - -/*****************************************************************************/ -/* AT#BND 2G values */ - -#define MM_MODEM_BAND_TELIT_2G_FIRST MM_MODEM_BAND_EGSM -#define MM_MODEM_BAND_TELIT_2G_LAST MM_MODEM_BAND_G850 - -#define B2G_FLAG(band) (1 << (band - MM_MODEM_BAND_TELIT_2G_FIRST)) - -/* Index of the array is the telit 2G band value [0-5] - * The bitmask value here is built from the 2G MMModemBand values right away. */ -static const guint32 telit_2g_to_mm_band_mask[] = { - [0] = B2G_FLAG (MM_MODEM_BAND_EGSM) + B2G_FLAG (MM_MODEM_BAND_DCS), - [1] = B2G_FLAG (MM_MODEM_BAND_EGSM) + B2G_FLAG (MM_MODEM_BAND_PCS), - [2] = B2G_FLAG (MM_MODEM_BAND_DCS) + B2G_FLAG (MM_MODEM_BAND_G850), - [3] = B2G_FLAG (MM_MODEM_BAND_PCS) + B2G_FLAG (MM_MODEM_BAND_G850), - [4] = B2G_FLAG (MM_MODEM_BAND_EGSM) + B2G_FLAG (MM_MODEM_BAND_DCS) + B2G_FLAG (MM_MODEM_BAND_PCS), - [5] = B2G_FLAG (MM_MODEM_BAND_EGSM) + B2G_FLAG (MM_MODEM_BAND_DCS) + B2G_FLAG (MM_MODEM_BAND_PCS) + B2G_FLAG (MM_MODEM_BAND_G850), -}; - -/*****************************************************************************/ -/* AT#BND 3G values */ - -/* NOTE: UTRAN_1 to UTRAN_9 enum values are NOT IN ORDER! - * E.g. numerically UTRAN_7 is after UTRAN_9... - * - * This array allows us to iterate them in a way which is a bit - * more friendly. - */ -static const guint band_utran_index[] = { - [MM_MODEM_BAND_UTRAN_1] = 1, - [MM_MODEM_BAND_UTRAN_2] = 2, - [MM_MODEM_BAND_UTRAN_3] = 3, - [MM_MODEM_BAND_UTRAN_4] = 4, - [MM_MODEM_BAND_UTRAN_5] = 5, - [MM_MODEM_BAND_UTRAN_6] = 6, - [MM_MODEM_BAND_UTRAN_7] = 7, - [MM_MODEM_BAND_UTRAN_8] = 8, - [MM_MODEM_BAND_UTRAN_9] = 9, - [MM_MODEM_BAND_UTRAN_10] = 10, - [MM_MODEM_BAND_UTRAN_11] = 11, - [MM_MODEM_BAND_UTRAN_12] = 12, - [MM_MODEM_BAND_UTRAN_13] = 13, - [MM_MODEM_BAND_UTRAN_14] = 14, - [MM_MODEM_BAND_UTRAN_19] = 19, - [MM_MODEM_BAND_UTRAN_20] = 20, - [MM_MODEM_BAND_UTRAN_21] = 21, - [MM_MODEM_BAND_UTRAN_22] = 22, - [MM_MODEM_BAND_UTRAN_25] = 25, - [MM_MODEM_BAND_UTRAN_26] = 26, - [MM_MODEM_BAND_UTRAN_32] = 32, -}; - -#define MM_MODEM_BAND_TELIT_3G_FIRST MM_MODEM_BAND_UTRAN_1 -#define MM_MODEM_BAND_TELIT_3G_LAST MM_MODEM_BAND_UTRAN_19 - -#define B3G_NUM(band) band_utran_index[band] -#define B3G_FLAG(band) ((B3G_NUM (band) > 0) ? (1LL << (B3G_NUM (band) - B3G_NUM (MM_MODEM_BAND_TELIT_3G_FIRST))) : 0) - -/* Index of the arrays is the telit 3G band value. - * The bitmask value here is built from the 3G MMModemBand values right away. - * - * We have 2 different sets of bands that are different for values >=12, because - * the LM940/960 models support a different set of 3G bands. - */ - -#define TELIT_3G_TO_MM_BAND_MASK_DEFAULT_N_ELEMENTS 27 -static guint64 telit_3g_to_mm_band_mask_default[TELIT_3G_TO_MM_BAND_MASK_DEFAULT_N_ELEMENTS]; - -#define TELIT_3G_TO_MM_BAND_MASK_ALTERNATE_N_ELEMENTS 20 -static guint64 telit_3g_to_mm_band_mask_alternate[TELIT_3G_TO_MM_BAND_MASK_ALTERNATE_N_ELEMENTS]; - -static void -initialize_telit_3g_to_mm_band_masks (void) -{ - static gboolean initialized = FALSE; - - /* We need to initialize the arrays in runtime because gcc < 8 doesn't like initializing - * with operations that are using the band_utran_index constant array elements */ - - if (initialized) - return; - - telit_3g_to_mm_band_mask_default[0] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1); - telit_3g_to_mm_band_mask_default[1] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2); - telit_3g_to_mm_band_mask_default[2] = B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_default[3] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_default[4] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_default[5] = B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_default[6] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_default[7] = B3G_FLAG (MM_MODEM_BAND_UTRAN_4); - telit_3g_to_mm_band_mask_default[8] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_default[9] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_default[10] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_default[11] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_default[12] = B3G_FLAG (MM_MODEM_BAND_UTRAN_6); - telit_3g_to_mm_band_mask_default[13] = B3G_FLAG (MM_MODEM_BAND_UTRAN_3); - telit_3g_to_mm_band_mask_default[14] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6); - telit_3g_to_mm_band_mask_default[15] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_default[16] = B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_default[17] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_6); - telit_3g_to_mm_band_mask_default[18] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_default[19] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6); - telit_3g_to_mm_band_mask_default[20] = B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6); - telit_3g_to_mm_band_mask_default[21] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6); - telit_3g_to_mm_band_mask_default[22] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_default[23] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3); - telit_3g_to_mm_band_mask_default[24] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_default[25] = B3G_FLAG (MM_MODEM_BAND_UTRAN_19); - telit_3g_to_mm_band_mask_default[26] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_8) + B3G_FLAG (MM_MODEM_BAND_UTRAN_19); - - /* Initialize alternate 3G band set */ - telit_3g_to_mm_band_mask_alternate[0] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1); - telit_3g_to_mm_band_mask_alternate[1] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2); - telit_3g_to_mm_band_mask_alternate[2] = B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_alternate[3] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_alternate[4] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_alternate[5] = B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_alternate[6] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_alternate[7] = B3G_FLAG (MM_MODEM_BAND_UTRAN_4); - telit_3g_to_mm_band_mask_alternate[8] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_alternate[9] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_alternate[10] = B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_alternate[11] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_alternate[12] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_alternate[13] = B3G_FLAG (MM_MODEM_BAND_UTRAN_3); - telit_3g_to_mm_band_mask_alternate[14] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_alternate[15] = B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5); - telit_3g_to_mm_band_mask_alternate[16] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_3) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_alternate[17] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8); - telit_3g_to_mm_band_mask_alternate[18] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8) + B3G_FLAG (MM_MODEM_BAND_UTRAN_9) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_19); - telit_3g_to_mm_band_mask_alternate[19] = B3G_FLAG (MM_MODEM_BAND_UTRAN_1) + B3G_FLAG (MM_MODEM_BAND_UTRAN_2) + B3G_FLAG (MM_MODEM_BAND_UTRAN_4) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_5) + B3G_FLAG (MM_MODEM_BAND_UTRAN_6) + B3G_FLAG (MM_MODEM_BAND_UTRAN_8) + - B3G_FLAG (MM_MODEM_BAND_UTRAN_9) + B3G_FLAG (MM_MODEM_BAND_UTRAN_19); -} - -/*****************************************************************************/ -/* AT#BND 4G values - * - * The Telit-specific value for 4G bands is a bitmask of the band values, given - * in hexadecimal or decimal format. - */ - -#define MM_MODEM_BAND_TELIT_4G_FIRST MM_MODEM_BAND_EUTRAN_1 -#define MM_MODEM_BAND_TELIT_4G_LAST MM_MODEM_BAND_EUTRAN_64 - -#define B4G_FLAG(band) (((guint64) 1) << (band - MM_MODEM_BAND_TELIT_4G_FIRST)) - -#define MM_MODEM_BAND_TELIT_EXT_4G_FIRST MM_MODEM_BAND_EUTRAN_65 -#define MM_MODEM_BAND_TELIT_EXT_4G_LAST MM_MODEM_BAND_EUTRAN_85 - -#define B4G_FLAG_EXT(band) (((guint64) 1) << (band - MM_MODEM_BAND_TELIT_EXT_4G_FIRST)) - -/*****************************************************************************/ -/* Set current bands helpers */ - -gchar * -mm_telit_build_bnd_request (GArray *bands_array, - MMTelitBNDParseConfig *config, - GError **error) -{ - guint32 mask2g = 0; - guint64 mask3g = 0; - guint64 mask4g = 0; - guint64 mask4gext = 0; - guint i; - gint flag2g = -1; - gint64 flag3g = -1; - gint64 flag4g = -1; - gchar *cmd; - gboolean modem_is_2g = config->modem_is_2g; - gboolean modem_is_3g = config->modem_is_3g; - gboolean modem_is_4g = config->modem_is_4g; - - for (i = 0; i < bands_array->len; i++) { - MMModemBand band; - - band = g_array_index (bands_array, MMModemBand, i); - - /* Convert 2G bands into a bitmask, to match against telit_2g_to_mm_band_mask. */ - if (modem_is_2g && mm_common_band_is_gsm (band) && - (band >= MM_MODEM_BAND_TELIT_2G_FIRST) && (band <= MM_MODEM_BAND_TELIT_2G_LAST)) - mask2g += B2G_FLAG (band); - - /* Convert 3G bands into a bitmask, to match against telit_3g_to_mm_band_mask. We use - * a 64-bit explicit bitmask so that all values fit correctly. */ - if (modem_is_3g && mm_common_band_is_utran (band) && - (B3G_NUM (band) >= B3G_NUM (MM_MODEM_BAND_TELIT_3G_FIRST)) && (B3G_NUM (band) <= B3G_NUM (MM_MODEM_BAND_TELIT_3G_LAST))) - mask3g += B3G_FLAG (band); - - /* Convert 4G bands into a bitmask. We use a 64bit explicit bitmask so that - * all values fit correctly. */ - if (modem_is_4g && mm_common_band_is_eutran (band)) { - if (band >= MM_MODEM_BAND_TELIT_4G_FIRST && band <= MM_MODEM_BAND_TELIT_4G_LAST) - mask4g += B4G_FLAG (band); - else if (band >= MM_MODEM_BAND_TELIT_EXT_4G_FIRST && band <= MM_MODEM_BAND_TELIT_EXT_4G_LAST) - mask4gext += B4G_FLAG_EXT (band); - } - } - - /* Get 2G-specific telit value */ - if (mask2g) { - for (i = 0; i < G_N_ELEMENTS (telit_2g_to_mm_band_mask); i++) { - if (mask2g == telit_2g_to_mm_band_mask[i]) { - flag2g = i; - break; - } - } - if (flag2g == -1) { - gchar *bands_str; - - bands_str = mm_common_build_bands_string ((const MMModemBand *)(gconstpointer)(bands_array->data), bands_array->len); - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Couldn't find matching 2G bands Telit value for band combination: '%s'", bands_str); - g_free (bands_str); - return NULL; - } - } - - /* Get 3G-specific telit value */ - if (mask3g) { - const guint64 *telit_3g_to_mm_band_mask; - guint telit_3g_to_mm_band_mask_n_elements; - - initialize_telit_3g_to_mm_band_masks (); - - /* Select correct 3G band mask */ - if (config->modem_alternate_3g_bands) { - telit_3g_to_mm_band_mask = telit_3g_to_mm_band_mask_alternate; - telit_3g_to_mm_band_mask_n_elements = G_N_ELEMENTS (telit_3g_to_mm_band_mask_alternate); - } else { - telit_3g_to_mm_band_mask = telit_3g_to_mm_band_mask_default; - telit_3g_to_mm_band_mask_n_elements = G_N_ELEMENTS (telit_3g_to_mm_band_mask_default); - } - for (i = 0; i < telit_3g_to_mm_band_mask_n_elements; i++) { - if (mask3g == telit_3g_to_mm_band_mask[i]) { - flag3g = i; - break; - } - } - if (flag3g == -1) { - gchar *bands_str; - - bands_str = mm_common_build_bands_string ((const MMModemBand *)(gconstpointer)(bands_array->data), bands_array->len); - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Couldn't find matching 3G bands Telit value for band combination: '%s'", bands_str); - g_free (bands_str); - return NULL; - } - } - - /* Get 4G-specific telit band bitmask */ - flag4g = (mask4g != 0) ? ((gint64)mask4g) : -1; - - /* If the modem supports a given access tech, we must always give band settings - * for the specific tech */ - if (modem_is_2g && flag2g == -1) { - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND, - "None or invalid 2G bands combination in the provided list"); - return NULL; - } - if (modem_is_3g && flag3g == -1) { - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND, - "None or invalid 3G bands combination in the provided list"); - return NULL; - } - if (modem_is_4g && mask4g == 0 && mask4gext == 0) { - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_NOT_FOUND, - "None or invalid 4G bands combination in the provided list"); - return NULL; - } - - if (modem_is_2g && !modem_is_3g && !modem_is_4g) - cmd = g_strdup_printf ("#BND=%d", flag2g); - else if (!modem_is_2g && modem_is_3g && !modem_is_4g) - cmd = g_strdup_printf ("#BND=0,%" G_GINT64_FORMAT, flag3g); - else if (modem_is_2g && modem_is_3g && !modem_is_4g) - cmd = g_strdup_printf ("#BND=%d,%" G_GINT64_FORMAT, flag2g, flag3g); - else if (!modem_is_2g && !modem_is_3g && modem_is_4g) { - if (!config->modem_ext_4g_bands) - cmd = g_strdup_printf ("#BND=0,0,%" G_GINT64_FORMAT, flag4g); - else - cmd = g_strdup_printf ("#BND=0,0,%" G_GINT64_MODIFIER "x" ",%" G_GINT64_MODIFIER "x", mask4g, mask4gext); - } else if (!modem_is_2g && modem_is_3g && modem_is_4g) { - if (!config->modem_ext_4g_bands) - cmd = g_strdup_printf ("#BND=0,%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT, flag3g, flag4g); - else - cmd = g_strdup_printf ("#BND=0,%" G_GINT64_FORMAT ",%" G_GINT64_MODIFIER "x" ",%" G_GINT64_MODIFIER "x", flag3g, mask4g, mask4gext); - } else if (modem_is_2g && !modem_is_3g && modem_is_4g) { - if (!config->modem_ext_4g_bands) - cmd = g_strdup_printf ("#BND=%d,0,%" G_GINT64_FORMAT, flag2g, flag4g); - else - cmd = g_strdup_printf ("#BND=%d,0,%" G_GINT64_MODIFIER "x" ",%" G_GINT64_MODIFIER "x", flag2g, mask4g, mask4gext); - } else if (modem_is_2g && modem_is_3g && modem_is_4g) { - if (!config->modem_ext_4g_bands) - cmd = g_strdup_printf ("#BND=%d,%" G_GINT64_FORMAT ",%" G_GINT64_FORMAT, flag2g, flag3g, flag4g); - else - cmd = g_strdup_printf ("#BND=%d,%" G_GINT64_FORMAT ",%" G_GINT64_MODIFIER "x" ",%" G_GINT64_MODIFIER "x", flag2g, flag3g, mask4g, mask4gext); - } else - g_assert_not_reached (); - - return cmd; -} - -/*****************************************************************************/ -/* #BND response parser - * - * AT#BND=? - * #BND: <2G band flags range>,<3G band flags range>[, <4G band flags range>] - * - * where "band flags" is a list of numbers defining the supported bands. - * Note that the one Telit band flag may represent more than one MM band. - * - * e.g. - * - * #BND: (0-2),(3,4) - * - * (0,2) = 2G band flag 0 is EGSM + DCS - * = 2G band flag 1 is EGSM + PCS - * = 2G band flag 2 is DCS + G850 - * (3,4) = 3G band flag 3 is U2100 + U1900 + U850 - * = 3G band flag 4 is U1900 + U850 - * - * Modems that supports 4G bands, return a range value(X-Y) where - * X: represent the lower supported band, such as X = 2^(B-1), being B = B1, B2,..., B32 - * Y: is a 32 bit number resulting from a mask of all the supported bands: - * 1 - B1 - * 2 - B2 - * 4 - B3 - * 8 - B4 - * ... - * i - B(2exp(i-1)) - * ... - * 2147483648 - B32 - * - * e.g. - * (2-4106) - * 2 = 2^1 --> lower supported band B2 - * 4106 = 2^1 + 2^3 + 2^12 --> the supported bands are B2, B4, B13 - * - * - * AT#BND? - * #BND: <2G band flags>,<3G band flags>[, <4G band flags>] - * - * where "band flags" is a number defining the current bands. - * Note that the one Telit band flag may represent more than one MM band. - * - * e.g. - * - * #BND: 0,4 - * - * 0 = 2G band flag 0 is EGSM + DCS - * 4 = 3G band flag 4 is U1900 + U850 - * - * ---------------- - * - * For modems such as LN920 the #BND configuration/response for LTE bands is different - * from what is explained above: - * - * AT#BND=<GSM_band>[,<UMTS_band>[,<LTE_band>[,<LTE_band_ext>]]] - * - * <LTE_band>: hex: Indicates the LTE supported bands expressed as the sum of Band number (1+2+8 ...) calculated as shown in the table (mask of 64 bits): - * - * Band number(Hex) Band i - * 0 disable - * 1 B1 - * 2 B2 - * 4 B3 - * 8 B4 - * ... - * ... - * 80000000 B32 - * ... - * ... - * 800000000000 B48 - * - * It can take value, 0 - 87A03B0F38DF: range of the sum of Band number (1+2+4 ...) - * - * <LTE_band_ext>: hex: Indicates the LTE supported bands from B65 expressed as the sum of Band number (1+2+8 ...) calculated as shown in the table (mask of 64 bits): - * - * Band number(Hex) Band i - * 0 disable - * 2 B66 - * 40 B71 - * - * It can take value, 0 - 42: range of the sum of Band number (2+40) - * - * Note: LTE_band and LTE_band_ext cannot be 0 at the same time - * - * Example output: - * - * AT#BND=? - * #BND: (0),(0-11,17,18),(87A03B0F38DF),(42) - * - * AT#BND? - * #BND: 0,18,87A03B0F38DF,42 - * - */ - -static gboolean -telit_get_2g_mm_bands (GMatchInfo *match_info, - gpointer log_object, - GArray **bands, - GError **error) -{ - GError *inner_error = NULL; - GArray *values = NULL; - gchar *match_str = NULL; - guint i; - - match_str = g_match_info_fetch_named (match_info, "Bands2G"); - if (!match_str || match_str[0] == '\0') { - g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not find 2G band values from response"); - goto out; - } - - values = mm_parse_uint_list (match_str, &inner_error); - if (!values) - goto out; - - for (i = 0; i < values->len; i++) { - guint value; - - value = g_array_index (values, guint, i); - if (value < G_N_ELEMENTS (telit_2g_to_mm_band_mask)) { - guint j; - - for (j = MM_MODEM_BAND_TELIT_2G_FIRST; j <= MM_MODEM_BAND_TELIT_2G_LAST; j++) { - if ((telit_2g_to_mm_band_mask[value] & B2G_FLAG (j)) && !mm_common_bands_garray_lookup (*bands, j)) - *bands = g_array_append_val (*bands, j); - } - } else - mm_obj_dbg (log_object, "unhandled telit 2G band value configuration: %u", value); - } - -out: - g_free (match_str); - g_clear_pointer (&values, g_array_unref); - - if (inner_error) { - g_propagate_error (error, inner_error); - return FALSE; - } - return TRUE; -} - -static gboolean -telit_get_3g_mm_bands (GMatchInfo *match_info, - gpointer log_object, - gboolean modem_alternate_3g_bands, - GArray **bands, - GError **error) -{ - GError *inner_error = NULL; - GArray *values = NULL; - gchar *match_str = NULL; - guint i; - const guint64 *telit_3g_to_mm_band_mask; - guint telit_3g_to_mm_band_mask_n_elements; - - initialize_telit_3g_to_mm_band_masks (); - - /* Select correct 3G band mask */ - if (modem_alternate_3g_bands) { - telit_3g_to_mm_band_mask = telit_3g_to_mm_band_mask_alternate; - telit_3g_to_mm_band_mask_n_elements = G_N_ELEMENTS (telit_3g_to_mm_band_mask_alternate); - } else { - telit_3g_to_mm_band_mask = telit_3g_to_mm_band_mask_default; - telit_3g_to_mm_band_mask_n_elements = G_N_ELEMENTS (telit_3g_to_mm_band_mask_default); - } - - match_str = g_match_info_fetch_named (match_info, "Bands3G"); - if (!match_str || match_str[0] == '\0') { - g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not find 3G band values from response"); - goto out; - } - - values = mm_parse_uint_list (match_str, &inner_error); - if (!values) - goto out; - - for (i = 0; i < values->len; i++) { - guint value; - - value = g_array_index (values, guint, i); - - if (value < telit_3g_to_mm_band_mask_n_elements) { - guint j; - - for (j = 0; j < G_N_ELEMENTS (band_utran_index); j++) { - /* ignore non-3G bands */ - if (band_utran_index[j] == 0) - continue; - - if ((telit_3g_to_mm_band_mask[value] & B3G_FLAG (j)) && !mm_common_bands_garray_lookup (*bands, j)) - *bands = g_array_append_val (*bands, j); - } - } else - mm_obj_dbg (log_object, "unhandled telit 3G band value configuration: %u", value); - } - -out: - g_free (match_str); - g_clear_pointer (&values, g_array_unref); - - if (inner_error) { - g_propagate_error (error, inner_error); - return FALSE; - } - return TRUE; -} - -static gboolean -telit_get_4g_mm_bands (GMatchInfo *match_info, - GArray **bands, - GError **error) -{ - GError *inner_error = NULL; - MMModemBand band; - gchar *match_str = NULL; - guint64 value; - gchar **tokens = NULL; - gboolean hex_format = FALSE; - gboolean ok; - - match_str = g_match_info_fetch_named (match_info, "Bands4GDec"); - if (!match_str) { - match_str = g_match_info_fetch_named (match_info, "Bands4GHex"); - hex_format = match_str != NULL; - } - - if (!match_str || match_str[0] == '\0') { - g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not find 4G band flags from response"); - goto out; - } - - /* splitting will never return NULL as string is not empty */ - tokens = g_strsplit (match_str, "-", -1); - - /* If this is a range, get upper threshold, which contains the total supported mask */ - ok = hex_format? - mm_get_u64_from_hex_str (tokens[1] ? tokens[1] : tokens[0], &value): - mm_get_u64_from_str (tokens[1] ? tokens[1] : tokens[0], &value); - if (!ok) { - g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not parse 4G band mask from string: '%s'", match_str); - goto out; - } - - for (band = MM_MODEM_BAND_TELIT_4G_FIRST; band <= MM_MODEM_BAND_TELIT_4G_LAST; band++) { - if ((value & B4G_FLAG (band)) && !mm_common_bands_garray_lookup (*bands, band)) - g_array_append_val (*bands, band); - } - -out: - g_strfreev (tokens); - g_free (match_str); - - if (inner_error) { - g_propagate_error (error, inner_error); - return FALSE; - } - return TRUE; -} - -static gboolean -telit_get_ext_4g_mm_bands (GMatchInfo *match_info, - GArray **bands, - GError **error) -{ - GError *inner_error = NULL; - MMModemBand band; - gchar *match_str = NULL; - gchar *match_str_ext = NULL; - guint64 value; - - match_str = g_match_info_fetch_named (match_info, "Bands4GHex"); - if (!match_str || match_str[0] == '\0') { - g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not find 4G band hex mask flag from response"); - goto out; - } - - if (!mm_get_u64_from_hex_str (match_str, &value)) { - g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not parse 4G band hex mask from string: '%s'", match_str); - goto out; - } - - for (band = MM_MODEM_BAND_TELIT_4G_FIRST; band <= MM_MODEM_BAND_TELIT_4G_LAST; band++) { - if ((value & B4G_FLAG (band)) && !mm_common_bands_garray_lookup (*bands, band)) - g_array_append_val (*bands, band); - } - - /* extended bands */ - match_str_ext = g_match_info_fetch_named (match_info, "Bands4GExt"); - if (match_str_ext) { - - if (!mm_get_u64_from_hex_str (match_str_ext, &value)) { - g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not parse 4G ext band mask from string: '%s'", match_str_ext); - goto out; - } - - for (band = MM_MODEM_BAND_TELIT_EXT_4G_FIRST; band <= MM_MODEM_BAND_TELIT_EXT_4G_LAST; band++) { - if ((value & B4G_FLAG_EXT (band)) && !mm_common_bands_garray_lookup (*bands, band)) - g_array_append_val (*bands, band); - } - } - -out: - g_free (match_str); - g_free (match_str_ext); - - if (inner_error) { - g_propagate_error (error, inner_error); - return FALSE; - } - return TRUE; -} - -typedef enum { - LOAD_BANDS_TYPE_SUPPORTED, - LOAD_BANDS_TYPE_CURRENT, -} LoadBandsType; - -/* Regex tokens for #BND parsing */ -#define MM_SUPPORTED_BANDS_2G "\\s*\\((?P<Bands2G>[0-9\\-,]*)\\)" -#define MM_SUPPORTED_BANDS_3G "(,\\s*\\((?P<Bands3G>[0-9\\-,]*)\\))?" -#define MM_SUPPORTED_BANDS_4G_HEX "(,\\s*\\((?P<Bands4GHex>[0-9A-F\\-,]*)\\))?" -#define MM_SUPPORTED_BANDS_4G_DEC "(,\\s*\\((?P<Bands4GDec>[0-9\\-,]*)\\))?" -#define MM_SUPPORTED_BANDS_4G_EXT "(,\\s*\\((?P<Bands4GHex>[0-9A-F]+)\\))?(,\\s*\\((?P<Bands4GExt>[0-9A-F]+)\\))?" -#define MM_CURRENT_BANDS_2G "\\s*(?P<Bands2G>\\d+)" -#define MM_CURRENT_BANDS_3G "(,\\s*(?P<Bands3G>\\d+))?" -#define MM_CURRENT_BANDS_4G_HEX "(,\\s*(?P<Bands4GHex>[0-9A-F]+))?" -#define MM_CURRENT_BANDS_4G_DEC "(,\\s*(?P<Bands4GDec>\\d+))?" -#define MM_CURRENT_BANDS_4G_EXT "(,\\s*(?P<Bands4GHex>[0-9A-F]+))?(,\\s*(?P<Bands4GExt>[0-9A-F]+))?" - -static GArray * -common_parse_bnd_response (const gchar *response, - MMTelitBNDParseConfig *config, - LoadBandsType load_type, - gpointer log_object, - GError **error) -{ - g_autoptr(GMatchInfo) match_info = NULL; - g_autoptr(GRegex) r = NULL; - GError *inner_error = NULL; - GArray *bands = NULL; - const gchar *load_bands_regex = NULL; - - static const gchar *load_bands_regex_4g_hex[] = { - [LOAD_BANDS_TYPE_SUPPORTED] = "#BND:"MM_SUPPORTED_BANDS_2G MM_SUPPORTED_BANDS_3G MM_SUPPORTED_BANDS_4G_HEX, - [LOAD_BANDS_TYPE_CURRENT] = "#BND:"MM_CURRENT_BANDS_2G MM_CURRENT_BANDS_3G MM_CURRENT_BANDS_4G_HEX, - - }; - static const gchar *load_bands_regex_4g_dec[] = { - [LOAD_BANDS_TYPE_SUPPORTED] = "#BND:"MM_SUPPORTED_BANDS_2G MM_SUPPORTED_BANDS_3G MM_SUPPORTED_BANDS_4G_DEC, - [LOAD_BANDS_TYPE_CURRENT] = "#BND:"MM_CURRENT_BANDS_2G MM_CURRENT_BANDS_3G MM_CURRENT_BANDS_4G_DEC, - }; - static const gchar *load_bands_regex_4g_ext[] = { - [LOAD_BANDS_TYPE_SUPPORTED] = "#BND:"MM_SUPPORTED_BANDS_2G MM_SUPPORTED_BANDS_3G MM_SUPPORTED_BANDS_4G_EXT, - [LOAD_BANDS_TYPE_CURRENT] = "#BND:"MM_CURRENT_BANDS_2G MM_CURRENT_BANDS_3G MM_CURRENT_BANDS_4G_EXT, - }; - - if (config->modem_ext_4g_bands) - load_bands_regex = load_bands_regex_4g_ext[load_type]; - else if (config->modem_has_hex_format_4g_bands) - load_bands_regex = load_bands_regex_4g_hex[load_type]; - else - load_bands_regex = load_bands_regex_4g_dec[load_type]; - - r = g_regex_new (load_bands_regex, G_REGEX_RAW, 0, NULL); - g_assert (r); - - if (!g_regex_match (r, response, 0, &match_info)) { - g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not parse response '%s'", response); - goto out; - } - - if (!g_match_info_matches (match_info)) { - g_set_error (&inner_error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not find matches in response '%s'", response); - goto out; - } - - bands = g_array_new (TRUE, TRUE, sizeof (MMModemBand)); - - if (config->modem_is_2g && !telit_get_2g_mm_bands (match_info, log_object, &bands, &inner_error)) - goto out; - - if (config->modem_is_3g && !telit_get_3g_mm_bands (match_info, log_object, config->modem_alternate_3g_bands, &bands, &inner_error)) - goto out; - - if (config->modem_is_4g) { - gboolean ok; - - ok = config->modem_ext_4g_bands? - telit_get_ext_4g_mm_bands (match_info, &bands, &inner_error) : - telit_get_4g_mm_bands (match_info, &bands, &inner_error); - if (!ok) - goto out; - } -out: - if (inner_error) { - g_propagate_error (error, inner_error); - g_clear_pointer (&bands, g_array_unref); - return NULL; - } - - return bands; -} - -GArray * -mm_telit_parse_bnd_query_response (const gchar *response, - MMTelitBNDParseConfig *config, - gpointer log_object, - GError **error) -{ - return common_parse_bnd_response (response, - config, - LOAD_BANDS_TYPE_CURRENT, - log_object, - error); -} - -GArray * -mm_telit_parse_bnd_test_response (const gchar *response, - MMTelitBNDParseConfig *config, - gpointer log_object, - GError **error) -{ - return common_parse_bnd_response (response, - config, - LOAD_BANDS_TYPE_SUPPORTED, - log_object, - error); -} - -/*****************************************************************************/ -/* #QSS? response parser */ - -MMTelitQssStatus -mm_telit_parse_qss_query (const gchar *response, - GError **error) -{ - gint qss_status; - gint qss_mode; - - qss_status = QSS_STATUS_UNKNOWN; - if (sscanf (response, "#QSS: %d,%d", &qss_mode, &qss_status) != 2) { - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Could not parse \"#QSS?\" response: %s", response); - return QSS_STATUS_UNKNOWN; - } - - switch (qss_status) { - case QSS_STATUS_SIM_REMOVED: - case QSS_STATUS_SIM_INSERTED: - case QSS_STATUS_SIM_INSERTED_AND_UNLOCKED: - case QSS_STATUS_SIM_INSERTED_AND_READY: - return (MMTelitQssStatus) qss_status; - default: - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Unknown QSS status value given: %d", qss_status); - return QSS_STATUS_UNKNOWN; - } -} - -/*****************************************************************************/ -/* Supported modes list helper */ - -GArray * -mm_telit_build_modes_list (void) -{ - GArray *combinations; - MMModemModeCombination mode; - - /* Build list of combinations for 3GPP devices */ - combinations = g_array_sized_new (FALSE, FALSE, sizeof (MMModemModeCombination), 7); - - /* 2G only */ - mode.allowed = MM_MODEM_MODE_2G; - mode.preferred = MM_MODEM_MODE_NONE; - g_array_append_val (combinations, mode); - /* 3G only */ - mode.allowed = MM_MODEM_MODE_3G; - mode.preferred = MM_MODEM_MODE_NONE; - g_array_append_val (combinations, mode); - /* 2G and 3G */ - mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); - mode.preferred = MM_MODEM_MODE_NONE; - g_array_append_val (combinations, mode); - /* 4G only */ - mode.allowed = MM_MODEM_MODE_4G; - mode.preferred = MM_MODEM_MODE_NONE; - g_array_append_val (combinations, mode); - /* 2G and 4G */ - mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_4G); - mode.preferred = MM_MODEM_MODE_NONE; - g_array_append_val (combinations, mode); - /* 3G and 4G */ - mode.allowed = (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G); - mode.preferred = MM_MODEM_MODE_NONE; - g_array_append_val (combinations, mode); - /* 2G, 3G and 4G */ - mode.allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G); - mode.preferred = MM_MODEM_MODE_NONE; - g_array_append_val (combinations, mode); - - return combinations; -} - -/*****************************************************************************/ -/* Software Package version response parser */ - -gchar * -mm_telit_parse_swpkgv_response (const gchar *response) -{ - gchar *version = NULL; - g_autofree gchar *base_version = NULL; - g_autoptr(GRegex) r = NULL; - g_autoptr(GMatchInfo) match_info = NULL; - guint matches; - - /* We are interested only in the first line of the response */ - r = g_regex_new ("(?P<Base>\\d{2}.\\d{2}.*)", - G_REGEX_RAW | G_REGEX_MULTILINE | G_REGEX_NEWLINE_CRLF, - G_REGEX_MATCH_NEWLINE_CR, - NULL); - g_assert (r != NULL); - - if (!g_regex_match_full (r, response, strlen (response), 0, 0, &match_info, NULL)) { - return NULL; - } - - matches = g_match_info_get_match_count (match_info); - if (matches < 2 || matches > 4) { - return NULL; - } - - base_version = g_match_info_fetch_named (match_info, "Base"); - if (base_version) - version = g_strdup (base_version); - - return version; -} - -/*****************************************************************************/ -/* MM Telit Model from revision string */ - -MMTelitModel -mm_telit_model_from_revision (const gchar *revision) -{ - guint i; - static const struct { - const gchar *revision_prefix; - MMTelitModel model; - } revision_to_model_map [] = { - {"24.01", MM_TELIT_MODEL_LM940}, - {"25.", MM_TELIT_MODEL_LE910C1}, - {"32.", MM_TELIT_MODEL_LM960}, - {"38.", MM_TELIT_MODEL_FN980}, - {"40.", MM_TELIT_MODEL_LN920}, - {"45.00", MM_TELIT_MODEL_FN990}, - }; - - if (!revision) - return MM_TELIT_MODEL_DEFAULT; - - for (i = 0; i < G_N_ELEMENTS (revision_to_model_map); ++i) { - if (g_str_has_prefix (revision, revision_to_model_map[i].revision_prefix)) - return revision_to_model_map[i].model; - } - - return MM_TELIT_MODEL_DEFAULT; -} - -static MMTelitSwRevCmp lm9x0_software_revision_cmp (const gchar *revision_a, - const gchar *revision_b) -{ - /* LM940 and LM960 share the same software revision format - * WW.XY.ABC[-ZZZZ], where WW is the chipset code and C the major version. - * If WW is the same, the other values X, Y, A and B are also the same, so - * we can limit the comparison to C only. ZZZZ is the minor version (it - * includes if version is beta, test, or alpha), but at this stage we are - * not interested in compare it. */ - guint chipset_a, chipset_b; - guint major_a, major_b; - guint x, y, a, b; - - g_return_val_if_fail ( - sscanf (revision_a, "%2u.%1u%1u.%1u%1u%1u", &chipset_a, &x, &y, &a, &b, &major_a) == 6, - MM_TELIT_SW_REV_CMP_INVALID); - g_return_val_if_fail ( - sscanf (revision_b, "%2u.%1u%1u.%1u%1u%1u", &chipset_b, &x, &y, &a, &b, &major_b) == 6, - MM_TELIT_SW_REV_CMP_INVALID); - - if (chipset_a != chipset_b) - return MM_TELIT_SW_REV_CMP_INVALID; - if (major_a > major_b) - return MM_TELIT_SW_REV_CMP_NEWER; - if (major_a < major_b) - return MM_TELIT_SW_REV_CMP_OLDER; - return MM_TELIT_SW_REV_CMP_EQUAL; -} - -MMTelitSwRevCmp mm_telit_software_revision_cmp (const gchar *revision_a, - const gchar *revision_b) -{ - MMTelitModel model_a; - MMTelitModel model_b; - - model_a = mm_telit_model_from_revision (revision_a); - model_b = mm_telit_model_from_revision (revision_b); - - if ((model_a == MM_TELIT_MODEL_LM940 || model_a == MM_TELIT_MODEL_LM960) && - (model_b == MM_TELIT_MODEL_LM940 || model_b == MM_TELIT_MODEL_LM960)) { - return lm9x0_software_revision_cmp (revision_a, revision_b); - } - - return MM_TELIT_SW_REV_CMP_UNSUPPORTED; -} diff --git a/plugins/telit/mm-modem-helpers-telit.h b/plugins/telit/mm-modem-helpers-telit.h deleted file mode 100644 index 38449769..00000000 --- a/plugins/telit/mm-modem-helpers-telit.h +++ /dev/null @@ -1,90 +0,0 @@ -/* -*- 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) 2015-2019 Telit. - * Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es> - */ -#ifndef MM_MODEM_HELPERS_TELIT_H -#define MM_MODEM_HELPERS_TELIT_H - -#include <glib.h> -#include "ModemManager.h" - -typedef enum { - MM_TELIT_MODEL_DEFAULT, - MM_TELIT_MODEL_FN980, - MM_TELIT_MODEL_LE910C1, - MM_TELIT_MODEL_LM940, - MM_TELIT_MODEL_LM960, - MM_TELIT_MODEL_LN920, - MM_TELIT_MODEL_FN990, -} MMTelitModel; - -typedef struct { - gboolean modem_is_2g; - gboolean modem_is_3g; - gboolean modem_is_4g; - gboolean modem_alternate_3g_bands; - gboolean modem_has_hex_format_4g_bands; - gboolean modem_ext_4g_bands; -} MMTelitBNDParseConfig; - -typedef enum { - MM_TELIT_SW_REV_CMP_INVALID, - MM_TELIT_SW_REV_CMP_UNSUPPORTED, - MM_TELIT_SW_REV_CMP_OLDER, - MM_TELIT_SW_REV_CMP_EQUAL, - MM_TELIT_SW_REV_CMP_NEWER, -} MMTelitSwRevCmp; - -/* #BND response parsers and request builder */ -GArray *mm_telit_parse_bnd_query_response (const gchar *response, - MMTelitBNDParseConfig *config, - gpointer log_object, - GError **error); -GArray *mm_telit_parse_bnd_test_response (const gchar *response, - MMTelitBNDParseConfig *config, - gpointer log_object, - GError **error); -gchar *mm_telit_build_bnd_request (GArray *bands_array, - MMTelitBNDParseConfig *config, - GError **error); - -/* #QSS? response parser */ -typedef enum { /*< underscore_name=mm_telit_qss_status >*/ - QSS_STATUS_UNKNOWN = -1, - QSS_STATUS_SIM_REMOVED, - QSS_STATUS_SIM_INSERTED, - QSS_STATUS_SIM_INSERTED_AND_UNLOCKED, - QSS_STATUS_SIM_INSERTED_AND_READY, -} MMTelitQssStatus; - -MMTelitQssStatus mm_telit_parse_qss_query (const gchar *response, GError **error); - -/* CSIM lock state */ -typedef enum { /*< underscore_name=mm_telit_csim_lock_state >*/ - CSIM_LOCK_STATE_UNKNOWN, - CSIM_LOCK_STATE_UNLOCKED, - CSIM_LOCK_STATE_LOCK_REQUESTED, - CSIM_LOCK_STATE_LOCKED, -} MMTelitCsimLockState; - -GArray *mm_telit_build_modes_list (void); - -gchar *mm_telit_parse_swpkgv_response (const gchar *response); - -MMTelitModel mm_telit_model_from_revision (const gchar *revision); - -MMTelitSwRevCmp mm_telit_software_revision_cmp (const gchar *reference, - const gchar *revision); - -#endif /* MM_MODEM_HELPERS_TELIT_H */ diff --git a/plugins/telit/mm-plugin-telit.c b/plugins/telit/mm-plugin-telit.c deleted file mode 100644 index d19966d6..00000000 --- a/plugins/telit/mm-plugin-telit.c +++ /dev/null @@ -1,132 +0,0 @@ -/* -*- 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) 2008 - 2009 Novell, Inc. - * Copyright (C) 2009 - 2013 Red Hat, Inc. - * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org> - */ - -#include <string.h> -#include <gmodule.h> - -#define _LIBMM_INSIDE_MM -#include <libmm-glib.h> - -#include "mm-log-object.h" -#include "mm-modem-helpers.h" -#include "mm-plugin-telit.h" -#include "mm-common-telit.h" -#include "mm-broadband-modem-telit.h" - - -#if defined WITH_QMI -# include "mm-broadband-modem-qmi.h" -#endif - -#if defined WITH_MBIM -# include "mm-broadband-modem-mbim-telit.h" -#endif - -G_DEFINE_TYPE (MMPluginTelit, mm_plugin_telit, MM_TYPE_PLUGIN) - -MM_PLUGIN_DEFINE_MAJOR_VERSION -MM_PLUGIN_DEFINE_MINOR_VERSION - -/*****************************************************************************/ - -static MMBaseModem * -create_modem (MMPlugin *self, - const gchar *uid, - const gchar **drivers, - guint16 vendor, - guint16 product, - guint16 subsystem_vendor, - GList *probes, - GError **error) -{ -#if defined WITH_QMI - if (mm_port_probe_list_has_qmi_port (probes)) { - mm_obj_dbg (self, "QMI-powered Telit modem found..."); - return MM_BASE_MODEM (mm_broadband_modem_qmi_new (uid, - drivers, - mm_plugin_get_name (self), - vendor, - product)); - } -#endif - -#if defined WITH_MBIM - if (mm_port_probe_list_has_mbim_port (probes)) { - mm_obj_dbg (self, "MBIM-powered Telit modem found..."); - return MM_BASE_MODEM (mm_broadband_modem_mbim_telit_new (uid, - drivers, - mm_plugin_get_name (self), - vendor, - product, - subsystem_vendor)); - } -#endif - - return MM_BASE_MODEM (mm_broadband_modem_telit_new (uid, - drivers, - mm_plugin_get_name (self), - vendor, - product)); -} - -/*****************************************************************************/ - -G_MODULE_EXPORT MMPlugin * -mm_plugin_create (void) -{ - static const gchar *subsystems[] = { "tty", "net", "usbmisc", "wwan", NULL }; - /* Vendors: Telit */ - static const guint16 vendor_ids[] = { 0x1bc7, 0 }; - static const mm_uint16_pair subsystem_vendor_ids[] = { - { 0x17cb, 0x1c5d }, /* FN990 */ - { 0, 0 } - }; - static const gchar *vendor_strings[] = { "telit", NULL }; - /* Custom init for port identification */ - static const MMAsyncMethod custom_init = { - .async = G_CALLBACK (telit_custom_init), - .finish = G_CALLBACK (telit_custom_init_finish), - }; - - return MM_PLUGIN ( - g_object_new (MM_TYPE_PLUGIN_TELIT, - MM_PLUGIN_NAME, MM_MODULE_NAME, - MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, - MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids, - MM_PLUGIN_ALLOWED_SUBSYSTEM_VENDOR_IDS, subsystem_vendor_ids, - MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings, - MM_PLUGIN_ALLOWED_AT, TRUE, - MM_PLUGIN_ALLOWED_QMI, TRUE, - MM_PLUGIN_ALLOWED_MBIM, TRUE, - MM_PLUGIN_ALLOWED_QCDM, TRUE, - MM_PLUGIN_CUSTOM_INIT, &custom_init, - NULL)); -} - -static void -mm_plugin_telit_init (MMPluginTelit *self) -{ -} - -static void -mm_plugin_telit_class_init (MMPluginTelitClass *klass) -{ - MMPluginClass *plugin_class = MM_PLUGIN_CLASS (klass); - - plugin_class->create_modem = create_modem; - plugin_class->grab_port = telit_grab_port; -} diff --git a/plugins/telit/mm-plugin-telit.h b/plugins/telit/mm-plugin-telit.h deleted file mode 100644 index 0c61fbb8..00000000 --- a/plugins/telit/mm-plugin-telit.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- 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) 2008 - 2009 Novell, Inc. - * Copyright (C) 2009 - 2013 Red Hat, Inc. - * Copyright (C) 2012 Aleksander Morgado <aleksander@gnu.org> - */ - -#ifndef MM_PLUGIN_TELIT_H -#define MM_PLUGIN_TELIT_H - -#include "mm-plugin.h" - -#define MM_TYPE_PLUGIN_TELIT (mm_plugin_telit_get_type ()) -#define MM_PLUGIN_TELIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PLUGIN_TELIT, MMPluginTelit)) -#define MM_PLUGIN_TELIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_PLUGIN_TELIT, MMPluginTelitClass)) -#define MM_IS_PLUGIN_TELIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_PLUGIN_TELIT)) -#define MM_IS_PLUGIN_TELIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PLUGIN_TELIT)) -#define MM_PLUGIN_TELIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_TELIT, MMPluginTelitClass)) - -typedef struct { - MMPlugin parent; -} MMPluginTelit; - -typedef struct { - MMPluginClass parent; -} MMPluginTelitClass; - -GType mm_plugin_telit_get_type (void); - -G_MODULE_EXPORT MMPlugin *mm_plugin_create (void); - -#endif /* MM_PLUGIN_TELIT_H */ diff --git a/plugins/telit/mm-shared-telit.c b/plugins/telit/mm-shared-telit.c deleted file mode 100644 index 09c122bb..00000000 --- a/plugins/telit/mm-shared-telit.c +++ /dev/null @@ -1,795 +0,0 @@ -/* -*- 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) 2019 Daniele Palmas <dnlplm@gmail.com> - */ - -#include <config.h> - -#include <stdio.h> - -#include <glib-object.h> -#include <gio/gio.h> - -#define _LIBMM_INSIDE_MM -#include <libmm-glib.h> - -#include "mm-log-object.h" -#include "mm-iface-modem.h" -#include "mm-iface-modem-location.h" -#include "mm-base-modem.h" -#include "mm-base-modem-at.h" -#include "mm-modem-helpers-telit.h" -#include "mm-shared-telit.h" - -/*****************************************************************************/ -/* Private data context */ - -#define TELIT_LM940_EXT_LTE_BND_SW_REVISION "24.01.516" - -#define PRIVATE_TAG "shared-telit-private-tag" -static GQuark private_quark; - -typedef struct { - MMIfaceModem *iface_modem_parent; - gboolean alternate_3g_bands; - gboolean ext_4g_bands; - GArray *supported_bands; - GArray *supported_modes; - gchar *software_package_version; -} Private; - -static void -private_free (Private *priv) -{ - if (priv->supported_bands) - g_array_unref (priv->supported_bands); - if (priv->supported_modes) - g_array_unref (priv->supported_modes); - g_free (priv->software_package_version); - g_slice_free (Private, priv); -} - -static gboolean -has_alternate_3g_bands (const gchar *revision) -{ - MMTelitModel model; - - model = mm_telit_model_from_revision (revision); - return (model == MM_TELIT_MODEL_FN980 || - model == MM_TELIT_MODEL_FN990 || - model == MM_TELIT_MODEL_LM940 || - model == MM_TELIT_MODEL_LM960 || - model == MM_TELIT_MODEL_LN920); -} - -static gboolean -is_bnd_4g_format_hex (const gchar *revision) -{ - MMTelitModel model; - - model = mm_telit_model_from_revision (revision); - - return (model == MM_TELIT_MODEL_FN980 || - model == MM_TELIT_MODEL_LE910C1 || - model == MM_TELIT_MODEL_LM940 || - model == MM_TELIT_MODEL_LM960 || - model == MM_TELIT_MODEL_LN920); -} - -static gboolean -has_extended_4g_bands (const gchar *revision) -{ - MMTelitModel model; - - model = mm_telit_model_from_revision (revision); - if (model == MM_TELIT_MODEL_LM940) - return mm_telit_software_revision_cmp (revision, TELIT_LM940_EXT_LTE_BND_SW_REVISION) >= MM_TELIT_SW_REV_CMP_EQUAL; - - return (model == MM_TELIT_MODEL_FN980 || - model == MM_TELIT_MODEL_FN990 || - model == MM_TELIT_MODEL_LM960 || - model == MM_TELIT_MODEL_LN920); -} - -static Private * -get_private (MMSharedTelit *self) -{ - Private *priv; - - if (G_UNLIKELY (!private_quark)) - private_quark = g_quark_from_static_string (PRIVATE_TAG); - - priv = g_object_get_qdata (G_OBJECT (self), private_quark); - if (!priv) { - priv = g_slice_new0 (Private); - - if (MM_SHARED_TELIT_GET_INTERFACE (self)->peek_parent_modem_interface) - priv->iface_modem_parent = MM_SHARED_TELIT_GET_INTERFACE (self)->peek_parent_modem_interface (self); - - g_object_set_qdata_full (G_OBJECT (self), private_quark, priv, (GDestroyNotify)private_free); - } - - return priv; -} - -void -mm_shared_telit_store_supported_modes (MMSharedTelit *self, - GArray *modes) -{ - Private *priv; - - priv = get_private (MM_SHARED_TELIT (self)); - priv->supported_modes = g_array_ref (modes); -} - -void -mm_shared_telit_store_revision (MMSharedTelit *self, - const gchar *revision) -{ - Private *priv; - - priv = get_private (MM_SHARED_TELIT (self)); - g_clear_pointer (&priv->software_package_version, g_free); - priv->software_package_version = g_strdup (revision); - priv->alternate_3g_bands = has_alternate_3g_bands (revision); - priv->ext_4g_bands = has_extended_4g_bands (revision); -} - -void -mm_shared_telit_get_bnd_parse_config (MMIfaceModem *self, MMTelitBNDParseConfig *config) -{ - Private *priv; - - priv = get_private (MM_SHARED_TELIT (self)); - - config->modem_is_2g = mm_iface_modem_is_2g (self); - config->modem_is_3g = mm_iface_modem_is_3g (self); - config->modem_is_4g = mm_iface_modem_is_4g (self); - config->modem_alternate_3g_bands = priv->alternate_3g_bands; - config->modem_has_hex_format_4g_bands = is_bnd_4g_format_hex (priv->software_package_version); - config->modem_ext_4g_bands = priv->ext_4g_bands; -} - -/*****************************************************************************/ -/* Load current mode (Modem interface) */ - -gboolean -mm_shared_telit_load_current_modes_finish (MMIfaceModem *self, - GAsyncResult *res, - MMModemMode *allowed, - MMModemMode *preferred, - GError **error) -{ - const gchar *response; - const gchar *str; - gint a; - - response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, error); - if (!response) - return FALSE; - - str = mm_strip_tag (response, "+WS46: "); - - if (!sscanf (str, "%d", &a)) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Couldn't parse +WS46 response: '%s'", - response); - return FALSE; - } - - *preferred = MM_MODEM_MODE_NONE; - switch (a) { - case 12: - *allowed = MM_MODEM_MODE_2G; - return TRUE; - case 22: - *allowed = MM_MODEM_MODE_3G; - return TRUE; - case 25: - if (mm_iface_modem_is_3gpp_lte (self)) - *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G); - else - *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); - return TRUE; - case 28: - *allowed = MM_MODEM_MODE_4G; - return TRUE; - case 29: - *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G); - return TRUE; - case 30: - *allowed = (MM_MODEM_MODE_2G | MM_MODEM_MODE_4G); - return TRUE; - case 31: - *allowed = (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G); - return TRUE; - default: - break; - } - - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Couldn't parse unexpected +WS46 response: '%s'", - response); - return FALSE; -} - -void -mm_shared_telit_load_current_modes (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+WS46?", - 3, - FALSE, - callback, - user_data); -} - -/*****************************************************************************/ -/* Load supported bands (Modem interface) */ - -GArray * -mm_shared_telit_modem_load_supported_bands_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_pointer (G_TASK (res), error); -} - -static void -load_supported_bands_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - const gchar *response; - GError *error = NULL; - Private *priv; - - priv = get_private (MM_SHARED_TELIT (self)); - - response = mm_base_modem_at_command_finish (self, res, &error); - if (!response) - g_task_return_error (task, error); - else { - GArray *bands; - MMTelitBNDParseConfig config; - - mm_shared_telit_get_bnd_parse_config (MM_IFACE_MODEM (self), &config); - - bands = mm_telit_parse_bnd_test_response (response, &config, self, &error); - if (!bands) - g_task_return_error (task, error); - else { - /* Store supported bands to be able to build ANY when setting */ - priv->supported_bands = g_array_ref (bands); - if (priv->ext_4g_bands) - mm_obj_dbg (self, "telit modem using extended 4G band setup"); - g_task_return_pointer (task, bands, (GDestroyNotify)g_array_unref); - } - } - - g_object_unref (task); -} - -static void -load_supported_bands_at (MMIfaceModem *self, - GTask *task) -{ - mm_base_modem_at_command (MM_BASE_MODEM (self), - "#BND=?", - 3, - TRUE, - (GAsyncReadyCallback) load_supported_bands_ready, - task); -} - -static void -parent_load_supported_bands_ready (MMIfaceModem *self, - GAsyncResult *res, - GTask *task) -{ - GArray *bands; - GError *error = NULL; - Private *priv; - - priv = get_private (MM_SHARED_TELIT (self)); - - bands = priv->iface_modem_parent->load_supported_bands_finish (MM_IFACE_MODEM (self), res, &error); - if (bands) { - g_task_return_pointer (task, bands, (GDestroyNotify)g_array_unref); - g_object_unref (task); - } else { - mm_obj_dbg (self, "parent load supported bands failure, falling back to AT commands"); - load_supported_bands_at (self, task); - g_clear_error (&error); - } -} - -void -mm_shared_telit_modem_load_supported_bands (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - Private *priv; - - task = g_task_new (self, NULL, callback, user_data); - priv = get_private (MM_SHARED_TELIT (self)); - - if (priv->iface_modem_parent && - priv->iface_modem_parent->load_supported_bands && - priv->iface_modem_parent->load_supported_bands_finish) { - priv->iface_modem_parent->load_supported_bands (self, - (GAsyncReadyCallback) parent_load_supported_bands_ready, - task); - } else - load_supported_bands_at (self, task); -} - -/*****************************************************************************/ -/* Load current bands (Modem interface) */ - -GArray * -mm_shared_telit_modem_load_current_bands_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_pointer (G_TASK (res), error); -} - -static void -load_current_bands_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - const gchar *response; - GError *error = NULL; - - response = mm_base_modem_at_command_finish (self, res, &error); - if (!response) - g_task_return_error (task, error); - else { - GArray *bands; - MMTelitBNDParseConfig config; - - mm_shared_telit_get_bnd_parse_config (MM_IFACE_MODEM (self), &config); - - bands = mm_telit_parse_bnd_query_response (response, &config, self, &error); - if (!bands) - g_task_return_error (task, error); - else - g_task_return_pointer (task, bands, (GDestroyNotify)g_array_unref); - } - - g_object_unref (task); -} - -static void -load_current_bands_at (MMIfaceModem *self, - GTask *task) -{ - mm_base_modem_at_command (MM_BASE_MODEM (self), - "#BND?", - 3, - FALSE, - (GAsyncReadyCallback) load_current_bands_ready, - task); -} - -static void -parent_load_current_bands_ready (MMIfaceModem *self, - GAsyncResult *res, - GTask *task) -{ - GArray *bands; - GError *error = NULL; - Private *priv; - - priv = get_private (MM_SHARED_TELIT (self)); - - bands = priv->iface_modem_parent->load_current_bands_finish (MM_IFACE_MODEM (self), res, &error); - if (bands) { - g_task_return_pointer (task, bands, (GDestroyNotify)g_array_unref); - g_object_unref (task); - } else { - mm_obj_dbg (self, "parent load current bands failure, falling back to AT commands"); - load_current_bands_at (self, task); - g_clear_error (&error); - } -} - -void -mm_shared_telit_modem_load_current_bands (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - Private *priv; - - task = g_task_new (self, NULL, callback, user_data); - priv = get_private (MM_SHARED_TELIT (self)); - - if (priv->iface_modem_parent && - priv->iface_modem_parent->load_current_bands && - priv->iface_modem_parent->load_current_bands_finish) { - priv->iface_modem_parent->load_current_bands (self, - (GAsyncReadyCallback) parent_load_current_bands_ready, - task); - } else - load_current_bands_at (self, task); -} - -/*****************************************************************************/ -/* Set current bands (Modem interface) */ - -gboolean -mm_shared_telit_modem_set_current_bands_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -set_current_bands_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - - mm_base_modem_at_command_finish (self, res, &error); - if (error) - g_task_return_error (task, error); - else - g_task_return_boolean (task, TRUE); - - g_object_unref (task); -} - -static void -set_current_bands_at (MMIfaceModem *self, - GTask *task) -{ - GError *error = NULL; - gchar *cmd; - GArray *bands_array; - MMTelitBNDParseConfig config; - - bands_array = g_task_get_task_data (task); - g_assert (bands_array); - - if (bands_array->len == 1 && g_array_index (bands_array, MMModemBand, 0) == MM_MODEM_BAND_ANY) { - Private *priv; - - priv = get_private (MM_SHARED_TELIT (self)); - if (!priv->supported_bands) { - g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Couldn't build ANY band settings: unknown supported bands"); - g_object_unref (task); - return; - } - bands_array = priv->supported_bands; - } - - mm_shared_telit_get_bnd_parse_config (self, &config); - cmd = mm_telit_build_bnd_request (bands_array, &config, &error); - if (!cmd) { - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - mm_base_modem_at_command (MM_BASE_MODEM (self), - cmd, - 20, - FALSE, - (GAsyncReadyCallback)set_current_bands_ready, - task); - g_free (cmd); -} - -static void -parent_set_current_bands_ready (MMIfaceModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - Private *priv; - - priv = get_private (MM_SHARED_TELIT (self)); - - if (priv->iface_modem_parent->set_current_bands_finish (MM_IFACE_MODEM (self), res, &error)) { - g_task_return_boolean (task, TRUE); - g_object_unref (task); - } else { - g_clear_error (&error); - set_current_bands_at (self, task); - } -} - -void -mm_shared_telit_modem_set_current_bands (MMIfaceModem *self, - GArray *bands_array, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - Private *priv; - - priv = get_private (MM_SHARED_TELIT (self)); - - task = g_task_new (self, NULL, callback, user_data); - g_task_set_task_data (task, g_array_ref (bands_array), (GDestroyNotify)g_array_unref); - - if (priv->iface_modem_parent && - priv->iface_modem_parent->set_current_bands && - priv->iface_modem_parent->set_current_bands_finish) { - priv->iface_modem_parent->set_current_bands (self, - bands_array, - (GAsyncReadyCallback) parent_set_current_bands_ready, - task); - } else - set_current_bands_at (self, task); -} - -/*****************************************************************************/ -/* Set current modes (Modem interface) */ - -gboolean -mm_shared_telit_set_current_modes_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -ws46_set_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - - mm_base_modem_at_command_finish (self, res, &error); - if (error) - /* Let the error be critical. */ - g_task_return_error (task, error); - else - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -void -mm_shared_telit_set_current_modes (MMIfaceModem *self, - MMModemMode allowed, - MMModemMode preferred, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - gchar *command; - Private *priv; - gint ws46_mode = -1; - - priv = get_private (MM_SHARED_TELIT (self)); - task = g_task_new (self, NULL, callback, user_data); - - if (allowed == MM_MODEM_MODE_ANY && priv->supported_modes) { - guint i; - - allowed = MM_MODEM_MODE_NONE; - /* Process list of modes to gather supported ones */ - for (i = 0; i < priv->supported_modes->len; i++) { - if (g_array_index (priv->supported_modes, MMModemMode, i) & MM_MODEM_MODE_2G) - allowed |= MM_MODEM_MODE_2G; - if (g_array_index (priv->supported_modes, MMModemMode, i) & MM_MODEM_MODE_3G) - allowed |= MM_MODEM_MODE_3G; - if (g_array_index (priv->supported_modes, MMModemMode, i) & MM_MODEM_MODE_4G) - allowed |= MM_MODEM_MODE_4G; - } - } - - if (allowed == MM_MODEM_MODE_2G) - ws46_mode = 12; - else if (allowed == MM_MODEM_MODE_3G) - ws46_mode = 22; - else if (allowed == MM_MODEM_MODE_4G) - ws46_mode = 28; - else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G)) { - if (mm_iface_modem_is_3gpp_lte (self)) - ws46_mode = 29; - else - ws46_mode = 25; - } else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_4G)) - ws46_mode = 30; - else if (allowed == (MM_MODEM_MODE_3G | MM_MODEM_MODE_4G)) - ws46_mode = 31; - else if (allowed == (MM_MODEM_MODE_2G | MM_MODEM_MODE_3G | MM_MODEM_MODE_4G)) - ws46_mode = 25; - - /* Telit modems do not support preferred mode selection */ - if ((ws46_mode < 0) || (preferred != MM_MODEM_MODE_NONE)) { - gchar *allowed_str; - gchar *preferred_str; - - allowed_str = mm_modem_mode_build_string_from_mask (allowed); - preferred_str = mm_modem_mode_build_string_from_mask (preferred); - g_task_return_new_error (task, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Requested mode (allowed: '%s', preferred: '%s') not " - "supported by the modem.", - allowed_str, - preferred_str); - g_free (allowed_str); - g_free (preferred_str); - - g_object_unref (task); - return; - } - - command = g_strdup_printf ("AT+WS46=%d", ws46_mode); - mm_base_modem_at_command ( - MM_BASE_MODEM (self), - command, - 10, - FALSE, - (GAsyncReadyCallback) ws46_set_ready, - task); - g_free (command); -} - -/*****************************************************************************/ -/* Revision loading */ - -gchar * -mm_shared_telit_modem_load_revision_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_pointer (G_TASK (res), error); -} - -static void -load_revision_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error; - GVariant *result; - - result = mm_base_modem_at_sequence_finish (self, res, NULL, &error); - if (!result) { - g_task_return_error (task, error); - g_object_unref (task); - } else { - gchar *revision = NULL; - - revision = g_variant_dup_string (result, NULL); - mm_shared_telit_store_revision (MM_SHARED_TELIT (self), revision); - g_task_return_pointer (task, revision, g_free); - g_object_unref (task); - } -} - -/* - * parse AT#SWPKGV command - * Execution command returns the software package version without #SWPKGV: command echo. - * The response is as follows: - * - * AT#SWPKGV - * <Telit Software Package Version>-<Production Parameters Version> - * <Modem FW Version> (Usually the same value returned by AT+GMR) - * <Production Parameters Version> - * <Application FW Version> - */ -static MMBaseModemAtResponseProcessorResult -software_package_version_ready (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) -{ - gchar *version = NULL; - - if (error) { - *result = NULL; - - /* Ignore AT errors (ie, ERROR or CMx ERROR) */ - if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) { - *result_error = g_error_copy (error); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; - } - - *result_error = NULL; - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; - } - - version = mm_telit_parse_swpkgv_response (response); - if (!version) - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; - - *result = g_variant_new_take_string (version); - return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; -} - -static const MMBaseModemAtCommand revisions[] = { - { "#SWPKGV", 3, TRUE, software_package_version_ready }, - { "+CGMR", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, - { "+GMR", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, - { NULL } -}; - -void -mm_shared_telit_modem_load_revision (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - Private *priv; - - task = g_task_new (self, NULL, callback, user_data); - priv = get_private (MM_SHARED_TELIT (self)); - - mm_obj_dbg (self, "loading revision..."); - if (priv->software_package_version) { - g_task_return_pointer (task, - g_strdup (priv->software_package_version), - g_free); - g_object_unref (task); - return; - } - - mm_base_modem_at_sequence ( - MM_BASE_MODEM (self), - revisions, - NULL, /* response_processor_context */ - NULL, /* response_processor_context_free */ - (GAsyncReadyCallback) load_revision_ready, - task); -} - -/*****************************************************************************/ - -static void -shared_telit_init (gpointer g_iface) -{ -} - -GType -mm_shared_telit_get_type (void) -{ - static GType shared_telit_type = 0; - - if (!G_UNLIKELY (shared_telit_type)) { - static const GTypeInfo info = { - sizeof (MMSharedTelit), /* class_size */ - shared_telit_init, /* base_init */ - NULL, /* base_finalize */ - }; - - shared_telit_type = g_type_register_static (G_TYPE_INTERFACE, "MMSharedTelit", &info, 0); - g_type_interface_add_prerequisite (shared_telit_type, MM_TYPE_IFACE_MODEM); - } - - return shared_telit_type; -} - diff --git a/plugins/telit/mm-shared-telit.h b/plugins/telit/mm-shared-telit.h deleted file mode 100644 index bf093ea5..00000000 --- a/plugins/telit/mm-shared-telit.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- 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) 2019 Daniele Palmas <dnlplm@gmail.com> - */ - -#ifndef MM_SHARED_TELIT_H -#define MM_SHARED_TELIT_H - -#include <glib-object.h> -#include <gio/gio.h> - -#define _LIBMM_INSIDE_MM -#include <libmm-glib.h> - -#include "mm-broadband-modem.h" -#include "mm-iface-modem.h" -#include "mm-iface-modem-location.h" -#include "mm-modem-helpers-telit.h" - -#define MM_TYPE_SHARED_TELIT (mm_shared_telit_get_type ()) -#define MM_SHARED_TELIT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SHARED_TELIT, MMSharedTelit)) -#define MM_IS_SHARED_TELIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_SHARED_TELIT)) -#define MM_SHARED_TELIT_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_SHARED_TELIT, MMSharedTelit)) - -typedef struct _MMSharedTelit MMSharedTelit; - -struct _MMSharedTelit { - GTypeInterface g_iface; - - /* Peek modem interface of the parent class of the object */ - MMIfaceModem * (* peek_parent_modem_interface) (MMSharedTelit *self); -}; - -GType mm_shared_telit_get_type (void); - -void mm_shared_telit_store_supported_modes (MMSharedTelit *self, - GArray *modes); - -gboolean mm_shared_telit_load_current_modes_finish (MMIfaceModem *self, - GAsyncResult *res, - MMModemMode *allowed, - MMModemMode *preferred, - GError **error); - -void mm_shared_telit_load_current_modes (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); - -gboolean mm_shared_telit_set_current_modes_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - -void mm_shared_telit_set_current_modes (MMIfaceModem *self, - MMModemMode allowed, - MMModemMode preferred, - GAsyncReadyCallback callback, - gpointer user_data); - -void mm_shared_telit_modem_load_supported_bands (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); - -GArray * mm_shared_telit_modem_load_supported_bands_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - -void mm_shared_telit_modem_load_current_bands (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); - -GArray * mm_shared_telit_modem_load_current_bands_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - -gboolean mm_shared_telit_modem_set_current_bands_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - -void mm_shared_telit_modem_set_current_bands (MMIfaceModem *self, - GArray *bands_array, - GAsyncReadyCallback callback, - gpointer user_data); - -void mm_shared_telit_modem_load_revision (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); - -gchar * mm_shared_telit_modem_load_revision_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); - -void mm_shared_telit_store_revision (MMSharedTelit *self, - const gchar *revision); - -void mm_shared_telit_get_bnd_parse_config (MMIfaceModem *self, - MMTelitBNDParseConfig *config); -#endif /* MM_SHARED_TELIT_H */ diff --git a/plugins/telit/mm-shared.c b/plugins/telit/mm-shared.c deleted file mode 100644 index ad2843dd..00000000 --- a/plugins/telit/mm-shared.c +++ /dev/null @@ -1,20 +0,0 @@ -/* -*- 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) 2019 Aleksander Morgado <aleksander@aleksander.es> - */ - -#include "mm-shared.h" - -MM_SHARED_DEFINE_MAJOR_VERSION -MM_SHARED_DEFINE_MINOR_VERSION -MM_SHARED_DEFINE_NAME(Telit) diff --git a/plugins/telit/tests/test-mm-modem-helpers-telit.c b/plugins/telit/tests/test-mm-modem-helpers-telit.c deleted file mode 100644 index e14ba6ba..00000000 --- a/plugins/telit/tests/test-mm-modem-helpers-telit.c +++ /dev/null @@ -1,695 +0,0 @@ -/* -*- 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) 2015-2019 Telit - * Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es> - * - */ -#include <stdio.h> -#include <glib.h> -#include <glib-object.h> -#include <locale.h> - -#include <ModemManager.h> -#define _LIBMM_INSIDE_MM -#include <libmm-glib.h> - -#include "mm-log-test.h" -#include "mm-modem-helpers.h" -#include "mm-modem-helpers-telit.h" - -#include "test-helpers.h" - -/******************************************************************************/ - -#define MAX_BANDS_LIST_LEN 17 - -typedef struct { - const gchar *response; - MMTelitBNDParseConfig config; - guint mm_bands_len; - MMModemBand mm_bands [MAX_BANDS_LIST_LEN]; -} BndResponseTest; - -static BndResponseTest supported_band_mapping_tests [] = { - { - "#BND: (0-3)", {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE}, 4, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_PCS, - MM_MODEM_BAND_G850 } - }, - { - "#BND: (0-3),(0,2,5,6)", {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE}, 7, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_PCS, - MM_MODEM_BAND_G850, - MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_5, - MM_MODEM_BAND_UTRAN_8 } - }, - { - "#BND: (0,3),(0,2,5,6)", {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE}, 7, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_PCS, - MM_MODEM_BAND_G850, - MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_5, - MM_MODEM_BAND_UTRAN_8 } - }, - { - "#BND: (0,2),(0,2,5,6)", {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE}, 6, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_G850, - MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_5, - MM_MODEM_BAND_UTRAN_8 } - }, - { - "#BND: (0,2),(0-4,5,6)", {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE}, 7, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_G850, - MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_2, - MM_MODEM_BAND_UTRAN_5, - MM_MODEM_BAND_UTRAN_8 } - }, - { - "#BND: (0-3),(0,2,5,6),(1-1)", {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE}, 8, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_PCS, - MM_MODEM_BAND_G850, - MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_5, - MM_MODEM_BAND_UTRAN_8, - MM_MODEM_BAND_EUTRAN_1 } - }, - { - "#BND: (0),(0),(1-3)", {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE}, 5, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_EUTRAN_1, - MM_MODEM_BAND_EUTRAN_2 } - }, - { - "#BND: (0),(0),(1-3)", {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE}, 2, - { MM_MODEM_BAND_EUTRAN_1, - MM_MODEM_BAND_EUTRAN_2 } - }, - /* 3G alternate band settings: default */ - { - "#BND: (0),(0,2,5,6,12,25)", {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE}, 5, - { MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_5, - MM_MODEM_BAND_UTRAN_8, - MM_MODEM_BAND_UTRAN_6, - MM_MODEM_BAND_UTRAN_19 } - }, - /* 3G alternate band settings: alternate */ - { - "#BND: (0),(0,2,5,6,12,13)", {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE}, 4, - { MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_3, - MM_MODEM_BAND_UTRAN_5, - MM_MODEM_BAND_UTRAN_8 } - }, - /* ME910 (2G+4G device) - * 168695967: 0xA0E189F: 0000 1010 0000 1110 0001 1000 1001 1111 - */ - { - "#BND: (0-5),(0),(1-168695967)", {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE}, 17, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_PCS, - MM_MODEM_BAND_G850, - MM_MODEM_BAND_EUTRAN_1, - MM_MODEM_BAND_EUTRAN_2, - MM_MODEM_BAND_EUTRAN_3, - MM_MODEM_BAND_EUTRAN_4, - MM_MODEM_BAND_EUTRAN_5, - MM_MODEM_BAND_EUTRAN_8, - MM_MODEM_BAND_EUTRAN_12, - MM_MODEM_BAND_EUTRAN_13, - MM_MODEM_BAND_EUTRAN_18, - MM_MODEM_BAND_EUTRAN_19, - MM_MODEM_BAND_EUTRAN_20, - MM_MODEM_BAND_EUTRAN_26, - MM_MODEM_BAND_EUTRAN_28 } - }, - /* 4G ext band settings: devices such as LN920 */ - { - "#BND: (0),(0),(1003100185A),(42)", {FALSE, TRUE, TRUE, FALSE, TRUE, TRUE}, 13, - { MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_EUTRAN_2, - MM_MODEM_BAND_EUTRAN_4, - MM_MODEM_BAND_EUTRAN_5, - MM_MODEM_BAND_EUTRAN_7, - MM_MODEM_BAND_EUTRAN_12, - MM_MODEM_BAND_EUTRAN_13, - MM_MODEM_BAND_EUTRAN_25, - MM_MODEM_BAND_EUTRAN_29, - MM_MODEM_BAND_EUTRAN_30, - MM_MODEM_BAND_EUTRAN_41, - MM_MODEM_BAND_EUTRAN_66, - MM_MODEM_BAND_EUTRAN_71 } - }, - /* 4G band in hex format: devices such as LE910C1-EUX */ - { - "#BND: (0),(0,5,6,13,15,23),(80800C5)", {TRUE, TRUE, TRUE, FALSE, TRUE, FALSE}, 11, - { - MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_3, - MM_MODEM_BAND_UTRAN_8, - MM_MODEM_BAND_EUTRAN_1, - MM_MODEM_BAND_EUTRAN_3, - MM_MODEM_BAND_EUTRAN_7, - MM_MODEM_BAND_EUTRAN_8, - MM_MODEM_BAND_EUTRAN_20, - MM_MODEM_BAND_EUTRAN_28 } - } -}; - -static void -test_parse_supported_bands_response (void) -{ - guint i; - - for (i = 0; i < G_N_ELEMENTS (supported_band_mapping_tests); i++) { - GError *error = NULL; - GArray *bands = NULL; - - bands = mm_telit_parse_bnd_test_response (supported_band_mapping_tests[i].response, - &supported_band_mapping_tests[i].config, - NULL, - &error); - g_assert_no_error (error); - g_assert (bands); - - mm_test_helpers_compare_bands (bands, - supported_band_mapping_tests[i].mm_bands, - supported_band_mapping_tests[i].mm_bands_len); - g_array_unref (bands); - } -} - -static BndResponseTest current_band_mapping_tests [] = { - { - "#BND: 0", {TRUE, FALSE, FALSE, FALSE, FALSE, FALSE}, 2, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS } - }, - { - "#BND: 0,5", {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE}, 3, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_UTRAN_8 } - }, - { - "#BND: 1,3", {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE}, 5, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_PCS, - MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_2, - MM_MODEM_BAND_UTRAN_5 } - }, - { - "#BND: 2,7", {TRUE, TRUE, FALSE, FALSE, FALSE, FALSE}, 3, - { MM_MODEM_BAND_DCS, - MM_MODEM_BAND_G850, - MM_MODEM_BAND_UTRAN_4 } - }, - { - "#BND: 3,0,1", {TRUE, TRUE, TRUE, FALSE, FALSE, FALSE}, 4, - { MM_MODEM_BAND_PCS, - MM_MODEM_BAND_G850, - MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_EUTRAN_1 } - }, - { - "#BND: 0,0,3", {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE}, 4, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_EUTRAN_1, - MM_MODEM_BAND_EUTRAN_2 } - }, - { - "#BND: 0,0,3", {FALSE, FALSE, TRUE, FALSE, FALSE, FALSE}, 2, - { MM_MODEM_BAND_EUTRAN_1, - MM_MODEM_BAND_EUTRAN_2 } - }, - /* 3G alternate band settings: default */ - { - "#BND: 0,12", {FALSE, TRUE, FALSE, FALSE, FALSE, FALSE}, 1, - { MM_MODEM_BAND_UTRAN_6 } - }, - /* 3G alternate band settings: alternate */ - { - "#BND: 0,12", {FALSE, TRUE, FALSE, TRUE, FALSE, FALSE}, 4, - { MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_UTRAN_3, - MM_MODEM_BAND_UTRAN_5, - MM_MODEM_BAND_UTRAN_8 } - }, - /* ME910 (2G+4G device) - * 168695967: 0xA0E189F: 0000 1010 0000 1110 0001 1000 1001 1111 - */ - { - "#BND: 5,0,168695967", {TRUE, FALSE, TRUE, FALSE, FALSE, FALSE}, 17, - { MM_MODEM_BAND_EGSM, - MM_MODEM_BAND_DCS, - MM_MODEM_BAND_PCS, - MM_MODEM_BAND_G850, - MM_MODEM_BAND_EUTRAN_1, - MM_MODEM_BAND_EUTRAN_2, - MM_MODEM_BAND_EUTRAN_3, - MM_MODEM_BAND_EUTRAN_4, - MM_MODEM_BAND_EUTRAN_5, - MM_MODEM_BAND_EUTRAN_8, - MM_MODEM_BAND_EUTRAN_12, - MM_MODEM_BAND_EUTRAN_13, - MM_MODEM_BAND_EUTRAN_18, - MM_MODEM_BAND_EUTRAN_19, - MM_MODEM_BAND_EUTRAN_20, - MM_MODEM_BAND_EUTRAN_26, - MM_MODEM_BAND_EUTRAN_28 } - }, - /* 4G ext band settings: devices such as LN920 */ - { - "#BND: 0,0,1003100185A,42", {FALSE, TRUE, TRUE, FALSE, FALSE, TRUE}, 13, - { MM_MODEM_BAND_UTRAN_1, - MM_MODEM_BAND_EUTRAN_2, - MM_MODEM_BAND_EUTRAN_4, - MM_MODEM_BAND_EUTRAN_5, - MM_MODEM_BAND_EUTRAN_7, - MM_MODEM_BAND_EUTRAN_12, - MM_MODEM_BAND_EUTRAN_13, - MM_MODEM_BAND_EUTRAN_25, - MM_MODEM_BAND_EUTRAN_29, - MM_MODEM_BAND_EUTRAN_30, - MM_MODEM_BAND_EUTRAN_41, - MM_MODEM_BAND_EUTRAN_66, - MM_MODEM_BAND_EUTRAN_71 } - } -}; - -static void -test_parse_current_bands_response (void) -{ - guint i; - - for (i = 0; i < G_N_ELEMENTS (current_band_mapping_tests); i++) { - GError *error = NULL; - GArray *bands = NULL; - - bands = mm_telit_parse_bnd_query_response (current_band_mapping_tests[i].response, - ¤t_band_mapping_tests[i].config, - NULL, - &error); - g_assert_no_error (error); - g_assert (bands); - - mm_test_helpers_compare_bands (bands, - current_band_mapping_tests[i].mm_bands, - current_band_mapping_tests[i].mm_bands_len); - g_array_unref (bands); - } -} - -/******************************************************************************/ - -static void -test_common_bnd_cmd (const gchar *expected_cmd, - gboolean modem_is_2g, - gboolean modem_is_3g, - gboolean modem_is_4g, - gboolean modem_alternate_3g_bands, - gboolean modem_ext_4g_bands, - GArray *bands_array) -{ - gchar *cmd; - GError *error = NULL; - MMTelitBNDParseConfig config = { - .modem_is_2g = modem_is_2g, - .modem_is_3g = modem_is_3g, - .modem_is_4g = modem_is_4g, - .modem_alternate_3g_bands = modem_alternate_3g_bands, - .modem_ext_4g_bands = modem_ext_4g_bands - }; - - cmd = mm_telit_build_bnd_request (bands_array, &config, &error); - g_assert_no_error (error); - g_assert_cmpstr (cmd, ==, expected_cmd); - g_free (cmd); -} - -#define test_common_bnd_cmd_2g(EXPECTED_CMD, BANDS_ARRAY) test_common_bnd_cmd (EXPECTED_CMD, TRUE, FALSE, FALSE, FALSE, FALSE, BANDS_ARRAY) -#define test_common_bnd_cmd_3g(EXPECTED_CMD, ALTERNATE, BANDS_ARRAY) test_common_bnd_cmd (EXPECTED_CMD, FALSE, TRUE, FALSE, ALTERNATE, FALSE, BANDS_ARRAY) -#define test_common_bnd_cmd_4g(EXPECTED_CMD, EXTENDED, BANDS_ARRAY) test_common_bnd_cmd (EXPECTED_CMD, FALSE, FALSE, TRUE, FALSE, EXTENDED, BANDS_ARRAY) - -static void -test_common_bnd_cmd_error (gboolean modem_is_2g, - gboolean modem_is_3g, - gboolean modem_is_4g, - GArray *bands_array, - MMCoreError expected_error) -{ - gchar *cmd; - GError *error = NULL; - MMTelitBNDParseConfig config = { - .modem_is_2g = modem_is_2g, - .modem_is_3g = modem_is_3g, - .modem_is_4g = modem_is_4g, - .modem_alternate_3g_bands = FALSE, - .modem_ext_4g_bands = FALSE, - }; - cmd = mm_telit_build_bnd_request (bands_array, &config, &error); - g_assert_error (error, MM_CORE_ERROR, (gint)expected_error); - g_assert (!cmd); -} - -#define test_common_bnd_cmd_2g_invalid(BANDS_ARRAY) test_common_bnd_cmd_error (TRUE, FALSE, FALSE, BANDS_ARRAY, MM_CORE_ERROR_FAILED) -#define test_common_bnd_cmd_3g_invalid(BANDS_ARRAY) test_common_bnd_cmd_error (FALSE, TRUE, FALSE, BANDS_ARRAY, MM_CORE_ERROR_FAILED) -#define test_common_bnd_cmd_4g_invalid(BANDS_ARRAY) test_common_bnd_cmd_error (FALSE, FALSE, TRUE, BANDS_ARRAY, MM_CORE_ERROR_FAILED) -#define test_common_bnd_cmd_2g_not_found(BANDS_ARRAY) test_common_bnd_cmd_error (TRUE, FALSE, FALSE, BANDS_ARRAY, MM_CORE_ERROR_NOT_FOUND) -#define test_common_bnd_cmd_3g_not_found(BANDS_ARRAY) test_common_bnd_cmd_error (FALSE, TRUE, FALSE, BANDS_ARRAY, MM_CORE_ERROR_NOT_FOUND) -#define test_common_bnd_cmd_4g_not_found(BANDS_ARRAY) test_common_bnd_cmd_error (FALSE, FALSE, TRUE, BANDS_ARRAY, MM_CORE_ERROR_NOT_FOUND) - -static void -test_telit_get_2g_bnd_flag (void) -{ - GArray *bands_array; - MMModemBand egsm = MM_MODEM_BAND_EGSM; - MMModemBand dcs = MM_MODEM_BAND_DCS; - MMModemBand pcs = MM_MODEM_BAND_PCS; - MMModemBand g850 = MM_MODEM_BAND_G850; - MMModemBand u2100 = MM_MODEM_BAND_UTRAN_1; - MMModemBand eutran_i = MM_MODEM_BAND_EUTRAN_1; - - /* Test Flag 0 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, egsm); - g_array_append_val (bands_array, dcs); - test_common_bnd_cmd_2g ("#BND=0", bands_array); - g_array_unref (bands_array); - - /* Test flag 1 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, egsm); - g_array_append_val (bands_array, pcs); - test_common_bnd_cmd_2g ("#BND=1", bands_array); - g_array_unref (bands_array); - - /* Test flag 2 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, g850); - g_array_append_val (bands_array, dcs); - test_common_bnd_cmd_2g ("#BND=2", bands_array); - g_array_unref (bands_array); - - /* Test flag 3 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, g850); - g_array_append_val (bands_array, pcs); - test_common_bnd_cmd_2g ("#BND=3", bands_array); - g_array_unref (bands_array); - - /* Test invalid band array */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, g850); - g_array_append_val (bands_array, egsm); - test_common_bnd_cmd_2g_invalid (bands_array); - g_array_unref (bands_array); - - /* Test unmatched band array */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, u2100); - g_array_append_val (bands_array, eutran_i); - test_common_bnd_cmd_2g_not_found (bands_array); - g_array_unref (bands_array); -} - -static void -test_telit_get_3g_bnd_flag (void) -{ - GArray *bands_array; - MMModemBand u2100 = MM_MODEM_BAND_UTRAN_1; - MMModemBand u1900 = MM_MODEM_BAND_UTRAN_2; - MMModemBand u1800 = MM_MODEM_BAND_UTRAN_3; - MMModemBand u850 = MM_MODEM_BAND_UTRAN_5; - MMModemBand u800 = MM_MODEM_BAND_UTRAN_6; - MMModemBand u900 = MM_MODEM_BAND_UTRAN_8; - MMModemBand u17iv = MM_MODEM_BAND_UTRAN_4; - MMModemBand u17ix = MM_MODEM_BAND_UTRAN_9; - MMModemBand egsm = MM_MODEM_BAND_EGSM; - MMModemBand eutran_i = MM_MODEM_BAND_EUTRAN_1; - - /* Test flag 0 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1); - g_array_append_val (bands_array, u2100); - test_common_bnd_cmd_3g ("#BND=0,0", FALSE, bands_array); - test_common_bnd_cmd_3g ("#BND=0,0", TRUE, bands_array); - g_array_unref (bands_array); - - /* Test flag 1 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1); - g_array_append_val (bands_array, u1900); - test_common_bnd_cmd_3g ("#BND=0,1", FALSE, bands_array); - test_common_bnd_cmd_3g ("#BND=0,1", TRUE, bands_array); - g_array_unref (bands_array); - - /* Test flag 2 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1); - g_array_append_val (bands_array, u850); - test_common_bnd_cmd_3g ("#BND=0,2", FALSE, bands_array); - test_common_bnd_cmd_3g ("#BND=0,2", TRUE, bands_array); - g_array_unref (bands_array); - - /* Test flag 3 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 3); - g_array_append_val (bands_array, u2100); - g_array_append_val (bands_array, u1900); - g_array_append_val (bands_array, u850); - test_common_bnd_cmd_3g ("#BND=0,3", FALSE, bands_array); - test_common_bnd_cmd_3g ("#BND=0,3", TRUE, bands_array); - g_array_unref (bands_array); - - /* Test flag 4 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, u1900); - g_array_append_val (bands_array, u850); - test_common_bnd_cmd_3g ("#BND=0,4", FALSE, bands_array); - test_common_bnd_cmd_3g ("#BND=0,4", TRUE, bands_array); - g_array_unref (bands_array); - - /* Test flag 5 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1); - g_array_append_val (bands_array, u900); - test_common_bnd_cmd_3g ("#BND=0,5", FALSE, bands_array); - test_common_bnd_cmd_3g ("#BND=0,5", TRUE, bands_array); - g_array_unref (bands_array); - - /* Test flag 6 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, u2100); - g_array_append_val (bands_array, u900); - test_common_bnd_cmd_3g ("#BND=0,6", FALSE, bands_array); - test_common_bnd_cmd_3g ("#BND=0,6", TRUE, bands_array); - g_array_unref (bands_array); - - /* Test flag 7 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1); - g_array_append_val (bands_array, u17iv); - test_common_bnd_cmd_3g ("#BND=0,7", FALSE, bands_array); - test_common_bnd_cmd_3g ("#BND=0,7", TRUE, bands_array); - g_array_unref (bands_array); - - /* Test flag 12 in default */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1); - g_array_append_val (bands_array, u800); - test_common_bnd_cmd_3g ("#BND=0,12", FALSE, bands_array); - g_array_unref (bands_array); - - /* Test flag 12 in alternate */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 4); - g_array_append_val (bands_array, u2100); - g_array_append_val (bands_array, u1800); - g_array_append_val (bands_array, u850); - g_array_append_val (bands_array, u900); - test_common_bnd_cmd_3g ("#BND=0,12", TRUE, bands_array); - g_array_unref (bands_array); - - /* Test invalid band array */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1); - g_array_append_val (bands_array, u17ix); - test_common_bnd_cmd_3g_invalid (bands_array); - g_array_unref (bands_array); - - /* Test unmatched band array */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, egsm); - g_array_append_val (bands_array, eutran_i); - test_common_bnd_cmd_3g_not_found (bands_array); - g_array_unref (bands_array); -} - -static void -test_telit_get_4g_bnd_flag (void) -{ - GArray *bands_array; - MMModemBand eutran_i = MM_MODEM_BAND_EUTRAN_1; - MMModemBand eutran_ii = MM_MODEM_BAND_EUTRAN_2; - MMModemBand u2100 = MM_MODEM_BAND_UTRAN_1; - MMModemBand egsm = MM_MODEM_BAND_EGSM; - - /* Test flag 1 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 1); - g_array_append_val (bands_array, eutran_i); - test_common_bnd_cmd_4g ("#BND=0,0,1", FALSE, bands_array); - g_array_unref (bands_array); - - /* Test flag 3 */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, eutran_i); - g_array_append_val (bands_array, eutran_ii); - test_common_bnd_cmd_4g ("#BND=0,0,3", FALSE, bands_array); - g_array_unref (bands_array); - - /* Test unmatched band array */ - bands_array = g_array_sized_new (FALSE, FALSE, sizeof (MMModemBand), 2); - g_array_append_val (bands_array, egsm); - g_array_append_val (bands_array, u2100); - test_common_bnd_cmd_4g_not_found (bands_array); - g_array_unref (bands_array); -} - -/******************************************************************************/ - -typedef struct { - const char* response; - MMTelitQssStatus expected_qss; - const char *error_message; -} QssParseTest; - -static QssParseTest qss_parse_tests [] = { - {"#QSS: 0,0", QSS_STATUS_SIM_REMOVED, NULL}, - {"#QSS: 1,0", QSS_STATUS_SIM_REMOVED, NULL}, - {"#QSS: 0,1", QSS_STATUS_SIM_INSERTED, NULL}, - {"#QSS: 0,2", QSS_STATUS_SIM_INSERTED_AND_UNLOCKED, NULL}, - {"#QSS: 0,3", QSS_STATUS_SIM_INSERTED_AND_READY, NULL}, - {"#QSS:0,3", QSS_STATUS_SIM_INSERTED_AND_READY, NULL}, - {"#QSS: 0, 3", QSS_STATUS_SIM_INSERTED_AND_READY, NULL}, - {"#QSS: 0", QSS_STATUS_UNKNOWN, "Could not parse \"#QSS?\" response: #QSS: 0"}, - {"QSS:0,1", QSS_STATUS_UNKNOWN, "Could not parse \"#QSS?\" response: QSS:0,1"}, - {"#QSS: 0,5", QSS_STATUS_UNKNOWN, "Unknown QSS status value given: 5"}, -}; - -static void -test_telit_parse_qss_query (void) -{ - MMTelitQssStatus actual_qss_status; - GError *error = NULL; - guint i; - - for (i = 0; i < G_N_ELEMENTS (qss_parse_tests); i++) { - actual_qss_status = mm_telit_parse_qss_query (qss_parse_tests[i].response, &error); - - g_assert_cmpint (actual_qss_status, ==, qss_parse_tests[i].expected_qss); - if (qss_parse_tests[i].error_message) { - g_assert_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED); - g_assert_cmpstr (error->message, ==, qss_parse_tests[i].error_message); - g_clear_error (&error); - } - } -} - -static void -test_telit_parse_swpkgv_response (void) -{ - static struct { - const gchar *response; - const gchar *expected; - } tt [] = { - {"\r\n12.34.567\r\nM0F.223004-B001\r\nP0F.224700\r\nA0F.223004-B001\r\n\r\nOK\r\n", "12.34.567"}, - {"\r\n13.35.568-A123\r\nM0F.223004-B001\r\nP0F.224700\r\nA0F.223004-B001\r\n\r\nOK\r\n", "13.35.568-A123"}, - {"\r\n14.36.569-B124\r\nM0F.223004-B001\r\nP0F.224700\r\nA0F.223004-B001\r\n\r\nOK\r\n", "14.36.569-B124"}, - {"\r\n15.37.570-T125\r\nM0F.223004-B001\r\nP0F.224700\r\nA0F.223004-B001\r\n\r\nOK\r\n", "15.37.570-T125"}, - {"\r\n16.38.571-P0F.224700\r\nM0F.223004-B001\r\nP0F.224700\r\nA0F.223004-B001\r\n\r\nOK\r\n", "16.38.571-P0F.224700"}, - /* real example from LE910C1-EUX */ - {"\r\n25.30.224-B001-P0F.224700\r\nM0F.223004-B001\r\nP0F.224700\r\nA0F.223004-B001\r\n\r\nOK\r\n", "25.30.224-B001-P0F.224700"}, - }; - guint i; - - for (i = 0; i < G_N_ELEMENTS (tt); i++) { - gchar *actual = NULL; - - actual = mm_telit_parse_swpkgv_response(tt[i].response); - - g_assert_cmpstr (tt[i].expected, ==, actual); - g_free (actual); - } -} - -static void -test_telit_compare_software_revision_string (void) -{ - struct { - const char *revision_a; - const char *revision_b; - MMTelitSwRevCmp expected; - } tt [] = { - {"24.01.514", "24.01.514", MM_TELIT_SW_REV_CMP_EQUAL}, - {"24.01.514", "24.01.513", MM_TELIT_SW_REV_CMP_NEWER}, - {"24.01.513", "24.01.514", MM_TELIT_SW_REV_CMP_OLDER}, - {"32.00.013", "24.01.514", MM_TELIT_SW_REV_CMP_INVALID}, - {"32.00.014", "32.00.014", MM_TELIT_SW_REV_CMP_EQUAL}, - {"32.00.014", "32.00.013", MM_TELIT_SW_REV_CMP_NEWER}, - {"32.00.013", "32.00.014", MM_TELIT_SW_REV_CMP_OLDER}, - {"38.00.000", "38.00.000", MM_TELIT_SW_REV_CMP_UNSUPPORTED}, - /* LM9x0 Minor version (e.g. beta, test, alpha) value is currently - * ignored because not required by any implemented feature. */ - {"24.01.516-B123", "24.01.516-B134", MM_TELIT_SW_REV_CMP_EQUAL}, - }; - guint i; - - for (i = 0; i < G_N_ELEMENTS (tt); i++) { - g_assert_cmpint (tt[i].expected, - ==, - mm_telit_software_revision_cmp (tt[i].revision_a, tt[i].revision_b)); - } -} - -/******************************************************************************/ - -int main (int argc, char **argv) -{ - setlocale (LC_ALL, ""); - - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/MM/telit/bands/supported/parse_bands_response", test_parse_supported_bands_response); - g_test_add_func ("/MM/telit/bands/current/parse_bands_response", test_parse_current_bands_response); - g_test_add_func ("/MM/telit/bands/current/set_bands/2g", test_telit_get_2g_bnd_flag); - g_test_add_func ("/MM/telit/bands/current/set_bands/3g", test_telit_get_3g_bnd_flag); - g_test_add_func ("/MM/telit/bands/current/set_bands/4g", test_telit_get_4g_bnd_flag); - g_test_add_func ("/MM/telit/qss/query", test_telit_parse_qss_query); - g_test_add_func ("/MM/telit/swpkv/parse_response", test_telit_parse_swpkgv_response); - g_test_add_func ("/MM/telit/revision/compare", test_telit_compare_software_revision_string); - return g_test_run (); -} |