diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem.c | 789 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.c | 334 | ||||
-rw-r--r-- | src/mm-iface-modem-3gpp.h | 113 |
3 files changed, 559 insertions, 677 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 3c9cfcb2..04b505df 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -2486,9 +2486,9 @@ modem_3gpp_load_operator_name (MMIfaceModem3gpp *self, /* Unsolicited registration messages handling (3GPP interface) */ static gboolean -modem_3gpp_setup_unsolicited_registration_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) +modem_3gpp_setup_unsolicited_registration_events_finish (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error) { return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } @@ -2533,9 +2533,9 @@ registration_state_changed (MMAtSerialPort *port, } static void -modem_3gpp_setup_unsolicited_registration (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data) +modem_3gpp_setup_unsolicited_registration_events (MMIfaceModem3gpp *self, + GAsyncReadyCallback callback, + gpointer user_data) { GSimpleAsyncResult *result; MMAtSerialPort *ports[2]; @@ -2546,7 +2546,7 @@ modem_3gpp_setup_unsolicited_registration (MMIfaceModem3gpp *self, result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, - modem_3gpp_setup_unsolicited_registration); + modem_3gpp_setup_unsolicited_registration_events); ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); @@ -2579,17 +2579,17 @@ modem_3gpp_setup_unsolicited_registration (MMIfaceModem3gpp *self, /* Unsolicited registration messages cleaning up (3GPP interface) */ static gboolean -modem_3gpp_cleanup_unsolicited_registration_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) +modem_3gpp_cleanup_unsolicited_registration_events_finish (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error) { return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } static void -modem_3gpp_cleanup_unsolicited_registration (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data) +modem_3gpp_cleanup_unsolicited_registration_events (MMIfaceModem3gpp *self, + GAsyncReadyCallback callback, + gpointer user_data) { GSimpleAsyncResult *result; MMAtSerialPort *ports[2]; @@ -2600,7 +2600,7 @@ modem_3gpp_cleanup_unsolicited_registration (MMIfaceModem3gpp *self, result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, - modem_3gpp_cleanup_unsolicited_registration); + modem_3gpp_cleanup_unsolicited_registration_events); ports[0] = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); ports[1] = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); @@ -2710,31 +2710,31 @@ modem_3gpp_register_in_network_finish (MMIfaceModem3gpp *self, state == MM_MODEM_3GPP_REGISTRATION_STATE_ROAMING || \ state == MM_MODEM_3GPP_REGISTRATION_STATE_DENIED) -static void run_all_3gpp_registration_checks_ready (MMBroadbandModem *self, - GAsyncResult *res, - RegisterIn3gppNetworkContext *ctx); +static void run_3gpp_registration_checks_ready (MMBroadbandModem *self, + GAsyncResult *res, + RegisterIn3gppNetworkContext *ctx); static gboolean -run_all_3gpp_registration_checks_again (RegisterIn3gppNetworkContext *ctx) +run_3gpp_registration_checks_again (RegisterIn3gppNetworkContext *ctx) { /* Get fresh registration state */ - mm_iface_modem_3gpp_run_all_registration_checks ( + mm_iface_modem_3gpp_run_registration_checks ( MM_IFACE_MODEM_3GPP (ctx->self), - (GAsyncReadyCallback)run_all_3gpp_registration_checks_ready, + (GAsyncReadyCallback)run_3gpp_registration_checks_ready, ctx); return FALSE; } static void -run_all_3gpp_registration_checks_ready (MMBroadbandModem *self, - GAsyncResult *res, - RegisterIn3gppNetworkContext *ctx) +run_3gpp_registration_checks_ready (MMBroadbandModem *self, + GAsyncResult *res, + RegisterIn3gppNetworkContext *ctx) { GError *error = NULL; - mm_iface_modem_3gpp_run_all_registration_checks_finish (MM_IFACE_MODEM_3GPP (self), - res, - &error); + 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); @@ -2785,7 +2785,7 @@ run_all_3gpp_registration_checks_ready (MMBroadbandModem *self, */ mm_dbg ("Modem not yet registered in a 3GPP network... will recheck soon"); g_timeout_add_seconds (3, - (GSourceFunc)run_all_3gpp_registration_checks_again, + (GSourceFunc)run_3gpp_registration_checks_again, ctx); } @@ -2815,9 +2815,9 @@ register_in_3gpp_network_ready (MMBroadbandModem *self, /* Get fresh registration state */ ctx->timer = g_timer_new (); - mm_iface_modem_3gpp_run_all_registration_checks ( + mm_iface_modem_3gpp_run_registration_checks ( MM_IFACE_MODEM_3GPP (self), - (GAsyncReadyCallback)run_all_3gpp_registration_checks_ready, + (GAsyncReadyCallback)run_3gpp_registration_checks_ready, ctx); } @@ -2893,334 +2893,303 @@ modem_3gpp_register_in_network (MMIfaceModem3gpp *self, /* Get fresh registration state */ ctx->timer = g_timer_new (); - mm_iface_modem_3gpp_run_all_registration_checks ( + mm_iface_modem_3gpp_run_registration_checks ( MM_IFACE_MODEM_3GPP (self), - (GAsyncReadyCallback)run_all_3gpp_registration_checks_ready, + (GAsyncReadyCallback)run_3gpp_registration_checks_ready, ctx); } /*****************************************************************************/ -/* CS and PS Registration checks (3GPP interface) */ +/* Registration checks (3GPP interface) */ -static gboolean -modem_3gpp_run_cs_registration_check_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) +typedef struct { + MMBroadbandModem *self; + GSimpleAsyncResult *result; + gboolean cs_supported; + gboolean ps_supported; + gboolean run_cs; + gboolean run_ps; + gboolean running_cs; + gboolean running_ps; + GError *cs_error; + GError *ps_error; +} RunRegistrationChecksContext; + +static void +run_registration_checks_context_complete_and_free (RunRegistrationChecksContext *ctx) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); + g_simple_async_result_complete_in_idle (ctx->result); + if (ctx->cs_error) + g_error_free (ctx->cs_error); + if (ctx->ps_error) + g_error_free (ctx->ps_error); + g_object_unref (ctx->result); + g_object_unref (ctx->self); + g_free (ctx); } static gboolean -modem_3gpp_run_ps_registration_check_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) +modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error) { return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } +static void run_registration_checks_context_step (RunRegistrationChecksContext *ctx); + static void registration_status_check_ready (MMBroadbandModem *self, GAsyncResult *res, - GSimpleAsyncResult *operation_result) + RunRegistrationChecksContext *ctx) { const gchar *response; GError *error = NULL; + GMatchInfo *match_info; + guint i; + gboolean parsed; + gboolean cgreg; + MMModem3gppRegistrationState state; + MMModemAccessTechnology act; + gulong lac; + gulong cid; + + /* Only one must be running */ + g_assert (!(ctx->running_ps && ctx->running_cs) && + (ctx->running_cs || ctx->running_ps)); response = mm_base_modem_at_command_finish (MM_BASE_MODEM (self), res, &error); if (!response) { g_assert (error != NULL); - g_simple_async_result_take_error (operation_result, error); + if (ctx->running_cs) + ctx->cs_error = error; + else + ctx->ps_error = error; + + run_registration_checks_context_step (ctx); + return; } + /* Unsolicited registration status handlers will usually process the * response for us, but just in case they don't, do that here. */ - else if (!response[0]) + if (!response[0]) { /* Done */ - g_simple_async_result_set_op_res_gboolean (operation_result, TRUE); - else { - GMatchInfo *match_info; - guint i; - - /* Try to match the response */ - for (i = 0; - i < self->priv->modem_3gpp_registration_regex->len; - i++) { - if (g_regex_match ((GRegex *)g_ptr_array_index ( - self->priv->modem_3gpp_registration_regex, i), - response, - 0, - &match_info)) - break; - g_match_info_free (match_info); - match_info = NULL; - } - - if (!match_info) { - g_simple_async_result_set_error (operation_result, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Unknown registration status response: '%s'", - response); - } else { - GError *inner_error = NULL; - gboolean parsed; - gboolean cgreg = FALSE; - MMModem3gppRegistrationState state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; - MMModemAccessTechnology act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; - gulong lac = 0; - gulong cid = 0; - - parsed = mm_3gpp_parse_creg_response (match_info, - &state, - &lac, - &cid, - &act, - &cgreg, - &inner_error); - g_match_info_free (match_info); - - if (!parsed) { - if (inner_error) - g_simple_async_result_take_error (operation_result, inner_error); - else - g_simple_async_result_set_error (operation_result, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Error parsing registration response: '%s'", - response); - } else { - /* Report new registration state */ - if (cgreg) - mm_iface_modem_3gpp_update_ps_registration_state ( - MM_IFACE_MODEM_3GPP (self), - state, - act, - lac, - cid); - else - mm_iface_modem_3gpp_update_cs_registration_state ( - MM_IFACE_MODEM_3GPP (self), - state, - act, - lac, - cid); - - g_simple_async_result_set_op_res_gboolean (operation_result, TRUE); - } - } + run_registration_checks_context_step (ctx); + return; } - g_simple_async_result_complete (operation_result); - g_object_unref (operation_result); -} - -static void -modem_3gpp_run_cs_registration_check (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *result; - - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_3gpp_run_cs_registration_check); - - /* Check current CS-registration state. */ - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+CREG?", - 10, - FALSE, - (GAsyncReadyCallback)registration_status_check_ready, - result); -} - -static void -modem_3gpp_run_ps_registration_check (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data) -{ - GSimpleAsyncResult *result; - - result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_3gpp_run_ps_registration_check); - - /* Check current PS-registration state. */ - mm_base_modem_at_command (MM_BASE_MODEM (self), - "+CGREG?", - 10, - FALSE, - (GAsyncReadyCallback)registration_status_check_ready, - result); -} - -/*****************************************************************************/ -/* CS and PS Registrations cleanup (3GPP interface) */ - -typedef struct { - GSimpleAsyncResult *result; - gchar *command; - gboolean secondary_done; -} CleanupRegistrationContext; - -static void -cleanup_registration_context_free (CleanupRegistrationContext *ctx) -{ - g_object_unref (ctx->result); - g_free (ctx->command); - g_free (ctx); -} - -static gboolean -modem_3gpp_cleanup_cs_registration_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static gboolean -modem_3gpp_cleanup_ps_registration_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) -{ - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} + /* Try to match the response */ + for (i = 0; + i < self->priv->modem_3gpp_registration_regex->len; + i++) { + if (g_regex_match ((GRegex *)g_ptr_array_index ( + self->priv->modem_3gpp_registration_regex, i), + response, + 0, + &match_info)) + break; + g_match_info_free (match_info); + match_info = NULL; + } -static void -cleanup_registration_sequence_ready (MMBroadbandModem *self, - GAsyncResult *res, - CleanupRegistrationContext *ctx) -{ - GError *error = NULL; + if (!match_info) { + error = g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Unknown registration status response: '%s'", + response); + if (ctx->running_cs) + ctx->cs_error = error; + else + ctx->ps_error = error; - mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, &error); - if (error) { - g_simple_async_result_take_error (ctx->result, error); - g_simple_async_result_complete (ctx->result); - cleanup_registration_context_free (ctx); + run_registration_checks_context_step (ctx); return; } - if (!ctx->secondary_done) { - MMAtSerialPort *secondary; + cgreg = FALSE; + state = MM_MODEM_3GPP_REGISTRATION_STATE_UNKNOWN; + act = MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN; + lac = 0; + cid = 0; + parsed = mm_3gpp_parse_creg_response (match_info, + &state, + &lac, + &cid, + &act, + &cgreg, + &error); + g_match_info_free (match_info); - secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); - if (secondary) { - /* Now use the same registration setup in secondary port, if any */ - ctx->secondary_done = TRUE; - mm_base_modem_at_command_full ( - MM_BASE_MODEM (self), - secondary, - ctx->command, - 10, - FALSE, - NULL, /* cancellable */ - (GAsyncReadyCallback)cleanup_registration_sequence_ready, - ctx); - return; - } + if (!parsed) { + if (!error) + error = g_error_new (MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Error parsing registration response: '%s'", + response); + if (ctx->running_cs) + ctx->cs_error = error; + else + ctx->ps_error = error; + run_registration_checks_context_step (ctx); + return; } - /* Update registration state(s) */ - if (g_str_has_prefix (ctx->command, "+CREG")) - 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); - else + /* Report new registration state */ + if (cgreg) { + if (ctx->running_cs) + mm_dbg ("Got PS registration state when checking CS registration state"); 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); + state, + act, + lac, + cid); + } else { + if (ctx->running_ps) + mm_dbg ("Got CS registration state when checking PS registration state"); + mm_iface_modem_3gpp_update_cs_registration_state ( + MM_IFACE_MODEM_3GPP (self), + state, + act, + lac, + cid); + } - /* We're done */ - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - g_simple_async_result_complete (ctx->result); - cleanup_registration_context_free (ctx); + run_registration_checks_context_step (ctx); } static void -modem_3gpp_cleanup_cs_registration (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data) +run_registration_checks_context_step (RunRegistrationChecksContext *ctx) { - CleanupRegistrationContext *ctx; + ctx->running_cs = FALSE; + ctx->running_ps = FALSE; - ctx = g_new0 (CleanupRegistrationContext, 1); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_3gpp_cleanup_cs_registration); - ctx->command = g_strdup ("+CREG=0"); + if (ctx->run_cs) { + ctx->running_cs = TRUE; + ctx->run_cs = FALSE; + /* Check current CS-registration state. */ + mm_base_modem_at_command (MM_BASE_MODEM (ctx->self), + "+CREG?", + 10, + FALSE, + (GAsyncReadyCallback)registration_status_check_ready, + ctx); + return; + } - mm_base_modem_at_command_full ( - MM_BASE_MODEM (self), - mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)), - ctx->command, - 10, - FALSE, - NULL, /* cancellable */ - (GAsyncReadyCallback)cleanup_registration_sequence_ready, - ctx); + if (ctx->run_ps) { + ctx->running_ps = TRUE; + ctx->run_ps = FALSE; + /* Check current PS-registration state. */ + mm_base_modem_at_command (MM_BASE_MODEM (ctx->self), + "+CGREG?", + 10, + FALSE, + (GAsyncReadyCallback)registration_status_check_ready, + ctx); + return; + } + + /* If all run checks returned errors we fail */ + if ((ctx->ps_supported && ctx->ps_error && ctx->cs_supported && ctx->cs_error) || + (ctx->ps_supported && ctx->ps_error && !ctx->cs_supported) || + (ctx->cs_supported && ctx->cs_error && !ctx->ps_supported)) { + /* Prefer the PS error if any */ + if (ctx->ps_error) { + g_simple_async_result_set_from_error (ctx->result, ctx->ps_error); + ctx->ps_error = NULL; + } else if (ctx->cs_error) { + g_simple_async_result_set_from_error (ctx->result, ctx->cs_error); + ctx->cs_error = NULL; + } else + g_assert_not_reached (); + } else + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + + run_registration_checks_context_complete_and_free (ctx); } static void -modem_3gpp_cleanup_ps_registration (MMIfaceModem3gpp *self, +modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self, + gboolean cs_supported, + gboolean ps_supported, GAsyncReadyCallback callback, gpointer user_data) { - CleanupRegistrationContext *ctx; + RunRegistrationChecksContext *ctx; - ctx = g_new0 (CleanupRegistrationContext, 1); + ctx = g_new0 (RunRegistrationChecksContext, 1); + ctx->self = g_object_ref (self); ctx->result = g_simple_async_result_new (G_OBJECT (self), callback, user_data, - modem_3gpp_cleanup_cs_registration); - ctx->command = g_strdup ("+CGREG=0"); + modem_3gpp_run_registration_checks); + ctx->cs_supported = cs_supported; + ctx->ps_supported = ps_supported; + ctx->run_cs = cs_supported; + ctx->run_ps = ps_supported; - mm_base_modem_at_command_full ( - MM_BASE_MODEM (self), - mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)), - ctx->command, - 10, - FALSE, - NULL, /* cancellable */ - (GAsyncReadyCallback)cleanup_registration_sequence_ready, - ctx); + run_registration_checks_context_step (ctx); } /*****************************************************************************/ -/* CS and PS Registrations setup (3GPP interface) */ +/* Enable/Disable unsolicited registration events (3GPP interface) */ typedef struct { + MMBroadbandModem *self; GSimpleAsyncResult *result; + gboolean enable; /* TRUE for enabling, FALSE for disabling */ + gboolean run_cs; + gboolean run_ps; + gboolean running_cs; + gboolean running_ps; + GError *cs_error; + GError *ps_error; + gboolean secondary_sequence; gboolean secondary_done; -} SetupRegistrationContext; +} UnsolicitedRegistrationEventsContext; static void -setup_registration_context_free (SetupRegistrationContext *ctx) +unsolicited_registration_events_context_complete_and_free (UnsolicitedRegistrationEventsContext *ctx) { + g_simple_async_result_complete_in_idle (ctx->result); + if (ctx->cs_error) + g_error_free (ctx->cs_error); + if (ctx->ps_error) + g_error_free (ctx->ps_error); g_object_unref (ctx->result); + g_object_unref (ctx->self); g_free (ctx); } -static gboolean -modem_3gpp_setup_cs_registration_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) +static UnsolicitedRegistrationEventsContext * +unsolicited_registration_events_context_new (MMBroadbandModem *self, + gboolean enable, + gboolean cs_supported, + gboolean ps_supported, + GAsyncReadyCallback callback, + gpointer user_data) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); + UnsolicitedRegistrationEventsContext *ctx; + + ctx = g_new0 (UnsolicitedRegistrationEventsContext, 1); + ctx->self = g_object_ref (self); + ctx->result = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + unsolicited_registration_events_context_new); + ctx->enable = FALSE; + ctx->run_cs = cs_supported; + ctx->run_ps = ps_supported; + + return ctx; } static gboolean -modem_3gpp_setup_ps_registration_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error) +modem_3gpp_enable_disable_unsolicited_registration_events_finish (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error) { return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } @@ -3252,6 +3221,12 @@ static const MMBaseModemAtCommand cs_registration_sequence[] = { { NULL } }; +static const MMBaseModemAtCommand cs_unregistration_sequence[] = { + /* Disable unsolicited registration notifications in CS network */ + { "+CREG=0", 3, FALSE, parse_registration_setup_reply }, + { NULL } +}; + static const MMBaseModemAtCommand ps_registration_sequence[] = { /* Enable unsolicited registration notifications in PS network, with location */ { "+CGREG=2", 3, FALSE, parse_registration_setup_reply }, @@ -3260,103 +3235,195 @@ static const MMBaseModemAtCommand ps_registration_sequence[] = { { NULL } }; +static const MMBaseModemAtCommand ps_unregistration_sequence[] = { + /* Disable unsolicited registration notifications in PS network */ + { "+CGREG=0", 3, FALSE, parse_registration_setup_reply }, + { NULL } +}; + +static void unsolicited_registration_events_context_step (UnsolicitedRegistrationEventsContext *ctx); + static void -setup_registration_sequence_ready (MMBroadbandModem *self, - GAsyncResult *res, - SetupRegistrationContext *ctx) +unsolicited_registration_events_sequence_ready (MMBroadbandModem *self, + GAsyncResult *res, + UnsolicitedRegistrationEventsContext *ctx) { GError *error = NULL; + GVariant *command; + MMAtSerialPort *secondary; + + /* Only one must be running */ + g_assert (!(ctx->running_ps && ctx->running_cs) && + (ctx->running_cs || ctx->running_ps)); if (ctx->secondary_done) { - mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, &error); + if (ctx->secondary_sequence) + mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &error); + else + mm_base_modem_at_command_full_finish (MM_BASE_MODEM (self), res, &error); + if (error) { - g_simple_async_result_take_error (ctx->result, error); - g_simple_async_result_complete (ctx->result); - setup_registration_context_free (ctx); - return; - } - /* success */ - } else { - GVariant *command; - MMAtSerialPort *secondary; - - command = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &error); - if (!command) { - g_assert (error != NULL); - g_simple_async_result_take_error (ctx->result, error); - g_simple_async_result_complete (ctx->result); - setup_registration_context_free (ctx); - return; + mm_dbg ("%s unsolicited registration events in secondary port failed: '%s'", + ctx->enable ? "Enabling" : "Disabling", + error->message); + /* Keep errors reported */ + if (ctx->running_cs && !ctx->cs_error) + ctx->cs_error = error; + else if (ctx->running_ps && !ctx->ps_error) + ctx->ps_error = error; + else + g_error_free (error); + } else { + /* If successful in secondary port, cleanup primary error if any */ + if (ctx->running_cs && ctx->cs_error) { + g_error_free (ctx->cs_error); + ctx->cs_error = NULL; + } + else if (ctx->running_ps && ctx->ps_error) { + g_error_free (ctx->ps_error); + ctx->ps_error = NULL; + } } - secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); - if (secondary) { - /* Now use the same registration setup in secondary port, if any */ - ctx->secondary_done = TRUE; + /* Done with primary and secondary, keep on */ + unsolicited_registration_events_context_step (ctx); + return; + } + + /* We just run the sequence in the primary port */ + command = mm_base_modem_at_sequence_finish (MM_BASE_MODEM (self), res, NULL, &error); + if (!command) { + g_assert (error != NULL); + mm_dbg ("%s unsolicited registration events in primary port failed: '%s'", + ctx->enable ? "Enabling" : "Disabling", + error->message); + /* Keep errors reported */ + if (ctx->running_cs) + ctx->cs_error = error; + else + ctx->ps_error = error; + /* Even if primary failed, go on and try to enable in secondary port */ + } + + secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); + if (secondary) { + ctx->secondary_done = TRUE; + + /* Now use the same registration setup in secondary port, if any */ + if (command) { mm_base_modem_at_command_full ( MM_BASE_MODEM (self), - mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)), + secondary, g_variant_get_string (command, NULL), 3, FALSE, NULL, /* cancellable */ - (GAsyncReadyCallback)setup_registration_sequence_ready, + (GAsyncReadyCallback)unsolicited_registration_events_sequence_ready, ctx); return; } - /* success */ + + /* If primary failed, run the whole sequence in secondary */ + ctx->secondary_sequence = TRUE; + mm_base_modem_at_sequence_full ( + MM_BASE_MODEM (self), + secondary, + (ctx->running_cs ? + (ctx->enable ? cs_registration_sequence : cs_unregistration_sequence) : + (ctx->enable ? ps_registration_sequence : ps_unregistration_sequence)), + NULL, /* response processor context */ + NULL, /* response processor context free */ + NULL, /* cancellable */ + (GAsyncReadyCallback)unsolicited_registration_events_sequence_ready, + ctx); + return; } /* We're done */ - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - g_simple_async_result_complete (ctx->result); - setup_registration_context_free (ctx); + unsolicited_registration_events_context_step (ctx); } static void -modem_3gpp_setup_cs_registration (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data) +unsolicited_registration_events_context_step (UnsolicitedRegistrationEventsContext *ctx) { - SetupRegistrationContext *ctx; + ctx->running_cs = FALSE; + ctx->running_ps = FALSE; + ctx->secondary_done = FALSE; - ctx = g_new0 (SetupRegistrationContext, 1); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_3gpp_setup_cs_registration); - mm_base_modem_at_sequence_full ( - MM_BASE_MODEM (self), - mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)), - cs_registration_sequence, - NULL, /* response processor context */ - NULL, /* response processor context free */ - NULL, /* cancellable */ - (GAsyncReadyCallback)setup_registration_sequence_ready, - ctx); + if (ctx->run_cs) { + ctx->running_cs = TRUE; + ctx->run_cs = FALSE; + mm_base_modem_at_sequence_full ( + MM_BASE_MODEM (ctx->self), + mm_base_modem_peek_port_primary (MM_BASE_MODEM (ctx->self)), + cs_registration_sequence, + NULL, /* response processor context */ + NULL, /* response processor context free */ + NULL, /* cancellable */ + (GAsyncReadyCallback)unsolicited_registration_events_sequence_ready, + ctx); + return; + } + + if (ctx->run_ps) { + ctx->running_ps = TRUE; + ctx->run_ps = FALSE; + mm_base_modem_at_sequence_full ( + MM_BASE_MODEM (ctx->self), + mm_base_modem_peek_port_primary (MM_BASE_MODEM (ctx->self)), + ps_registration_sequence, + NULL, /* response processor context */ + NULL, /* response processor context free */ + NULL, /* cancellable */ + (GAsyncReadyCallback)unsolicited_registration_events_sequence_ready, + ctx); + return; + } + + /* All done! + * If we have any error reported, we'll propagate it. PS errors take + * precendence over CS errors. */ + if (ctx->ps_error) { + g_simple_async_result_take_error (ctx->result, ctx->ps_error); + ctx->ps_error = NULL; + } else if (ctx->cs_error) { + g_simple_async_result_take_error (ctx->result, ctx->cs_error); + ctx->cs_error = NULL; + } else + g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); + unsolicited_registration_events_context_complete_and_free (ctx); } static void -modem_3gpp_setup_ps_registration (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data) +modem_3gpp_disable_unsolicited_registration_events (MMIfaceModem3gpp *self, + gboolean cs_supported, + gboolean ps_supported, + GAsyncReadyCallback callback, + gpointer user_data) { - SetupRegistrationContext *ctx; + unsolicited_registration_events_context_step ( + unsolicited_registration_events_context_new (MM_BROADBAND_MODEM (self), + FALSE, + cs_supported, + ps_supported, + callback, + user_data)); +} - ctx = g_new0 (SetupRegistrationContext, 1); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - modem_3gpp_setup_ps_registration); - mm_base_modem_at_sequence_full ( - MM_BASE_MODEM (self), - mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)), - ps_registration_sequence, - NULL, /* response processor context */ - NULL, /* response processor context free */ - NULL, /* cancellable */ - (GAsyncReadyCallback)setup_registration_sequence_ready, - ctx); +static void +modem_3gpp_enable_unsolicited_registration_events (MMIfaceModem3gpp *self, + gboolean cs_supported, + gboolean ps_supported, + GAsyncReadyCallback callback, + gpointer user_data) +{ + unsolicited_registration_events_context_step ( + unsolicited_registration_events_context_new (MM_BROADBAND_MODEM (self), + TRUE, + cs_supported, + ps_supported, + callback, + user_data)); } /*****************************************************************************/ @@ -6098,7 +6165,7 @@ enable_location_gathering (MMIfaceModemLocation *self, if (source == MM_MODEM_LOCATION_SOURCE_3GPP_LAC_CI && mm_iface_modem_is_3gpp (MM_IFACE_MODEM (self))) { /* Reload registration to get LAC/CI */ - mm_iface_modem_3gpp_run_all_registration_checks (MM_IFACE_MODEM_3GPP (self), NULL, NULL); + mm_iface_modem_3gpp_run_registration_checks (MM_IFACE_MODEM_3GPP (self), NULL, NULL); /* Reload operator to get MCC/MNC */ mm_iface_modem_3gpp_reload_current_operator (MM_IFACE_MODEM_3GPP (self)); } @@ -7912,34 +7979,28 @@ iface_modem_3gpp_init (MMIfaceModem3gpp *iface) iface->setup_unsolicited_events_finish = modem_3gpp_setup_cleanup_unsolicited_events_finish; iface->enable_unsolicited_events = modem_3gpp_enable_unsolicited_events; iface->enable_unsolicited_events_finish = modem_3gpp_enable_disable_unsolicited_events_finish; - iface->setup_unsolicited_registration = modem_3gpp_setup_unsolicited_registration; - iface->setup_unsolicited_registration_finish = modem_3gpp_setup_unsolicited_registration_finish; - iface->setup_cs_registration = modem_3gpp_setup_cs_registration; - iface->setup_cs_registration_finish = modem_3gpp_setup_cs_registration_finish; - iface->setup_ps_registration = modem_3gpp_setup_ps_registration; - iface->setup_ps_registration_finish = modem_3gpp_setup_ps_registration_finish; + iface->setup_unsolicited_registration_events = modem_3gpp_setup_unsolicited_registration_events; + iface->setup_unsolicited_registration_events_finish = modem_3gpp_setup_unsolicited_registration_events_finish; + iface->enable_unsolicited_registration_events = modem_3gpp_enable_unsolicited_registration_events; + iface->enable_unsolicited_registration_events_finish = modem_3gpp_enable_disable_unsolicited_registration_events_finish; /* Disabling steps */ iface->disable_unsolicited_events = modem_3gpp_disable_unsolicited_events; iface->disable_unsolicited_events_finish = modem_3gpp_enable_disable_unsolicited_events_finish; iface->cleanup_unsolicited_events = modem_3gpp_cleanup_unsolicited_events; iface->cleanup_unsolicited_events_finish = modem_3gpp_setup_cleanup_unsolicited_events_finish; - iface->cleanup_unsolicited_registration = modem_3gpp_cleanup_unsolicited_registration; - iface->cleanup_unsolicited_registration_finish = modem_3gpp_cleanup_unsolicited_registration_finish; - iface->cleanup_cs_registration = modem_3gpp_cleanup_cs_registration; - iface->cleanup_cs_registration_finish = modem_3gpp_cleanup_cs_registration_finish; - iface->cleanup_ps_registration = modem_3gpp_cleanup_ps_registration; - iface->cleanup_ps_registration_finish = modem_3gpp_cleanup_ps_registration_finish; + iface->disable_unsolicited_registration_events = modem_3gpp_disable_unsolicited_registration_events; + iface->disable_unsolicited_registration_events_finish = modem_3gpp_enable_disable_unsolicited_registration_events_finish; + iface->cleanup_unsolicited_registration_events = modem_3gpp_cleanup_unsolicited_registration_events; + iface->cleanup_unsolicited_registration_events_finish = modem_3gpp_cleanup_unsolicited_registration_events_finish; /* Additional actions */ iface->load_operator_code = modem_3gpp_load_operator_code; iface->load_operator_code_finish = modem_3gpp_load_operator_code_finish; iface->load_operator_name = modem_3gpp_load_operator_name; iface->load_operator_name_finish = modem_3gpp_load_operator_name_finish; - iface->run_cs_registration_check = modem_3gpp_run_cs_registration_check; - iface->run_cs_registration_check_finish = modem_3gpp_run_cs_registration_check_finish; - iface->run_ps_registration_check = modem_3gpp_run_ps_registration_check; - iface->run_ps_registration_check_finish = modem_3gpp_run_ps_registration_check_finish; + iface->run_registration_checks = modem_3gpp_run_registration_checks; + iface->run_registration_checks_finish = modem_3gpp_run_registration_checks_finish; iface->register_in_network = modem_3gpp_register_in_network; iface->register_in_network_finish = modem_3gpp_register_in_network_finish; iface->scan_networks = modem_3gpp_scan_networks; diff --git a/src/mm-iface-modem-3gpp.c b/src/mm-iface-modem-3gpp.c index 8d6c6ce0..50d1f8b5 100644 --- a/src/mm-iface-modem-3gpp.c +++ b/src/mm-iface-modem-3gpp.c @@ -434,121 +434,34 @@ handle_scan (MmGdbusModem3gpp *skeleton, /*****************************************************************************/ -typedef struct { - GSimpleAsyncResult *result; - gboolean cs_supported; - gboolean ps_supported; - gboolean cs_done; - GError *cs_reg_error; - GError *ps_reg_error; -} RunAllRegistrationChecksContext; - -static void -run_all_registration_checks_context_complete_and_free (RunAllRegistrationChecksContext *ctx) -{ - g_simple_async_result_complete_in_idle (ctx->result); - g_clear_error (&ctx->cs_reg_error); - g_clear_error (&ctx->ps_reg_error); - g_object_unref (ctx->result); - g_free (ctx); -} - gboolean -mm_iface_modem_3gpp_run_all_registration_checks_finish (MMIfaceModem3gpp *self, +mm_iface_modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self, GAsyncResult *res, GError **error) { - return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); -} - -static void -run_ps_registration_check_ready (MMIfaceModem3gpp *self, - GAsyncResult *res, - RunAllRegistrationChecksContext *ctx) -{ - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_ps_registration_check_finish (self, res, &ctx->ps_reg_error); - - /* If both CS and PS registration checks returned errors we fail */ - if (ctx->ps_reg_error && - (ctx->cs_reg_error || !ctx->cs_done)) - /* Prefer the PS error */ - g_simple_async_result_set_from_error (ctx->result, ctx->ps_reg_error); - else - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - run_all_registration_checks_context_complete_and_free (ctx); -} - -static void -run_cs_registration_check_ready (MMIfaceModem3gpp *self, - GAsyncResult *res, - RunAllRegistrationChecksContext *ctx) -{ - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_cs_registration_check_finish (self, res, &ctx->cs_reg_error); - - if (ctx->ps_supported && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_ps_registration_check && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_ps_registration_check_finish) { - ctx->cs_done = TRUE; - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_ps_registration_check ( - self, - (GAsyncReadyCallback)run_ps_registration_check_ready, - ctx); - return; - } - - /* All done */ - if (ctx->cs_reg_error) - g_simple_async_result_set_from_error (ctx->result, ctx->cs_reg_error); - else - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - run_all_registration_checks_context_complete_and_free (ctx); + 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); } void -mm_iface_modem_3gpp_run_all_registration_checks (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data) +mm_iface_modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self, + GAsyncReadyCallback callback, + gpointer user_data) { - RunAllRegistrationChecksContext *ctx; + gboolean cs_supported = FALSE; + gboolean ps_supported = FALSE; - ctx = g_new0 (RunAllRegistrationChecksContext, 1); - ctx->result = g_simple_async_result_new (G_OBJECT (self), - callback, - user_data, - mm_iface_modem_3gpp_run_all_registration_checks); + g_assert (MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks != NULL); g_object_get (self, - MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ctx->ps_supported, - MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &ctx->cs_supported, + MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &cs_supported, + MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ps_supported, NULL); - mm_dbg ("Running registration checks (CS: '%s', PS: '%s')", - ctx->cs_supported ? "yes" : "no", - ctx->ps_supported ? "yes" : "no"); - - if (ctx->cs_supported && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_cs_registration_check && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_cs_registration_check_finish) { - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_cs_registration_check ( - self, - (GAsyncReadyCallback)run_cs_registration_check_ready, - ctx); - return; - } - - if (ctx->ps_supported && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_ps_registration_check && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_ps_registration_check_finish) { - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_ps_registration_check ( - self, - (GAsyncReadyCallback)run_ps_registration_check_ready, - ctx); - return; - } - - /* Nothing to do :-/ all done */ - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - run_all_registration_checks_context_complete_and_free (ctx); + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->run_registration_checks (self, + cs_supported, + ps_supported, + callback, user_data); } /*****************************************************************************/ @@ -879,7 +792,7 @@ periodic_registration_checks_ready (MMIfaceModem3gpp *self, RegistrationCheckContext *ctx; GError *error = NULL; - mm_iface_modem_3gpp_run_all_registration_checks_finish (self, res, &error); + mm_iface_modem_3gpp_run_registration_checks_finish (self, res, &error); if (error) { mm_dbg ("Couldn't refresh 3GPP registration status: '%s'", error->message); g_error_free (error); @@ -899,7 +812,7 @@ periodic_registration_check (MMIfaceModem3gpp *self) ctx = g_object_get_qdata (G_OBJECT (self), registration_check_context_quark); if (!ctx->running) { ctx->running = TRUE; - mm_iface_modem_3gpp_run_all_registration_checks ( + mm_iface_modem_3gpp_run_registration_checks ( self, (GAsyncReadyCallback)periodic_registration_checks_ready, NULL); @@ -957,9 +870,8 @@ static void interface_disabling_step (DisablingContext *ctx); typedef enum { DISABLING_STEP_FIRST, DISABLING_STEP_PERIODIC_REGISTRATION_CHECKS, - DISABLING_STEP_CLEANUP_PS_REGISTRATION, - DISABLING_STEP_CLEANUP_CS_REGISTRATION, - DISABLING_STEP_CLEANUP_UNSOLICITED_REGISTRATION, + DISABLING_STEP_DISABLE_UNSOLICITED_REGISTRATION_EVENTS, + DISABLING_STEP_CLEANUP_UNSOLICITED_REGISTRATION_EVENTS, DISABLING_STEP_CLEANUP_UNSOLICITED_EVENTS, DISABLING_STEP_DISABLE_UNSOLICITED_EVENTS, DISABLING_STEP_LAST @@ -1032,16 +944,14 @@ mm_iface_modem_3gpp_disable_finish (MMIfaceModem3gpp *self, interface_disabling_step (ctx); \ } -VOID_REPLY_READY_FN (cleanup_unsolicited_registration, - "cleanup unsolicited registration") -VOID_REPLY_READY_FN (cleanup_ps_registration, - "cleanup PS registration") -VOID_REPLY_READY_FN (cleanup_cs_registration, - "cleanup CS registration") VOID_REPLY_READY_FN (cleanup_unsolicited_events, "cleanup unsolicited events") VOID_REPLY_READY_FN (disable_unsolicited_events, "disable unsolicited events") +VOID_REPLY_READY_FN (cleanup_unsolicited_registration_events, + "cleanup unsolicited registration events") +VOID_REPLY_READY_FN (disable_unsolicited_registration_events, + "disable unsolicited registration events") static void interface_disabling_step (DisablingContext *ctx) @@ -1056,39 +966,22 @@ interface_disabling_step (DisablingContext *ctx) /* Fall down to next step */ ctx->step++; - case DISABLING_STEP_CLEANUP_PS_REGISTRATION: { - gboolean ps_supported = FALSE; - - g_object_get (ctx->self, - MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ps_supported, - NULL); - - if (ps_supported && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_ps_registration && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_ps_registration_finish) { - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_ps_registration ( - ctx->self, - (GAsyncReadyCallback)cleanup_ps_registration_ready, - ctx); - return; - } - /* Fall down to next step */ - ctx->step++; - } - - case DISABLING_STEP_CLEANUP_CS_REGISTRATION: { + case DISABLING_STEP_DISABLE_UNSOLICITED_REGISTRATION_EVENTS: { gboolean cs_supported = FALSE; + gboolean ps_supported = FALSE; g_object_get (ctx->self, MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &cs_supported, + MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ps_supported, NULL); - if (cs_supported && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_cs_registration && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_cs_registration_finish) { - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_cs_registration ( + if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_registration_events && + MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_registration_events_finish) { + MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->disable_unsolicited_registration_events ( ctx->self, - (GAsyncReadyCallback)cleanup_cs_registration_ready, + cs_supported, + ps_supported, + (GAsyncReadyCallback)disable_unsolicited_registration_events_ready, ctx); return; } @@ -1096,12 +989,12 @@ interface_disabling_step (DisablingContext *ctx) ctx->step++; } - case DISABLING_STEP_CLEANUP_UNSOLICITED_REGISTRATION: - if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_registration && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_registration_finish) { - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_registration ( + case DISABLING_STEP_CLEANUP_UNSOLICITED_REGISTRATION_EVENTS: + if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_registration_events && + MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_registration_events_finish) { + MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->cleanup_unsolicited_registration_events ( ctx->self, - (GAsyncReadyCallback)cleanup_unsolicited_registration_ready, + (GAsyncReadyCallback)cleanup_unsolicited_registration_events_ready, ctx); return; } @@ -1161,10 +1054,9 @@ typedef enum { ENABLING_STEP_FIRST, ENABLING_STEP_SETUP_UNSOLICITED_EVENTS, ENABLING_STEP_ENABLE_UNSOLICITED_EVENTS, - ENABLING_STEP_SETUP_UNSOLICITED_REGISTRATION, - ENABLING_STEP_SETUP_CS_REGISTRATION, - ENABLING_STEP_SETUP_PS_REGISTRATION, - ENABLING_STEP_RUN_ALL_REGISTRATION_CHECKS, + ENABLING_STEP_SETUP_UNSOLICITED_REGISTRATION_EVENTS, + ENABLING_STEP_ENABLE_UNSOLICITED_REGISTRATION_EVENTS, + ENABLING_STEP_RUN_REGISTRATION_CHECKS, ENABLING_STEP_LAST } EnablingStep; @@ -1233,46 +1125,6 @@ mm_iface_modem_3gpp_enable_finish (MMIfaceModem3gpp *self, return !g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error); } -#undef VOID_REPLY_READY_FN -#define VOID_REPLY_READY_FN(NAME) \ - static void \ - NAME##_ready (MMIfaceModem3gpp *self, \ - GAsyncResult *res, \ - EnablingContext *ctx) \ - { \ - GError *error = NULL; \ - \ - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->NAME##_finish (self, res, &error); \ - if (error) { \ - g_simple_async_result_take_error (ctx->result, error); \ - enabling_context_complete_and_free (ctx); \ - return; \ - } \ - \ - /* Go on to next step */ \ - ctx->step++; \ - interface_enabling_step (ctx); \ - } - -static void -enable_unsolicited_events_ready (MMIfaceModem3gpp *self, - GAsyncResult *res, - EnablingContext *ctx) -{ - GError *error = NULL; - - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error); - if (error) { - /* This error shouldn't be treated as critical */ - mm_dbg ("Enabling unsolicited events failed: '%s'", error->message); - g_error_free (error); - } - - /* Go on to next step */ - ctx->step++; - interface_enabling_step (ctx); -} - static void setup_unsolicited_events_ready (MMIfaceModem3gpp *self, GAsyncResult *res, @@ -1299,18 +1151,16 @@ setup_unsolicited_events_ready (MMIfaceModem3gpp *self, } static void -setup_cs_registration_ready (MMIfaceModem3gpp *self, - GAsyncResult *res, - EnablingContext *ctx) +enable_unsolicited_events_ready (MMIfaceModem3gpp *self, + GAsyncResult *res, + EnablingContext *ctx) { GError *error = NULL; - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->setup_cs_registration_finish (self, res, &error); + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->enable_unsolicited_events_finish (self, res, &error); if (error) { - /* If error, setup periodic registration checks */ - periodic_registration_check_enable (ctx->self); - mm_dbg ("Couldn't setup CS registration: '%s'", - error->message); + /* This error shouldn't be treated as critical */ + mm_dbg ("Enabling unsolicited events failed: '%s'", error->message); g_error_free (error); } @@ -1320,19 +1170,25 @@ setup_cs_registration_ready (MMIfaceModem3gpp *self, } static void -setup_ps_registration_ready (MMIfaceModem3gpp *self, - GAsyncResult *res, - EnablingContext *ctx) +setup_unsolicited_registration_events_ready (MMIfaceModem3gpp *self, + GAsyncResult *res, + EnablingContext *ctx) { GError *error = NULL; - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->setup_ps_registration_finish (self, res, &error); + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->setup_unsolicited_registration_events_finish (self, res, &error); if (error) { + /* This error shouldn't be treated as critical */ + mm_dbg ("Setting up unsolicited registration events failed: '%s'", error->message); + g_error_free (error); + + /* If we get an error setting up unsolicited events, don't even bother trying to + * enable them. */ + ctx->step = ENABLING_STEP_ENABLE_UNSOLICITED_REGISTRATION_EVENTS + 1; + interface_enabling_step (ctx); /* If error, setup periodic registration checks */ periodic_registration_check_enable (ctx->self); - mm_dbg ("Couldn't setup PS registration: '%s'", - error->message); - g_error_free (error); + return; } /* Go on to next step */ @@ -1341,17 +1197,19 @@ setup_ps_registration_ready (MMIfaceModem3gpp *self, } static void -run_all_registration_checks_ready (MMIfaceModem3gpp *self, - GAsyncResult *res, - EnablingContext *ctx) +enable_unsolicited_registration_events_ready (MMIfaceModem3gpp *self, + GAsyncResult *res, + EnablingContext *ctx) { GError *error = NULL; - mm_iface_modem_3gpp_run_all_registration_checks_finish (self, res, &error); + MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->enable_unsolicited_registration_events_finish (self, res, &error); if (error) { - g_simple_async_result_take_error (ctx->result, error); - enabling_context_complete_and_free (ctx); - return; + /* This error shouldn't be treated as critical */ + mm_dbg ("Enabling unsolicited registration events failed: '%s'", error->message); + g_error_free (error); + /* If error, setup periodic registration checks */ + periodic_registration_check_enable (ctx->self); } /* Go on to next step */ @@ -1360,13 +1218,13 @@ run_all_registration_checks_ready (MMIfaceModem3gpp *self, } static void -setup_unsolicited_registration_ready (MMIfaceModem3gpp *self, - GAsyncResult *res, - EnablingContext *ctx) +run_all_registration_checks_ready (MMIfaceModem3gpp *self, + GAsyncResult *res, + EnablingContext *ctx) { GError *error = NULL; - MM_IFACE_MODEM_3GPP_GET_INTERFACE (self)->setup_unsolicited_registration_finish (self, res, &error); + mm_iface_modem_3gpp_run_registration_checks_finish (self, res, &error); if (error) { g_simple_async_result_take_error (ctx->result, error); enabling_context_complete_and_free (ctx); @@ -1414,59 +1272,43 @@ interface_enabling_step (EnablingContext *ctx) /* Fall down to next step */ ctx->step++; - case ENABLING_STEP_SETUP_UNSOLICITED_REGISTRATION: - if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_registration && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_registration_finish) { - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_registration ( + case ENABLING_STEP_SETUP_UNSOLICITED_REGISTRATION_EVENTS: + if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_registration_events && + MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_registration_events_finish) { + MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_unsolicited_registration_events ( ctx->self, - (GAsyncReadyCallback)setup_unsolicited_registration_ready, + (GAsyncReadyCallback)setup_unsolicited_registration_events_ready, ctx); return; } /* Fall down to next step */ ctx->step++; - case ENABLING_STEP_SETUP_CS_REGISTRATION: { + case ENABLING_STEP_ENABLE_UNSOLICITED_REGISTRATION_EVENTS: { gboolean cs_supported = FALSE; - - g_object_get (ctx->self, - MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &cs_supported, - NULL); - - if (cs_supported && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_cs_registration && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_cs_registration_finish) { - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_cs_registration ( - ctx->self, - (GAsyncReadyCallback)setup_cs_registration_ready, - ctx); - return; - } - /* Fall down to next step */ - ctx->step++; - } - - case ENABLING_STEP_SETUP_PS_REGISTRATION: { gboolean ps_supported = FALSE; g_object_get (ctx->self, + MM_IFACE_MODEM_3GPP_CS_NETWORK_SUPPORTED, &cs_supported, MM_IFACE_MODEM_3GPP_PS_NETWORK_SUPPORTED, &ps_supported, NULL); - if (ps_supported && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_ps_registration && - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_ps_registration_finish) { - MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->setup_ps_registration ( + if (MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_registration_events && + MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_registration_events_finish) { + MM_IFACE_MODEM_3GPP_GET_INTERFACE (ctx->self)->enable_unsolicited_registration_events ( ctx->self, - (GAsyncReadyCallback)setup_ps_registration_ready, + cs_supported, + ps_supported, + (GAsyncReadyCallback)enable_unsolicited_registration_events_ready, ctx); return; } /* Fall down to next step */ ctx->step++; } - case ENABLING_STEP_RUN_ALL_REGISTRATION_CHECKS: - mm_iface_modem_3gpp_run_all_registration_checks ( + + case ENABLING_STEP_RUN_REGISTRATION_CHECKS: + mm_iface_modem_3gpp_run_registration_checks ( ctx->self, (GAsyncReadyCallback)run_all_registration_checks_ready, ctx); diff --git a/src/mm-iface-modem-3gpp.h b/src/mm-iface-modem-3gpp.h index 12dc8bda..c0fe03d0 100644 --- a/src/mm-iface-modem-3gpp.h +++ b/src/mm-iface-modem-3gpp.h @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details: * - * Copyright (C) 2011 Google, Inc. + * Copyright (C) 2011-2012 Google, Inc. */ #ifndef MM_IFACE_MODEM_3GPP_H @@ -99,73 +99,52 @@ struct _MMIfaceModem3gpp { GError **error); /* Setup unsolicited registration messages */ - void (* setup_unsolicited_registration) (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (*setup_unsolicited_registration_finish) (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error); + void (* setup_unsolicited_registration_events) (MMIfaceModem3gpp *self, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*setup_unsolicited_registration_events_finish) (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error); + + /* Asynchronous enabling of unsolicited registration events */ + void (*enable_unsolicited_registration_events) (MMIfaceModem3gpp *self, + gboolean cs_supported, + gboolean ps_supported, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*enable_unsolicited_registration_events_finish) (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error); /* Cleanup unsolicited registration messages */ - void (* cleanup_unsolicited_registration) (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (*cleanup_unsolicited_registration_finish) (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error); - - /* Setup CS Registration */ - void (* setup_cs_registration) (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (*setup_cs_registration_finish) (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error); - - /* Cleanup CS Registration */ - void (* cleanup_cs_registration) (MMIfaceModem3gpp *self, + void (* cleanup_unsolicited_registration_events) (MMIfaceModem3gpp *self, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*cleanup_unsolicited_registration_events_finish) (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error); + /* Asynchronous disabling of unsolicited registration events */ + void (*disable_unsolicited_registration_events) (MMIfaceModem3gpp *self, + gboolean cs_supported, + gboolean ps_supported, + GAsyncReadyCallback callback, + gpointer user_data); + gboolean (*disable_unsolicited_registration_events_finish) (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error); + + /* Run CS/PS registration state checks.. + * Note that no registration state is returned, implementations should call + * mm_iface_modem_3gpp_update_registration_state(). */ + void (* run_registration_checks) (MMIfaceModem3gpp *self, + gboolean cs_supported, + gboolean ps_supported, GAsyncReadyCallback callback, gpointer user_data); - gboolean (*cleanup_cs_registration_finish) (MMIfaceModem3gpp *self, + gboolean (*run_registration_checks_finish) (MMIfaceModem3gpp *self, GAsyncResult *res, GError **error); - /* Setup PS Registration */ - void (* setup_ps_registration) (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (*setup_ps_registration_finish) (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error); - - /* Cleanup PS Registration */ - void (* cleanup_ps_registration) (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (*cleanup_ps_registration_finish) (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error); - - /* Run CS registration state check. - * Note that no registration state is returned, implementations should call - * mm_iface_modem_3gpp_update_registration_state(). */ - void (* run_cs_registration_check) (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (*run_cs_registration_check_finish) (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error); - - /* Run PS registration state check. - * Note that no registration state is returned, implementations should call - * mm_iface_modem_3gpp_update_registration_state(). */ - void (* run_ps_registration_check) (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data); - gboolean (*run_ps_registration_check_finish) (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error); - /* Try to register in the network */ void (* register_in_network) (MMIfaceModem3gpp *self, const gchar *operator_id, @@ -247,12 +226,12 @@ void mm_iface_modem_3gpp_update_ps_registration_state (MMIfaceModem3gpp *self, gulong cell_id); /* Run all registration checks */ -void mm_iface_modem_3gpp_run_all_registration_checks (MMIfaceModem3gpp *self, - GAsyncReadyCallback callback, - gpointer user_data); -gboolean mm_iface_modem_3gpp_run_all_registration_checks_finish (MMIfaceModem3gpp *self, - GAsyncResult *res, - GError **error); +void mm_iface_modem_3gpp_run_registration_checks (MMIfaceModem3gpp *self, + GAsyncReadyCallback callback, + gpointer user_data); +gboolean mm_iface_modem_3gpp_run_registration_checks_finish (MMIfaceModem3gpp *self, + GAsyncResult *res, + GError **error); /* Request to reload current operator */ void mm_iface_modem_3gpp_reload_current_operator (MMIfaceModem3gpp *self); |