aboutsummaryrefslogtreecommitdiff
path: root/src/mm-iface-modem.c
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2018-12-18 14:52:44 +0100
committerAleksander Morgado <aleksander@aleksander.es>2019-04-02 12:11:25 +0200
commit94cf7f0ceb8c00a413d279a1fbdb491c01240d81 (patch)
tree5b5111e0c2c0f7d4e1fcb3b66e9219f7a2e285fc /src/mm-iface-modem.c
parentb8daedd3c015e150955d2063b9e79589640693e5 (diff)
iface-modem: new carrier config support
During initialization phase we will allow querying the modem for the details of which carrier-specific configuration is being used, and will expose a description string in the API. In addition to showing the current configuration, we will also allow automatically switching the configuration based on the SIM card detected in the device. In order to allow this, plugins/modems will need to provide the expected mapping between carrier config description and MCCMNC. This mapping cannot be generic, because different manufacturers may use different description strings.
Diffstat (limited to 'src/mm-iface-modem.c')
-rw-r--r--src/mm-iface-modem.c113
1 files changed, 113 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;
}