diff options
-rw-r--r-- | cli/mmcli-modem.c | 1 | ||||
-rw-r--r-- | cli/mmcli-output.c | 1 | ||||
-rw-r--r-- | cli/mmcli-output.h | 1 | ||||
-rw-r--r-- | docs/reference/libmm-glib/libmm-glib-sections.txt | 5 | ||||
-rw-r--r-- | introspection/org.freedesktop.ModemManager1.Modem.xml | 7 | ||||
-rw-r--r-- | libmm-glib/mm-modem.c | 41 | ||||
-rw-r--r-- | libmm-glib/mm-modem.h | 3 | ||||
-rw-r--r-- | src/mm-iface-modem.c | 113 | ||||
-rw-r--r-- | src/mm-iface-modem.h | 19 |
9 files changed, 191 insertions, 0 deletions
diff --git a/cli/mmcli-modem.c b/cli/mmcli-modem.c index 9c964294..5d3c2713 100644 --- a/cli/mmcli-modem.c +++ b/cli/mmcli-modem.c @@ -351,6 +351,7 @@ print_modem_info (void) mmcli_output_string (MMC_F_HARDWARE_MANUFACTURER, mm_modem_get_manufacturer (ctx->modem)); mmcli_output_string (MMC_F_HARDWARE_MODEL, mm_modem_get_model (ctx->modem)); mmcli_output_string (MMC_F_HARDWARE_REVISION, mm_modem_get_revision (ctx->modem)); + mmcli_output_string (MMC_F_HARDWARE_CARRIER_CONFIGURATION, mm_modem_get_carrier_configuration (ctx->modem)); mmcli_output_string (MMC_F_HARDWARE_HW_REVISION, mm_modem_get_hardware_revision (ctx->modem)); mmcli_output_string_multiline (MMC_F_HARDWARE_SUPPORTED_CAPABILITIES, supported_capabilities_string); mmcli_output_string_multiline (MMC_F_HARDWARE_CURRENT_CAPABILITIES, current_capabilities_string); diff --git a/cli/mmcli-output.c b/cli/mmcli-output.c index 5822ff51..33819feb 100644 --- a/cli/mmcli-output.c +++ b/cli/mmcli-output.c @@ -97,6 +97,7 @@ static FieldInfo field_infos[] = { [MMC_F_HARDWARE_MANUFACTURER] = { "modem.generic.manufacturer", "manufacturer", MMC_S_MODEM_HARDWARE, }, [MMC_F_HARDWARE_MODEL] = { "modem.generic.model", "model", MMC_S_MODEM_HARDWARE, }, [MMC_F_HARDWARE_REVISION] = { "modem.generic.revision", "revision", MMC_S_MODEM_HARDWARE, }, + [MMC_F_HARDWARE_CARRIER_CONFIGURATION] = { "modem.generic.carrier-configuration", "carrier config", MMC_S_MODEM_HARDWARE, }, [MMC_F_HARDWARE_HW_REVISION] = { "modem.generic.hardware-revision", "h/w revision", MMC_S_MODEM_HARDWARE, }, [MMC_F_HARDWARE_SUPPORTED_CAPABILITIES] = { "modem.generic.supported-capabilities", "supported", MMC_S_MODEM_HARDWARE, }, [MMC_F_HARDWARE_CURRENT_CAPABILITIES] = { "modem.generic.current-capabilities", "current", MMC_S_MODEM_HARDWARE, }, diff --git a/cli/mmcli-output.h b/cli/mmcli-output.h index 4a9a9c46..75533b00 100644 --- a/cli/mmcli-output.h +++ b/cli/mmcli-output.h @@ -91,6 +91,7 @@ typedef enum { MMC_F_HARDWARE_MANUFACTURER, MMC_F_HARDWARE_MODEL, MMC_F_HARDWARE_REVISION, + MMC_F_HARDWARE_CARRIER_CONFIGURATION, MMC_F_HARDWARE_HW_REVISION, MMC_F_HARDWARE_SUPPORTED_CAPABILITIES, MMC_F_HARDWARE_CURRENT_CAPABILITIES, diff --git a/docs/reference/libmm-glib/libmm-glib-sections.txt b/docs/reference/libmm-glib/libmm-glib-sections.txt index 41f3b0d6..40558684 100644 --- a/docs/reference/libmm-glib/libmm-glib-sections.txt +++ b/docs/reference/libmm-glib/libmm-glib-sections.txt @@ -137,6 +137,8 @@ mm_modem_get_model mm_modem_dup_model mm_modem_get_revision mm_modem_dup_revision +mm_modem_get_carrier_configuration +mm_modem_dup_carrier_configuration mm_modem_get_hardware_revision mm_modem_dup_hardware_revision mm_modem_get_drivers @@ -2022,6 +2024,8 @@ mm_gdbus_modem_get_ports mm_gdbus_modem_dup_ports mm_gdbus_modem_get_revision mm_gdbus_modem_dup_revision +mm_gdbus_modem_get_carrier_configuration +mm_gdbus_modem_dup_carrier_configuration mm_gdbus_modem_get_hardware_revision mm_gdbus_modem_dup_hardware_revision mm_gdbus_modem_get_signal_quality @@ -2093,6 +2097,7 @@ mm_gdbus_modem_set_plugin mm_gdbus_modem_set_primary_port mm_gdbus_modem_set_ports mm_gdbus_modem_set_revision +mm_gdbus_modem_set_carrier_configuration mm_gdbus_modem_set_hardware_revision mm_gdbus_modem_set_signal_quality mm_gdbus_modem_set_sim diff --git a/introspection/org.freedesktop.ModemManager1.Modem.xml b/introspection/org.freedesktop.ModemManager1.Modem.xml index 7ac7cdda..f647d2f0 100644 --- a/introspection/org.freedesktop.ModemManager1.Modem.xml +++ b/introspection/org.freedesktop.ModemManager1.Modem.xml @@ -297,6 +297,13 @@ <property name="Revision" type="s" access="read" /> <!-- + CarrierConfiguration: + + The description of the carrier-specific configuration (MCFG) in use by the modem. + --> + <property name="CarrierConfiguration" type="s" access="read" /> + + <!-- HardwareRevision: The revision identification of the hardware, as reported by the modem. diff --git a/libmm-glib/mm-modem.c b/libmm-glib/mm-modem.c index 80cb280b..d7d59542 100644 --- a/libmm-glib/mm-modem.c +++ b/libmm-glib/mm-modem.c @@ -503,6 +503,47 @@ mm_modem_dup_revision (MMModem *self) /*****************************************************************************/ /** + * mm_modem_get_carrier_configuration: + * @self: A #MMModem. + * + * Gets the carrier-specific configuration (MCFG) in use, as reported by this #MMModem. + * + * <warning>The returned value is only valid until the property changes so + * it is only safe to use this function on the thread where + * @self was constructed. Use mm_modem_dup_carrier_configuration() if on another + * thread.</warning> + * + * Returns: (transfer none): The carrier configuration, or %NULL if none available. Do not free the returned value, it belongs to @self. + */ +const gchar * +mm_modem_get_carrier_configuration (MMModem *self) +{ + g_return_val_if_fail (MM_IS_MODEM (self), NULL); + + RETURN_NON_EMPTY_CONSTANT_STRING ( + mm_gdbus_modem_get_carrier_configuration (MM_GDBUS_MODEM (self))); +} + +/** + * mm_modem_dup_carrier_configuration: + * @self: A #MMModem. + * + * Gets a copy of the carrier-specific configuration (MCFG) in use, as reported by this #MMModem. + * + * Returns: (transfer full): The carrier configuration, or %NULL if none available. The returned value should be freed with g_free(). + */ +gchar * +mm_modem_dup_carrier_configuration (MMModem *self) +{ + g_return_val_if_fail (MM_IS_MODEM (self), NULL); + + RETURN_NON_EMPTY_STRING ( + mm_gdbus_modem_dup_carrier_configuration (MM_GDBUS_MODEM (self))); +} + +/*****************************************************************************/ + +/** * mm_modem_get_hardware_revision: * @self: A #MMModem. * diff --git a/libmm-glib/mm-modem.h b/libmm-glib/mm-modem.h index 1b51b6c3..95719d6a 100644 --- a/libmm-glib/mm-modem.h +++ b/libmm-glib/mm-modem.h @@ -103,6 +103,9 @@ gchar *mm_modem_dup_model (MMModem *self); const gchar *mm_modem_get_revision (MMModem *self); gchar *mm_modem_dup_revision (MMModem *self); +const gchar *mm_modem_get_carrier_configuration (MMModem *self); +gchar *mm_modem_dup_carrier_configuration (MMModem *self); + const gchar *mm_modem_get_hardware_revision (MMModem *self); gchar *mm_modem_dup_hardware_revision (MMModem *self); diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c index 1ffcb967..9befbddb 100644 --- a/src/mm-iface-modem.c +++ b/src/mm-iface-modem.c @@ -3942,6 +3942,7 @@ typedef enum { INITIALIZATION_STEP_MANUFACTURER, INITIALIZATION_STEP_MODEL, INITIALIZATION_STEP_REVISION, + INITIALIZATION_STEP_CARRIER_CONFIG, INITIALIZATION_STEP_HARDWARE_REVISION, INITIALIZATION_STEP_EQUIPMENT_ID, INITIALIZATION_STEP_DEVICE_ID, @@ -3952,6 +3953,7 @@ typedef enum { INITIALIZATION_STEP_SIM_HOT_SWAP, INITIALIZATION_STEP_UNLOCK_REQUIRED, INITIALIZATION_STEP_SIM, + INITIALIZATION_STEP_SETUP_CARRIER_CONFIG, INITIALIZATION_STEP_OWN_NUMBERS, INITIALIZATION_STEP_CURRENT_MODES, INITIALIZATION_STEP_CURRENT_BANDS, @@ -4334,6 +4336,51 @@ sim_reinit_ready (MMBaseSim *sim, interface_initialization_step (task); } +static void +setup_carrier_config_ready (MMIfaceModem *self, + GAsyncResult *res, + GTask *task) +{ + InitializationContext *ctx; + GError *error = NULL; + + ctx = g_task_get_task_data (task); + + if (!MM_IFACE_MODEM_GET_INTERFACE (self)->setup_carrier_config_finish (self, res, &error)) { + mm_warn ("couldn't setup carrier config: '%s'", error->message); + g_error_free (error); + } + + /* Go on to next step */ + ctx->step++; + interface_initialization_step (task); +} + +static void +load_carrier_config_ready (MMIfaceModem *self, + GAsyncResult *res, + GTask *task) +{ + InitializationContext *ctx; + GError *error = NULL; + gchar *carrier_configuration; + + ctx = g_task_get_task_data (task); + + carrier_configuration = MM_IFACE_MODEM_GET_INTERFACE (self)->load_carrier_config_finish (self, res, &error); + if (!carrier_configuration) { + mm_warn ("couldn't load carrier config: '%s'", error->message); + g_error_free (error); + } else { + mm_gdbus_modem_set_carrier_configuration (ctx->skeleton, carrier_configuration); + g_free (carrier_configuration); + } + + /* Go on to next step */ + ctx->step++; + interface_initialization_step (task); +} + void mm_iface_modem_update_own_numbers (MMIfaceModem *self, const GStrv own_numbers) @@ -4700,6 +4747,21 @@ interface_initialization_step (GTask *task) /* Fall down to next step */ ctx->step++; + case INITIALIZATION_STEP_CARRIER_CONFIG: + /* Current carrier config is meant to be loaded only once during the whole + * lifetime of the modem. Therefore, if we already have them loaded, + * don't try to load them again. */ + if (mm_gdbus_modem_get_carrier_configuration (ctx->skeleton) == NULL && + MM_IFACE_MODEM_GET_INTERFACE (self)->load_carrier_config && + MM_IFACE_MODEM_GET_INTERFACE (self)->load_carrier_config_finish) { + MM_IFACE_MODEM_GET_INTERFACE (self)->load_carrier_config (self, + (GAsyncReadyCallback)load_carrier_config_ready, + task); + return; + } + /* Fall down to next step */ + ctx->step++; + case INITIALIZATION_STEP_HARDWARE_REVISION: /* HardwareRevision is meant to be loaded only once during the whole * lifetime of the modem. Therefore, if we already have them loaded, @@ -4899,6 +4961,49 @@ interface_initialization_step (GTask *task) /* Fall down to next step */ ctx->step++; + case INITIALIZATION_STEP_SETUP_CARRIER_CONFIG: + /* Setup and perform automatic carrier config switching as soon as the + * SIM initialization has been performed, only applicable if there is + * actually a SIM found with a valid IMSI read */ + if (!mm_iface_modem_is_cdma_only (self) && + MM_IFACE_MODEM_GET_INTERFACE (self)->setup_carrier_config && + MM_IFACE_MODEM_GET_INTERFACE (self)->setup_carrier_config_finish) { + MMBaseSim *sim = NULL; + gchar *carrier_config_mapping = NULL; + + g_object_get (self, + MM_IFACE_MODEM_SIM, &sim, + MM_IFACE_MODEM_CARRIER_CONFIG_MAPPING, &carrier_config_mapping, + NULL); + + /* If we have a SIM object, and carrier config switching is supported, + * validate whether we're already using the best config or not. */ + if (!sim) + mm_dbg ("not setting up carrier config: SIM not found"); + else if (!carrier_config_mapping) + mm_dbg ("not setting up carrier config: mapping file not configured"); + else { + const gchar *imsi; + + imsi = mm_gdbus_sim_get_imsi (MM_GDBUS_SIM (sim)); + if (imsi) { + MM_IFACE_MODEM_GET_INTERFACE (self)->setup_carrier_config (self, + imsi, + carrier_config_mapping, + (GAsyncReadyCallback)setup_carrier_config_ready, + task); + g_object_unref (sim); + g_free (carrier_config_mapping); + return; + } + mm_warn ("couldn't setup carrier config: unknown IMSI"); + } + g_clear_object (&sim); + g_free (carrier_config_mapping); + } + /* Fall down to next step */ + ctx->step++; + case INITIALIZATION_STEP_OWN_NUMBERS: /* Own numbers is meant to be loaded only once during the whole * lifetime of the modem. Therefore, if we already have them loaded, @@ -5415,6 +5520,14 @@ iface_modem_init (gpointer g_iface) FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_interface_install_property + (g_iface, + g_param_spec_string (MM_IFACE_MODEM_CARRIER_CONFIG_MAPPING, + "Carrier config mapping table", + "Path to the file including the carrier mapping for the module", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + initialized = TRUE; } diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h index 5b1c891d..cb7a75ed 100644 --- a/src/mm-iface-modem.h +++ b/src/mm-iface-modem.h @@ -39,6 +39,7 @@ #define MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED "iface-modem-sim-hot-swap-supported" #define MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED "iface-modem-sim-hot-swap-configured" #define MM_IFACE_MODEM_PERIODIC_SIGNAL_CHECK_DISABLED "iface-modem-periodic-signal-check-disabled" +#define MM_IFACE_MODEM_CARRIER_CONFIG_MAPPING "iface-modem-carrier-config-mapping" typedef struct _MMIfaceModem MMIfaceModem; @@ -356,6 +357,24 @@ struct _MMIfaceModem { gboolean (*setup_sim_hot_swap_finish) (MMIfaceModem *self, GAsyncResult *res, GError **error); + + /* Load carrier config */ + void (* load_carrier_config) (MMIfaceModem *self, + GAsyncReadyCallback callback, + gpointer user_data); + gchar * (* load_carrier_config_finish) (MMIfaceModem *self, + GAsyncResult *res, + GError **error); + + /* Setup carrier config based on IMSI */ + void (* setup_carrier_config) (MMIfaceModem *self, + const gchar *imsi, + const gchar *carrier_config_mapping, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (* setup_carrier_config_finish) (MMIfaceModem *self, + GAsyncResult *res, + GError **error); }; GType mm_iface_modem_get_type (void); |