summaryrefslogtreecommitdiff
path: root/src/mm-base-modem-at.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mm-base-modem-at.c')
-rw-r--r--src/mm-base-modem-at.c265
1 files changed, 153 insertions, 112 deletions
diff --git a/src/mm-base-modem-at.c b/src/mm-base-modem-at.c
index 77661e5b..d1352e08 100644
--- a/src/mm-base-modem-at.c
+++ b/src/mm-base-modem-at.c
@@ -30,7 +30,7 @@ abort_async_if_port_unusable (MMBaseModem *self,
GError *error = NULL;
gboolean init_sequence_enabled = FALSE;
- /* If no port given, probably the port dissapeared */
+ /* If no port given, probably the port disappeared */
if (!port) {
g_simple_async_report_error_in_idle (
G_OBJECT (self),
@@ -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,65 +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,
- MM_CORE_ERROR,
- MM_CORE_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 */
@@ -226,7 +227,6 @@ at_sequence_parse_response (MMPortSerialAt *port,
ctx);
return;
}
-
/* On last command, end. */
}
@@ -252,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;
@@ -301,7 +301,7 @@ mm_base_modem_at_sequence_full (MMBaseModem *self,
ctx->current->command,
ctx->current->timeout,
FALSE,
- FALSE,
+ ctx->current->allow_cached,
ctx->cancellable,
(GAsyncReadyCallback)at_sequence_parse_response,
ctx);
@@ -356,76 +356,113 @@ mm_base_modem_at_sequence (MMBaseModem *self,
/*****************************************************************************/
/* Response processor helpers */
-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)
{
if (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
-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)
{
if (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
-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)
{
- if (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
-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)
{
- if (error)
- 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;
}
/*****************************************************************************/
@@ -483,9 +520,7 @@ at_command_ready (MMPortSerialAt *port,
/* Cancelled? */
if (g_cancellable_is_cancelled (ctx->cancellable)) {
- g_simple_async_result_set_error (ctx->result,
- MM_CORE_ERROR,
- MM_CORE_ERROR_CANCELLED,
+ g_simple_async_result_set_error (ctx->result, G_IO_ERROR, G_IO_ERROR_CANCELLED,
"AT command was cancelled");
if (error)
g_error_free (error);
@@ -620,3 +655,9 @@ mm_base_modem_at_command_raw (MMBaseModem *self,
{
_at_command (self, command, timeout, allow_cached, TRUE, callback, user_data);
}
+
+void
+mm_base_modem_at_command_alloc_clear (MMBaseModemAtCommandAlloc *command)
+{
+ g_free (command->command);
+}