On 02/16/2013 12:17 AM, Ben Chan wrote: > This patch defers the update of 3GPP registration state by 15 seconds > when the registration state changes from 'registered' (home / roaming) > to 'searching'. This allows a temporary loss of 3GPP registration to > recover itself when relying on ModemManager to explicitly disconnect and > reconnect to the network. > --- > I rebase patch v3 on top of HEAD, so that this v4 patch can be applied > cleanly on HEAD. >
Pushed, thanks. > src/mm-iface-modem-3gpp.c | 122 > ++++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 102 insertions(+), 20 deletions(-) > > diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c > index 7117e9c..fa8da1a 100644 > --- a/src/mm-iface-modem-3gpp.c > +++ b/src/mm-iface-modem-3gpp.c > @@ -29,6 +29,7 @@ > #include "mm-log.h" > > #define REGISTRATION_CHECK_TIMEOUT_SEC 30 > +#define DEFERRED_REGISTRATION_STATE_UPDATE_TIMEOUT_SEC 15 > > #define SUBSYSTEM_3GPP "3gpp" > > @@ -73,6 +74,8 @@ typedef struct { > MMModem3gppRegistrationState cs; > MMModem3gppRegistrationState ps; > MMModem3gppRegistrationState eps; > + MMModem3gppRegistrationState deferred_new_state; > + guint deferred_update_id; > gboolean manual_registration; > GCancellable *pending_registration_cancellable; > gboolean reloading_operator; > @@ -85,6 +88,9 @@ registration_state_context_free (RegistrationStateContext > *ctx) > g_cancellable_cancel (ctx->pending_registration_cancellable); > g_object_unref (ctx->pending_registration_cancellable); > } > + if (ctx->deferred_update_id) { > + g_source_remove (ctx->deferred_update_id); > + } > g_slice_free (RegistrationStateContext, ctx); > } > > @@ -104,6 +110,7 @@ get_registration_state_context (MMIfaceModem3gpp *self) > ctx->cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; > ctx->ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; > ctx->eps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; > + ctx->deferred_new_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; > > g_object_set_qdata_full ( > G_OBJECT (self), > @@ -1033,25 +1040,98 @@ update_registration_reload_current_operator_ready > (MMIfaceModem3gpp *self, > } > > static void > +update_non_registered_state (MMIfaceModem3gpp *self, > + MMModem3gppRegistrationState old_state, > + MMModem3gppRegistrationState new_state) > +{ > + /* Not registered neither in home nor roaming network */ > + mm_iface_modem_3gpp_clear_current_operator (self); > + > + /* The property in the interface is bound to the property > + * in the skeleton, so just updating here is enough */ > + g_object_set (self, > + MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state, > + NULL); > + > + mm_iface_modem_update_subsystem_state ( > + MM_IFACE_MODEM (self), > + SUBSYSTEM_3GPP, > + (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ? > + MM_MODEM_STATE_SEARCHING : > + MM_MODEM_STATE_ENABLED), > + MM_MODEM_STATE_CHANGE_REASON_UNKNOWN); > +} > + > +static gboolean > +run_deferred_registration_state_update (MMIfaceModem3gpp *self) > +{ > + MMModem3gppRegistrationState old_state = > MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; > + MMModem3gppRegistrationState new_state; > + RegistrationStateContext *ctx; > + > + ctx = get_registration_state_context (self); > + ctx->deferred_update_id = 0; > + > + g_object_get (self, > + MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, &old_state, > + NULL); > + new_state = ctx->deferred_new_state; > + > + /* Only set new state if different */ > + if (new_state == old_state) > + return FALSE; > + > + mm_info ("Modem %s: (deferred) 3GPP Registration state changed (%s -> > %s)", > + g_dbus_object_get_object_path (G_DBUS_OBJECT (self)), > + mm_modem_3gpp_registration_state_get_string (old_state), > + mm_modem_3gpp_registration_state_get_string (new_state)); > + > + update_non_registered_state (self, old_state, new_state); > + > + return FALSE; > +} > + > +static void > update_registration_state (MMIfaceModem3gpp *self, > MMModem3gppRegistrationState new_state) > { > MMModem3gppRegistrationState old_state = > MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; > + RegistrationStateContext *ctx; > > g_object_get (self, > MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, &old_state, > NULL); > > + ctx = get_registration_state_context (self); > + g_assert (ctx); > + > + if (ctx->deferred_update_id != 0) { > + /* If there is already a deferred 'registration loss' state update > and the new update > + * is not a registered state, update the deferred state update > without extending the > + * timeout. */ > + if (new_state != MM_MODEM_3GPP_REGISTRATION_STATE_HOME && > + new_state != MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) { > + mm_info ("Modem %s: 3GPP Registration state changed (%s -> %s), > update deferred", > + g_dbus_object_get_object_path (G_DBUS_OBJECT (self)), > + mm_modem_3gpp_registration_state_get_string (old_state), > + mm_modem_3gpp_registration_state_get_string > (new_state)); > + > + ctx->deferred_new_state = new_state; > + return; > + } > + > + /* Otherwise, cancel any deferred registration state update */ > + g_source_remove (ctx->deferred_update_id); > + ctx->deferred_update_id = 0; > + ctx->deferred_new_state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; > + } > + > /* Only set new state if different */ > if (new_state == old_state) > return; > > if (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || > new_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) { > - RegistrationStateContext *ctx; > - > - ctx = get_registration_state_context (self); > - > /* If already reloading operator, skip it */ > if (ctx->reloading_operator) > return; > @@ -1070,27 +1150,29 @@ update_registration_state (MMIfaceModem3gpp *self, > return; > } > > + if ((old_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || > + old_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) && > + (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING || > + new_state == MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN)) { > + mm_info ("Modem %s: 3GPP Registration state changed (%s -> %s), > update deferred", > + g_dbus_object_get_object_path (G_DBUS_OBJECT (self)), > + mm_modem_3gpp_registration_state_get_string (old_state), > + mm_modem_3gpp_registration_state_get_string (new_state)); > + > + ctx->deferred_new_state = new_state; > + ctx->deferred_update_id = g_timeout_add_seconds ( > + DEFERRED_REGISTRATION_STATE_UPDATE_TIMEOUT_SEC, > + (GSourceFunc)run_deferred_registration_state_update, > + self); > + return; > + } > + > mm_info ("Modem %s: 3GPP Registration state changed (%s -> %s)", > g_dbus_object_get_object_path (G_DBUS_OBJECT (self)), > mm_modem_3gpp_registration_state_get_string (old_state), > mm_modem_3gpp_registration_state_get_string (new_state)); > > - /* Not registered neither in home nor roaming network */ > - mm_iface_modem_3gpp_clear_current_operator (self); > - > - /* The property in the interface is bound to the property > - * in the skeleton, so just updating here is enough */ > - g_object_set (self, > - MM_IFACE_MODEM_3GPP_REGISTRATION_STATE, new_state, > - NULL); > - > - mm_iface_modem_update_subsystem_state ( > - MM_IFACE_MODEM (self), > - SUBSYSTEM_3GPP, > - (new_state == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING ? > - MM_MODEM_STATE_SEARCHING : > - MM_MODEM_STATE_ENABLED), > - MM_MODEM_STATE_CHANGE_REASON_UNKNOWN); > + update_non_registered_state (self, old_state, new_state); > } > > void > -- Aleksander _______________________________________________ networkmanager-list mailing list networkmanager-list@gnome.org https://mail.gnome.org/mailman/listinfo/networkmanager-list