diff options
author | Thieu Le <thieule@chromium.org> | 2013-11-19 13:06:19 -0800 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2013-11-21 10:48:53 +0100 |
commit | c21709b32e1af46f1764888a03b21fd747db7da1 (patch) | |
tree | d13410e55040939001813e1a02d934856be07b57 | |
parent | 5e7fee1d116f69fbee0b984e11c39f1f9c5277f3 (diff) |
altair-lte: add SIMREFRESH support
Register for SIMREFRESH event and reload own numbers and reregister
modem with network when this happens.
-rw-r--r-- | plugins/altair/mm-broadband-modem-altair-lte.c | 189 | ||||
-rw-r--r-- | src/mm-iface-modem.c | 15 | ||||
-rw-r--r-- | src/mm-iface-modem.h | 4 |
3 files changed, 191 insertions, 17 deletions
diff --git a/plugins/altair/mm-broadband-modem-altair-lte.c b/plugins/altair/mm-broadband-modem-altair-lte.c index 64d4c51e..4e2349e4 100644 --- a/plugins/altair/mm-broadband-modem-altair-lte.c +++ b/plugins/altair/mm-broadband-modem-altair-lte.c @@ -53,6 +53,12 @@ G_DEFINE_TYPE_EXTENDED (MMBroadbandModemAltairLte, mm_broadband_modem_altair_lte G_IMPLEMENT_INTERFACE (MM_TYPE_IFACE_MODEM_MESSAGING, iface_modem_messaging_init)); struct _MMBroadbandModemAltairLtePrivate { + /* Regex for SIM refresh notifications */ + GRegex *sim_refresh_regex; + /* Timer that goes off 10s after the last SIM refresh notification. + * This indicates that there are no more SIM refreshes and we should + * reregister the device.*/ + guint sim_refresh_timer_id; /* Regex for bearer related notifications */ GRegex *statcm_regex; }; @@ -634,7 +640,101 @@ modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self, } /*****************************************************************************/ -/* Setup/Cleanup unsolicited events (3GPP interface) */ +/* SIMREFRESH unsolicited event handler */ + +static void +altair_reregister_ready (MMBaseModem *self, + GAsyncResult *res, + gpointer user_data) +{ + if (!mm_base_modem_at_command_finish (self, res, NULL)) { + mm_dbg ("Failed to reregister modem"); + } else { + mm_dbg ("Modem reregistered successfully"); + } +} + +static void +altair_deregister_ready (MMBaseModem *self, + GAsyncResult *res, + gpointer user_data) +{ + if (!mm_base_modem_at_command_finish (self, res, NULL)) { + mm_dbg ("Deregister modem failed"); + return; + } + + mm_dbg ("Deregistered modem, now reregistering"); + + /* Register */ + mm_base_modem_at_command ( + MM_BASE_MODEM (self), + "%CMATT=1", + 10, + FALSE, /* allow_cached */ + (GAsyncReadyCallback)altair_reregister_ready, + NULL); +} + +static void +altair_load_own_numbers_ready (MMIfaceModem *iface_modem, + GAsyncResult *res, + MMBroadbandModemAltairLte *self) +{ + GError *error = NULL; + GStrv str_list; + + str_list = MM_IFACE_MODEM_GET_INTERFACE (self)->load_own_numbers_finish (MM_IFACE_MODEM (self), res, &error); + if (error) { + mm_warn ("Couldn't reload Own Numbers: '%s'", error->message); + g_error_free (error); + } + if (str_list) { + mm_iface_modem_update_own_numbers (iface_modem, str_list); + g_strfreev (str_list); + } + + /* Deregister */ + mm_dbg ("Reregistering modem"); + mm_base_modem_at_command ( + MM_BASE_MODEM (self), + "%CMATT=0", + 10, + FALSE, /* allow_cached */ + (GAsyncReadyCallback)altair_deregister_ready, + NULL); +} + +static gboolean +altair_sim_refresh_timer_expired (MMBroadbandModemAltairLte *self) +{ + mm_dbg ("No more SIM refreshes, reloading Own Numbers and reregistering modem"); + + g_assert (MM_IFACE_MODEM_GET_INTERFACE (self)->load_own_numbers); + g_assert (MM_IFACE_MODEM_GET_INTERFACE (self)->load_own_numbers_finish); + MM_IFACE_MODEM_GET_INTERFACE (self)->load_own_numbers ( + MM_IFACE_MODEM (self), + (GAsyncReadyCallback)altair_load_own_numbers_ready, + self); + + self->priv->sim_refresh_timer_id = 0; + return FALSE; +} + +static void +altair_sim_refresh_changed (MMAtSerialPort *port, + GMatchInfo *match_info, + MMBroadbandModemAltairLte *self) +{ + mm_dbg ("Received SIM refresh notification"); + if (self->priv->sim_refresh_timer_id) { + g_source_remove (self->priv->sim_refresh_timer_id); + } + self->priv->sim_refresh_timer_id = + g_timeout_add_seconds(10, + (GSourceFunc)altair_sim_refresh_timer_expired, + self); +} typedef enum { MM_STATCM_ALTAIR_LTE_DEREGISTERED = 0, @@ -651,6 +751,9 @@ bearer_list_report_disconnect_status_foreach (MMBearer *bearer, MM_BEARER_CONNECTION_STATUS_DISCONNECTED); } +/*****************************************************************************/ +/* STATCM unsolicited event handler */ + static void altair_statcm_changed (MMAtSerialPort *port, GMatchInfo *match_info, @@ -682,6 +785,9 @@ altair_statcm_changed (MMAtSerialPort *port, } +/*****************************************************************************/ +/* Setup/Cleanup unsolicited events (3GPP interface) */ + static void set_3gpp_unsolicited_events_handlers (MMBroadbandModemAltairLte *self, gboolean enable) @@ -697,6 +803,14 @@ set_3gpp_unsolicited_events_handlers (MMBroadbandModemAltairLte *self, if (!ports[i]) continue; + /* SIM refresh handler */ + mm_at_serial_port_add_unsolicited_msg_handler ( + ports[i], + self->priv->sim_refresh_regex, + enable ? (MMAtSerialUnsolicitedMsgFn)altair_sim_refresh_changed : NULL, + enable ? self : NULL, + NULL); + /* bearer mode related */ mm_at_serial_port_add_unsolicited_msg_handler ( ports[i], @@ -794,6 +908,31 @@ modem_3gpp_cleanup_unsolicited_events (MMIfaceModem3gpp *self, /* Enabling unsolicited events (3GPP interface) */ static gboolean +response_processor_no_result_stop_on_error (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) +{ + if (error) { + *result_error = g_error_copy (error); + return TRUE; + } + + *result = NULL; + return FALSE; +} + +static const MMBaseModemAtCommand unsolicited_events_enable_sequence[] = { + { "%STATCM=1", 10, FALSE, response_processor_no_result_stop_on_error }, + { "%NOTIFYEV=\"SIMREFRESH\",1", 10, FALSE, NULL }, + { NULL } +}; + +static gboolean modem_3gpp_enable_unsolicited_events_finish (MMIfaceModem3gpp *self, GAsyncResult *res, GError **error) @@ -808,7 +947,7 @@ own_enable_unsolicited_events_ready (MMBaseModem *self, { GError *error = NULL; - mm_base_modem_at_command_full_finish (self, res, &error); + mm_base_modem_at_sequence_finish (self, res, NULL, &error); if (error) g_simple_async_result_take_error (simple, error); else @@ -832,14 +971,11 @@ parent_enable_unsolicited_events_ready (MMIfaceModem3gpp *self, } /* Our own enable now */ - mm_base_modem_at_command_full ( + mm_base_modem_at_sequence ( MM_BASE_MODEM (self), - mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)), - "%STATCM=1", - 10, - FALSE, /* allow_cached */ - FALSE, /* raw */ - NULL, /* cancellable */ + unsolicited_events_enable_sequence, + NULL, /* response_processor_context */ + NULL, /* response_processor_context_free */ (GAsyncReadyCallback)own_enable_unsolicited_events_ready, simple); } @@ -866,6 +1002,12 @@ modem_3gpp_enable_unsolicited_events (MMIfaceModem3gpp *self, /*****************************************************************************/ /* Disabling unsolicited events (3GPP interface) */ +static const MMBaseModemAtCommand unsolicited_events_disable_sequence[] = { + { "%STATCM=0", 10, FALSE, NULL }, + { "%NOTIFYEV=\"SIMREFRESH\",0", 10, FALSE, NULL }, + { NULL } +}; + static gboolean modem_3gpp_disable_unsolicited_events_finish (MMIfaceModem3gpp *self, GAsyncResult *res, @@ -896,7 +1038,7 @@ own_disable_unsolicited_events_ready (MMBaseModem *self, { GError *error = NULL; - mm_base_modem_at_command_full_finish (self, res, &error); + mm_base_modem_at_sequence_finish (self, res, NULL, &error); if (error) { g_simple_async_result_take_error (simple, error); g_simple_async_result_complete (simple); @@ -924,14 +1066,11 @@ modem_3gpp_disable_unsolicited_events (MMIfaceModem3gpp *self, modem_3gpp_disable_unsolicited_events); /* Our own disable first */ - mm_base_modem_at_command_full ( + mm_base_modem_at_sequence ( MM_BASE_MODEM (self), - mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)), - "%STATCM=0", - 10, - FALSE, /* allow_cached */ - FALSE, /* raw */ - NULL, /* cancellable */ + unsolicited_events_disable_sequence, + NULL, /* response_processor_context */ + NULL, /* response_processor_context_free */ (GAsyncReadyCallback)own_disable_unsolicited_events_ready, result); } @@ -1086,11 +1225,26 @@ mm_broadband_modem_altair_lte_init (MMBroadbandModemAltairLte *self) MM_TYPE_BROADBAND_MODEM_ALTAIR_LTE, MMBroadbandModemAltairLtePrivate); + self->priv->sim_refresh_regex = g_regex_new ("\\r\\n\\%NOTIFYEV:\\s*SIMREFRESH,?(\\d*)\\r+\\n", + G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); + self->priv->sim_refresh_timer_id = 0; self->priv->statcm_regex = g_regex_new ("\\r\\n\\%STATCM:\\s*(\\d*),?(\\d*)\\r+\\n", G_REGEX_RAW | G_REGEX_OPTIMIZE, 0, NULL); } static void +finalize (GObject *object) +{ + MMBroadbandModemAltairLte *self = MM_BROADBAND_MODEM_ALTAIR_LTE (object); + + if (self->priv->sim_refresh_timer_id) + g_source_remove (self->priv->sim_refresh_timer_id); + g_regex_unref (self->priv->sim_refresh_regex); + g_regex_unref (self->priv->statcm_regex); + G_OBJECT_CLASS (mm_broadband_modem_altair_lte_parent_class)->finalize (object); +} + +static void iface_modem_init (MMIfaceModem *iface) { iface->modem_power_down = modem_power_down; @@ -1174,6 +1328,7 @@ mm_broadband_modem_altair_lte_class_init (MMBroadbandModemAltairLteClass *klass) g_type_class_add_private (object_class, sizeof (MMBroadbandModemAltairLtePrivate)); + object_class->finalize = finalize; broadband_modem_class->setup_ports = setup_ports; /* The Altair LTE modem reboots itself upon receiving an ATZ command. We diff --git a/src/mm-iface-modem.c b/src/mm-iface-modem.c index 77c9c657..0a3f096a 100644 --- a/src/mm-iface-modem.c +++ b/src/mm-iface-modem.c @@ -3965,6 +3965,21 @@ sim_reinit_ready (MMSim *sim, interface_initialization_step (ctx); } +void +mm_iface_modem_update_own_numbers (MMIfaceModem *self, + const GStrv own_numbers) +{ + MmGdbusModem *skeleton = NULL; + + g_object_get (self, + MM_IFACE_MODEM_DBUS_SKELETON, &skeleton, + NULL); + if (skeleton) { + mm_gdbus_modem_set_own_numbers (skeleton, (const gchar * const *)own_numbers); + g_object_unref (skeleton); + } +} + static void load_own_numbers_ready (MMIfaceModem *self, GAsyncResult *res, diff --git a/src/mm-iface-modem.h b/src/mm-iface-modem.h index a092333e..d8819c13 100644 --- a/src/mm-iface-modem.h +++ b/src/mm-iface-modem.h @@ -419,6 +419,10 @@ void mm_iface_modem_update_state (MMIfaceModem *self, void mm_iface_modem_update_failed_state (MMIfaceModem *self, MMModemStateFailedReason failed_reason); +/* Allow update own numbers */ +void mm_iface_modem_update_own_numbers (MMIfaceModem *self, + const GStrv own_numbers); + /* Allow reporting new access tech */ void mm_iface_modem_update_access_technologies (MMIfaceModem *self, MMModemAccessTechnology access_tech, |