diff options
author | Dan Williams <dcbw@redhat.com> | 2010-03-20 02:57:33 -0700 |
---|---|---|
committer | Dan Williams <dcbw@redhat.com> | 2010-03-20 02:57:33 -0700 |
commit | ff2182fe1d1fdc6817835839c062129d1adb629d (patch) | |
tree | 0e09fa1733502ee9c5235918653c8f18d11599d6 /src | |
parent | 4006ca4decaec051aa4449977d92f96545b3aa88 (diff) |
core: let partial serial responses be consumed by the handlers
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-at-serial-port.c | 4 | ||||
-rw-r--r-- | src/mm-qcdm-serial-port.c | 32 | ||||
-rw-r--r-- | src/mm-serial-port.c | 18 | ||||
-rw-r--r-- | src/mm-serial-port.h | 5 |
4 files changed, 41 insertions, 18 deletions
diff --git a/src/mm-at-serial-port.c b/src/mm-at-serial-port.c index d038c50c..60a75d91 100644 --- a/src/mm-at-serial-port.c +++ b/src/mm-at-serial-port.c @@ -85,7 +85,7 @@ parse_response (MMSerialPort *port, GByteArray *response, GError **error) return found; } -static void +static gsize handle_response (MMSerialPort *port, GByteArray *response, GError *error, @@ -101,6 +101,8 @@ handle_response (MMSerialPort *port, g_string_append_len (string, (const char *) response->data, response->len); response_callback (self, string, error, callback_data); g_string_free (string, TRUE); + + return response->len; } /*****************************************************************************/ diff --git a/src/mm-qcdm-serial-port.c b/src/mm-qcdm-serial-port.c index 14ccf561..e79dbea2 100644 --- a/src/mm-qcdm-serial-port.c +++ b/src/mm-qcdm-serial-port.c @@ -53,7 +53,7 @@ parse_response (MMSerialPort *port, GByteArray *response, GError **error) return FALSE; } -static void +static gsize handle_response (MMSerialPort *port, GByteArray *response, GError *error, @@ -62,18 +62,34 @@ handle_response (MMSerialPort *port, { MMQcdmSerialResponseFn response_callback = (MMQcdmSerialResponseFn) callback; GByteArray *unescaped = NULL; - gboolean escaping = FALSE; GError *dm_error = NULL; + gsize used = 0; + + /* Ignore empty frames */ + if (!response->len > 0 && response->data[0] == 0x7E) + return 1; if (!error) { - unescaped = g_byte_array_sized_new (response->len); - unescaped->len = dm_unescape ((const char *) response->data, response->len, - (char *) unescaped->data, unescaped->len, - &escaping); - if (unescaped->len == 0) { + gboolean more = FALSE, success; + + /* FIXME: don't munge around with byte array internals */ + unescaped = g_byte_array_sized_new (1024); + success = dm_decapsulate_buffer ((const char *) response->data, + response->len, + (char *) unescaped->data, + sizeof (1024), + &unescaped->len, + &used, + &more); + if (!success) { g_set_error_literal (&dm_error, 0, 0, "Failed to unescape QCDM packet."); g_byte_array_free (unescaped, TRUE); unescaped = NULL; + } else if (more) { + /* Need more data; we shouldn't have gotten here since the parse + * function checks for the end-of-frame marker, but whatever. + */ + return 0; } } @@ -84,6 +100,8 @@ handle_response (MMSerialPort *port, if (unescaped) g_byte_array_free (unescaped, TRUE); + + return used; } /*****************************************************************************/ diff --git a/src/mm-serial-port.c b/src/mm-serial-port.c index 46e9c567..609e20de 100644 --- a/src/mm-serial-port.c +++ b/src/mm-serial-port.c @@ -492,7 +492,7 @@ mm_serial_port_schedule_queue_process (MMSerialPort *self) g_source_unref (source); } -static void +static gsize real_handle_response (MMSerialPort *self, GByteArray *response, GError *error, @@ -502,6 +502,7 @@ real_handle_response (MMSerialPort *self, MMSerialResponseFn response_callback = (MMSerialResponseFn) callback; response_callback (self, response, error, callback_data); + return response->len; } static void @@ -509,6 +510,7 @@ mm_serial_port_got_response (MMSerialPort *self, GError *error) { MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self); MMQueueData *info; + gsize consumed = priv->response->len; if (priv->timeout_id) { g_source_remove (priv->timeout_id); @@ -522,11 +524,11 @@ mm_serial_port_got_response (MMSerialPort *self, GError *error) if (info->callback) { g_warn_if_fail (MM_SERIAL_PORT_GET_CLASS (self)->handle_response != NULL); - MM_SERIAL_PORT_GET_CLASS (self)->handle_response (self, - priv->response, - error, - info->callback, - info->user_data); + consumed = MM_SERIAL_PORT_GET_CLASS (self)->handle_response (self, + priv->response, + error, + info->callback, + info->user_data); } g_byte_array_free (info->command, TRUE); @@ -536,8 +538,8 @@ mm_serial_port_got_response (MMSerialPort *self, GError *error) if (error) g_error_free (error); - if (priv->response->len) - g_byte_array_remove_range (priv->response, 0, priv->response->len); + if (consumed) + g_byte_array_remove_range (priv->response, 0, consumed); if (!g_queue_is_empty (priv->queue)) mm_serial_port_schedule_queue_process (self); } diff --git a/src/mm-serial-port.h b/src/mm-serial-port.h index a757c932..67f2a37a 100644 --- a/src/mm-serial-port.h +++ b/src/mm-serial-port.h @@ -74,9 +74,10 @@ struct _MMSerialPortClass { GError **error); /* Called after parsing to allow the command response to be delivered to - * it's callback to be handled. + * it's callback to be handled. Returns the # of bytes of the response + * consumed. */ - void (*handle_response) (MMSerialPort *self, + gsize (*handle_response) (MMSerialPort *self, GByteArray *response, GError *error, GCallback callback, |