diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem.c | 238 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.c | 386 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.h | 2 |
3 files changed, 310 insertions, 316 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index d2cd9692..99229423 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -129,8 +129,6 @@ struct _MMBroadbandModemPrivate { gboolean modem_3gpp_ps_network_supported; /* Implementation helpers */ GPtrArray *modem_3gpp_registration_regex; - gboolean modem_3gpp_manual_registration; - GCancellable *modem_3gpp_pending_registration_cancellable; /*<--- Modem 3GPP USSD interface --->*/ /* Properties */ @@ -2655,252 +2653,44 @@ modem_3gpp_scan_networks (MMIfaceModem3gpp *self, /*****************************************************************************/ /* Register in network (3GPP interface) */ -typedef struct { - MMBroadbandModem *self; - GSimpleAsyncResult *result; - GCancellable *cancellable; - GTimer *timer; - guint max_registration_time; -} RegisterIn3gppNetworkContext; - -static void -register_in_3gpp_network_context_complete_and_free (RegisterIn3gppNetworkContext *ctx) -{ - /* If our cancellable reference is still around, clear it */ - if (ctx->self->priv->modem_3gpp_pending_registration_cancellable == - ctx->cancellable) { - g_clear_object (&ctx->self->priv->modem_3gpp_pending_registration_cancellable); - } - - if (ctx->timer) - g_timer_destroy (ctx->timer); - - g_simple_async_result_complete (ctx->result); - g_object_unref (ctx->result); - g_object_unref (ctx->cancellable); - g_object_unref (ctx->self); - g_free (ctx); -} - static gboolean modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self, GAsyncResult *res, GError **error) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -#undef REG_IS_IDLE -#define REG_IS_IDLE(state) \ - (state != MM_MODEM_3GPP_REGISTRATION_STATE_HOME && \ - state != MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING && \ - state != MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) - -#undef REG_IS_DONE -#define REG_IS_DONE(state) \ - (state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || \ - state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING || \ - state == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED) - -static void run_3gpp_registration_checks_ready (MMBroadbandModem *self, - GAsyncResult *res, - RegisterIn3gppNetworkContext *ctx); - -static gboolean -run_3gpp_registration_checks_again (RegisterIn3gppNetworkContext *ctx) -{ - /* Get fresh registration state */ - mm_iface_modem_3gpp_run_registration_checks ( - MM_IFACE_MODEM_3GPP (ctx->self), - (GAsyncReadyCallback)run_3gpp_registration_checks_ready, - ctx); - return FALSE; -} - -static void -run_3gpp_registration_checks_ready (MMBroadbandModem *self, - GAsyncResult *res, - RegisterIn3gppNetworkContext *ctx) -{ - GError *error = NULL; - - mm_iface_modem_3gpp_run_registration_checks_finish (MM_IFACE_MODEM_3GPP (self), - res, - &error); - - if (error) { - mm_dbg ("3GPP registration check failed: '%s'", error->message); - mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), - MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, - MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, - 0, 0); - mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), - MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, - MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, - 0, 0); - g_simple_async_result_take_error (ctx->result, error); - register_in_3gpp_network_context_complete_and_free (ctx); - return; - } - - /* If we got registered, end registration checks */ - if (REG_IS_DONE (self->priv->modem_3gpp_registration_state)) { - mm_dbg ("Modem is currently registered in a 3GPP network"); - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - register_in_3gpp_network_context_complete_and_free (ctx); - return; - } - - /* Don't spend too much time waiting to get registered */ - if (g_timer_elapsed (ctx->timer, NULL) > ctx->max_registration_time) { - mm_dbg ("3GPP registration check timed out"); - mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), - MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, - MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, - 0, 0); - mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), - MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, - MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, - 0, 0); - g_simple_async_result_take_error ( - ctx->result, - mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT)); - register_in_3gpp_network_context_complete_and_free (ctx); - return; - } - - /* If we're still waiting for automatic registration to complete or - * fail, check again in a few seconds. - * - * This 3s timeout will catch results from automatic registrations as - * well. - */ - mm_dbg ("Modem not yet registered in a 3GPP network... will recheck soon"); - g_timeout_add_seconds (3, - (GSourceFunc)run_3gpp_registration_checks_again, - ctx); -} - -static void -register_in_3gpp_network_ready (MMBroadbandModem *self, - GAsyncResult *res, - RegisterIn3gppNetworkContext *ctx) -{ - GError *error = NULL; - - mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, &error); - - if (error) { - /* Propagate error in COPS, if any */ - mm_iface_modem_3gpp_update_cs_registration_state (MM_IFACE_MODEM_3GPP (self), - MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, - MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, - 0, 0); - mm_iface_modem_3gpp_update_ps_registration_state (MM_IFACE_MODEM_3GPP (self), - MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, - MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, - 0, 0); - g_simple_async_result_take_error (ctx->result, error); - register_in_3gpp_network_context_complete_and_free (ctx); - return; - } - - /* Get fresh registration state */ - ctx->timer = g_timer_new (); - mm_iface_modem_3gpp_run_registration_checks ( - MM_IFACE_MODEM_3GPP (self), - (GAsyncReadyCallback)run_3gpp_registration_checks_ready, - ctx); + return !!mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, error); } static void modem_3gpp_register_in_network (MMIfaceModem3gpp *self, const gchar *operator_id, - guint max_registration_time, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data) { - MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self); - RegisterIn3gppNetworkContext *ctx; - gchar *command = NULL; - GError *error = NULL; - - /* Validate input MCC/MNC */ - if (operator_id && !mm_3gpp_parse_operator_id (operator_id, NULL, NULL, &error)) { - g_assert (error != NULL); - g_simple_async_report_take_gerror_in_idle (G_OBJECT (self), - callback, - user_data, - error); - return; - } - - /* (Try to) cancel previous registration request */ - if (broadband->priv->modem_3gpp_pending_registration_cancellable) { - g_cancellable_cancel (broadband->priv->modem_3gpp_pending_registration_cancellable); - g_clear_object (&broadband->priv->modem_3gpp_pending_registration_cancellable); - } - - ctx = g_new0 (RegisterIn3gppNetworkContext, 1); - ctx->self = g_object_ref (self); - ctx->max_registration_time = max_registration_time; - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_3gpp_register_in_network); - ctx->cancellable = g_cancellable_new (); - - /* Keep an accessible reference to the cancellable, so that we can cancel - * previous request when needed */ - broadband->priv->modem_3gpp_pending_registration_cancellable = - g_object_ref (ctx->cancellable); + gchar *command; /* If the user sent a specific network to use, lock it in. */ - if (operator_id && operator_id[0]) { + if (operator_id) command = g_strdup_printf ("+COPS=1,2,\"%s\"", operator_id); - broadband->priv->modem_3gpp_manual_registration = TRUE; - } /* If no specific network was given, and the modem is not registered and not * searching, kick it to search for a network. Also do auto registration if * the modem had been set to manual registration last time but now is not. */ - else if (REG_IS_IDLE (broadband->priv->modem_3gpp_registration_state) || - broadband->priv->modem_3gpp_manual_registration) { + else /* Note that '+COPS=0,,' (same but with commas) won't work in some Nokia * phones */ command = g_strdup ("+COPS=0"); - broadband->priv->modem_3gpp_manual_registration = FALSE; - } - - if (command) { - /* Don't setup an additional timeout to handle registration timeouts. We - * already do this with the 120s timeout in the AT command: if that times - * out, we can consider the registration itself timed out. - * - * NOTE that we provide our own Cancellable here; we want to be able to - * cancel the operation at any time. */ - mm_base_modem_at_command_full (MM_BASE_MODEM (self), - mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL), - command, - 120, - FALSE, - FALSE, /* raw */ - ctx->cancellable, - (GAsyncReadyCallback)register_in_3gpp_network_ready, - ctx); - g_free (command); - return; - } - - /* Just rely on the unsolicited registration and periodic registration checks */ - mm_dbg ("Not launching any new network selection request"); - /* Get fresh registration state */ - ctx->timer = g_timer_new (); - mm_iface_modem_3gpp_run_registration_checks ( - MM_IFACE_MODEM_3GPP (self), - (GAsyncReadyCallback)run_3gpp_registration_checks_ready, - ctx); + mm_base_modem_at_command_full (MM_BASE_MODEM (self), + mm_base_modem_peek_best_at_port (MM_BASE_MODEM (self), NULL), + command, + 120, + FALSE, + FALSE, /* raw */ + cancellable, + callback, + user_data); } /*****************************************************************************/ diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c index 4056284f..f2cd62f4 100644 --- a/src/mm-iface-modem-3gpp.c +++ b/src/mm-iface-modem-3gpp.c @@ -24,6 +24,7 @@ #include "mm-iface-modem-3gpp.h" #include "mm-base-modem.h" #include "mm-modem-helpers.h" +#include "mm-error-helpers.h" #include "mm-log.h" #define REGISTRATION_CHECK_TIMEOUT_SEC 30 @@ -65,6 +66,128 @@ mm_iface_modem_3gpp_bind_simple_status (MMIfaceModem3gpp *self, /*****************************************************************************/ +typedef struct { + MMModem3gppRegistrationState cs; + MMModem3gppRegistrationState ps; + gboolean manual_registration; + GCancellable *pending_registration_cancellable; +} RegistrationStateContext; + +static void +registration_state_context_free (RegistrationStateContext *ctx) +{ + if (ctx->pending_registration_cancellable) { + g_cancellable_cancel (ctx->pending_registration_cancellable); + g_object_unref (ctx->pending_registration_cancellable); + } + g_slice_free (RegistrationStateContext, ctx); +} + +static RegistrationStateContext * +get_registration_state_context (MMIfaceModem3gpp *self) +{ + RegistrationStateContext *ctx; + + if (G_UNLIKELY (!registration_state_context_quark)) + registration_state_context_quark = (g_quark_from_static_string ( + REGISTRATION_STATE_CONTEXT_TAG)); + + ctx = g_object_get_qdata (G_OBJECT (self), registration_state_context_quark); + if (!ctx) { + /* Create context and keep it as object data */ + ctx = g_slice_new0 (RegistrationStateContext); + ctx->cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; + ctx->ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; + + g_object_set_qdata_full ( + G_OBJECT (self), + registration_state_context_quark, + ctx, + (GDestroyNotify)registration_state_context_free); + } + + return ctx; +} + +static MMModem3gppRegistrationState +get_consolidated_reg_state (RegistrationStateContext *ctx) +{ + /* Some devices (Blackberries for example) will respond to +CGREG, but + * return ERROR for +CREG, probably because their firmware is just stupid. + * So here we prefer the +CREG response, but if we never got a successful + * +CREG response, we'll take +CGREG instead. + */ + if (ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || + ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) + return ctx->cs; + + if (ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || + ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) + return ctx->ps; + + if (ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING) + return ctx->cs; + + if (ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING) + return ctx->ps; + + return ctx->cs; +} + +/*****************************************************************************/ + +typedef struct { + MMIfaceModem3gpp *self; + MmGdbusModem3gpp *skeleton; + GSimpleAsyncResult *result; + GCancellable *cancellable; + gchar *operator_id; + GTimer *timer; + guint max_registration_time; +} RegisterInNetworkContext; + +static void +register_in_network_context_complete_and_free (RegisterInNetworkContext *ctx) +{ + g_simple_async_result_complete_in_idle (ctx->result); + g_object_unref (ctx->result); + + if (ctx->timer) + g_timer_destroy (ctx->timer); + + if (ctx->cancellable) { + RegistrationStateContext *registration_state_context; + + /* Clear our cancellable if still around */ + registration_state_context = get_registration_state_context (ctx->self); + if (registration_state_context->pending_registration_cancellable == ctx->cancellable) + g_clear_object (®istration_state_context->pending_registration_cancellable); + + g_object_unref (ctx->cancellable); + } + + g_free (ctx->operator_id); + g_object_unref (ctx->skeleton); + g_object_unref (ctx->self); + g_slice_free (RegisterInNetworkContext, ctx); +} + +static void +register_in_network_context_failed (RegisterInNetworkContext *ctx, + GError *error) +{ + mm_iface_modem_3gpp_update_cs_registration_state (ctx->self, + MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, + MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, + 0, 0); + mm_iface_modem_3gpp_update_ps_registration_state (ctx->self, + MM_MODEM_3GPP_REGISTRATION_STATE_IDLE, + MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN, + 0, 0); + + g_simple_async_result_take_error (ctx->result, error); +} + gboolean mm_iface_modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self, GAsyncResult *res, @@ -73,19 +196,101 @@ mm_iface_modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self, return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } +static void run_registration_checks_ready (MMIfaceModem3gpp *self, + GAsyncResult *res, + RegisterInNetworkContext *ctx); + +static gboolean +run_registration_checks_again (RegisterInNetworkContext *ctx) +{ + /* Get fresh registration state */ + mm_iface_modem_3gpp_run_registration_checks ( + ctx->self, + (GAsyncReadyCallback)run_registration_checks_ready, + ctx); + return FALSE; +} + +static void +run_registration_checks_ready (MMIfaceModem3gpp *self, + GAsyncResult *res, + RegisterInNetworkContext *ctx) +{ + GError *error = NULL; + RegistrationStateContext *registration_state_context; + MMModem3gppRegistrationState current_registration_state; + + mm_iface_modem_3gpp_run_registration_checks_finish (MM_IFACE_MODEM_3GPP (self), res, &error); + if (error) { + mm_dbg ("3GPP registration check failed: '%s'", error->message); + register_in_network_context_failed (ctx, error); + register_in_network_context_complete_and_free (ctx); + return; + } + + registration_state_context = get_registration_state_context (ctx->self); + current_registration_state = get_consolidated_reg_state (registration_state_context); + + /* If we got a final state and it's denied, we can assume the registration is + * finished */ + if (current_registration_state == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED) { + mm_dbg ("Registration denied"); + register_in_network_context_failed ( + ctx, + mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_NOT_ALLOWED)); + register_in_network_context_complete_and_free (ctx); + return; + } + + /* If we got registered, end registration checks */ + if (current_registration_state == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || + current_registration_state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) { + mm_dbg ("Modem is currently registered in a 3GPP network"); + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + register_in_network_context_complete_and_free (ctx); + return; + } + + /* Don't spend too much time waiting to get registered */ + if (g_timer_elapsed (ctx->timer, NULL) > ctx->max_registration_time) { + mm_dbg ("3GPP registration check timed out"); + register_in_network_context_failed ( + ctx, + mm_mobile_equipment_error_for_code (MM_MOBILE_EQUIPMENT_ERROR_NETWORK_TIMEOUT)); + register_in_network_context_complete_and_free (ctx); + return; + } + + /* If we're still waiting for automatic registration to complete or + * fail, check again in a few seconds. + * + * This 3s timeout will catch results from automatic registrations as + * well. + */ + mm_dbg ("Modem not yet registered in a 3GPP network... will recheck soon"); + g_timeout_add_seconds (3, (GSourceFunc)run_registration_checks_again, ctx); +} + static void register_in_network_ready (MMIfaceModem3gpp *self, GAsyncResult *res, - GSimpleAsyncResult *simple) + RegisterInNetworkContext *ctx) { GError *error = NULL; - if (!MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->register_in_network_finish (self, res, &error)) - g_simple_async_result_take_error (simple, error); - else - g_simple_async_result_set_op_res_gboolean (simple, TRUE); - g_simple_async_result_complete (simple); - g_object_unref (simple); + if (!MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->register_in_network_finish (self, res, &error)) { + /* Propagate error when trying to lock to network */ + register_in_network_context_failed (ctx, error); + register_in_network_context_complete_and_free (ctx); + return; + } + + /* Now try to gather current registration status until we're registered or + * the time goes off */ + mm_iface_modem_3gpp_run_registration_checks ( + self, + (GAsyncReadyCallback)run_registration_checks_ready, + ctx); } void @@ -95,38 +300,93 @@ mm_iface_modem_3gpp_register_in_network (MMIfaceModem3gpp *self, GAsyncReadyCallback callback, gpointer user_data) { - GSimpleAsyncResult *result; - MmGdbusModem3gpp *skeleton; + RegisterInNetworkContext *ctx; const gchar *current_operator_code; + RegistrationStateContext *registration_state_context; + GError *error = NULL; - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - mm_iface_modem_3gpp_register_in_network); - - /* If no operator ID given, or if we're already registered with the requested one, - * then we're done */ + ctx = g_slice_new0 (RegisterInNetworkContext); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + mm_iface_modem_3gpp_register_in_network); + ctx->operator_id = (operator_id && operator_id[0]) ? g_strdup (operator_id) : NULL; + ctx->max_registration_time = max_registration_time; g_object_get (self, - MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &skeleton, + MM_IFACE_MODEM_3GPP_DBUS_SKELETON, &ctx->skeleton, NULL); - current_operator_code = mm_gdbus_modem3gpp_get_operator_code (skeleton); - if (current_operator_code && - (!operator_id || g_str_equal (current_operator_code, operator_id))) { - /* Already registered, no need to request it again */ - mm_dbg ("Already registered in network '%s'...", current_operator_code); - g_simple_async_result_set_op_res_gboolean (result, TRUE); - g_simple_async_result_complete_in_idle (result); - g_object_unref (result); - } else { - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->register_in_network ( - self, - operator_id, - max_registration_time, - (GAsyncReadyCallback)register_in_network_ready, - result); + + /* Validate input MCC/MNC */ + if (ctx->operator_id && !mm_3gpp_parse_operator_id (ctx->operator_id, NULL, NULL, &error)) { + g_assert (error != NULL); + g_simple_async_result_take_error (ctx->result, error); + register_in_network_context_complete_and_free (ctx); + return; } - g_object_unref (skeleton); + /* Get registration state context */ + registration_state_context = get_registration_state_context (self); + + /* (Try to) cancel previous registration request */ + if (registration_state_context->pending_registration_cancellable) { + g_cancellable_cancel (registration_state_context->pending_registration_cancellable); + g_clear_object (®istration_state_context->pending_registration_cancellable); + } + + current_operator_code = mm_gdbus_modem3gpp_get_operator_code (ctx->skeleton); + + /* Manual registration requested? */ + if (ctx->operator_id) { + /* If already registered with the requested operator, we're done */ + if (current_operator_code && + g_str_equal (current_operator_code, ctx->operator_id)) { + registration_state_context->manual_registration = TRUE; + mm_dbg ("Already registered in selected network '%s'...", + current_operator_code); + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + register_in_network_context_complete_and_free (ctx); + return; + } + + /* Manual registration to a new operator required */ + mm_dbg ("Launching manual network registration (%s)...", + ctx->operator_id); + registration_state_context->manual_registration = TRUE; + } + /* Automatic registration requested? */ + else { + /* If the modem is already registered and the last time it was asked + * automatic registration, we're done */ + if (current_operator_code && + !registration_state_context->manual_registration) { + mm_dbg ("Already registered in network '%s'," + " automatic registration not launched...", + current_operator_code); + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + register_in_network_context_complete_and_free (ctx); + return; + } + + /* Automatic registration to a new operator requested */ + mm_dbg ("Launching automatic network registration..."); + registration_state_context->manual_registration = FALSE; + } + + ctx->cancellable = g_cancellable_new (); + + /* Keep an accessible reference to the cancellable, so that we can cancel + * previous request when needed */ + registration_state_context->pending_registration_cancellable = + g_object_ref (ctx->cancellable); + + ctx->timer = g_timer_new (); + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->register_in_network ( + self, + ctx->operator_id, + ctx->cancellable, + (GAsyncReadyCallback)register_in_network_ready, + ctx); } typedef struct { @@ -436,8 +696,8 @@ handle_scan (MmGdbusModem3gpp *skeleton, gboolean mm_iface_modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) + GAsyncResult *res, + GError **error) { g_assert (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks_finish != NULL); return MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks_finish (self, res, error); @@ -665,62 +925,6 @@ update_registration_state (MMIfaceModem3gpp *self, g_object_unref (skeleton); } -typedef struct { - MMModem3gppRegistrationState cs; - MMModem3gppRegistrationState ps; -} RegistrationStateContext; - -static RegistrationStateContext * -get_registration_state_context (MMIfaceModem3gpp *self) -{ - RegistrationStateContext *ctx; - - if (G_UNLIKELY (!registration_state_context_quark)) - registration_state_context_quark = (g_quark_from_static_string ( - REGISTRATION_STATE_CONTEXT_TAG)); - - ctx = g_object_get_qdata (G_OBJECT (self), registration_state_context_quark); - if (!ctx) { - /* Create context and keep it as object data */ - ctx = g_new0 (RegistrationStateContext, 1); - ctx->cs = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; - ctx->ps = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; - - g_object_set_qdata_full ( - G_OBJECT (self), - registration_state_context_quark, - ctx, - (GDestroyNotify)g_free); - } - - return ctx; -} - -static MMModem3gppRegistrationState -get_consolidated_reg_state (RegistrationStateContext *ctx) -{ - /* Some devices (Blackberries for example) will respond to +CGREG, but - * return ERROR for +CREG, probably because their firmware is just stupid. - * So here we prefer the +CREG response, but if we never got a successful - * +CREG response, we'll take +CGREG instead. - */ - if (ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || - ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) - return ctx->cs; - - if (ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_HOME || - ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING) - return ctx->ps; - - if (ctx->cs == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING) - return ctx->cs; - - if (ctx->ps == MM_MODEM_3GPP_REGISTRATION_STATE_SEARCHING) - return ctx->ps; - - return ctx->cs; -} - void mm_iface_modem_3gpp_update_cs_registration_state (MMIfaceModem3gpp *self, MMModem3gppRegistrationState state, diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h index c0fe03d0..dc96ff1b 100644 --- a/src/mm-iface-modem-3gpp.h +++ b/src/mm-iface-modem-3gpp.h @@ -148,7 +148,7 @@ struct _MMIfaceModem3gpp { /* Try to register in the network */ void (* register_in_network) (MMIfaceModem3gpp *self, const gchar *operator_id, - guint max_registration_time, + GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); gboolean (*register_in_network_finish) (MMIfaceModem3gpp *self, |