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).
This commit is contained in:
Aleksander Morgado
2020-06-28 15:07:34 +02:00
parent c4d82aaf1e
commit 4b37b7d3cf
9 changed files with 401 additions and 338 deletions
+4 -23
View File
@@ -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
+12 -10
View File
@@ -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[] = {
+15 -12
View File
@@ -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)
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 = context;
Band *b = g_slist_nth_data (ctx->check_bands, ctx->idx++);
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
@@ -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[] = {
+15 -11
View File
@@ -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 }
};
+47 -34
View File
@@ -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[] = {
+113 -78
View File
@@ -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_error = g_error_copy (error);
*result = NULL;
/* Return FALSE so that we keep on with the next steps in the sequence */
return FALSE;
if (error) {
*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;
}
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;
}
/*****************************************************************************/
+66 -46
View File
@@ -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. */
+93 -99
View File
@@ -367,30 +367,6 @@ ports_context_new (void)
return ctx;
}
/*****************************************************************************/
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) */
@@ -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[] = {