diff options
Diffstat (limited to 'plugins/quectel')
-rw-r--r-- | plugins/quectel/77-mm-quectel-port-types.rules | 104 | ||||
-rw-r--r-- | plugins/quectel/mm-broadband-modem-mbim-quectel.c | 88 | ||||
-rw-r--r-- | plugins/quectel/mm-broadband-modem-mbim-quectel.h | 48 | ||||
-rw-r--r-- | plugins/quectel/mm-broadband-modem-qmi-quectel.c | 138 | ||||
-rw-r--r-- | plugins/quectel/mm-broadband-modem-qmi-quectel.h | 47 | ||||
-rw-r--r-- | plugins/quectel/mm-broadband-modem-quectel.c | 136 | ||||
-rw-r--r-- | plugins/quectel/mm-broadband-modem-quectel.h | 47 | ||||
-rw-r--r-- | plugins/quectel/mm-modem-helpers-quectel.c | 91 | ||||
-rw-r--r-- | plugins/quectel/mm-modem-helpers-quectel.h | 32 | ||||
-rw-r--r-- | plugins/quectel/mm-plugin-quectel.c | 117 | ||||
-rw-r--r-- | plugins/quectel/mm-plugin-quectel.h | 40 | ||||
-rw-r--r-- | plugins/quectel/mm-shared-quectel.c | 1039 | ||||
-rw-r--r-- | plugins/quectel/mm-shared-quectel.h | 93 | ||||
-rw-r--r-- | plugins/quectel/tests/test-modem-helpers-quectel.c | 93 |
14 files changed, 0 insertions, 2113 deletions
diff --git a/plugins/quectel/77-mm-quectel-port-types.rules b/plugins/quectel/77-mm-quectel-port-types.rules deleted file mode 100644 index 08564161..00000000 --- a/plugins/quectel/77-mm-quectel-port-types.rules +++ /dev/null @@ -1,104 +0,0 @@ -# do not edit this file, it will be overwritten on update -ACTION!="add|change|move|bind", GOTO="mm_quectel_end" -SUBSYSTEMS=="usb", ATTRS{idVendor}=="2c7c", GOTO="mm_quectel_usb" -SUBSYSTEMS=="pci", ATTRS{vendor}=="0x1eac", GOTO="mm_quectel_pci" -GOTO="mm_quectel_end" - -LABEL="mm_quectel_usb" - -SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="?*", ENV{.MM_USBIFNUM}="$attr{bInterfaceNumber}" - -# Quectel EG06 -# ttyUSB0 (if #0): QCDM/DIAG port -# ttyUSB1 (if #1): GPS data port -# ttyUSB2 (if #2): AT primary port -# ttyUSB3 (if #3): AT secondary port -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0306", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0306", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0306", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0306", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# Quectel EG91 -# ttyUSB0 (if #0): QCDM/DIAG port -# ttyUSB1 (if #1): GPS data port -# ttyUSB2 (if #2): AT primary port -# ttyUSB3 (if #3): AT secondary port -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0191", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0191", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0191", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0191", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# Quectel EG95 -# ttyUSB0 (if #0): QCDM/DIAG port -# ttyUSB1 (if #1): GPS data port -# ttyUSB2 (if #2): AT primary port -# ttyUSB3 (if #3): AT secondary port -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0195", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0195", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0195", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0195", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# Quectel BG96 -# ttyUSB0 (if #0): QCDM/DIAG port -# ttyUSB1 (if #1): GPS data port -# ttyUSB2 (if #2): AT primary port -# ttyUSB3 (if #3): AT secondary port -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0296", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0296", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0296", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0296", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# Quectel EC25/EG25 -# ttyUSB0 (if #0): QCDM/DIAG port -# ttyUSB1 (if #1): GPS data port -# ttyUSB2 (if #2): AT primary port -# ttyUSB3 (if #3): AT secondary port -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0125", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# Quectel RM500 -# ttyUSB0 (if #0): QCDM/DIAG port -# ttyUSB1 (if #1): GPS data port -# ttyUSB2 (if #2): AT primary port -# ttyUSB3 (if #3): AT secondary port -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0800", ENV{.MM_USBIFNUM}=="00", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_QCDM}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0800", ENV{.MM_USBIFNUM}=="01", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_GPS}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0800", ENV{.MM_USBIFNUM}=="02", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0800", ENV{.MM_USBIFNUM}=="03", SUBSYSTEM=="tty", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" - -# Quectel EM05-G variants with Sahara-Firehose support: -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="030a", ENV{ID_MM_QUECTEL_FIREHOSE}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="030a", ENV{ID_MM_QUECTEL_SAHARA}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="030c", ENV{ID_MM_QUECTEL_FIREHOSE}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="030c", ENV{ID_MM_QUECTEL_SAHARA}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0311", ENV{ID_MM_QUECTEL_FIREHOSE}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0311", ENV{ID_MM_QUECTEL_SAHARA}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0313", ENV{ID_MM_QUECTEL_FIREHOSE}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0313", ENV{ID_MM_QUECTEL_SAHARA}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0314", ENV{ID_MM_QUECTEL_FIREHOSE}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0314", ENV{ID_MM_QUECTEL_SAHARA}="1" - -# Quectel EM05-CN variants with Sahara-Firehose support -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0310", ENV{ID_MM_QUECTEL_FIREHOSE}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0310", ENV{ID_MM_QUECTEL_SAHARA}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0312", ENV{ID_MM_QUECTEL_FIREHOSE}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0312", ENV{ID_MM_QUECTEL_SAHARA}="1" - -# Quectel EM05-CE with Sahara-Firehose support -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0127", ENV{ID_MM_QUECTEL_FIREHOSE}="1" -ATTRS{idVendor}=="2c7c", ATTRS{idProduct}=="0127", ENV{ID_MM_QUECTEL_SAHARA}="1" - -GOTO="mm_quectel_end" - -LABEL="mm_quectel_pci" - -# Quectel EM120 and EM160 with firehose support -ATTRS{vendor}=="0x1eac", ATTRS{device}=="0x1001", ENV{ID_MM_QUECTEL_FIREHOSE}="1" -ATTRS{vendor}=="0x1eac", ATTRS{device}=="0x1002", ENV{ID_MM_QUECTEL_FIREHOSE}="1" - -# Quectel RM520 with firehose support -ATTRS{vendor}=="0x1eac", ATTRS{device}=="0x1004", ENV{ID_MM_QUECTEL_FIREHOSE}="1" - -LABEL="mm_quectel_end" diff --git a/plugins/quectel/mm-broadband-modem-mbim-quectel.c b/plugins/quectel/mm-broadband-modem-mbim-quectel.c deleted file mode 100644 index 0ab40610..00000000 --- a/plugins/quectel/mm-broadband-modem-mbim-quectel.c +++ /dev/null @@ -1,88 +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) 2020 Aleksander Morgado <aleksander@aleksander.es> - * Copyright (C) 2021 Ivan Mikhanchuk <ivan.mikhanchuk@quectel.com> - */ - -#include <config.h> - -#include "mm-base-modem-at.h" -#include "mm-log-object.h" -#include "mm-iface-modem.h" -#include "mm-iface-modem-firmware.h" -#include "mm-iface-modem-time.h" -#include "mm-shared-quectel.h" -#include "mm-modem-helpers-quectel.h" -#include "mm-broadband-modem-mbim-quectel.h" - -static void iface_modem_firmware_init (MMIfaceModemFirmware *iface); -static void iface_modem_time_init (MMIfaceModemTime *iface); -static void shared_quectel_init (MMSharedQuectel *iface); - -G_DEFINE_TYPE_EXTENDED (MMBroadbandModemMbimQuectel, mm_broadband_modem_mbim_quectel, MM_TYPE_BROADBAND_MODEM_MBIM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_FIRMWARE, iface_modem_firmware_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_QUECTEL, shared_quectel_init)) - -/*****************************************************************************/ - -MMBroadbandModemMbimQuectel * -mm_broadband_modem_mbim_quectel_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id) -{ - return g_object_new (MM_TYPE_BROADBAND_MODEM_MBIM_QUECTEL, - 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, - /* include carrier information */ - MM_IFACE_MODEM_FIRMWARE_IGNORE_CARRIER, FALSE, - /* 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_quectel_init (MMBroadbandModemMbimQuectel *self) -{ -} - -static void -iface_modem_firmware_init (MMIfaceModemFirmware *iface) -{ - iface->load_update_settings = mm_shared_quectel_firmware_load_update_settings; - iface->load_update_settings_finish = mm_shared_quectel_firmware_load_update_settings_finish; -} - -static void -iface_modem_time_init (MMIfaceModemTime *iface) -{ - iface->check_support = mm_shared_quectel_time_check_support; - iface->check_support_finish = mm_shared_quectel_time_check_support_finish; -} - -static void -shared_quectel_init (MMSharedQuectel *iface) -{ -} - -static void -mm_broadband_modem_mbim_quectel_class_init (MMBroadbandModemMbimQuectelClass *klass) -{ -} diff --git a/plugins/quectel/mm-broadband-modem-mbim-quectel.h b/plugins/quectel/mm-broadband-modem-mbim-quectel.h deleted file mode 100644 index 0d0c2b95..00000000 --- a/plugins/quectel/mm-broadband-modem-mbim-quectel.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) 2020 Aleksander Morgado <aleksander@aleksander.es> - * Copyright (C) 2021 Ivan Mikhanchuk <ivan.mikhanchuk@quectel.com> - */ - -#ifndef MM_BROADBAND_MODEM_MBIM_QUECTEL_H -#define MM_BROADBAND_MODEM_MBIM_QUECTEL_H - -#include "mm-broadband-modem-mbim.h" - -#define MM_TYPE_BROADBAND_MODEM_MBIM_QUECTEL (mm_broadband_modem_mbim_quectel_get_type ()) -#define MM_BROADBAND_MODEM_MBIM_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BROADBAND_MODEM_MBIM_QUECTEL, MMBroadbandModemMbimQuectel)) -#define MM_BROADBAND_MODEM_MBIM_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BROADBAND_MODEM_MBIM_QUECTEL, MMBroadbandModemMbimQuectelClass)) -#define MM_IS_BROADBAND_MODEM_MBIM_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BROADBAND_MODEM_MBIM_QUECTEL)) -#define MM_IS_BROADBAND_MODEM_MBIM_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BROADBAND_MODEM_MBIM_QUECTEL)) -#define MM_BROADBAND_MODEM_MBIM_QUECTEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BROADBAND_MODEM_MBIM_QUECTEL, MMBroadbandModemMbimQuectelClass)) - -typedef struct _MMBroadbandModemMbimQuectel MMBroadbandModemMbimQuectel; -typedef struct _MMBroadbandModemMbimQuectelClass MMBroadbandModemMbimQuectelClass; - -struct _MMBroadbandModemMbimQuectel { - MMBroadbandModemMbim parent; -}; - -struct _MMBroadbandModemMbimQuectelClass{ - MMBroadbandModemMbimClass parent; -}; - -GType mm_broadband_modem_mbim_quectel_get_type (void); - -MMBroadbandModemMbimQuectel *mm_broadband_modem_mbim_quectel_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id); - -#endif /* MM_BROADBAND_MODEM_MBIM_QUECTEL_H */ diff --git a/plugins/quectel/mm-broadband-modem-qmi-quectel.c b/plugins/quectel/mm-broadband-modem-qmi-quectel.c deleted file mode 100644 index a4ccbfc9..00000000 --- a/plugins/quectel/mm-broadband-modem-qmi-quectel.c +++ /dev/null @@ -1,138 +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) 2018-2020 Aleksander Morgado <aleksander@aleksander.es> - */ - -#include <config.h> - -#include "mm-broadband-modem-qmi-quectel.h" -#include "mm-iface-modem-firmware.h" -#include "mm-iface-modem-location.h" -#include "mm-iface-modem-time.h" -#include "mm-shared-quectel.h" - -static void iface_modem_init (MMIfaceModem *iface); -static void iface_modem_firmware_init (MMIfaceModemFirmware *iface); -static void iface_modem_location_init (MMIfaceModemLocation *iface); -static void iface_modem_time_init (MMIfaceModemTime *iface); -static void shared_quectel_init (MMSharedQuectel *iface); - -static MMIfaceModem *iface_modem_parent; -static MMIfaceModemLocation *iface_modem_location_parent; - -G_DEFINE_TYPE_EXTENDED (MMBroadbandModemQmiQuectel, mm_broadband_modem_qmi_quectel, MM_TYPE_BROADBAND_MODEM_QMI, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_FIRMWARE, iface_modem_firmware_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_QUECTEL, shared_quectel_init)) - -/*****************************************************************************/ - -MMBroadbandModemQmiQuectel * -mm_broadband_modem_qmi_quectel_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id) -{ - return g_object_new (MM_TYPE_BROADBAND_MODEM_QMI_QUECTEL, - 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, - /* exclude carrier information */ - MM_IFACE_MODEM_FIRMWARE_IGNORE_CARRIER, TRUE, - /* QMI 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_qmi_quectel_init (MMBroadbandModemQmiQuectel *self) -{ -} - -static void -iface_modem_init (MMIfaceModem *iface) -{ - iface_modem_parent = g_type_interface_peek_parent (iface); - - iface->setup_sim_hot_swap = mm_shared_quectel_setup_sim_hot_swap; - iface->setup_sim_hot_swap_finish = mm_shared_quectel_setup_sim_hot_swap_finish; - iface->cleanup_sim_hot_swap = mm_shared_quectel_cleanup_sim_hot_swap; -} - -static MMIfaceModem * -peek_parent_modem_interface (MMSharedQuectel *self) -{ - return iface_modem_parent; -} - -static MMBroadbandModemClass * -peek_parent_broadband_modem_class (MMSharedQuectel *self) -{ - return MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_qmi_quectel_parent_class); -} - -static void -iface_modem_firmware_init (MMIfaceModemFirmware *iface) -{ - iface->load_update_settings = mm_shared_quectel_firmware_load_update_settings; - iface->load_update_settings_finish = mm_shared_quectel_firmware_load_update_settings_finish; -} - -static void -iface_modem_location_init (MMIfaceModemLocation *iface) -{ - iface_modem_location_parent = g_type_interface_peek_parent (iface); - - iface->load_capabilities = mm_shared_quectel_location_load_capabilities; - iface->load_capabilities_finish = mm_shared_quectel_location_load_capabilities_finish; - iface->enable_location_gathering = mm_shared_quectel_enable_location_gathering; - iface->enable_location_gathering_finish = mm_shared_quectel_enable_location_gathering_finish; - iface->disable_location_gathering = mm_shared_quectel_disable_location_gathering; - iface->disable_location_gathering_finish = mm_shared_quectel_disable_location_gathering_finish; -} - -static MMIfaceModemLocation * -peek_parent_modem_location_interface (MMSharedQuectel *self) -{ - return iface_modem_location_parent; -} - -static void -iface_modem_time_init (MMIfaceModemTime *iface) -{ - iface->check_support = mm_shared_quectel_time_check_support; - iface->check_support_finish = mm_shared_quectel_time_check_support_finish; -} - -static void -shared_quectel_init (MMSharedQuectel *iface) -{ - iface->peek_parent_modem_interface = peek_parent_modem_interface; - iface->peek_parent_modem_location_interface = peek_parent_modem_location_interface; - iface->peek_parent_broadband_modem_class = peek_parent_broadband_modem_class; -} - -static void -mm_broadband_modem_qmi_quectel_class_init (MMBroadbandModemQmiQuectelClass *klass) -{ - MMBroadbandModemClass *broadband_modem_class = MM_BROADBAND_MODEM_CLASS (klass); - - broadband_modem_class->setup_ports = mm_shared_quectel_setup_ports; -} diff --git a/plugins/quectel/mm-broadband-modem-qmi-quectel.h b/plugins/quectel/mm-broadband-modem-qmi-quectel.h deleted file mode 100644 index f1580f0e..00000000 --- a/plugins/quectel/mm-broadband-modem-qmi-quectel.h +++ /dev/null @@ -1,47 +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) 2018 Aleksander Morgado <aleksander@aleksander.es> - */ - -#ifndef MM_BROADBAND_MODEM_QMI_QUECTEL_H -#define MM_BROADBAND_MODEM_QMI_QUECTEL_H - -#include "mm-broadband-modem-qmi.h" - -#define MM_TYPE_BROADBAND_MODEM_QMI_QUECTEL (mm_broadband_modem_qmi_quectel_get_type ()) -#define MM_BROADBAND_MODEM_QMI_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BROADBAND_MODEM_QMI_QUECTEL, MMBroadbandModemQmiQuectel)) -#define MM_BROADBAND_MODEM_QMI_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BROADBAND_MODEM_QMI_QUECTEL, MMBroadbandModemQmiQuectelClass)) -#define MM_IS_BROADBAND_MODEM_QMI_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BROADBAND_MODEM_QMI_QUECTEL)) -#define MM_IS_BROADBAND_MODEM_QMI_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BROADBAND_MODEM_QMI_QUECTEL)) -#define MM_BROADBAND_MODEM_QMI_QUECTEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BROADBAND_MODEM_QMI_QUECTEL, MMBroadbandModemQmiQuectelClass)) - -typedef struct _MMBroadbandModemQmiQuectel MMBroadbandModemQmiQuectel; -typedef struct _MMBroadbandModemQmiQuectelClass MMBroadbandModemQmiQuectelClass; - -struct _MMBroadbandModemQmiQuectel { - MMBroadbandModemQmi parent; -}; - -struct _MMBroadbandModemQmiQuectelClass{ - MMBroadbandModemQmiClass parent; -}; - -GType mm_broadband_modem_qmi_quectel_get_type (void); - -MMBroadbandModemQmiQuectel *mm_broadband_modem_qmi_quectel_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id); - -#endif /* MM_BROADBAND_MODEM_QMI_QUECTEL_H */ diff --git a/plugins/quectel/mm-broadband-modem-quectel.c b/plugins/quectel/mm-broadband-modem-quectel.c deleted file mode 100644 index ad66b783..00000000 --- a/plugins/quectel/mm-broadband-modem-quectel.c +++ /dev/null @@ -1,136 +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) 2018-2020 Aleksander Morgado <aleksander@aleksander.es> - */ - -#include <config.h> - -#include "mm-broadband-modem-quectel.h" -#include "mm-iface-modem-firmware.h" -#include "mm-iface-modem-location.h" -#include "mm-iface-modem-time.h" -#include "mm-shared-quectel.h" - -static void iface_modem_init (MMIfaceModem *iface); -static void iface_modem_firmware_init (MMIfaceModemFirmware *iface); -static void iface_modem_location_init (MMIfaceModemLocation *iface); -static void iface_modem_time_init (MMIfaceModemTime *iface); -static void shared_quectel_init (MMSharedQuectel *iface); - -static MMIfaceModem *iface_modem_parent; -static MMIfaceModemLocation *iface_modem_location_parent; - -G_DEFINE_TYPE_EXTENDED (MMBroadbandModemQuectel, mm_broadband_modem_quectel, MM_TYPE_BROADBAND_MODEM, 0, - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM, iface_modem_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_FIRMWARE, iface_modem_firmware_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_TIME, iface_modem_time_init) - G_IMPLEMENT_INTERFACE (MM_TYPE_SHARED_QUECTEL, shared_quectel_init)) - -/*****************************************************************************/ - -MMBroadbandModemQuectel * -mm_broadband_modem_quectel_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id) -{ - return g_object_new (MM_TYPE_BROADBAND_MODEM_QUECTEL, - 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 TTY 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_quectel_init (MMBroadbandModemQuectel *self) -{ -} - -static void -iface_modem_init (MMIfaceModem *iface) -{ - iface_modem_parent = g_type_interface_peek_parent (iface); - - iface->setup_sim_hot_swap = mm_shared_quectel_setup_sim_hot_swap; - iface->setup_sim_hot_swap_finish = mm_shared_quectel_setup_sim_hot_swap_finish; - iface->cleanup_sim_hot_swap = mm_shared_quectel_cleanup_sim_hot_swap; -} - -static MMIfaceModem * -peek_parent_modem_interface (MMSharedQuectel *self) -{ - return iface_modem_parent; -} - -static MMBroadbandModemClass * -peek_parent_broadband_modem_class (MMSharedQuectel *self) -{ - return MM_BROADBAND_MODEM_CLASS (mm_broadband_modem_quectel_parent_class); -} - -static void -iface_modem_firmware_init (MMIfaceModemFirmware *iface) -{ - iface->load_update_settings = mm_shared_quectel_firmware_load_update_settings; - iface->load_update_settings_finish = mm_shared_quectel_firmware_load_update_settings_finish; -} - -static void -iface_modem_location_init (MMIfaceModemLocation *iface) -{ - iface_modem_location_parent = g_type_interface_peek_parent (iface); - - iface->load_capabilities = mm_shared_quectel_location_load_capabilities; - iface->load_capabilities_finish = mm_shared_quectel_location_load_capabilities_finish; - iface->enable_location_gathering = mm_shared_quectel_enable_location_gathering; - iface->enable_location_gathering_finish = mm_shared_quectel_enable_location_gathering_finish; - iface->disable_location_gathering = mm_shared_quectel_disable_location_gathering; - iface->disable_location_gathering_finish = mm_shared_quectel_disable_location_gathering_finish; -} - -static MMIfaceModemLocation * -peek_parent_modem_location_interface (MMSharedQuectel *self) -{ - return iface_modem_location_parent; -} - -static void -iface_modem_time_init (MMIfaceModemTime *iface) -{ - iface->check_support = mm_shared_quectel_time_check_support; - iface->check_support_finish = mm_shared_quectel_time_check_support_finish; -} - -static void -shared_quectel_init (MMSharedQuectel *iface) -{ - iface->peek_parent_modem_interface = peek_parent_modem_interface; - iface->peek_parent_modem_location_interface = peek_parent_modem_location_interface; - iface->peek_parent_broadband_modem_class = peek_parent_broadband_modem_class; -} - -static void -mm_broadband_modem_quectel_class_init (MMBroadbandModemQuectelClass *klass) -{ - MMBroadbandModemClass *broadband_modem_class = MM_BROADBAND_MODEM_CLASS (klass); - - broadband_modem_class->setup_ports = mm_shared_quectel_setup_ports; -} diff --git a/plugins/quectel/mm-broadband-modem-quectel.h b/plugins/quectel/mm-broadband-modem-quectel.h deleted file mode 100644 index bf4ef7a7..00000000 --- a/plugins/quectel/mm-broadband-modem-quectel.h +++ /dev/null @@ -1,47 +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) 2018 Aleksander Morgado <aleksander@aleksander.es> - */ - -#ifndef MM_BROADBAND_MODEM_QUECTEL_H -#define MM_BROADBAND_MODEM_QUECTEL_H - -#include "mm-broadband-modem.h" - -#define MM_TYPE_BROADBAND_MODEM_QUECTEL (mm_broadband_modem_quectel_get_type ()) -#define MM_BROADBAND_MODEM_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BROADBAND_MODEM_QUECTEL, MMBroadbandModemQuectel)) -#define MM_BROADBAND_MODEM_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BROADBAND_MODEM_QUECTEL, MMBroadbandModemQuectelClass)) -#define MM_IS_BROADBAND_MODEM_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BROADBAND_MODEM_QUECTEL)) -#define MM_IS_BROADBAND_MODEM_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BROADBAND_MODEM_QUECTEL)) -#define MM_BROADBAND_MODEM_QUECTEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BROADBAND_MODEM_QUECTEL, MMBroadbandModemQuectelClass)) - -typedef struct _MMBroadbandModemQuectel MMBroadbandModemQuectel; -typedef struct _MMBroadbandModemQuectelClass MMBroadbandModemQuectelClass; - -struct _MMBroadbandModemQuectel { - MMBroadbandModem parent; -}; - -struct _MMBroadbandModemQuectelClass{ - MMBroadbandModemClass parent; -}; - -GType mm_broadband_modem_quectel_get_type (void); - -MMBroadbandModemQuectel *mm_broadband_modem_quectel_new (const gchar *device, - const gchar **drivers, - const gchar *plugin, - guint16 vendor_id, - guint16 product_id); - -#endif /* MM_BROADBAND_MODEM_QUECTEL_H */ diff --git a/plugins/quectel/mm-modem-helpers-quectel.c b/plugins/quectel/mm-modem-helpers-quectel.c deleted file mode 100644 index 262d9794..00000000 --- a/plugins/quectel/mm-modem-helpers-quectel.c +++ /dev/null @@ -1,91 +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) 2020 Aleksander Morgado <aleksander@aleksander.es> - */ - -#include <glib.h> - -#include <ModemManager.h> -#define _LIBMM_INSIDE_MM -#include <libmm-glib.h> - -#include "mm-log.h" -#include "mm-modem-helpers.h" -#include "mm-modem-helpers-quectel.h" - -gboolean -mm_quectel_parse_ctzu_test_response (const gchar *response, - gpointer log_object, - gboolean *supports_disable, - gboolean *supports_enable, - gboolean *supports_enable_update_rtc, - GError **error) -{ - g_auto(GStrv) split = NULL; - g_autoptr(GArray) modes = NULL; - guint i; - - /* - * Response may be: - * - +CTZU: (0,1) - * - +CTZU: (0,1,3) - */ - -#define N_EXPECTED_GROUPS 1 - - split = mm_split_string_groups (mm_strip_tag (response, "+CTZU:")); - if (!split) { - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Couldn't split the +CTZU test response in groups"); - return FALSE; - } - - if (g_strv_length (split) != N_EXPECTED_GROUPS) { - g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, - "Cannot parse +CTZU test response: invalid number of groups (%u != %u)", - g_strv_length (split), N_EXPECTED_GROUPS); - return FALSE; - } - - modes = mm_parse_uint_list (split[0], error); - if (!modes) { - g_prefix_error (error, "Failed to parse integer list in +CTZU test response: "); - return FALSE; - } - - *supports_disable = FALSE; - *supports_enable = FALSE; - *supports_enable_update_rtc = FALSE; - - for (i = 0; i < modes->len; i++) { - guint mode; - - mode = g_array_index (modes, guint, i); - switch (mode) { - case 0: - *supports_disable = TRUE; - break; - case 1: - *supports_enable = TRUE; - break; - case 3: - *supports_enable_update_rtc = TRUE; - break; - default: - mm_obj_dbg (log_object, "unknown +CTZU mode: %u", mode); - break; - } - } - - return TRUE; -} diff --git a/plugins/quectel/mm-modem-helpers-quectel.h b/plugins/quectel/mm-modem-helpers-quectel.h deleted file mode 100644 index d4ec0eae..00000000 --- a/plugins/quectel/mm-modem-helpers-quectel.h +++ /dev/null @@ -1,32 +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) 2020 Aleksander Morgado <aleksander@aleksander.es> - */ - -#ifndef MM_MODEM_HELPERS_QUECTEL_H -#define MM_MODEM_HELPERS_QUECTEL_H - -#include <glib.h> - -#include <ModemManager.h> -#define _LIBMM_INSIDE_MM -#include <libmm-glib.h> - -gboolean mm_quectel_parse_ctzu_test_response (const gchar *response, - gpointer log_object, - gboolean *supports_disable, - gboolean *supports_enable, - gboolean *supports_enable_update_rtc, - GError **error); - -#endif /* MM_MODEM_HELPERS_QUECTEL_H */ diff --git a/plugins/quectel/mm-plugin-quectel.c b/plugins/quectel/mm-plugin-quectel.c deleted file mode 100644 index 80e1b74d..00000000 --- a/plugins/quectel/mm-plugin-quectel.c +++ /dev/null @@ -1,117 +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) 2017-2018 Aleksander Morgado <aleksander@aleksander.es> - */ - -#include <stdlib.h> -#include <gmodule.h> - -#define _LIBMM_INSIDE_MM -#include <libmm-glib.h> - -#include "mm-log-object.h" -#include "mm-plugin-quectel.h" -#include "mm-broadband-modem-quectel.h" - -#if defined WITH_QMI -#include "mm-broadband-modem-qmi-quectel.h" -#endif - -#if defined WITH_MBIM -#include "mm-broadband-modem-mbim.h" -#include "mm-broadband-modem-mbim-quectel.h" -#endif - -G_DEFINE_TYPE (MMPluginQuectel, mm_plugin_quectel, 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 Quectel modem found..."); - return MM_BASE_MODEM (mm_broadband_modem_qmi_quectel_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 Quectel modem found..."); - return MM_BASE_MODEM (mm_broadband_modem_mbim_quectel_new (uid, - drivers, - mm_plugin_get_name (self), - vendor, - product)); - } -#endif - - return MM_BASE_MODEM (mm_broadband_modem_quectel_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 }; - static const gchar *vendor_strings[] = { "quectel", NULL }; - static const guint16 vendor_ids[] = { - 0x2c7c, /* usb vid */ - 0x1eac, /* pci vid */ - 0 }; - - return MM_PLUGIN ( - g_object_new (MM_TYPE_PLUGIN_QUECTEL, - MM_PLUGIN_NAME, MM_MODULE_NAME, - MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, - MM_PLUGIN_ALLOWED_VENDOR_IDS, vendor_ids, - MM_PLUGIN_ALLOWED_VENDOR_STRINGS, vendor_strings, - MM_PLUGIN_ALLOWED_AT, TRUE, - MM_PLUGIN_REQUIRED_QCDM, TRUE, - MM_PLUGIN_ALLOWED_QMI, TRUE, - MM_PLUGIN_ALLOWED_MBIM, TRUE, - NULL)); -} - -static void -mm_plugin_quectel_init (MMPluginQuectel *self) -{ -} - -static void -mm_plugin_quectel_class_init (MMPluginQuectelClass *klass) -{ - MMPluginClass *plugin_class = MM_PLUGIN_CLASS (klass); - - plugin_class->create_modem = create_modem; -} diff --git a/plugins/quectel/mm-plugin-quectel.h b/plugins/quectel/mm-plugin-quectel.h deleted file mode 100644 index ec888821..00000000 --- a/plugins/quectel/mm-plugin-quectel.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) 2017 Aleksander Morgado <aleksander@aleksander.es> - */ - -#ifndef MM_PLUGIN_QUECTEL_H -#define MM_PLUGIN_QUECTEL_H - -#include "mm-plugin.h" - -#define MM_TYPE_PLUGIN_QUECTEL (mm_plugin_quectel_get_type ()) -#define MM_PLUGIN_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PLUGIN_QUECTEL, MMPluginQuectel)) -#define MM_PLUGIN_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_PLUGIN_QUECTEL, MMPluginQuectelClass)) -#define MM_IS_PLUGIN_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_PLUGIN_QUECTEL)) -#define MM_IS_PLUGIN_QUECTEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PLUGIN_QUECTEL)) -#define MM_PLUGIN_QUECTEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_QUECTEL, MMPluginQuectelClass)) - -typedef struct { - MMPlugin parent; -} MMPluginQuectel; - -typedef struct { - MMPluginClass parent; -} MMPluginQuectelClass; - -GType mm_plugin_quectel_get_type (void); - -G_MODULE_EXPORT MMPlugin *mm_plugin_create (void); - -#endif /* MM_PLUGIN_QUECTEL_H */ diff --git a/plugins/quectel/mm-shared-quectel.c b/plugins/quectel/mm-shared-quectel.c deleted file mode 100644 index 47d7cd33..00000000 --- a/plugins/quectel/mm-shared-quectel.c +++ /dev/null @@ -1,1039 +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) 2018-2020 Aleksander Morgado <aleksander@aleksander.es> - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. - */ - -#include <config.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-firmware.h" -#include "mm-iface-modem-location.h" -#include "mm-base-modem.h" -#include "mm-base-modem-at.h" -#include "mm-shared-quectel.h" -#include "mm-modem-helpers-quectel.h" - -#if defined WITH_MBIM -#include "mm-broadband-modem-mbim.h" -#endif - -/*****************************************************************************/ -/* Private context */ - -#define PRIVATE_TAG "shared-quectel-private-tag" -static GQuark private_quark; - -typedef enum { - FEATURE_SUPPORT_UNKNOWN, - FEATURE_NOT_SUPPORTED, - FEATURE_SUPPORTED, -} FeatureSupport; - -typedef struct { - MMBroadbandModemClass *broadband_modem_class_parent; - MMIfaceModem *iface_modem_parent; - MMIfaceModemLocation *iface_modem_location_parent; - MMModemLocationSource provided_sources; - MMModemLocationSource enabled_sources; - FeatureSupport qgps_supported; - GRegex *qgpsurc_regex; - GRegex *qlwurc_regex; - GRegex *rdy_regex; -} Private; - -static void -private_free (Private *priv) -{ - g_regex_unref (priv->qgpsurc_regex); - g_regex_unref (priv->qlwurc_regex); - g_regex_unref (priv->rdy_regex); - g_slice_free (Private, priv); -} - -static Private * -get_private (MMSharedQuectel *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); - - priv->provided_sources = MM_MODEM_LOCATION_SOURCE_NONE; - priv->enabled_sources = MM_MODEM_LOCATION_SOURCE_NONE; - priv->qgps_supported = FEATURE_SUPPORT_UNKNOWN; - priv->qgpsurc_regex = g_regex_new ("\\r\\n\\+QGPSURC:.*", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - priv->qlwurc_regex = g_regex_new ("\\r\\n\\+QLWURC:.*", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - priv->rdy_regex = g_regex_new ("\\r\\nRDY", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); - - g_assert (priv->qgpsurc_regex); - g_assert (priv->qlwurc_regex); - g_assert (priv->rdy_regex); - - g_assert (MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_broadband_modem_class); - priv->broadband_modem_class_parent = MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_broadband_modem_class (self); - - g_assert (MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_modem_location_interface); - priv->iface_modem_location_parent = MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_modem_location_interface (self); - - g_assert (MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_modem_interface); - priv->iface_modem_parent = MM_SHARED_QUECTEL_GET_INTERFACE (self)->peek_parent_modem_interface (self); - - g_object_set_qdata_full (G_OBJECT (self), private_quark, priv, (GDestroyNotify)private_free); - } - return priv; -} - -/*****************************************************************************/ -/* RDY unsolicited event handler */ - -static void -rdy_handler (MMPortSerialAt *port, - GMatchInfo *match_info, - MMBroadbandModem *self) -{ - /* The RDY URC indicates a modem reset that may or may not go hand-in-hand - * with USB re-enumeration. For the latter case, we must make sure to - * re-synchronize modem and ModemManager states by re-probing. - */ - mm_obj_warn (self, "modem reset detected, triggering reprobe"); - mm_base_modem_set_reprobe (MM_BASE_MODEM (self), TRUE); - mm_base_modem_set_valid (MM_BASE_MODEM (self), FALSE); -} - -/*****************************************************************************/ -/* Setup ports (Broadband modem class) */ - -void -mm_shared_quectel_setup_ports (MMBroadbandModem *self) -{ - Private *priv; - MMPortSerialAt *ports[2]; - guint i; - - priv = get_private (MM_SHARED_QUECTEL (self)); - g_assert (priv->broadband_modem_class_parent); - g_assert (priv->broadband_modem_class_parent->setup_ports); - - /* Parent setup always first */ - priv->broadband_modem_class_parent->setup_ports (self); - - ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); - ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); - - /* Enable/disable unsolicited events in given port */ - for (i = 0; i < G_N_ELEMENTS (ports); i++) { - if (!ports[i]) - continue; - - /* Ignore +QGPSURC */ - mm_port_serial_at_add_unsolicited_msg_handler ( - ports[i], - priv->qgpsurc_regex, - NULL, NULL, NULL); - - /* Ignore +QLWURC */ - mm_port_serial_at_add_unsolicited_msg_handler ( - ports[i], - priv->qlwurc_regex, - NULL, NULL, NULL); - - /* Handle RDY */ - mm_port_serial_at_add_unsolicited_msg_handler ( - ports[i], - priv->rdy_regex, - (MMPortSerialAtUnsolicitedMsgFn)rdy_handler, - self, - NULL); - } -} - -/*****************************************************************************/ -/* Firmware update settings loading (Firmware interface) */ - -MMFirmwareUpdateSettings * -mm_shared_quectel_firmware_load_update_settings_finish (MMIfaceModemFirmware *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_pointer (G_TASK (res), error); -} - -static gboolean -quectel_is_sahara_supported (MMBaseModem *modem, - MMPort *port) -{ - return mm_kernel_device_get_global_property_as_boolean (mm_port_peek_kernel_device (port), "ID_MM_QUECTEL_SAHARA"); -} - -static gboolean -quectel_is_firehose_supported (MMBaseModem *modem, - MMPort *port) -{ - return mm_kernel_device_get_global_property_as_boolean (mm_port_peek_kernel_device (port), "ID_MM_QUECTEL_FIREHOSE"); -} - -static MMModemFirmwareUpdateMethod -quectel_get_firmware_update_methods (MMBaseModem *modem, - MMPort *port) -{ - MMModemFirmwareUpdateMethod update_methods; - - update_methods = MM_MODEM_FIRMWARE_UPDATE_METHOD_NONE; - - if (quectel_is_firehose_supported (modem, port)) - update_methods |= MM_MODEM_FIRMWARE_UPDATE_METHOD_FIREHOSE; - if (quectel_is_sahara_supported (modem, port)) - update_methods |= MM_MODEM_FIRMWARE_UPDATE_METHOD_SAHARA; - - return update_methods; -} - -static void -quectel_at_port_get_firmware_version_ready (MMBaseModem *modem, - GAsyncResult *res, - GTask *task) -{ - MMFirmwareUpdateSettings *update_settings; - const gchar *version; - - update_settings = g_task_get_task_data (task); - - version = mm_base_modem_at_command_finish (modem, res, NULL); - if (version) - mm_firmware_update_settings_set_version (update_settings, version); - - g_task_return_pointer (task, g_object_ref (update_settings), g_object_unref); - g_object_unref (task); -} - -#if defined WITH_MBIM -static void -quectel_mbim_port_get_firmware_version_ready (MbimDevice *device, - GAsyncResult *res, - GTask *task) -{ - g_autoptr(MbimMessage) response = NULL; - guint32 version_id; - g_autofree gchar *version_str = NULL; - MMFirmwareUpdateSettings *update_settings; - - update_settings = g_task_get_task_data (task); - - response = mbim_device_command_finish (device, res, NULL); - if (response && mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, NULL) && - mbim_message_qdu_quectel_read_version_response_parse (response, &version_id, &version_str, NULL)) { - mm_firmware_update_settings_set_version (update_settings, version_str); - } - - g_task_return_pointer (task, g_object_ref (update_settings), g_object_unref); - g_object_unref (task); -} -#endif - -static void -qfastboot_test_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - MMFirmwareUpdateSettings *update_settings; - - update_settings = g_task_get_task_data (task); - - /* Set update method */ - if (mm_base_modem_at_command_finish (self, res, NULL)) { - mm_firmware_update_settings_set_method (update_settings, MM_MODEM_FIRMWARE_UPDATE_METHOD_FASTBOOT); - mm_firmware_update_settings_set_fastboot_at (update_settings, "AT+QFASTBOOT"); - } else - mm_firmware_update_settings_set_method (update_settings, MM_MODEM_FIRMWARE_UPDATE_METHOD_NONE); - - /* Fetch full firmware info */ - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+QGMR?", - 3, - FALSE, - (GAsyncReadyCallback) quectel_at_port_get_firmware_version_ready, - task); -} - -static void -quectel_at_port_get_firmware_revision_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - MMFirmwareUpdateSettings *update_settings; - MMModemFirmwareUpdateMethod update_methods; - const gchar *revision; - const gchar *name; - const gchar *id; - g_autoptr(GPtrArray) ids = NULL; - GError *error = NULL; - - update_settings = g_task_get_task_data (task); - update_methods = mm_firmware_update_settings_get_method (update_settings); - - /* Set device ids */ - ids = mm_iface_firmware_build_generic_device_ids (MM_IFACE_MODEM_FIRMWARE (self), &error); - if (error) { - mm_obj_warn (self, "failed to build generic device ids: %s", error->message); - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - /* Add device id based on modem name */ - revision = mm_base_modem_at_command_finish (self, res, NULL); - if (revision && g_utf8_validate (revision, -1, NULL)) { - name = g_strndup (revision, 7); - mm_obj_dbg (self, "revision %s converted to modem name %s", revision, name); - id = (const gchar *) g_ptr_array_index (ids, 0); - g_ptr_array_insert (ids, 0, g_strdup_printf ("%s&NAME_%s", id, name)); - } - - mm_firmware_update_settings_set_device_ids (update_settings, (const gchar **)ids->pdata); - - /* Set update methods */ - if (update_methods & MM_MODEM_FIRMWARE_UPDATE_METHOD_FIREHOSE) { - /* Fetch full firmware info */ - mm_base_modem_at_command (self, - "+QGMR?", - 3, - TRUE, - (GAsyncReadyCallback) quectel_at_port_get_firmware_version_ready, - task); - } else { - /* Check fastboot support */ - mm_base_modem_at_command (self, - "AT+QFASTBOOT=?", - 3, - TRUE, - (GAsyncReadyCallback) qfastboot_test_ready, - task); - } -} - -void -mm_shared_quectel_firmware_load_update_settings (MMIfaceModemFirmware *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - MMPortSerialAt *at_port; - MMModemFirmwareUpdateMethod update_methods; - MMFirmwareUpdateSettings *update_settings; -#if defined WITH_MBIM - MMPortMbim *mbim; -#endif - - task = g_task_new (self, NULL, callback, user_data); - - at_port = mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL); - if (at_port) { - update_methods = quectel_get_firmware_update_methods (MM_BASE_MODEM (self), MM_PORT (at_port)); - update_settings = mm_firmware_update_settings_new (update_methods); - g_task_set_task_data (task, update_settings, g_object_unref); - - /* Fetch modem name */ - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+CGMR", - 3, - TRUE, - (GAsyncReadyCallback) quectel_at_port_get_firmware_revision_ready, - task); - - return; - } - -#if defined WITH_MBIM - mbim = mm_broadband_modem_mbim_peek_port_mbim (MM_BROADBAND_MODEM_MBIM (self)); - if (mbim) { - g_autoptr(MbimMessage) message = NULL; - - update_methods = quectel_get_firmware_update_methods (MM_BASE_MODEM (self), MM_PORT (mbim)); - update_settings = mm_firmware_update_settings_new (update_methods); - - /* Fetch firmware info */ - g_task_set_task_data (task, update_settings, g_object_unref); - message = mbim_message_qdu_quectel_read_version_set_new (MBIM_QDU_QUECTEL_VERSION_TYPE_FW_BUILD_ID, NULL); - mbim_device_command (mm_port_mbim_peek_device (mbim), - message, - 5, - NULL, - (GAsyncReadyCallback) quectel_mbim_port_get_firmware_version_ready, - task); - return; - } -#endif - - g_task_return_new_error (task, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Couldn't find a port to fetch firmware info"); - g_object_unref (task); -} - -/*****************************************************************************/ -/* "+QUSIM: 1" URC is emitted by Quectel modems after the USIM has been - * (re)initialized. We register a handler for this URC and perform a check - * for SIM swap when it is encountered. The motivation for this is to detect - * M2M eUICC profile switches. According to SGP.02 chapter 3.2.1, the eUICC - * shall trigger a REFRESH operation with eUICC reset when a new profile is - * enabled. The +QUSIM URC appears after the eUICC has restarted and can act - * as a trigger for profile switch check. This should basically be handled - * the same as a physical SIM swap, so the existing SIM hot swap mechanism - * is used. - */ - -static void -quectel_qusim_check_for_sim_swap_ready (MMIfaceModem *self, - GAsyncResult *res) -{ - g_autoptr(GError) error = NULL; - - if (!MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish (self, res, &error)) - mm_obj_warn (self, "couldn't check SIM swap: %s", error->message); - else - mm_obj_dbg (self, "check SIM swap completed"); -} - -static void -quectel_qusim_unsolicited_handler (MMPortSerialAt *port, - GMatchInfo *match_info, - MMIfaceModem *self) -{ - if (!MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap || - !MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap_finish) - return; - - mm_obj_dbg (self, "checking SIM swap"); - MM_IFACE_MODEM_GET_INTERFACE (self)->check_for_sim_swap ( - self, - NULL, - NULL, - (GAsyncReadyCallback)quectel_qusim_check_for_sim_swap_ready, - NULL); -} - -/*****************************************************************************/ -/* Setup SIM hot swap context (Modem interface) */ - -gboolean -mm_shared_quectel_setup_sim_hot_swap_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -parent_setup_sim_hot_swap_ready (MMIfaceModem *self, - GAsyncResult *res, - GTask *task) -{ - Private *priv; - g_autoptr(GError) error = NULL; - - priv = get_private (MM_SHARED_QUECTEL (self)); - - if (!priv->iface_modem_parent->setup_sim_hot_swap_finish (self, res, &error)) - mm_obj_dbg (self, "additional SIM hot swap detection setup failed: %s", error->message); - - /* The +QUSIM based setup never fails, so we can safely return success here */ - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -void -mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - Private *priv; - MMPortSerialAt *ports[2]; - GTask *task; - guint i; - g_autoptr(GRegex) pattern = NULL; - g_autoptr(GError) error = NULL; - - priv = get_private (MM_SHARED_QUECTEL (self)); - - task = g_task_new (self, NULL, callback, user_data); - - ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); - ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); - - pattern = g_regex_new ("\\+QUSIM:\\s*1\\r\\n", G_REGEX_RAW, 0, NULL); - g_assert (pattern); - - for (i = 0; i < G_N_ELEMENTS (ports); i++) { - if (ports[i]) - mm_port_serial_at_add_unsolicited_msg_handler ( - ports[i], - pattern, - (MMPortSerialAtUnsolicitedMsgFn)quectel_qusim_unsolicited_handler, - self, - NULL); - } - - mm_obj_dbg (self, "+QUSIM detection set up"); - - 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); - - /* Now, if available, setup parent logic */ - if (priv->iface_modem_parent->setup_sim_hot_swap && - priv->iface_modem_parent->setup_sim_hot_swap_finish) { - priv->iface_modem_parent->setup_sim_hot_swap (self, - (GAsyncReadyCallback) parent_setup_sim_hot_swap_ready, - task); - return; - } - - /* Otherwise, we're done */ - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -/*****************************************************************************/ -/* SIM hot swap cleanup (Modem interface) */ - -void -mm_shared_quectel_cleanup_sim_hot_swap (MMIfaceModem *self) -{ - mm_broadband_modem_sim_hot_swap_ports_context_reset (MM_BROADBAND_MODEM (self)); -} - -/*****************************************************************************/ -/* GPS trace received */ - -static void -trace_received (MMPortSerialGps *port, - const gchar *trace, - MMIfaceModemLocation *self) -{ - mm_iface_modem_location_gps_update (self, trace); -} - -/*****************************************************************************/ -/* Location capabilities loading (Location interface) */ - -MMModemLocationSource -mm_shared_quectel_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 -probe_qgps_ready (MMBaseModem *_self, - GAsyncResult *res, - GTask *task) -{ - MMSharedQuectel *self; - Private *priv; - MMModemLocationSource sources; - - self = MM_SHARED_QUECTEL (g_task_get_source_object (task)); - priv = get_private (self); - - priv->qgps_supported = (!!mm_base_modem_at_command_finish (_self, res, NULL) ? - FEATURE_SUPPORTED : FEATURE_NOT_SUPPORTED); - - mm_obj_dbg (self, "GPS management with +QGPS is %ssupported", - priv->qgps_supported ? "" : "not "); - - /* Recover parent sources */ - sources = GPOINTER_TO_UINT (g_task_get_task_data (task)); - - /* Only flag as provided those sources not already provided by the parent */ - if (priv->qgps_supported == FEATURE_SUPPORTED) { - if (!(sources & MM_MODEM_LOCATION_SOURCE_GPS_NMEA)) - priv->provided_sources |= MM_MODEM_LOCATION_SOURCE_GPS_NMEA; - if (!(sources & MM_MODEM_LOCATION_SOURCE_GPS_RAW)) - priv->provided_sources |= MM_MODEM_LOCATION_SOURCE_GPS_RAW; - if (!(sources & MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) - priv->provided_sources |= MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED; - - sources |= priv->provided_sources; - - /* Add handler for the NMEA traces in the GPS data port */ - mm_port_serial_gps_add_trace_handler (mm_base_modem_peek_port_gps (MM_BASE_MODEM (self)), - (MMPortSerialGpsTraceFn)trace_received, - self, - NULL); - } - - /* So we're done, complete */ - g_task_return_int (task, sources); - g_object_unref (task); -} - -static void -parent_load_capabilities_ready (MMIfaceModemLocation *self, - GAsyncResult *res, - GTask *task) -{ - Private *priv; - MMModemLocationSource sources; - GError *error = NULL; - - priv = get_private (MM_SHARED_QUECTEL (self)); - sources = priv->iface_modem_location_parent->load_capabilities_finish (self, res, &error); - if (error) { - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - /* Now our own check. If we don't have any GPS port, we're done */ - if (!mm_base_modem_peek_port_gps (MM_BASE_MODEM (self))) { - mm_obj_dbg (self, "no GPS data port found: no GPS capabilities"); - g_task_return_int (task, sources); - g_object_unref (task); - return; - } - - /* Store parent supported sources in task data */ - g_task_set_task_data (task, GUINT_TO_POINTER (sources), NULL); - - /* Probe QGPS support */ - g_assert (priv->qgps_supported == FEATURE_SUPPORT_UNKNOWN); - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+QGPS=?", - 3, - TRUE, /* cached */ - (GAsyncReadyCallback)probe_qgps_ready, - task); -} - -void -mm_shared_quectel_location_load_capabilities (MMIfaceModemLocation *_self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - Private *priv; - - task = g_task_new (_self, NULL, callback, user_data); - priv = get_private (MM_SHARED_QUECTEL (_self)); - - /* Chain up parent's setup */ - priv->iface_modem_location_parent->load_capabilities (_self, - (GAsyncReadyCallback)parent_load_capabilities_ready, - task); -} - -/*****************************************************************************/ -/* Enable location gathering (Location interface) */ - -/* NOTES: - * 1) "+QGPSCFG=\"nmeasrc\",1" will be necessary for getting location data - * without the nmea port. - * 2) may be necessary to set "+QGPSCFG=\"gpsnmeatype\". - * 3) QGPSXTRA=1 is necessary to support XTRA assistance data for - * faster GNSS location locks. - */ -static const MMBaseModemAtCommand gps_startup[] = { - { "+QGPSCFG=\"outport\",\"usbnmea\"", 3, FALSE, mm_base_modem_response_processor_no_result_continue }, - { "+QGPS=1", 3, FALSE, mm_base_modem_response_processor_no_result_continue }, - { "+QGPSXTRA=1", 3, FALSE, mm_base_modem_response_processor_no_result_continue }, - { NULL } -}; - -gboolean -mm_shared_quectel_enable_location_gathering_finish (MMIfaceModemLocation *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -gps_startup_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - MMModemLocationSource source; - GError *error = NULL; - Private *priv; - - priv = get_private (MM_SHARED_QUECTEL (self)); - - mm_base_modem_at_sequence_finish (self, res, NULL, &error); - if (error) { - g_task_return_error (task, error); - g_object_unref (task); - return; - } - - source = GPOINTER_TO_UINT (g_task_get_task_data (task)); - - /* Check if the nmea/raw gps port exists and is available */ - if (source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | MM_MODEM_LOCATION_SOURCE_GPS_RAW)) { - MMPortSerialGps *gps_port; - - gps_port = mm_base_modem_peek_port_gps (MM_BASE_MODEM (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 { - /* GPS port was successfully opened */ - priv->enabled_sources |= source; - g_task_return_boolean (task, TRUE); - } - } else { - /* No need to open GPS port */ - priv->enabled_sources |= source; - g_task_return_boolean (task, TRUE); - } - g_object_unref (task); -} - -static void -parent_enable_location_gathering_ready (MMIfaceModemLocation *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - Private *priv; - - priv = get_private (MM_SHARED_QUECTEL (self)); - if (!priv->iface_modem_location_parent->enable_location_gathering_finish (self, res, &error)) - g_task_return_error (task, error); - else - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -void -mm_shared_quectel_enable_location_gathering (MMIfaceModemLocation *self, - MMModemLocationSource source, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - Private *priv; - gboolean start_gps = FALSE; - - priv = get_private (MM_SHARED_QUECTEL (self)); - g_assert (priv->iface_modem_location_parent); - g_assert (priv->iface_modem_location_parent->enable_location_gathering); - g_assert (priv->iface_modem_location_parent->enable_location_gathering_finish); - - task = g_task_new (self, NULL, callback, user_data); - g_task_set_task_data (task, GUINT_TO_POINTER (source), NULL); - - /* Check if the source is provided by the parent */ - if (!(priv->provided_sources & source)) { - priv->iface_modem_location_parent->enable_location_gathering ( - self, - source, - (GAsyncReadyCallback)parent_enable_location_gathering_ready, - task); - return; - } - - /* Only start GPS engine if not done already */ - start_gps = ((source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) && - !(priv->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED))); - - if (start_gps) { - mm_base_modem_at_sequence ( - MM_BASE_MODEM (self), - gps_startup, - NULL, /* response_processor_context */ - NULL, /* response_processor_context_free */ - (GAsyncReadyCallback)gps_startup_ready, - task); - return; - } - - /* If the GPS is already running just return */ - priv->enabled_sources |= source; - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -/*****************************************************************************/ -/* Disable location gathering (Location interface) */ - -gboolean -mm_shared_quectel_disable_location_gathering_finish (MMIfaceModemLocation *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -qgps_end_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - - if (!mm_base_modem_at_command_finish (self, res, &error)) - g_task_return_error (task, error); - else - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -static void -disable_location_gathering_parent_ready (MMIfaceModemLocation *self, - GAsyncResult *res, - GTask *task) -{ - GError *error = NULL; - Private *priv; - - priv = get_private (MM_SHARED_QUECTEL (self)); - if (!priv->iface_modem_location_parent->disable_location_gathering_finish (self, res, &error)) - g_task_return_error (task, error); - else - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -void -mm_shared_quectel_disable_location_gathering (MMIfaceModemLocation *self, - MMModemLocationSource source, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GTask *task; - Private *priv; - - priv = get_private (MM_SHARED_QUECTEL (self)); - g_assert (priv->iface_modem_location_parent); - - task = g_task_new (self, NULL, callback, user_data); - priv->enabled_sources &= ~source; - - /* Pass handling to parent if we don't handle it */ - if (!(source & priv->provided_sources)) { - /* The step to disable location gathering may not exist */ - if (priv->iface_modem_location_parent->disable_location_gathering && - priv->iface_modem_location_parent->disable_location_gathering_finish) { - priv->iface_modem_location_parent->disable_location_gathering (self, - source, - (GAsyncReadyCallback)disable_location_gathering_parent_ready, - task); - return; - } - - g_task_return_boolean (task, TRUE); - g_object_unref (task); - return; - } - - /* Turn off gps on the modem if the source uses gps, - * and there are no other gps sources enabled */ - if ((source & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) && - !(priv->enabled_sources & (MM_MODEM_LOCATION_SOURCE_GPS_NMEA | - MM_MODEM_LOCATION_SOURCE_GPS_RAW | - MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED))) { - /* Close the data port if we don't need it anymore */ - if (source & (MM_MODEM_LOCATION_SOURCE_GPS_RAW | MM_MODEM_LOCATION_SOURCE_GPS_NMEA)) { - MMPortSerialGps *gps_port; - - gps_port = mm_base_modem_peek_port_gps (MM_BASE_MODEM (self)); - if (gps_port) - mm_port_serial_close (MM_PORT_SERIAL (gps_port)); - } - - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+QGPSEND", - 3, - FALSE, - (GAsyncReadyCallback)qgps_end_ready, - task); - return; - } - - g_task_return_boolean (task, TRUE); - g_object_unref (task); -} - -/*****************************************************************************/ -/* Check support (Time interface) */ - -gboolean -mm_shared_quectel_time_check_support_finish (MMIfaceModemTime *self, - GAsyncResult *res, - GError **error) -{ - return g_task_propagate_boolean (G_TASK (res), error); -} - -static void -support_cclk_query_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - /* error never returned */ - g_task_return_boolean (task, !!mm_base_modem_at_command_finish (self, res, NULL)); - g_object_unref (task); -} - -static void -support_cclk_query (GTask *task) -{ - MMBaseModem *self; - - self = g_task_get_source_object (task); - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+CCLK?", - 3, - FALSE, - (GAsyncReadyCallback)support_cclk_query_ready, - task); -} - -static void -ctzu_set_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - g_autoptr(GError) error = NULL; - - if (!mm_base_modem_at_command_finish (self, res, &error)) - mm_obj_warn (self, "couldn't enable automatic time zone update: %s", error->message); - - support_cclk_query (task); -} - -static void -ctzu_test_ready (MMBaseModem *self, - GAsyncResult *res, - GTask *task) -{ - g_autoptr(GError) error = NULL; - const gchar *response; - gboolean supports_disable; - gboolean supports_enable; - gboolean supports_enable_update_rtc; - const gchar *cmd = NULL; - - /* If CTZU isn't supported, run CCLK right away */ - response = mm_base_modem_at_command_finish (self, res, NULL); - if (!response) { - support_cclk_query (task); - return; - } - - if (!mm_quectel_parse_ctzu_test_response (response, - self, - &supports_disable, - &supports_enable, - &supports_enable_update_rtc, - &error)) { - mm_obj_warn (self, "couldn't parse +CTZU test response: %s", error->message); - support_cclk_query (task); - return; - } - - /* Custom time support check because some Quectel modems (e.g. EC25) require - * +CTZU=3 in order to have the CCLK? time reported in localtime, instead of - * UTC time. */ - if (supports_enable_update_rtc) - cmd = "+CTZU=3"; - else if (supports_enable) - cmd = "+CTZU=1"; - - if (!cmd) { - mm_obj_warn (self, "unknown +CTZU support"); - support_cclk_query (task); - return; - } - - mm_base_modem_at_command (MM_BASE_MODEM (self), - cmd, - 3, - FALSE, - (GAsyncReadyCallback)ctzu_set_ready, - task); -} - -void -mm_shared_quectel_time_check_support (MMIfaceModemTime *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), - "+CTZU=?", - 3, - TRUE, /* cached! */ - (GAsyncReadyCallback)ctzu_test_ready, - task); -} - -/*****************************************************************************/ - -static void -shared_quectel_init (gpointer g_iface) -{ -} - -GType -mm_shared_quectel_get_type (void) -{ - static GType shared_quectel_type = 0; - - if (!G_UNLIKELY (shared_quectel_type)) { - static const GTypeInfo info = { - sizeof (MMSharedQuectel), /* class_size */ - shared_quectel_init, /* base_init */ - NULL, /* base_finalize */ - }; - - shared_quectel_type = g_type_register_static (G_TYPE_INTERFACE, "MMSharedQuectel", &info, 0); - g_type_interface_add_prerequisite (shared_quectel_type, MM_TYPE_IFACE_MODEM_FIRMWARE); - } - - return shared_quectel_type; -} diff --git a/plugins/quectel/mm-shared-quectel.h b/plugins/quectel/mm-shared-quectel.h deleted file mode 100644 index 0dfcbde4..00000000 --- a/plugins/quectel/mm-shared-quectel.h +++ /dev/null @@ -1,93 +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) 2018-2020 Aleksander Morgado <aleksander@aleksander.es> - */ - -#ifndef MM_SHARED_QUECTEL_H -#define MM_SHARED_QUECTEL_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-firmware.h" -#include "mm-iface-modem-location.h" -#include "mm-iface-modem-time.h" - -#define MM_TYPE_SHARED_QUECTEL (mm_shared_quectel_get_type ()) -#define MM_SHARED_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_SHARED_QUECTEL, MMSharedQuectel)) -#define MM_IS_SHARED_QUECTEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_SHARED_QUECTEL)) -#define MM_SHARED_QUECTEL_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), MM_TYPE_SHARED_QUECTEL, MMSharedQuectel)) - -typedef struct _MMSharedQuectel MMSharedQuectel; - -struct _MMSharedQuectel { - GTypeInterface g_iface; - MMBroadbandModemClass * (* peek_parent_broadband_modem_class) (MMSharedQuectel *self); - MMIfaceModem * (* peek_parent_modem_interface) (MMSharedQuectel *self); - MMIfaceModemLocation * (* peek_parent_modem_location_interface) (MMSharedQuectel *self); -}; - -GType mm_shared_quectel_get_type (void); - -void mm_shared_quectel_setup_ports (MMBroadbandModem *self); - -void mm_shared_quectel_firmware_load_update_settings (MMIfaceModemFirmware *self, - GAsyncReadyCallback callback, - gpointer user_data); - -MMFirmwareUpdateSettings *mm_shared_quectel_firmware_load_update_settings_finish (MMIfaceModemFirmware *self, - GAsyncResult *res, - GError **error); - -void mm_shared_quectel_setup_sim_hot_swap (MMIfaceModem *self, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_shared_quectel_setup_sim_hot_swap_finish (MMIfaceModem *self, - GAsyncResult *res, - GError **error); -void mm_shared_quectel_cleanup_sim_hot_swap (MMIfaceModem *self); - -void mm_shared_quectel_location_load_capabilities (MMIfaceModemLocation *self, - GAsyncReadyCallback callback, - gpointer user_data); -MMModemLocationSource mm_shared_quectel_location_load_capabilities_finish (MMIfaceModemLocation *self, - GAsyncResult *res, - GError **error); -void mm_shared_quectel_enable_location_gathering (MMIfaceModemLocation *self, - MMModemLocationSource source, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_shared_quectel_enable_location_gathering_finish (MMIfaceModemLocation *self, - GAsyncResult *res, - GError **error); -void mm_shared_quectel_disable_location_gathering (MMIfaceModemLocation *self, - MMModemLocationSource source, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_shared_quectel_disable_location_gathering_finish (MMIfaceModemLocation *self, - GAsyncResult *res, - GError **error); - -void mm_shared_quectel_time_check_support (MMIfaceModemTime *self, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_shared_quectel_time_check_support_finish (MMIfaceModemTime *self, - GAsyncResult *res, - GError **error); - -#endif /* MM_SHARED_QUECTEL_H */ diff --git a/plugins/quectel/tests/test-modem-helpers-quectel.c b/plugins/quectel/tests/test-modem-helpers-quectel.c deleted file mode 100644 index 0e2c7420..00000000 --- a/plugins/quectel/tests/test-modem-helpers-quectel.c +++ /dev/null @@ -1,93 +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) 2020 Aleksander Morgado <aleksander@aleksander.es> - */ - -#include <glib.h> -#include <glib-object.h> -#include <locale.h> - -#include <ModemManager.h> -#define _LIBMM_INSIDE_MM -#include <libmm-glib.h> -#include <math.h> - -#include "mm-log-test.h" -#include "mm-modem-helpers.h" -#include "mm-modem-helpers-quectel.h" - -/*****************************************************************************/ -/* Test ^CTZU test responses */ - -typedef struct { - const gchar *response; - gboolean expect_supports_disable; - gboolean expect_supports_enable; - gboolean expect_supports_enable_update_rtc; -} TestCtzuResponse; - -static const TestCtzuResponse test_ctzu_response[] = { - { "+CTZU: (0,1)", TRUE, TRUE, FALSE }, - { "+CTZU: (0,1,3)", TRUE, TRUE, TRUE }, -}; - -static void -common_test_ctzu (const gchar *response, - gboolean expect_supports_disable, - gboolean expect_supports_enable, - gboolean expect_supports_enable_update_rtc) -{ - g_autoptr(GError) error = NULL; - gboolean res; - gboolean supports_disable = FALSE; - gboolean supports_enable = FALSE; - gboolean supports_enable_update_rtc = FALSE; - - res = mm_quectel_parse_ctzu_test_response (response, - NULL, - &supports_disable, - &supports_enable, - &supports_enable_update_rtc, - &error); - g_assert_no_error (error); - g_assert (res); - - g_assert_cmpuint (expect_supports_disable, ==, supports_disable); - g_assert_cmpuint (expect_supports_enable, ==, supports_enable); - g_assert_cmpuint (expect_supports_enable_update_rtc, ==, supports_enable_update_rtc); -} - -static void -test_ctzu (void) -{ - guint i; - - for (i = 0; i < G_N_ELEMENTS (test_ctzu_response); i++) - common_test_ctzu (test_ctzu_response[i].response, - test_ctzu_response[i].expect_supports_disable, - test_ctzu_response[i].expect_supports_enable, - test_ctzu_response[i].expect_supports_enable_update_rtc); -} - -/*****************************************************************************/ - -int main (int argc, char **argv) -{ - setlocale (LC_ALL, ""); - - g_test_init (&argc, &argv, NULL); - - g_test_add_func ("/MM/quectel/ctzu", test_ctzu); - - return g_test_run (); -} |