diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2020-06-28 14:05:58 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2020-06-28 15:07:34 +0200 |
commit | 4b37b7d3cfd8c8e98af25eed334b1880b6b6c597 (patch) | |
tree | abff683b28c0ffda31b0974107cd4d2b1d93fcbe | |
parent | c4d82aaf1e7cf10475204102533ac7784f83f0d3 (diff) |
base-modem,at: response processors return a more specific enum
Instead of using the FALSE return of the method to indicate either a
fatal error (if result_error was set) or the continuation request (if
result_error wasn't set), provide a enum that has explicit states for
all three possible values (failure, success or continue).
-rw-r--r-- | plugins/altair/mm-broadband-modem-altair-lte.c | 27 | ||||
-rw-r--r-- | plugins/huawei/mm-broadband-modem-huawei.c | 22 | ||||
-rw-r--r-- | plugins/icera/mm-broadband-modem-icera.c | 29 | ||||
-rw-r--r-- | plugins/novatel/mm-broadband-modem-novatel-lte.c | 61 | ||||
-rw-r--r-- | plugins/sierra/mm-broadband-modem-sierra.c | 28 | ||||
-rw-r--r-- | plugins/telit/mm-broadband-modem-telit.c | 81 | ||||
-rw-r--r-- | src/mm-base-modem-at.c | 189 | ||||
-rw-r--r-- | src/mm-base-modem-at.h | 112 | ||||
-rw-r--r-- | src/mm-broadband-modem.c | 192 |
9 files changed, 402 insertions, 339 deletions
diff --git a/plugins/altair/mm-broadband-modem-altair-lte.c b/plugins/altair/mm-broadband-modem-altair-lte.c index 54702172..9e555f5b 100644 --- a/plugins/altair/mm-broadband-modem-altair-lte.c +++ b/plugins/altair/mm-broadband-modem-altair-lte.c @@ -857,30 +857,11 @@ 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 }, - { "%PCOINFO=1", 10, FALSE, NULL }, - { NULL } + { "%STATCM=1", 10, FALSE, mm_base_modem_response_processor_no_result_continue }, + { "%NOTIFYEV=\"SIMREFRESH\",1", 10, FALSE, NULL }, + { "%PCOINFO=1", 10, FALSE, NULL }, + { NULL } }; static gboolean diff --git a/plugins/huawei/mm-broadband-modem-huawei.c b/plugins/huawei/mm-broadband-modem-huawei.c index a676b7a7..82e439e1 100644 --- a/plugins/huawei/mm-broadband-modem-huawei.c +++ b/plugins/huawei/mm-broadband-modem-huawei.c @@ -4137,15 +4137,15 @@ modem_time_check_ready (MMBaseModem *_self, g_object_unref (task); } -static gboolean -modem_check_time_reply (MMBaseModem *_self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) +static MMBaseModemAtResponseProcessorResult +modem_check_time_reply (MMBaseModem *_self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) { MMBroadbandModemHuawei *self = MM_BROADBAND_MODEM_HUAWEI (_self); @@ -4161,7 +4161,9 @@ modem_check_time_reply (MMBaseModem *_self, self->priv->time_support = FEATURE_NOT_SUPPORTED; } - return FALSE; + *result = NULL; + *result_error = NULL; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } static const MMBaseModemAtCommand time_cmd_sequence[] = { diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c index b459cb57..ebaac9ad 100644 --- a/plugins/icera/mm-broadband-modem-icera.c +++ b/plugins/icera/mm-broadband-modem-icera.c @@ -1223,18 +1223,21 @@ load_supported_bands_ready (MMBaseModem *self, g_object_unref (task); } -static gboolean -load_supported_bands_response_processor (MMBaseModem *self, - gpointer context, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) -{ - SupportedBandsContext *ctx = context; - Band *b = g_slist_nth_data (ctx->check_bands, ctx->idx++); +static MMBaseModemAtResponseProcessorResult +load_supported_bands_response_processor (MMBaseModem *self, + gpointer context, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) +{ + SupportedBandsContext *ctx; + Band *b; + + ctx = context; + b = g_slist_nth_data (ctx->check_bands, ctx->idx++); /* If there was no error setting the band, that band is supported. We * abuse the 'enabled' item to mean supported/unsupported. @@ -1242,7 +1245,7 @@ load_supported_bands_response_processor (MMBaseModem *self, b->enabled = !error; /* Continue to next band */ - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } static void diff --git a/plugins/novatel/mm-broadband-modem-novatel-lte.c b/plugins/novatel/mm-broadband-modem-novatel-lte.c index ebcbe499..df331381 100644 --- a/plugins/novatel/mm-broadband-modem-novatel-lte.c +++ b/plugins/novatel/mm-broadband-modem-novatel-lte.c @@ -184,54 +184,65 @@ load_own_numbers_finish (MMIfaceModem *self, return own_numbers; } -static gboolean -response_processor_cnum_ignore_at_errors (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) +static MMBaseModemAtResponseProcessorResult +response_processor_cnum_ignore_at_errors (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) { GStrv own_numbers; + *result = NULL; + *result_error = NULL; + if (error) { /* Ignore AT errors (ie, ERROR or CMx ERROR) */ - if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) + if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) { *result_error = g_error_copy (error); + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; + } - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } own_numbers = mm_3gpp_parse_cnum_exec_response (response); if (!own_numbers) - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; *result = g_variant_new_strv ((const gchar *const *) own_numbers, -1); g_strfreev (own_numbers); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } -static gboolean -response_processor_nwmdn_ignore_at_errors (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) +static MMBaseModemAtResponseProcessorResult +response_processor_nwmdn_ignore_at_errors (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) { g_auto(GStrv) own_numbers = NULL; GPtrArray *array; gchar *mdn; + *result = NULL; + *result_error = NULL; + if (error) { /* Ignore AT errors (ie, ERROR or CMx ERROR) */ - if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) + if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) { *result_error = g_error_copy (error); - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; + } + + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } mdn = g_strdup (mm_strip_tag (response, "$NWMDN:")); @@ -242,7 +253,7 @@ response_processor_nwmdn_ignore_at_errors (MMBaseModem *self, own_numbers = (GStrv) g_ptr_array_free (array, FALSE); *result = g_variant_new_strv ((const gchar *const *) own_numbers, -1); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } static const MMBaseModemAtCommand own_numbers_commands[] = { diff --git a/plugins/sierra/mm-broadband-modem-sierra.c b/plugins/sierra/mm-broadband-modem-sierra.c index c08aec48..7e2dba9b 100644 --- a/plugins/sierra/mm-broadband-modem-sierra.c +++ b/plugins/sierra/mm-broadband-modem-sierra.c @@ -1780,16 +1780,18 @@ modem_time_check_ready (MMBaseModem *self, g_object_unref (task); } -static gboolean -parse_time_reply (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) -{ +static MMBaseModemAtResponseProcessorResult +parse_time_reply (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) +{ + *result_error = NULL; + /* If error, try next command */ if (!error) { if (strstr (command, "!TIME")) @@ -1799,11 +1801,13 @@ parse_time_reply (MMBaseModem *self, } /* Stop sequence if we get a result, but not on errors */ - return *result ? TRUE : FALSE; + return (*result ? + MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS : + MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE); } static const MMBaseModemAtCommand time_check_sequence[] = { - { "!TIME?", 3, FALSE, parse_time_reply }, /* 3GPP */ + { "!TIME?", 3, FALSE, parse_time_reply }, /* 3GPP */ { "!SYSTIME?", 3, FALSE, parse_time_reply }, /* CDMA */ { NULL } }; diff --git a/plugins/telit/mm-broadband-modem-telit.c b/plugins/telit/mm-broadband-modem-telit.c index 48ae4de1..94a6ddcc 100644 --- a/plugins/telit/mm-broadband-modem-telit.c +++ b/plugins/telit/mm-broadband-modem-telit.c @@ -1080,23 +1080,30 @@ load_access_technologies_finish (MMIfaceModem *self, return TRUE; } -static gboolean -response_processor_psnt_ignore_at_errors (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) +static MMBaseModemAtResponseProcessorResult +response_processor_psnt_ignore_at_errors (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) { - const gchar *psnt, *mode; + const gchar *psnt; + const gchar *mode; + + *result = NULL; + *result_error = NULL; if (error) { /* Ignore AT errors (ie, ERROR or CMx ERROR) */ - if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) + if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) { *result_error = g_error_copy (error); - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; + } + + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } psnt = mm_strip_tag (response, "#PSNT:"); @@ -1105,26 +1112,26 @@ response_processor_psnt_ignore_at_errors (MMBaseModem *self, switch (atoi (++mode)) { case 0: *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_GPRS); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; case 1: *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_EDGE); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; case 2: *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_UMTS); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; case 3: *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_HSDPA); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; case 4: if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_LTE); else *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; case 5: if (mm_iface_modem_is_3gpp_lte (MM_IFACE_MODEM (self))) { *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } /* Fall-through since #PSNT: 5 is not supported in other than lte modems */ default: @@ -1137,26 +1144,32 @@ response_processor_psnt_ignore_at_errors (MMBaseModem *self, MM_CORE_ERROR_FAILED, "Failed to parse #PSNT response: '%s'", response); - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; } -static gboolean -response_processor_service_ignore_at_errors (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) +static MMBaseModemAtResponseProcessorResult +response_processor_service_ignore_at_errors (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) { const gchar *service; + *result = NULL; + *result_error = NULL; + if (error) { /* Ignore AT errors (ie, ERROR or CMx ERROR) */ - if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) + if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) { *result_error = g_error_copy (error); - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; + } + + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } service = mm_strip_tag (response, "+SERVICE:"); @@ -1164,13 +1177,13 @@ response_processor_service_ignore_at_errors (MMBaseModem *self, switch (atoi (service)) { case 1: *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_1XRTT); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; case 2: *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_EVDO0); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; case 3: *result = g_variant_new_uint32 (MM_MODEM_ACCESS_TECHNOLOGY_EVDOA); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; default: break; } @@ -1181,7 +1194,7 @@ response_processor_service_ignore_at_errors (MMBaseModem *self, MM_CORE_ERROR_FAILED, "Failed to parse +SERVICE response: '%s'", response); - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; } static const MMBaseModemAtCommand access_tech_commands[] = { diff --git a/src/mm-base-modem-at.c b/src/mm-base-modem-at.c index 94bd3956..d1352e08 100644 --- a/src/mm-base-modem-at.c +++ b/src/mm-base-modem-at.c @@ -90,18 +90,18 @@ modem_cancellable_cancelled (GCancellable *modem_cancellable, /* AT sequence handling */ typedef struct { - MMBaseModem *self; - MMPortSerialAt *port; - GCancellable *cancellable; - gulong cancelled_id; - GCancellable *modem_cancellable; - GCancellable *user_cancellable; + MMBaseModem *self; + MMPortSerialAt *port; + GCancellable *cancellable; + gulong cancelled_id; + GCancellable *modem_cancellable; + GCancellable *user_cancellable; const MMBaseModemAtCommand *current; const MMBaseModemAtCommand *sequence; - GSimpleAsyncResult *simple; - gpointer response_processor_context; - GDestroyNotify response_processor_context_free; - GVariant *result; + GSimpleAsyncResult *simple; + gpointer response_processor_context; + GDestroyNotify response_processor_context_free; + GVariant *result; } AtSequenceContext; static void @@ -131,15 +131,14 @@ at_sequence_context_free (AtSequenceContext *ctx) } GVariant * -mm_base_modem_at_sequence_full_finish (MMBaseModem *self, - GAsyncResult *res, - gpointer *response_processor_context, - GError **error) +mm_base_modem_at_sequence_full_finish (MMBaseModem *self, + GAsyncResult *res, + gpointer *response_processor_context, + GError **error) { AtSequenceContext *ctx; - if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), - error)) + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) return NULL; ctx = g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); @@ -153,63 +152,67 @@ mm_base_modem_at_sequence_full_finish (MMBaseModem *self, } static void -at_sequence_parse_response (MMPortSerialAt *port, - GAsyncResult *res, +at_sequence_parse_response (MMPortSerialAt *port, + GAsyncResult *res, AtSequenceContext *ctx) { - GVariant *result = NULL; - GError *result_error = NULL; - gboolean continue_sequence; - GSimpleAsyncResult *simple; - const gchar *response; - GError *error = NULL; + MMBaseModemAtResponseProcessorResult processor_result; + GVariant *result = NULL; + GError *result_error = NULL; + GSimpleAsyncResult *simple; + const gchar *response; + GError *error = NULL; response = mm_port_serial_at_command_finish (port, res, &error); /* Cancelled? */ if (g_cancellable_is_cancelled (ctx->cancellable)) { - g_simple_async_result_set_error (ctx->simple, G_IO_ERROR, G_IO_ERROR_CANCELLED, - "AT sequence was cancelled"); - if (error) - g_error_free (error); + g_simple_async_result_set_error (ctx->simple, G_IO_ERROR, G_IO_ERROR_CANCELLED, "AT sequence was cancelled"); + g_clear_error (&error); g_simple_async_result_complete (ctx->simple); at_sequence_context_free (ctx); return; } if (!ctx->current->response_processor) - /* No need to process response, go on to next command */ - continue_sequence = TRUE; + processor_result = MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; else { const MMBaseModemAtCommand *next = ctx->current + 1; /* Response processor will tell us if we need to keep on the sequence */ - continue_sequence = !ctx->current->response_processor ( - ctx->self, - ctx->response_processor_context, - ctx->current->command, - response, - next->command ? FALSE : TRUE, /* Last command in sequence? */ - error, - &result, - &result_error); - /* Were we told to abort the sequence? */ - if (result_error) { - g_assert (result == NULL); - g_simple_async_result_take_error (ctx->simple, result_error); - g_simple_async_result_complete (ctx->simple); - at_sequence_context_free (ctx); - if (error) - g_error_free (error); - return; + processor_result = ctx->current->response_processor (ctx->self, + ctx->response_processor_context, + ctx->current->command, + response, + next->command ? FALSE : TRUE, /* Last command in sequence? */ + error, + &result, + &result_error); + switch (processor_result) { + case MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE: + g_assert (!result && !result_error); + break; + case MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS: + g_assert (!result_error); /* result is optional */ + break; + case MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE: + /* On failure, complete with error right away */ + g_assert (!result && result_error); /* result is optional */ + g_simple_async_result_take_error (ctx->simple, result_error); + g_simple_async_result_complete (ctx->simple); + at_sequence_context_free (ctx); + if (error) + g_error_free (error); + return; + default: + g_assert_not_reached (); } } if (error) g_error_free (error); - if (continue_sequence) { - g_assert (result == NULL); + if (processor_result == MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE) { ctx->current++; if (ctx->current->command) { /* Schedule the next command in the probing group */ @@ -224,7 +227,6 @@ at_sequence_parse_response (MMPortSerialAt *port, ctx); return; } - /* On last command, end. */ } @@ -250,14 +252,14 @@ at_sequence_parse_response (MMPortSerialAt *port, } void -mm_base_modem_at_sequence_full (MMBaseModem *self, - MMPortSerialAt *port, +mm_base_modem_at_sequence_full (MMBaseModem *self, + MMPortSerialAt *port, const MMBaseModemAtCommand *sequence, - gpointer response_processor_context, - GDestroyNotify response_processor_context_free, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) + gpointer response_processor_context, + GDestroyNotify response_processor_context_free, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { AtSequenceContext *ctx; @@ -354,7 +356,7 @@ mm_base_modem_at_sequence (MMBaseModem *self, /*****************************************************************************/ /* Response processor helpers */ -gboolean +MMBaseModemAtResponseProcessorResult mm_base_modem_response_processor_string (MMBaseModem *self, gpointer none, const gchar *command, @@ -365,16 +367,17 @@ mm_base_modem_response_processor_string (MMBaseModem *self, GError **result_error) { if (error) { - /* Abort sequence on command error */ + *result = NULL; *result_error = g_error_copy (error); - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; } *result = g_variant_new_string (response); - return TRUE; + *result_error = NULL; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } -gboolean +MMBaseModemAtResponseProcessorResult mm_base_modem_response_processor_no_result (MMBaseModem *self, gpointer none, const gchar *command, @@ -385,16 +388,17 @@ mm_base_modem_response_processor_no_result (MMBaseModem *self, GError **result_error) { if (error) { - /* Abort sequence on command error */ + *result = NULL; *result_error = g_error_copy (error); - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; } *result = NULL; - return TRUE; + *result_error = NULL; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } -gboolean +MMBaseModemAtResponseProcessorResult mm_base_modem_response_processor_no_result_continue (MMBaseModem *self, gpointer none, const gchar *command, @@ -404,15 +408,18 @@ mm_base_modem_response_processor_no_result_continue (MMBaseModem *self, GVariant **result, GError **result_error) { - if (error) - /* Abort sequence on command error */ + *result = NULL; + + if (error) { *result_error = g_error_copy (error); + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; + } - /* Return FALSE so that we keep on with the next steps in the sequence */ - return FALSE; + *result_error = NULL; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } -gboolean +MMBaseModemAtResponseProcessorResult mm_base_modem_response_processor_continue_on_error (MMBaseModem *self, gpointer none, const gchar *command, @@ -422,12 +429,40 @@ mm_base_modem_response_processor_continue_on_error (MMBaseModem *self, GVariant **result, GError **result_error) { - if (error) - /* Ignore errors, continue to next command */ - return FALSE; - *result = NULL; - return TRUE; + *result_error = NULL; + + return (error ? + MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE : + MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS); +} + +MMBaseModemAtResponseProcessorResult +mm_base_modem_response_processor_string_ignore_at_errors (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) +{ + if (error) { + *result = NULL; + + /* Ignore AT errors (ie, ERROR or CMx ERROR) */ + if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) { + + *result_error = g_error_copy (error); + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; + } + + *result_error = NULL; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; + } + + *result = g_variant_new_string (response); + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } /*****************************************************************************/ diff --git a/src/mm-base-modem-at.h b/src/mm-base-modem-at.h index f5f0601e..770c0e4b 100644 --- a/src/mm-base-modem-at.h +++ b/src/mm-base-modem-at.h @@ -21,19 +21,25 @@ #include "mm-base-modem.h" #include "mm-port-serial-at.h" +typedef enum { + MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE, + MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS, + MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE, +} MMBaseModemAtResponseProcessorResult; + /* * The expected result depends on the specific operation, so the GVariant * created by the response processor needs to match the one expected in * finish(). * - * TRUE must be returned when the operation is to be considered successful, + * SUCCESS must be returned when the operation is to be considered successful, * and a result may be given. * - * FALSE must be returned when: - * - A GError is propagated into result_error, which will be treated as a - * critical error and therefore the operation will be aborted. - * - When no result_error is given, to instruct the operation to go on with - * the next scheduled command. + * FAILURE must be returned when a GError is propagated into result_error, + * which will be treated as a critical error and therefore the operation will be aborted. + * + * CONTINUE must be returned when neither result nor result_error are given and + * the operation should go on with the next scheduled command. * * This setup, therefore allows: * - Running a single command and processing its result. @@ -42,14 +48,14 @@ * - Running a set of N commands out of M (N<M), where the global result is * obtained without having executed all configured commands. */ -typedef gboolean (* MMBaseModemAtResponseProcessor) (MMBaseModem *self, - gpointer response_processor_context, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error); +typedef MMBaseModemAtResponseProcessorResult (* MMBaseModemAtResponseProcessor) (MMBaseModem *self, + gpointer response_processor_context, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error); /* Struct to configure AT command operations (constant) */ typedef struct { @@ -98,28 +104,28 @@ GVariant *mm_base_modem_at_sequence_full_finish (MMBaseModem *self, * failure in the command triggers a failure in the sequence. If successful, * provides the output result as a STRING. */ -gboolean mm_base_modem_response_processor_string (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error); +MMBaseModemAtResponseProcessorResult mm_base_modem_response_processor_string (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error); /* * Response processor for commands that are treated as MANDATORY, where a * failure in the command triggers a failure in the sequence. If successful, * provides the output result as a BOOLEAN. */ -gboolean mm_base_modem_response_processor_no_result (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error); +MMBaseModemAtResponseProcessorResult mm_base_modem_response_processor_no_result (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error); /* * Response processor for commands that are treated as MANDATORY, where a @@ -129,14 +135,14 @@ gboolean mm_base_modem_response_processor_no_result (MMBaseModem *self, * E.g. used when we provide a list of commands and we want to run all of * them successfully, and fail the sequence if one of them fails. */ -gboolean mm_base_modem_response_processor_no_result_continue (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error); +MMBaseModemAtResponseProcessorResult mm_base_modem_response_processor_no_result_continue (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error); /* * Response processor for commands that are treated as OPTIONAL, where a @@ -146,15 +152,29 @@ gboolean mm_base_modem_response_processor_no_result_continue (MMBaseModem *sel * E.g. used when we provide a list of commands and we want to stop * as soon as one of them doesn't fail. */ -gboolean mm_base_modem_response_processor_continue_on_error (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error); +MMBaseModemAtResponseProcessorResult mm_base_modem_response_processor_continue_on_error (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error); +/* + * Response processor for commands that are partialy treated as OPTIONAL, where + * a failure in the command triggers a failure in the sequence only for non-AT + * generic errors. If successful, it finishes the sequence with the response of + * the command which didn't fail. + */ +MMBaseModemAtResponseProcessorResult mm_base_modem_response_processor_string_ignore_at_errors (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error); /* Generic AT command handling, using the best AT port available and without * explicit cancellations. */ diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index 2e651190..6977fe33 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -368,30 +368,6 @@ ports_context_new (void) } /*****************************************************************************/ - -static gboolean -response_processor_string_ignore_at_errors (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) -{ - if (error) { - /* Ignore AT errors (ie, ERROR or CMx ERROR) */ - if (error->domain != MM_MOBILE_EQUIPMENT_ERROR || last_command) - *result_error = g_error_copy (error); - - return FALSE; - } - - *result = g_variant_new_string (response); - return TRUE; -} - -/*****************************************************************************/ /* Create Bearer (Modem interface) */ static MMBaseBearer * @@ -583,27 +559,30 @@ static const ModemCaps modem_caps[] = { { NULL } }; -static gboolean -parse_caps_gcap (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **variant, - GError **result_error) +static MMBaseModemAtResponseProcessorResult +parse_caps_gcap (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) { const ModemCaps *cap = modem_caps; guint32 ret = 0; + *result = NULL; + *result_error = NULL; + if (!response) - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; /* Some modems (Huawei E160g) won't respond to +GCAP with no SIM, but * will respond to ATI. Ignore the error and continue. */ - if (strstr (response, "+CME ERROR:")) - return FALSE; + if (strstr (response, "+CME ERROR:") || (error && error->domain == MM_MOBILE_EQUIPMENT_ERROR)) + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; while (cap->name) { if (strstr (response, cap->name)) @@ -613,22 +592,25 @@ parse_caps_gcap (MMBaseModem *self, /* No result built? */ if (ret == 0) - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; - *variant = g_variant_new_uint32 (ret); - return TRUE; + *result = g_variant_new_uint32 (ret); + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } -static gboolean -parse_caps_cpin (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) +static MMBaseModemAtResponseProcessorResult +parse_caps_cpin (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) { + *result = NULL; + *result_error = NULL; + if (!response) { if (error && (g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_NOT_INSERTED) || @@ -637,9 +619,9 @@ parse_caps_cpin (MMBaseModem *self, g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, MM_MOBILE_EQUIPMENT_ERROR_SIM_WRONG))) { /* At least, it's a GSM modem */ *result = g_variant_new_uint32 (MM_MODEM_CAPABILITY_GSM_UMTS); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } if (strcasestr (response, "SIM PIN") || @@ -660,23 +642,27 @@ parse_caps_cpin (MMBaseModem *self, strcasestr (response, "READY")) { /* At least, it's a GSM modem */ *result = g_variant_new_uint32 (MM_MODEM_CAPABILITY_GSM_UMTS); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } - return FALSE; + + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } -static gboolean -parse_caps_cgmm (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) +static MMBaseModemAtResponseProcessorResult +parse_caps_cgmm (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) { + *result = NULL; + *result_error = NULL; + if (!response) - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; /* This check detects some really old Motorola GPRS dongles and phones */ if (strstr (response, "GSM900") || @@ -685,9 +671,10 @@ parse_caps_cgmm (MMBaseModem *self, strstr (response, "GSM850")) { /* At least, it's a GSM modem */ *result = g_variant_new_uint32 (MM_MODEM_CAPABILITY_GSM_UMTS); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } - return FALSE; + + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } static const MMBaseModemAtCommand capabilities[] = { @@ -942,8 +929,8 @@ modem_load_manufacturer_finish (MMIfaceModem *self, } static const MMBaseModemAtCommand manufacturers[] = { - { "+CGMI", 3, TRUE, response_processor_string_ignore_at_errors }, - { "+GMI", 3, TRUE, response_processor_string_ignore_at_errors }, + { "+CGMI", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, + { "+GMI", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, { NULL } }; @@ -982,8 +969,8 @@ modem_load_model_finish (MMIfaceModem *self, } static const MMBaseModemAtCommand models[] = { - { "+CGMM", 3, TRUE, response_processor_string_ignore_at_errors }, - { "+GMM", 3, TRUE, response_processor_string_ignore_at_errors }, + { "+CGMM", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, + { "+GMM", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, { NULL } }; @@ -1022,8 +1009,8 @@ modem_load_revision_finish (MMIfaceModem *self, } static const MMBaseModemAtCommand revisions[] = { - { "+CGMR", 3, TRUE, response_processor_string_ignore_at_errors }, - { "+GMR", 3, TRUE, response_processor_string_ignore_at_errors }, + { "+CGMR", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, + { "+GMR", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, { NULL } }; @@ -1082,8 +1069,8 @@ modem_load_equipment_identifier_finish (MMIfaceModem *self, } static const MMBaseModemAtCommand equipment_identifiers[] = { - { "+CGSN", 3, TRUE, response_processor_string_ignore_at_errors }, - { "+GSN", 3, TRUE, response_processor_string_ignore_at_errors }, + { "+CGSN", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, + { "+GSN", 3, TRUE, mm_base_modem_response_processor_string_ignore_at_errors }, { NULL } }; @@ -2099,8 +2086,8 @@ signal_quality_csq_ready (MMBroadbandModem *self, * try the other command if the first one fails. */ static const MMBaseModemAtCommand signal_quality_csq_sequence[] = { - { "+CSQ", 3, FALSE, response_processor_string_ignore_at_errors }, - { "+CSQ?", 3, FALSE, response_processor_string_ignore_at_errors }, + { "+CSQ", 3, FALSE, mm_base_modem_response_processor_string_ignore_at_errors }, + { "+CSQ?", 3, FALSE, mm_base_modem_response_processor_string_ignore_at_errors }, { NULL } }; @@ -5269,23 +5256,27 @@ modem_3gpp_enable_disable_unsolicited_registration_events_finish (MMIfaceModem3g return g_task_propagate_boolean (G_TASK (res), error); } -static gboolean -parse_registration_setup_reply (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, +static MMBaseModemAtResponseProcessorResult +parse_registration_setup_reply (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, const GError *error, - GVariant **result, - GError **result_error) + GVariant **result, + GError **result_error) { + *result_error = NULL; + /* If error, try next command */ - if (error) - return FALSE; + if (error) { + *result = NULL; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; + } /* Set COMMAND as result! */ *result = g_variant_new_string (command); - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } static const MMBaseModemAtCommand cs_registration_sequence[] = { @@ -7060,28 +7051,31 @@ modem_messaging_enable_unsolicited_events_finish (MMIfaceModemMessaging *self, return g_task_propagate_boolean (G_TASK (res), error); } -static gboolean -cnmi_response_processor (MMBaseModem *self, - gpointer none, - const gchar *command, - const gchar *response, - gboolean last_command, - const GError *error, - GVariant **result, - GError **result_error) +static MMBaseModemAtResponseProcessorResult +cnmi_response_processor (MMBaseModem *self, + gpointer none, + const gchar *command, + const gchar *response, + gboolean last_command, + const GError *error, + GVariant **result, + GError **result_error) { + *result = NULL; + *result_error = NULL; + if (error) { /* If we get a not-supported error and we're not in the last command, we * won't set 'result_error', so we'll keep on the sequence */ - if (!g_error_matches (error, MM_MESSAGE_ERROR, MM_MESSAGE_ERROR_NOT_SUPPORTED) || - last_command) + if (!g_error_matches (error, MM_MESSAGE_ERROR, MM_MESSAGE_ERROR_NOT_SUPPORTED) || last_command) { *result_error = g_error_copy (error); + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_FAILURE; + } - return FALSE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_CONTINUE; } - *result = NULL; - return TRUE; + return MM_BASE_MODEM_AT_RESPONSE_PROCESSOR_RESULT_SUCCESS; } static const MMBaseModemAtCommand cnmi_sequence[] = { |