cinterion: Add SIM hot swap to AT broadband modems (PLS8 & PLAS9).
Enable the SCKS Unsolicited Result Code (URC) to detect SIM hot swap, and trigger SIM redetection.
This commit is contained in:

committed by
Aleksander Morgado

parent
b1679b5893
commit
7f39c16c8c
@@ -92,6 +92,8 @@ struct _MMBroadbandModemCinterionPrivate {
|
|||||||
GRegex *sysstart_regex;
|
GRegex *sysstart_regex;
|
||||||
/* +CIEV indications as configured via AT^SIND */
|
/* +CIEV indications as configured via AT^SIND */
|
||||||
GRegex *ciev_regex;
|
GRegex *ciev_regex;
|
||||||
|
/* Ignore SIM hotswap SCKS msg, until ready */
|
||||||
|
GRegex *scks_regex;
|
||||||
|
|
||||||
/* Flags for feature support checks */
|
/* Flags for feature support checks */
|
||||||
FeatureSupport swwan_support;
|
FeatureSupport swwan_support;
|
||||||
@@ -2356,6 +2358,107 @@ after_sim_unlock (MMIfaceModem *self,
|
|||||||
task);
|
task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Setup SIM hot swap (Modem interface) */
|
||||||
|
|
||||||
|
static void
|
||||||
|
cinterion_scks_unsolicited_handler (MMPortSerialAt *port,
|
||||||
|
GMatchInfo *match_info,
|
||||||
|
MMBroadbandModemCinterion *self)
|
||||||
|
{
|
||||||
|
guint scks;
|
||||||
|
|
||||||
|
if (!mm_get_uint_from_match_info (match_info, 1, &scks))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (scks) {
|
||||||
|
case 0:
|
||||||
|
mm_obj_info (self, "SIM removal detected");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
mm_obj_info (self, "SIM insertion detected");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
mm_obj_info (self, "SIM interface hardware deactivated (Potentially non-electrically compatible SIM inserted)");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
mm_obj_info (self, "SIM interface hardware deactivated (Technical problem, no precise diagnosis)");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_broadband_modem_sim_hot_swap_detected (MM_BROADBAND_MODEM (self));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
modem_setup_sim_hot_swap_finish (MMIfaceModem *self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
return g_task_propagate_boolean (G_TASK (res), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cinterion_hot_swap_init_ready (MMBaseModem *_self,
|
||||||
|
GAsyncResult *res,
|
||||||
|
GTask *task)
|
||||||
|
{
|
||||||
|
MMBroadbandModemCinterion *self = MM_BROADBAND_MODEM_CINTERION (_self);
|
||||||
|
GError *error = NULL;
|
||||||
|
MMPortSerialAt *primary;
|
||||||
|
MMPortSerialAt *secondary;
|
||||||
|
|
||||||
|
if (!mm_base_modem_at_command_finish (_self, res, &error)) {
|
||||||
|
g_prefix_error (&error, "Could not enable SCKS: ");
|
||||||
|
g_task_return_error (task, error);
|
||||||
|
g_object_unref (task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mm_obj_dbg (self, "SIM hot swap detect successfully enabled");
|
||||||
|
|
||||||
|
primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
|
||||||
|
mm_port_serial_at_add_unsolicited_msg_handler (
|
||||||
|
primary,
|
||||||
|
self->priv->scks_regex,
|
||||||
|
(MMPortSerialAtUnsolicitedMsgFn) cinterion_scks_unsolicited_handler,
|
||||||
|
self,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
|
||||||
|
if (secondary)
|
||||||
|
mm_port_serial_at_add_unsolicited_msg_handler (
|
||||||
|
secondary,
|
||||||
|
self->priv->scks_regex,
|
||||||
|
(MMPortSerialAtUnsolicitedMsgFn) cinterion_scks_unsolicited_handler,
|
||||||
|
self,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_task_return_boolean (task, TRUE);
|
||||||
|
g_object_unref (task);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
modem_setup_sim_hot_swap (MMIfaceModem *self,
|
||||||
|
GAsyncReadyCallback callback,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GTask *task;
|
||||||
|
|
||||||
|
mm_obj_dbg (self, "Enabling SCKS URCs for SIM hot swap detection");
|
||||||
|
|
||||||
|
task = g_task_new (self, NULL, callback, user_data);
|
||||||
|
|
||||||
|
mm_base_modem_at_command (MM_BASE_MODEM (self),
|
||||||
|
"^SCKS=1",
|
||||||
|
3,
|
||||||
|
FALSE,
|
||||||
|
(GAsyncReadyCallback) cinterion_hot_swap_init_ready,
|
||||||
|
task);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Create Bearer (Modem interface) */
|
/* Create Bearer (Modem interface) */
|
||||||
|
|
||||||
@@ -2502,6 +2605,8 @@ mm_broadband_modem_cinterion_new (const gchar *device,
|
|||||||
MM_BASE_MODEM_PLUGIN, plugin,
|
MM_BASE_MODEM_PLUGIN, plugin,
|
||||||
MM_BASE_MODEM_VENDOR_ID, vendor_id,
|
MM_BASE_MODEM_VENDOR_ID, vendor_id,
|
||||||
MM_BASE_MODEM_PRODUCT_ID, product_id,
|
MM_BASE_MODEM_PRODUCT_ID, product_id,
|
||||||
|
MM_IFACE_MODEM_SIM_HOT_SWAP_SUPPORTED, TRUE,
|
||||||
|
MM_IFACE_MODEM_SIM_HOT_SWAP_CONFIGURED, FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2523,6 +2628,8 @@ mm_broadband_modem_cinterion_init (MMBroadbandModemCinterion *self)
|
|||||||
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||||
self->priv->sysstart_regex = g_regex_new ("\\r\\n\\^SYSSTART.*\\r\\n",
|
self->priv->sysstart_regex = g_regex_new ("\\r\\n\\^SYSSTART.*\\r\\n",
|
||||||
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||||
|
self->priv->scks_regex = g_regex_new ("\\^SCKS:\\s*([0-3])\\r\\n",
|
||||||
|
G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2545,6 +2652,7 @@ finalize (GObject *object)
|
|||||||
|
|
||||||
g_regex_unref (self->priv->ciev_regex);
|
g_regex_unref (self->priv->ciev_regex);
|
||||||
g_regex_unref (self->priv->sysstart_regex);
|
g_regex_unref (self->priv->sysstart_regex);
|
||||||
|
g_regex_unref (self->priv->scks_regex);
|
||||||
|
|
||||||
G_OBJECT_CLASS (mm_broadband_modem_cinterion_parent_class)->finalize (object);
|
G_OBJECT_CLASS (mm_broadband_modem_cinterion_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@@ -2580,6 +2688,8 @@ iface_modem_init (MMIfaceModem *iface)
|
|||||||
iface->modem_power_down_finish = modem_power_down_finish;
|
iface->modem_power_down_finish = modem_power_down_finish;
|
||||||
iface->modem_power_off = modem_power_off;
|
iface->modem_power_off = modem_power_off;
|
||||||
iface->modem_power_off_finish = modem_power_off_finish;
|
iface->modem_power_off_finish = modem_power_off_finish;
|
||||||
|
iface->setup_sim_hot_swap = modem_setup_sim_hot_swap;
|
||||||
|
iface->setup_sim_hot_swap_finish = modem_setup_sim_hot_swap_finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -2700,6 +2810,11 @@ setup_ports (MMBroadbandModem *_self)
|
|||||||
port,
|
port,
|
||||||
self->priv->sysstart_regex,
|
self->priv->sysstart_regex,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
mm_port_serial_at_add_unsolicited_msg_handler (
|
||||||
|
port,
|
||||||
|
self->priv->scks_regex,
|
||||||
|
NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Secondary */
|
/* Secondary */
|
||||||
@@ -2709,6 +2824,11 @@ setup_ports (MMBroadbandModem *_self)
|
|||||||
port,
|
port,
|
||||||
self->priv->sysstart_regex,
|
self->priv->sysstart_regex,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
mm_port_serial_at_add_unsolicited_msg_handler (
|
||||||
|
port,
|
||||||
|
self->priv->scks_regex,
|
||||||
|
NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user