aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2010-03-20 02:57:33 -0700
committerDan Williams <dcbw@redhat.com>2010-03-20 02:57:33 -0700
commitff2182fe1d1fdc6817835839c062129d1adb629d (patch)
tree0e09fa1733502ee9c5235918653c8f18d11599d6
parent4006ca4decaec051aa4449977d92f96545b3aa88 (diff)
core: let partial serial responses be consumed by the handlers
-rw-r--r--src/mm-at-serial-port.c4
-rw-r--r--src/mm-qcdm-serial-port.c32
-rw-r--r--src/mm-serial-port.c18
-rw-r--r--src/mm-serial-port.h5
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,