diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-iface-modem.c | 113 | ||||
-rw-r--r-- | src/mm-iface-modem.h | 19 |
2 files changed, 132 insertions, 0 deletions
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); |