diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2019-11-12 10:55:06 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2019-11-13 12:31:58 +0100 |
commit | d7d2b9108e12f86f50f82f124066fab46792bd44 (patch) | |
tree | e5a599f1155f2e5ec14e2374c608d47601c69ea9 /plugins/foxconn | |
parent | 5ab5593edbf86a268f9b6d196f30e303c1e1b879 (diff) |
foxconn: new plugin to support the T77W968
The Dell DW5821e is really a re-branded Foxconn T77W968.
Diffstat (limited to 'plugins/foxconn')
-rw-r--r-- | plugins/foxconn/77-mm-foxconn-port-types.rules | 26 | ||||
-rw-r--r-- | plugins/foxconn/mm-broadband-modem-foxconn-t77w968.c | 437 | ||||
-rw-r--r-- | plugins/foxconn/mm-broadband-modem-foxconn-t77w968.h | 49 | ||||
-rw-r--r-- | plugins/foxconn/mm-foxconn-t77w968-carrier-mapping.conf | 281 | ||||
-rw-r--r-- | plugins/foxconn/mm-plugin-foxconn.c | 127 | ||||
-rw-r--r-- | plugins/foxconn/mm-plugin-foxconn.h | 46 |
6 files changed, 966 insertions, 0 deletions
diff --git a/plugins/foxconn/77-mm-foxconn-port-types.rules b/plugins/foxconn/77-mm-foxconn-port-types.rules new file mode 100644 index 00000000..6b501ba2 --- /dev/null +++ b/plugins/foxconn/77-mm-foxconn-port-types.rules @@ -0,0 +1,26 @@ +# do not edit this file, it will be overwritten on update + +ACTION!="add|change|move|bind", GOTO="mm_foxconn_port_types_end" + +SUBSYSTEMS=="usb", ATTRS{idVendor}=="0489", GOTO="mm_foxconn_vendorcheck" +GOTO="mm_foxconn_port_types_end" + +LABEL="mm_foxconn_vendorcheck" +SUBSYSTEMS=="usb", ATTRS{bInterfaceNumber}=="?*", ENV{.MM_USBIFNUM}="$attr{bInterfaceNumber}" + +# Foxconn T77w968 (default 0xe0b4, with esim support 0xe0b5) +# if 02: primary port +# if 03: secondary port +# if 04: raw NMEA port +# if 05: diag/qcdm port +ATTRS{idVendor}=="0489", ATTRS{idProduct}=="e0b4", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" +ATTRS{idVendor}=="0489", ATTRS{idProduct}=="e0b4", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" +ATTRS{idVendor}=="0489", ATTRS{idProduct}=="e0b4", ENV{.MM_USBIFNUM}=="04", ENV{ID_MM_PORT_TYPE_GPS}="1" +ATTRS{idVendor}=="0489", ATTRS{idProduct}=="e0b4", ENV{.MM_USBIFNUM}=="05", ENV{ID_MM_PORT_TYPE_QCDM}="1" +ATTRS{idVendor}=="0489", ATTRS{idProduct}=="e0b5", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" +ATTRS{idVendor}=="0489", ATTRS{idProduct}=="e0b5", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" +ATTRS{idVendor}=="0489", ATTRS{idProduct}=="e0b5", ENV{.MM_USBIFNUM}=="04", ENV{ID_MM_PORT_TYPE_GPS}="1" +ATTRS{idVendor}=="0489", ATTRS{idProduct}=="e0b5", ENV{.MM_USBIFNUM}=="05", ENV{ID_MM_PORT_TYPE_QCDM}="1" + +GOTO="mm_foxconn_port_types_end" +LABEL="mm_foxconn_port_types_end" diff --git a/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.c b/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.c new file mode 100644 index 00000000..c5940194 --- /dev/null +++ b/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.c @@ -0,0 +1,437 @@ +/* -*- 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-2019 Aleksander Morgado <aleksander@aleksander.es> + */ + +#include <config.h> + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <ctype.h> +#include <time.h> + +#include <ModemManager.h> +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#include "mm-log.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-location.h" +#include "mm-broadband-modem-foxconn-t77w968.h" + +#if defined WITH_QMI +# include "mm-iface-modem-firmware.h" +# include "mm-shared-qmi.h" +#endif + +static void iface_modem_location_init (MMIfaceModemLocation *iface); + +#if defined WITH_QMI +static void iface_modem_firmware_init (MMIfaceModemFirmware *iface); +#endif + +static MMIfaceModemLocation *iface_modem_location_parent; + +G_DEFINE_TYPE_EXTENDED (MMBroadbandModemFoxconnT77w968, mm_broadband_modem_foxconn_t77w968, MM_TYPE_BROADBAND_MODEM_MBIM, 0, +#if defined WITH_QMI + G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_FIRMWARE, iface_modem_firmware_init) +#endif + G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_LOCATION, iface_modem_location_init)) + +typedef enum { + FEATURE_SUPPORT_UNKNOWN, + FEATURE_NOT_SUPPORTED, + FEATURE_SUPPORTED +} FeatureSupport; + +struct _MMBroadbandModemFoxconnT77w968Private { + FeatureSupport unmanaged_gps_support; +}; + +/*****************************************************************************/ +/* Firmware update settings + * + * We only support reporting firmware update settings when QMI support is built, + * because this is the only clean way to get the expected firmware version to + * report. + */ + +#if defined WITH_QMI + +static MMFirmwareUpdateSettings * +firmware_load_update_settings_finish (MMIfaceModemFirmware *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_pointer (G_TASK (res), error); +} + +static void +foxconn_get_firmware_version_ready (QmiClientDms *client, + GAsyncResult *res, + GTask *task) +{ + QmiMessageDmsFoxconnGetFirmwareVersionOutput *output; + GError *error = NULL; + MMFirmwareUpdateSettings *update_settings = NULL; + const gchar *str; + + output = qmi_client_dms_foxconn_get_firmware_version_finish (client, res, &error); + if (!output || !qmi_message_dms_foxconn_get_firmware_version_output_get_result (output, &error)) + goto out; + + /* Create update settings now */ + update_settings = mm_firmware_update_settings_new (MM_MODEM_FIRMWARE_UPDATE_METHOD_FASTBOOT | + MM_MODEM_FIRMWARE_UPDATE_METHOD_QMI_PDC); + mm_firmware_update_settings_set_fastboot_at (update_settings, "AT^FASTBOOT"); + + qmi_message_dms_foxconn_get_firmware_version_output_get_version (output, &str, NULL); + mm_firmware_update_settings_set_version (update_settings, str); + + out: + if (error) + g_task_return_error (task, error); + else { + g_assert (update_settings); + g_task_return_pointer (task, update_settings, g_object_unref); + } + g_object_unref (task); + if (output) + qmi_message_dms_foxconn_get_firmware_version_output_unref (output); +} + +static void +firmware_load_update_settings (MMIfaceModemFirmware *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + QmiMessageDmsFoxconnGetFirmwareVersionInput *input = NULL; + QmiClient *client = NULL; + + task = g_task_new (self, NULL, callback, user_data); + + client = mm_shared_qmi_peek_client (MM_SHARED_QMI (self), + QMI_SERVICE_DMS, + MM_PORT_QMI_FLAG_DEFAULT, + NULL); + if (!client) { + g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Unable to load T77w968 version info: no QMI DMS client available"); + g_object_unref (task); + return; + } + + input = qmi_message_dms_foxconn_get_firmware_version_input_new (); + qmi_message_dms_foxconn_get_firmware_version_input_set_version_type ( + input, + QMI_DMS_FOXCONN_FIRMWARE_VERSION_TYPE_FIRMWARE_MCFG, + NULL); + qmi_client_dms_foxconn_get_firmware_version ( + QMI_CLIENT_DMS (client), + input, + 10, + NULL, + (GAsyncReadyCallback)foxconn_get_firmware_version_ready, + task); + qmi_message_dms_foxconn_get_firmware_version_input_unref (input); +} + +#endif + +/*****************************************************************************/ +/* Location capabilities loading (Location interface) */ + +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 +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; + } + + /* If we have a GPS port and an AT port, enable unmanaged GPS support */ + if (mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)) && + mm_base_modem_peek_port_gps (MM_BASE_MODEM (self))) { + MM_BROADBAND_MODEM_FOXCONN_T77W968 (self)->priv->unmanaged_gps_support = FEATURE_SUPPORTED; + sources |= MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED; + } + + /* So we're done, complete */ + g_task_return_int (task, sources); + g_object_unref (task); +} + +static void +location_load_capabilities (MMIfaceModemLocation *self, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (self, NULL, callback, user_data); + + /* Chain up parent's setup */ + iface_modem_location_parent->load_capabilities (self, + (GAsyncReadyCallback)parent_load_capabilities_ready, + task); +} + +/*****************************************************************************/ +/* Disable location gathering (Location interface) */ + +static gboolean +disable_location_gathering_finish (MMIfaceModemLocation *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +parent_disable_location_gathering_ready (MMIfaceModemLocation *self, + GAsyncResult *res, + GTask *task) +{ + GError *error = NULL; + + if (!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); +} + +static void +parent_disable_location_gathering (GTask *task) +{ + MMIfaceModemLocation *self; + MMModemLocationSource source; + + self = MM_IFACE_MODEM_LOCATION (g_task_get_source_object (task)); + source = GPOINTER_TO_UINT (g_task_get_task_data (task)); + + iface_modem_location_parent->disable_location_gathering (self, + source, + (GAsyncReadyCallback)parent_disable_location_gathering_ready, + task); +} + +static void +unmanaged_gps_disabled_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); + g_object_unref (task); + return; + } + + parent_disable_location_gathering (task); +} + +static void +disable_location_gathering (MMIfaceModemLocation *_self, + MMModemLocationSource source, + GAsyncReadyCallback callback, + gpointer user_data) +{ + MMBroadbandModemFoxconnT77w968 *self = MM_BROADBAND_MODEM_FOXCONN_T77W968 (_self); + GTask *task; + + task = g_task_new (self, NULL, callback, user_data); + g_task_set_task_data (task, GUINT_TO_POINTER (source), NULL); + + /* We only support Unmanaged GPS at this level */ + if ((self->priv->unmanaged_gps_support != FEATURE_SUPPORTED) || + (source != MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) { + parent_disable_location_gathering (task); + return; + } + + mm_base_modem_at_command (MM_BASE_MODEM (_self), + "^NV=30007,01,\"00\"", + 3, + FALSE, + (GAsyncReadyCallback)unmanaged_gps_disabled_ready, + task); +} + +/*****************************************************************************/ +/* Enable location gathering (Location interface) */ + +static gboolean +enable_location_gathering_finish (MMIfaceModemLocation *self, + GAsyncResult *res, + GError **error) +{ + return g_task_propagate_boolean (G_TASK (res), error); +} + +static void +unmanaged_gps_enabled_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 +parent_enable_location_gathering_ready (MMIfaceModemLocation *_self, + GAsyncResult *res, + GTask *task) +{ + MMBroadbandModemFoxconnT77w968 *self = MM_BROADBAND_MODEM_FOXCONN_T77W968 (_self); + GError *error = NULL; + MMModemLocationSource source; + + if (!iface_modem_location_parent->enable_location_gathering_finish (_self, res, &error)) { + g_task_return_error (task, error); + g_object_unref (task); + return; + } + + /* We only support Unmanaged GPS at this level */ + source = GPOINTER_TO_UINT (g_task_get_task_data (task)); + if ((self->priv->unmanaged_gps_support != FEATURE_SUPPORTED) || + (source != MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) { + g_task_return_boolean (task, TRUE); + g_object_unref (task); + return; + } + + mm_base_modem_at_command (MM_BASE_MODEM (_self), + "^NV=30007,01,\"01\"", + 3, + FALSE, + (GAsyncReadyCallback)unmanaged_gps_enabled_ready, + task); +} + +static void +enable_location_gathering (MMIfaceModemLocation *self, + MMModemLocationSource source, + GAsyncReadyCallback callback, + gpointer user_data) +{ + GTask *task; + + task = g_task_new (self, NULL, callback, user_data); + g_task_set_task_data (task, GUINT_TO_POINTER (source), NULL); + + /* Chain up parent's gathering enable */ + iface_modem_location_parent->enable_location_gathering (self, + source, + (GAsyncReadyCallback)parent_enable_location_gathering_ready, + task); +} + +/*****************************************************************************/ + +MMBroadbandModemFoxconnT77w968 * +mm_broadband_modem_foxconn_t77w968_new (const gchar *device, + const gchar **drivers, + const gchar *plugin, + guint16 vendor_id, + guint16 product_id) +{ + return g_object_new (MM_TYPE_BROADBAND_MODEM_FOXCONN_T77W968, + 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_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED, TRUE, + MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED, FALSE, + MM_IFACE_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED, TRUE, + MM_IFACE_MODEM_LOCATION_ALLOW_GPS_UNMANAGED_ALWAYS, TRUE, + MM_IFACE_MODEM_CARRIER_CONFIG_MAPPING, PKGDATADIR "/mm-foxconn-t77w968-carrier-mapping.conf", + NULL); +} + +static void +mm_broadband_modem_foxconn_t77w968_init (MMBroadbandModemFoxconnT77w968 *self) +{ + /* Initialize private data */ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_BROADBAND_MODEM_FOXCONN_T77W968, MMBroadbandModemFoxconnT77w968Private); + self->priv->unmanaged_gps_support = FEATURE_SUPPORT_UNKNOWN; +} + +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; +} + +#if defined WITH_QMI + +static void +iface_modem_firmware_init (MMIfaceModemFirmware *iface) +{ + iface->load_update_settings = firmware_load_update_settings; + iface->load_update_settings_finish = firmware_load_update_settings_finish; +} + +#endif + +static void +mm_broadband_modem_foxconn_t77w968_class_init (MMBroadbandModemFoxconnT77w968Class *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMBroadbandModemFoxconnT77w968Private)); +} diff --git a/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.h b/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.h new file mode 100644 index 00000000..9d145033 --- /dev/null +++ b/plugins/foxconn/mm-broadband-modem-foxconn-t77w968.h @@ -0,0 +1,49 @@ +/* -*- 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-2019 Aleksander Morgado <aleksander@aleksander.es> + */ + +#ifndef MM_BROADBAND_MODEM_FOXCONN_T77W968_H +#define MM_BROADBAND_MODEM_FOXCONN_T77W968_H + +#include "mm-broadband-modem-mbim.h" + +#define MM_TYPE_BROADBAND_MODEM_FOXCONN_T77W968 (mm_broadband_modem_foxconn_t77w968_get_type ()) +#define MM_BROADBAND_MODEM_FOXCONN_T77W968(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_BROADBAND_MODEM_FOXCONN_T77W968, MMBroadbandModemFoxconnT77w968)) +#define MM_BROADBAND_MODEM_FOXCONN_T77W968_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_BROADBAND_MODEM_FOXCONN_T77W968, MMBroadbandModemFoxconnT77w968Class)) +#define MM_IS_BROADBAND_MODEM_FOXCONN_T77W968(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_BROADBAND_MODEM_FOXCONN_T77W968)) +#define MM_IS_BROADBAND_MODEM_FOXCONN_T77W968_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_BROADBAND_MODEM_FOXCONN_T77W968)) +#define MM_BROADBAND_MODEM_FOXCONN_T77W968_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_BROADBAND_MODEM_FOXCONN_T77W968, MMBroadbandModemFoxconnT77w968Class)) + +typedef struct _MMBroadbandModemFoxconnT77w968 MMBroadbandModemFoxconnT77w968; +typedef struct _MMBroadbandModemFoxconnT77w968Class MMBroadbandModemFoxconnT77w968Class; +typedef struct _MMBroadbandModemFoxconnT77w968Private MMBroadbandModemFoxconnT77w968Private; + +struct _MMBroadbandModemFoxconnT77w968 { + MMBroadbandModemMbim parent; + MMBroadbandModemFoxconnT77w968Private *priv; +}; + +struct _MMBroadbandModemFoxconnT77w968Class{ + MMBroadbandModemMbimClass parent; +}; + +GType mm_broadband_modem_foxconn_t77w968_get_type (void); + +MMBroadbandModemFoxconnT77w968 *mm_broadband_modem_foxconn_t77w968_new (const gchar *device, + const gchar **driver, + const gchar *plugin, + guint16 vendor_id, + guint16 product_id); + +#endif /* MM_BROADBAND_MODEM_FOXCONN_T77W968_H */ diff --git a/plugins/foxconn/mm-foxconn-t77w968-carrier-mapping.conf b/plugins/foxconn/mm-foxconn-t77w968-carrier-mapping.conf new file mode 100644 index 00000000..20639f73 --- /dev/null +++ b/plugins/foxconn/mm-foxconn-t77w968-carrier-mapping.conf @@ -0,0 +1,281 @@ + +# +# T77W968 carrier mapping table +# +# This table maps the MCCMNC of the SIM card with the corresponding +# configuration description as reported by the QMI PDC service in +# this module. +# + +[foxconn t77w968] + +# AT&T +302220=ATT +302221=ATT +31030=ATT +31070=ATT +31090=ATT +310150=ATT +310170=ATT +310280=ATT +310380=ATT +310410=ATT +310560=ATT +310680=ATT +311180=ATT + +# FirstNet +312670=A2 +313100=A2 +313110=A2 +313120=A2 +313130=A2 +313140=A2 + +# Verizon +310590=Verizon +310890=Verizon +311270=Verizon +311480=Verizon + +# Vodafone +20205=Vodafone +20404=Vodafone +20601=Vodafone +20810=Vodafone +21401=Vodafone +21670=Vodafone +21910=Vodafone +22005=Vodafone +22210=Vodafone +22601=Vodafone +23003=Vodafone +23201=Vodafone +23415=Vodafone +23801=Vodafone +24405=Vodafone +24602=Vodafone +24705=Vodafone +24802=Vodafone +25001=Vodafone +26202=Vodafone +26209=Vodafone +26801=Vodafone +27077=Vodafone +27201=Vodafone +27402=Vodafone +27602=Vodafone +27801=Vodafone +28001=Vodafone +28401=Vodafone +28602=Vodafone +28802=Vodafone +29340=Vodafone +29403=Vodafone +40004=Vodafone +40401=Vodafone +40405=Vodafone +40411=Vodafone +40413=Vodafone +40415=Vodafone +40420=Vodafone +40427=Vodafone +40430=Vodafone +40443=Vodafone +40446=Vodafone +40460=Vodafone +40484=Vodafone +40486=Vodafone +40488=Vodafone +40566=Vodafone +40567=Vodafone +405750=Vodafone +405751=Vodafone +405752=Vodafone +405753=Vodafone +405754=Vodafone +405755=Vodafone +405756=Vodafone +41302=Vodafone +42403=Vodafone +42602=Vodafone +42702=Vodafone +50213=Vodafone +50219=Vodafone +50503=Vodafone +52503=Vodafone +52505=Vodafone +53001=Vodafone +54201=Vodafone +60202=Vodafone +62002=Vodafone +63001=Vodafone +63902=Vodafone +64004=Vodafone +64304=Vodafone +64710=Vodafone +65101=Vodafone +65501=Vodafone +73001=Vodafone +90128=Vodafone + +# Orange +20610=Orange +20801=Orange +20802=Orange +21403=Orange +22610=Orange +23101=Orange +23430=Orange +23433=Orange +23434=Orange +25901=Orange +26003=Orange +27099=Orange +28310=Orange + +# Telefonica Movistar +21405=Telefonica +21407=Telefonica + +# Swisscom +22801=Swisscom +29501=Swisscom + +# Telstra +50501=Telstra +50506=Telstra +50571=Telstra +50572=Telstra + +# Sprint +310120=Sprint + +# Optus +50202=Optus + +# NTT DoCoMo +44002=Docomo +44003=Docomo +44009=Docomo +44010=Docomo +44011=Docomo +44012=Docomo +44013=Docomo +44014=Docomo +44015=Docomo +44016=Docomo +44017=Docomo +44018=Docomo +44019=Docomo +44022=Docomo +44023=Docomo +44024=Docomo +44025=Docomo +44026=Docomo +44027=Docomo +44028=Docomo +44029=Docomo +44030=Docomo +44031=Docomo +44032=Docomo +44033=Docomo +44034=Docomo +44035=Docomo +44036=Docomo +44037=Docomo +44038=Docomo +44039=Docomo +44049=Docomo +44058=Docomo +44060=Docomo +44061=Docomo +44062=Docomo +44063=Docomo +44064=Docomo +44065=Docomo +44066=Docomo +44067=Docomo +44068=Docomo +44069=Docomo +44087=Docomo +44099=Docomo +44140=Docomo +44141=Docomo +44142=Docomo +44143=Docomo +44144=Docomo +44145=Docomo +44190=Docomo +44101=Docomo +44192=Docomo +44193=Docomo +44194=Docomo +44198=Docomo +44199=Docomo + +# KDDI +44007=KDDI +44008=KDDI +44050=KDDI +44051=KDDI +44052=KDDI +44053=KDDI +44054=KDDI +44055=KDDI +44056=KDDI +44070=KDDI +44071=KDDI +44072=KDDI +44073=KDDI +44074=KDDI +44075=KDDI +44076=KDDI +44077=KDDI +44078=KDDI +44079=KDDI +44080=KDDI +44081=KDDI +44082=KDDI +44083=KDDI +44084=KDDI +44085=KDDI +44086=KDDI +44088=KDDI +44089=KDDI +44150=KDDI +44151=KDDI +44170=KDDI + +# SoftBank +44000=SBM +44004=SBM +44006=SBM +44020=SBM +44021=SBM +44040=SBM +44041=SBM +44042=SBM +44043=SBM +44044=SBM +44045=SBM +44046=SBM +44047=SBM +44048=SBM +44090=SBM +44092=SBM +44093=SBM +44094=SBM +44095=SBM +44096=SBM +44097=SBM +44098=SBM +44101=SBM +44161=SBM +44162=SBM +44163=SBM +44164=SBM +44165=SBM + +# Others +generic=GCF diff --git a/plugins/foxconn/mm-plugin-foxconn.c b/plugins/foxconn/mm-plugin-foxconn.c new file mode 100644 index 00000000..5bd2f886 --- /dev/null +++ b/plugins/foxconn/mm-plugin-foxconn.c @@ -0,0 +1,127 @@ +/* -*- 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. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es> + */ + +#include <string.h> +#include <gmodule.h> + +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#include "mm-plugin-foxconn.h" +#include "mm-log.h" +#include "mm-broadband-modem.h" + +#if defined WITH_QMI +#include "mm-broadband-modem-qmi.h" +#endif + +#if defined WITH_MBIM +#include "mm-broadband-modem-foxconn-t77w968.h" +#endif + +G_DEFINE_TYPE (MMPluginFoxconn, mm_plugin_foxconn, 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, + GList *probes, + GError **error) +{ +#if defined WITH_QMI + if (mm_port_probe_list_has_qmi_port (probes)) { + mm_dbg ("QMI-powered Foxconn-branded 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)) { + /* Specific implementation for the T77W968 */ + if (product == 0xe0b4 || product == 0xe0b5) { + mm_dbg ("MBIM-powered T77W968 modem found..."); + return MM_BASE_MODEM (mm_broadband_modem_foxconn_t77w968_new (uid, + drivers, + mm_plugin_get_name (self), + vendor, + product)); + } + + mm_dbg ("MBIM-powered Foxconn-branded modem found..."); + return MM_BASE_MODEM (mm_broadband_modem_mbim_new (uid, + drivers, + mm_plugin_get_name (self), + vendor, + product)); + } +#endif + + mm_dbg ("Foxconn-branded generic modem found..."); + return MM_BASE_MODEM (mm_broadband_modem_new (uid, + drivers, + mm_plugin_get_name (self), + vendor, + product)); +} + +/*****************************************************************************/ + +G_MODULE_EXPORT MMPlugin * +mm_plugin_create (void) +{ + static const gchar *subsystems[] = { "tty", "net", "usb", NULL }; + static const guint16 vendors[] = { 0x0489, 0 }; + + return MM_PLUGIN ( + g_object_new (MM_TYPE_PLUGIN_FOXCONN, + MM_PLUGIN_NAME, "Foxconn", + MM_PLUGIN_ALLOWED_SUBSYSTEMS, subsystems, + MM_PLUGIN_ALLOWED_VENDOR_IDS, vendors, + MM_PLUGIN_ALLOWED_AT, TRUE, + MM_PLUGIN_ALLOWED_QCDM, TRUE, + MM_PLUGIN_ALLOWED_QMI, TRUE, + MM_PLUGIN_ALLOWED_MBIM, TRUE, + NULL)); +} + +static void +mm_plugin_foxconn_init (MMPluginFoxconn *self) +{ +} + +static void +mm_plugin_foxconn_class_init (MMPluginFoxconnClass *klass) +{ + MMPluginClass *plugin_class = MM_PLUGIN_CLASS (klass); + + plugin_class->create_modem = create_modem; +} diff --git a/plugins/foxconn/mm-plugin-foxconn.h b/plugins/foxconn/mm-plugin-foxconn.h new file mode 100644 index 00000000..4a22ceeb --- /dev/null +++ b/plugins/foxconn/mm-plugin-foxconn.h @@ -0,0 +1,46 @@ +/* -*- 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. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Copyright (C) 2019 Aleksander Morgado <aleksander@aleksander.es> + */ + +#ifndef MM_PLUGIN_FOXCONN_H +#define MM_PLUGIN_FOXCONN_H + +#include "mm-plugin.h" + +#define MM_TYPE_PLUGIN_FOXCONN (mm_plugin_foxconn_get_type ()) +#define MM_PLUGIN_FOXCONN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_PLUGIN_FOXCONN, MMPluginFoxconn)) +#define MM_PLUGIN_FOXCONN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_PLUGIN_FOXCONN, MMPluginFoxconnClass)) +#define MM_IS_PLUGIN_FOXCONN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_PLUGIN_FOXCONN)) +#define MM_IS_PLUGIN_FOXCONN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PLUGIN_FOXCONN)) +#define MM_PLUGIN_FOXCONN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PLUGIN_FOXCONN, MMPluginFoxconnClass)) + +typedef struct { + MMPlugin parent; +} MMPluginFoxconn; + +typedef struct { + MMPluginClass parent; +} MMPluginFoxconnClass; + +GType mm_plugin_foxconn_get_type (void); + +G_MODULE_EXPORT MMPlugin *mm_plugin_create (void); + +#endif /* MM_PLUGIN_FOXCONN_H */ |