aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mm-iface-modem.c113
-rw-r--r--src/mm-iface-modem.h19
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);