diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2013-11-17 01:11:12 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2014-02-13 13:40:21 +0100 |
commit | d4dfd661b9bcfdad5a79e2a3f28374f0d0982c23 (patch) | |
tree | c6bf095648969ac35fc93a81922575deb228c392 | |
parent | 81ee07832d3ab733f59f869ad17d1d5577aef3ff (diff) |
port-serial-at: use GIO Async API like methods
-rw-r--r-- | plugins/cinterion/mm-plugin-cinterion.c | 31 | ||||
-rw-r--r-- | plugins/huawei/mm-plugin-huawei.c | 55 | ||||
-rw-r--r-- | plugins/longcheer/mm-plugin-longcheer.c | 19 | ||||
-rw-r--r-- | plugins/novatel/mm-plugin-novatel.c | 28 | ||||
-rw-r--r-- | plugins/sierra/mm-plugin-sierra.c | 32 | ||||
-rw-r--r-- | plugins/x22x/mm-plugin-x22x.c | 19 | ||||
-rw-r--r-- | src/mm-base-modem-at.c | 107 | ||||
-rw-r--r-- | src/mm-port-probe.c | 35 | ||||
-rw-r--r-- | src/mm-port-serial-at.c | 130 | ||||
-rw-r--r-- | src/mm-port-serial-at.h | 31 |
10 files changed, 276 insertions, 211 deletions
diff --git a/plugins/cinterion/mm-plugin-cinterion.c b/plugins/cinterion/mm-plugin-cinterion.c index 27672b5f..7a04fdaa 100644 --- a/plugins/cinterion/mm-plugin-cinterion.c +++ b/plugins/cinterion/mm-plugin-cinterion.c @@ -76,25 +76,23 @@ cinterion_custom_init_finish (MMPortProbe *probe, static void sqport_ready (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, CinterionCustomInitContext *ctx) { + const gchar *response; + /* Ignore errors, just avoid tagging */ - if (error) { - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); - cinterion_custom_init_context_complete_and_free (ctx); - return; + response = mm_port_serial_at_command_finish (port, res, NULL); + if (response) { + /* A valid reply to AT^SQPORT tells us this is an AT port already */ + mm_port_probe_set_result_at (ctx->probe, TRUE); + + if (strstr (response, "Application")) + g_object_set_data (G_OBJECT (ctx->probe), TAG_CINTERION_APP_PORT, GUINT_TO_POINTER (TRUE)); + else if (strstr (response, "Modem")) + g_object_set_data (G_OBJECT (ctx->probe), TAG_CINTERION_MODEM_PORT, GUINT_TO_POINTER (TRUE)); } - /* A valid reply to AT^SQPORT tells us this is an AT port already */ - mm_port_probe_set_result_at (ctx->probe, TRUE); - - if (strstr (response->str, "Application")) - g_object_set_data (G_OBJECT (ctx->probe), TAG_CINTERION_APP_PORT, GUINT_TO_POINTER (TRUE)); - else if (strstr (response->str, "Modem")) - g_object_set_data (G_OBJECT (ctx->probe), TAG_CINTERION_MODEM_PORT, GUINT_TO_POINTER (TRUE)); - g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); cinterion_custom_init_context_complete_and_free (ctx); } @@ -117,13 +115,14 @@ cinterion_custom_init (MMPortProbe *probe, ctx->port = g_object_ref (port); ctx->cancellable = cancellable ? g_object_ref (cancellable) : NULL; - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( ctx->port, "AT^SQPORT?", 3, FALSE, /* raw */ + FALSE, /* allow cached */ ctx->cancellable, - (MMPortSerialAtResponseFn)sqport_ready, + (GAsyncReadyCallback)sqport_ready, ctx); } diff --git a/plugins/huawei/mm-plugin-huawei.c b/plugins/huawei/mm-plugin-huawei.c index bae9ab1a..20787740 100644 --- a/plugins/huawei/mm-plugin-huawei.c +++ b/plugins/huawei/mm-plugin-huawei.c @@ -128,10 +128,13 @@ cache_port_mode (MMDevice *device, static void getportmode_ready (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, HuaweiCustomInitContext *ctx) { + const gchar *response; + GError *error = NULL; + + response = mm_port_serial_at_command_finish (port, res, &error); if (error) { mm_dbg ("(Huawei) couldn't get port mode: '%s'", error->message); @@ -141,11 +144,8 @@ getportmode_ready (MMPortSerialAt *port, */ if (!g_error_matches (error, MM_MOBILE_EQUIPMENT_ERROR, - MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN)) { - /* Retry */ - huawei_custom_init_step (ctx); - return; - } + MM_MOBILE_EQUIPMENT_ERROR_UNKNOWN)) + goto out; /* Port mode not supported */ } else { @@ -155,10 +155,10 @@ getportmode_ready (MMPortSerialAt *port, /* Results are cached in the parent device object */ device = mm_port_probe_peek_device (ctx->probe); - cache_port_mode (device, response->str, "PCUI:", TAG_HUAWEI_PCUI_PORT); - cache_port_mode (device, response->str, "MDM:", TAG_HUAWEI_MODEM_PORT); - cache_port_mode (device, response->str, "NDIS:", TAG_HUAWEI_NDIS_PORT); - cache_port_mode (device, response->str, "DIAG:", TAG_HUAWEI_DIAG_PORT); + cache_port_mode (device, response, "PCUI:", TAG_HUAWEI_PCUI_PORT); + cache_port_mode (device, response, "MDM:", TAG_HUAWEI_MODEM_PORT); + cache_port_mode (device, response, "NDIS:", TAG_HUAWEI_NDIS_PORT); + cache_port_mode (device, response, "DIAG:", TAG_HUAWEI_DIAG_PORT); g_object_set_data (G_OBJECT (device), TAG_GETPORTMODE_SUPPORTED, GUINT_TO_POINTER (TRUE)); /* Mark port as being AT already */ @@ -166,23 +166,29 @@ getportmode_ready (MMPortSerialAt *port, } ctx->getportmode_done = TRUE; + +out: + if (error) + g_error_free (error); + huawei_custom_init_step (ctx); } static void curc_ready (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, HuaweiCustomInitContext *ctx) { + const gchar *response; + GError *error = NULL; + + response = mm_port_serial_at_command_finish (port, res, &error); if (error) { /* Retry if we get a timeout error */ if (g_error_matches (error, MM_SERIAL_ERROR, - MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) { - huawei_custom_init_step (ctx); - return; - } + MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) + goto out; mm_dbg ("(Huawei) couldn't turn off unsolicited messages in" "secondary ports: '%s'", @@ -192,6 +198,11 @@ curc_ready (MMPortSerialAt *port, mm_dbg ("(Huawei) unsolicited messages in secondary ports turned off"); ctx->curc_done = TRUE; + +out: + if (error) + g_error_free (error); + huawei_custom_init_step (ctx); } @@ -263,13 +274,14 @@ huawei_custom_init_step (HuaweiCustomInitContext *ctx) ctx->curc_retries--; /* Turn off unsolicited messages on secondary ports until needed */ - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( ctx->port, "AT^CURC=0", 3, FALSE, /* raw */ + FALSE, /* allow_cached */ ctx->cancellable, - (MMPortSerialAtResponseFn)curc_ready, + (GAsyncReadyCallback)curc_ready, ctx); return; } @@ -283,13 +295,14 @@ huawei_custom_init_step (HuaweiCustomInitContext *ctx) } ctx->getportmode_retries--; - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( ctx->port, "AT^GETPORTMODE", 3, FALSE, /* raw */ + FALSE, /* allow_cached */ ctx->cancellable, - (MMPortSerialAtResponseFn)getportmode_ready, + (GAsyncReadyCallback)getportmode_ready, ctx); return; } diff --git a/plugins/longcheer/mm-plugin-longcheer.c b/plugins/longcheer/mm-plugin-longcheer.c index 55e574a7..d9217b79 100644 --- a/plugins/longcheer/mm-plugin-longcheer.c +++ b/plugins/longcheer/mm-plugin-longcheer.c @@ -67,20 +67,22 @@ static void longcheer_custom_init_step (LongcheerCustomInitContext *ctx); static void gmr_ready (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, LongcheerCustomInitContext *ctx) { const gchar *p; + const gchar *response; + GError *error = NULL; + response = mm_port_serial_at_command_finish (port, res, &error); if (error) { /* Just retry... */ longcheer_custom_init_step (ctx); - return; + goto out; } /* Note the lack of a ':' on the GMR; the X200 doesn't send one */ - p = mm_strip_tag (response->str, "AT+GMR"); + p = mm_strip_tag (response, "AT+GMR"); if (p && *p == 'L') { /* X200 modems have a GMR firmware revision that starts with 'L', and * as far as I can tell X060s devices have a revision starting with 'C'. @@ -98,6 +100,10 @@ gmr_ready (MMPortSerialAt *port, } longcheer_custom_init_context_complete_and_free (ctx); + +out: + if (error) + g_error_free (error); } static void @@ -124,13 +130,14 @@ longcheer_custom_init_step (LongcheerCustomInitContext *ctx) } ctx->retries--; - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( ctx->port, "AT+GMR", 3, FALSE, /* raw */ + FALSE, /* allow_cached */ ctx->cancellable, - (MMPortSerialAtResponseFn)gmr_ready, + (GAsyncReadyCallback)gmr_ready, ctx); } diff --git a/plugins/novatel/mm-plugin-novatel.c b/plugins/novatel/mm-plugin-novatel.c index ae5fdc1b..9eaf2859 100644 --- a/plugins/novatel/mm-plugin-novatel.c +++ b/plugins/novatel/mm-plugin-novatel.c @@ -91,16 +91,19 @@ static void custom_init_step (CustomInitContext *ctx); static void nwdmat_ready (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, CustomInitContext *ctx) { + const gchar *response; + GError *error = NULL; + + response = mm_port_serial_at_command_finish (port, res, &error); if (error) { if (g_error_matches (error, MM_SERIAL_ERROR, MM_SERIAL_ERROR_RESPONSE_TIMEOUT)) { custom_init_step (ctx); - return; + goto out; } mm_dbg ("(Novatel) Error flipping secondary ports to AT mode: %s", error->message); @@ -109,6 +112,10 @@ nwdmat_ready (MMPortSerialAt *port, /* Finish custom_init */ g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); custom_init_context_complete_and_free (ctx); + +out: + if (error) + g_error_free (error); } static gboolean @@ -147,13 +154,14 @@ custom_init_step (CustomInitContext *ctx) if (ctx->nwdmat_retries > 0) { ctx->nwdmat_retries--; - mm_port_serial_at_queue_command (ctx->port, - "$NWDMAT=1", - 3, - FALSE, /* raw */ - ctx->cancellable, - (MMPortSerialAtResponseFn)nwdmat_ready, - ctx); + mm_port_serial_at_command (ctx->port, + "$NWDMAT=1", + 3, + FALSE, /* raw */ + FALSE, /* allow_cached */ + ctx->cancellable, + (GAsyncReadyCallback)nwdmat_ready, + ctx); return; } diff --git a/plugins/sierra/mm-plugin-sierra.c b/plugins/sierra/mm-plugin-sierra.c index 86ffd664..6da74c3c 100644 --- a/plugins/sierra/mm-plugin-sierra.c +++ b/plugins/sierra/mm-plugin-sierra.c @@ -79,10 +79,13 @@ static void sierra_custom_init_step (SierraCustomInitContext *ctx); static void gcap_ready (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, SierraCustomInitContext *ctx) { + const gchar *response; + GError *error = NULL; + + response = mm_port_serial_at_command_finish (port, res, &error); if (error) { /* If consumed all tries and the last error was a timeout, assume the * port is not AT */ @@ -106,7 +109,7 @@ gcap_ready (MMPortSerialAt *port, /* Just retry... */ sierra_custom_init_step (ctx); - return; + goto out; } /* A valid reply to ATI tells us this is an AT port already */ @@ -118,23 +121,25 @@ gcap_ready (MMPortSerialAt *port, * or fail PPP. So we whitelist modems that are known to allow PPP on the * secondary APP ports. */ - if (strstr (response->str, "APP1")) { + if (strstr (response, "APP1")) { g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP_PORT, GUINT_TO_POINTER (TRUE)); /* PPP-on-APP1-port whitelist */ - if (strstr (response->str, "C885") || strstr (response->str, "USB 306") || strstr (response->str, "MC8790")) + if (strstr (response, "C885") || + strstr (response, "USB 306") || + strstr (response, "MC8790")) g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP1_PPP_OK, GUINT_TO_POINTER (TRUE)); /* For debugging: let users figure out if their device supports PPP * on the APP1 port or not. */ if (getenv ("MM_SIERRA_APP1_PPP_OK")) { - mm_dbg ("Sierra: APP1 PPP OK '%s'", response->str); + mm_dbg ("Sierra: APP1 PPP OK '%s'", response); g_object_set_data (G_OBJECT (ctx->probe), TAG_SIERRA_APP1_PPP_OK, GUINT_TO_POINTER (TRUE)); } - } else if (strstr (response->str, "APP2") || - strstr (response->str, "APP3") || - strstr (response->str, "APP4")) { + } else if (strstr (response, "APP2") || + strstr (response, "APP3") || + strstr (response, "APP4")) { /* Additional APP ports don't support most AT commands, so they cannot * be used as the primary port. */ @@ -143,6 +148,10 @@ gcap_ready (MMPortSerialAt *port, g_simple_async_result_set_op_res_gboolean (ctx->result, TRUE); sierra_custom_init_context_complete_and_free (ctx); + +out: + if (error) + g_error_free (error); } static void @@ -166,13 +175,14 @@ sierra_custom_init_step (SierraCustomInitContext *ctx) } ctx->retries--; - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( ctx->port, "ATI", 3, FALSE, /* raw */ + FALSE, /* allow_cached */ ctx->cancellable, - (MMPortSerialAtResponseFn)gcap_ready, + (GAsyncReadyCallback)gcap_ready, ctx); } diff --git a/plugins/x22x/mm-plugin-x22x.c b/plugins/x22x/mm-plugin-x22x.c index cbb80711..650109d0 100644 --- a/plugins/x22x/mm-plugin-x22x.c +++ b/plugins/x22x/mm-plugin-x22x.c @@ -71,20 +71,22 @@ static void x22x_custom_init_step (X22xCustomInitContext *ctx); static void gmr_ready (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, X22xCustomInitContext *ctx) { const gchar *p; + const gchar *response; + GError *error = NULL; + response = mm_port_serial_at_command_finish (port, res, &error); if (error) { /* Just retry... */ x22x_custom_init_step (ctx); - return; + goto out; } /* Note the lack of a ':' on the GMR; the X200 doesn't send one */ - p = mm_strip_tag (response->str, "AT+GMR"); + p = mm_strip_tag (response, "AT+GMR"); if (p && *p != 'L') { /* X200 modems have a GMR firmware revision that starts with 'L', and * as far as I can tell X060s devices have a revision starting with 'C'. @@ -101,6 +103,10 @@ gmr_ready (MMPortSerialAt *port, } x22x_custom_init_context_complete_and_free (ctx); + +out: + if (error) + g_error_free (error); } static void @@ -127,13 +133,14 @@ x22x_custom_init_step (X22xCustomInitContext *ctx) } ctx->retries--; - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( ctx->port, "AT+GMR", 3, FALSE, /* raw */ + FALSE, /* allow_cached */ ctx->cancellable, - (MMPortSerialAtResponseFn)gmr_ready, + (GAsyncReadyCallback)gmr_ready, ctx); } diff --git a/src/mm-base-modem-at.c b/src/mm-base-modem-at.c index 0b3c5a12..77661e5b 100644 --- a/src/mm-base-modem-at.c +++ b/src/mm-base-modem-at.c @@ -154,14 +154,17 @@ mm_base_modem_at_sequence_full_finish (MMBaseModem *self, static void at_sequence_parse_response (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, AtSequenceContext *ctx) { GVariant *result = NULL; GError *result_error = NULL; gboolean continue_sequence; 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)) { @@ -169,6 +172,8 @@ at_sequence_parse_response (MMPortSerialAt *port, MM_CORE_ERROR, MM_CORE_ERROR_CANCELLED, "AT sequence was cancelled"); + if (error) + g_error_free (error); g_simple_async_result_complete (ctx->simple); at_sequence_context_free (ctx); return; @@ -185,7 +190,7 @@ at_sequence_parse_response (MMPortSerialAt *port, ctx->self, ctx->response_processor_context, ctx->current->command, - response ? response->str : NULL, + response, next->command ? FALSE : TRUE, /* Last command in sequence? */ error, &result, @@ -196,33 +201,29 @@ at_sequence_parse_response (MMPortSerialAt *port, 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; } } + if (error) + g_error_free (error); + if (continue_sequence) { g_assert (result == NULL); ctx->current++; if (ctx->current->command) { /* Schedule the next command in the probing group */ - if (ctx->current->allow_cached) - mm_port_serial_at_queue_command_cached ( - ctx->port, - ctx->current->command, - ctx->current->timeout, - FALSE, - ctx->cancellable, - (MMPortSerialAtResponseFn)at_sequence_parse_response, - ctx); - else - mm_port_serial_at_queue_command ( - ctx->port, - ctx->current->command, - ctx->current->timeout, - FALSE, - ctx->cancellable, - (MMPortSerialAtResponseFn)at_sequence_parse_response, - ctx); + mm_port_serial_at_command ( + ctx->port, + ctx->current->command, + ctx->current->timeout, + FALSE, + ctx->current->allow_cached, + ctx->cancellable, + (GAsyncReadyCallback)at_sequence_parse_response, + ctx); return; } @@ -295,13 +296,14 @@ mm_base_modem_at_sequence_full (MMBaseModem *self, } /* Go on with the first one in the sequence */ - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( ctx->port, ctx->current->command, ctx->current->timeout, FALSE, + FALSE, ctx->cancellable, - (MMPortSerialAtResponseFn)at_sequence_parse_response, + (GAsyncReadyCallback)at_sequence_parse_response, ctx); } @@ -470,32 +472,34 @@ mm_base_modem_at_command_full_finish (MMBaseModem *self, } static void -at_command_parse_response (MMPortSerialAt *port, - GString *response, - GError *error, - AtCommandContext *ctx) +at_command_ready (MMPortSerialAt *port, + GAsyncResult *res, + AtCommandContext *ctx) { + const gchar *response; + GError *error = NULL; + + response = mm_port_serial_at_command_finish (port, res, &error); + /* Cancelled? */ - if (g_cancellable_is_cancelled (ctx->cancellable)) + if (g_cancellable_is_cancelled (ctx->cancellable)) { g_simple_async_result_set_error (ctx->result, MM_CORE_ERROR, MM_CORE_ERROR_CANCELLED, "AT command was cancelled"); - + if (error) + g_error_free (error); + } /* Error coming from the serial port? */ else if (error) - g_simple_async_result_set_from_error (ctx->result, error); - + g_simple_async_result_take_error (ctx->result, error); /* Valid string response */ - else if (response && response->str) - g_simple_async_result_set_op_res_gpointer (ctx->result, - g_strdup (response->str), - g_free); - - /* No response */ + else if (response) + g_simple_async_result_set_op_res_gpointer (ctx->result, (gchar *)response, NULL); else - g_simple_async_result_set_op_res_gpointer (ctx->result, NULL, NULL); + g_assert_not_reached (); + /* Never in idle! */ g_simple_async_result_complete (ctx->result); at_command_context_free (ctx); } @@ -542,24 +546,15 @@ mm_base_modem_at_command_full (MMBaseModem *self, } /* Go on with the command */ - if (allow_cached) - mm_port_serial_at_queue_command_cached ( - port, - command, - timeout, - is_raw, - ctx->cancellable, - (MMPortSerialAtResponseFn)at_command_parse_response, - ctx); - else - mm_port_serial_at_queue_command ( - port, - command, - timeout, - is_raw, - ctx->cancellable, - (MMPortSerialAtResponseFn)at_command_parse_response, - ctx); + mm_port_serial_at_command ( + port, + command, + timeout, + is_raw, + allow_cached, + ctx->cancellable, + (GAsyncReadyCallback)at_command_ready, + ctx); } const gchar * diff --git a/src/mm-port-probe.c b/src/mm-port-probe.c index 0198f1ca..35373f25 100644 --- a/src/mm-port-probe.c +++ b/src/mm-port-probe.c @@ -865,17 +865,20 @@ serial_probe_at_result_processor (MMPortProbe *self, static void serial_probe_at_parse_response (MMPortSerialAt *port, - GString *response, - GError *error, + GAsyncResult *res, MMPortProbe *self) { PortProbeRunTask *task = self->priv->task; GVariant *result = NULL; GError *result_error = NULL; + const gchar *response; + GError *error = NULL; + + response = mm_port_serial_at_command_finish (port, res, &error); /* If already cancelled, do nothing else */ if (port_probe_run_is_cancelled (self)) - return; + goto out; /* If AT probing cancelled, end this partial probing */ if (g_cancellable_is_cancelled (task->at_probing_cancellable)) { @@ -884,11 +887,11 @@ serial_probe_at_parse_response (MMPortSerialAt *port, g_udev_device_get_name (self->priv->port)); task->at_result_processor (self, NULL); serial_probe_schedule (self); - return; + goto out; } if (!task->at_commands->response_processor (task->at_commands->command, - response ? response->str : NULL, + response, !!task->at_commands[1].command, error, &result, @@ -904,8 +907,7 @@ serial_probe_at_parse_response (MMPortSerialAt *port, g_udev_device_get_subsystem (self->priv->port), g_udev_device_get_name (self->priv->port), result_error->message)); - g_error_free (result_error); - return; + goto out; } /* Go on to next command */ @@ -916,22 +918,28 @@ serial_probe_at_parse_response (MMPortSerialAt *port, task->at_result_processor (self, NULL); /* Reschedule */ serial_probe_schedule (self); - return; + goto out; } /* Schedule the next command in the probing group */ task->source_id = g_idle_add ((GSourceFunc)serial_probe_at, self); - return; + goto out; } /* Run result processor. * Note that custom init commands are allowed to not return anything */ task->at_result_processor (self, result); - if (result) - g_variant_unref (result); /* Reschedule probing */ serial_probe_schedule (self); + +out: + if (result) + g_variant_unref (result); + if (error) + g_error_free (error); + if (result_error) + g_error_free (result_error); } static gboolean @@ -955,13 +963,14 @@ serial_probe_at (MMPortProbe *self) return FALSE; } - mm_port_serial_at_queue_command ( + mm_port_serial_at_command ( MM_PORT_SERIAL_AT (task->serial), task->at_commands->command, task->at_commands->timeout, FALSE, + FALSE, task->at_probing_cancellable, - (MMPortSerialAtResponseFn)serial_probe_at_parse_response, + (GAsyncReadyCallback)serial_probe_at_parse_response, self); return FALSE; } diff --git a/src/mm-port-serial-at.c b/src/mm-port-serial-at.c index a8f95133..780bfbb9 100644 --- a/src/mm-port-serial-at.c +++ b/src/mm-port-serial-at.c @@ -158,16 +158,9 @@ handle_response (MMPortSerial *port, GCallback callback, gpointer callback_data) { - MMPortSerialAt *self = MM_PORT_SERIAL_AT (port); - MMPortSerialAtResponseFn response_callback = (MMPortSerialAtResponseFn) callback; - GString *string; - - /* Convert to a string and call the callback */ - string = g_string_sized_new (response->len + 1); - g_string_append_len (string, (const char *) response->data, response->len); - response_callback (self, string, error, callback_data); - g_string_free (string, TRUE); + MMSerialResponseFn response_callback = (MMSerialResponseFn) callback; + response_callback (port, response, error, callback_data); return response->len; } @@ -350,43 +343,61 @@ at_command_to_byte_array (const char *command, gboolean is_raw, gboolean send_lf return buf; } -void -mm_port_serial_at_queue_command (MMPortSerialAt *self, - const char *command, - guint32 timeout_seconds, - gboolean is_raw, - GCancellable *cancellable, - MMPortSerialAtResponseFn callback, - gpointer user_data) +const gchar * +mm_port_serial_at_command_finish (MMPortSerialAt *self, + GAsyncResult *res, + GError **error) { - GByteArray *buf; - MMPortSerialAtPrivate *priv = MM_PORT_SERIAL_AT_GET_PRIVATE (self); + GString *str; - g_return_if_fail (self != NULL); - g_return_if_fail (MM_IS_PORT_SERIAL_AT (self)); - g_return_if_fail (command != NULL); + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (res), error)) + return NULL; - buf = at_command_to_byte_array (command, is_raw, priv->send_lf); - g_return_if_fail (buf != NULL); + str = (GString *)g_simple_async_result_get_op_res_gpointer (G_SIMPLE_ASYNC_RESULT (res)); + return str->str; +} - mm_port_serial_queue_command (MM_PORT_SERIAL (self), - buf, - TRUE, - timeout_seconds, - cancellable, - (MMSerialResponseFn) callback, - user_data); +static void +string_free (GString *str) +{ + g_string_free (str, TRUE); +} + +static void +serial_command_ready (MMPortSerial *port, + GByteArray *response, + GError *error, + GSimpleAsyncResult *simple) +{ + if (error) + g_simple_async_result_set_from_error (simple, error); + else if (response) { + GString *str; + + /* Build a GString just with the response we need, and clear the + * processed range from the response buffer */ + str = g_string_new_len ((const gchar *)response->data, response->len); + g_simple_async_result_set_op_res_gpointer (simple, + str, + (GDestroyNotify)string_free); + } else + g_assert_not_reached (); + + g_simple_async_result_complete (simple); + g_object_unref (simple); } void -mm_port_serial_at_queue_command_cached (MMPortSerialAt *self, - const char *command, - guint32 timeout_seconds, - gboolean is_raw, - GCancellable *cancellable, - MMPortSerialAtResponseFn callback, - gpointer user_data) +mm_port_serial_at_command (MMPortSerialAt *self, + const char *command, + guint32 timeout_seconds, + gboolean is_raw, + gboolean allow_cached, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { + GSimpleAsyncResult *simple; GByteArray *buf; MMPortSerialAtPrivate *priv = MM_PORT_SERIAL_AT_GET_PRIVATE (self); @@ -397,13 +408,27 @@ mm_port_serial_at_queue_command_cached (MMPortSerialAt *self, buf = at_command_to_byte_array (command, is_raw, priv->send_lf); g_return_if_fail (buf != NULL); - mm_port_serial_queue_command_cached (MM_PORT_SERIAL (self), - buf, - TRUE, - timeout_seconds, - cancellable, - (MMSerialResponseFn) callback, - user_data); + simple = g_simple_async_result_new (G_OBJECT (self), + callback, + user_data, + mm_port_serial_at_command); + + if (!allow_cached) + mm_port_serial_queue_command (MM_PORT_SERIAL (self), + buf, + TRUE, + timeout_seconds, + cancellable, + (MMSerialResponseFn)serial_command_ready, + simple); + else + mm_port_serial_queue_command_cached (MM_PORT_SERIAL (self), + buf, + TRUE, + timeout_seconds, + cancellable, + (MMSerialResponseFn)serial_command_ready, + simple); } static void @@ -474,13 +499,14 @@ mm_port_serial_at_run_init_sequence (MMPortSerialAt *self) /* Just queue the init commands, don't wait for reply */ for (i = 0; priv->init_sequence[i]; i++) { - mm_port_serial_at_queue_command (self, - priv->init_sequence[i], - 3, - FALSE, - NULL, - NULL, - NULL); + mm_port_serial_at_command (self, + priv->init_sequence[i], + 3, + FALSE, + FALSE, + NULL, + NULL, + NULL); } } diff --git a/src/mm-port-serial-at.h b/src/mm-port-serial-at.h index 58cf51c1..52e6c604 100644 --- a/src/mm-port-serial-at.h +++ b/src/mm-port-serial-at.h @@ -60,11 +60,6 @@ typedef void (*MMPortSerialAtUnsolicitedMsgFn) (MMPortSerialAt *port, GMatchInfo *match_info, gpointer user_data); -typedef void (*MMPortSerialAtResponseFn) (MMPortSerialAt *port, - GString *response, - GError *error, - gpointer user_data); - #define MM_PORT_SERIAL_AT_REMOVE_ECHO "remove-echo" #define MM_PORT_SERIAL_AT_INIT_SEQUENCE_ENABLED "init-sequence-enabled" #define MM_PORT_SERIAL_AT_INIT_SEQUENCE "init-sequence" @@ -97,21 +92,17 @@ void mm_port_serial_at_set_response_parser (MMPortSerialAt *self, gpointer user_data, GDestroyNotify notify); -void mm_port_serial_at_queue_command (MMPortSerialAt *self, - const char *command, - guint32 timeout_seconds, - gboolean is_raw, - GCancellable *cancellable, - MMPortSerialAtResponseFn callback, - gpointer user_data); - -void mm_port_serial_at_queue_command_cached (MMPortSerialAt *self, - const char *command, - guint32 timeout_seconds, - gboolean is_raw, - GCancellable *cancellable, - MMPortSerialAtResponseFn callback, - gpointer user_data); +void mm_port_serial_at_command (MMPortSerialAt *self, + const char *command, + guint32 timeout_seconds, + gboolean is_raw, + gboolean allow_cached, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +const gchar *mm_port_serial_at_command_finish (MMPortSerialAt *self, + GAsyncResult *res, + GError **error); /* * Convert a string into a quoted and escaped string. Returns a new |