core: let partial serial responses be consumed by the handlers

This commit is contained in:
Dan Williams
2010-03-20 02:57:33 -07:00
parent 4006ca4dec
commit ff2182fe1d
4 changed files with 41 additions and 18 deletions

View File

@@ -85,7 +85,7 @@ parse_response (MMSerialPort *port, GByteArray *response, GError **error)
return found; return found;
} }
static void static gsize
handle_response (MMSerialPort *port, handle_response (MMSerialPort *port,
GByteArray *response, GByteArray *response,
GError *error, GError *error,
@@ -101,6 +101,8 @@ handle_response (MMSerialPort *port,
g_string_append_len (string, (const char *) response->data, response->len); g_string_append_len (string, (const char *) response->data, response->len);
response_callback (self, string, error, callback_data); response_callback (self, string, error, callback_data);
g_string_free (string, TRUE); g_string_free (string, TRUE);
return response->len;
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -53,7 +53,7 @@ parse_response (MMSerialPort *port, GByteArray *response, GError **error)
return FALSE; return FALSE;
} }
static void static gsize
handle_response (MMSerialPort *port, handle_response (MMSerialPort *port,
GByteArray *response, GByteArray *response,
GError *error, GError *error,
@@ -62,18 +62,34 @@ handle_response (MMSerialPort *port,
{ {
MMQcdmSerialResponseFn response_callback = (MMQcdmSerialResponseFn) callback; MMQcdmSerialResponseFn response_callback = (MMQcdmSerialResponseFn) callback;
GByteArray *unescaped = NULL; GByteArray *unescaped = NULL;
gboolean escaping = FALSE;
GError *dm_error = NULL; GError *dm_error = NULL;
gsize used = 0;
/* Ignore empty frames */
if (!response->len > 0 && response->data[0] == 0x7E)
return 1;
if (!error) { if (!error) {
unescaped = g_byte_array_sized_new (response->len); gboolean more = FALSE, success;
unescaped->len = dm_unescape ((const char *) response->data, response->len,
(char *) unescaped->data, unescaped->len, /* FIXME: don't munge around with byte array internals */
&escaping); unescaped = g_byte_array_sized_new (1024);
if (unescaped->len == 0) { 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_set_error_literal (&dm_error, 0, 0, "Failed to unescape QCDM packet.");
g_byte_array_free (unescaped, TRUE); g_byte_array_free (unescaped, TRUE);
unescaped = NULL; 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) if (unescaped)
g_byte_array_free (unescaped, TRUE); g_byte_array_free (unescaped, TRUE);
return used;
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -492,7 +492,7 @@ mm_serial_port_schedule_queue_process (MMSerialPort *self)
g_source_unref (source); g_source_unref (source);
} }
static void static gsize
real_handle_response (MMSerialPort *self, real_handle_response (MMSerialPort *self,
GByteArray *response, GByteArray *response,
GError *error, GError *error,
@@ -502,6 +502,7 @@ real_handle_response (MMSerialPort *self,
MMSerialResponseFn response_callback = (MMSerialResponseFn) callback; MMSerialResponseFn response_callback = (MMSerialResponseFn) callback;
response_callback (self, response, error, callback_data); response_callback (self, response, error, callback_data);
return response->len;
} }
static void static void
@@ -509,6 +510,7 @@ mm_serial_port_got_response (MMSerialPort *self, GError *error)
{ {
MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self); MMSerialPortPrivate *priv = MM_SERIAL_PORT_GET_PRIVATE (self);
MMQueueData *info; MMQueueData *info;
gsize consumed = priv->response->len;
if (priv->timeout_id) { if (priv->timeout_id) {
g_source_remove (priv->timeout_id); g_source_remove (priv->timeout_id);
@@ -522,7 +524,7 @@ mm_serial_port_got_response (MMSerialPort *self, GError *error)
if (info->callback) { if (info->callback) {
g_warn_if_fail (MM_SERIAL_PORT_GET_CLASS (self)->handle_response != NULL); g_warn_if_fail (MM_SERIAL_PORT_GET_CLASS (self)->handle_response != NULL);
MM_SERIAL_PORT_GET_CLASS (self)->handle_response (self, consumed = MM_SERIAL_PORT_GET_CLASS (self)->handle_response (self,
priv->response, priv->response,
error, error,
info->callback, info->callback,
@@ -536,8 +538,8 @@ mm_serial_port_got_response (MMSerialPort *self, GError *error)
if (error) if (error)
g_error_free (error); g_error_free (error);
if (priv->response->len) if (consumed)
g_byte_array_remove_range (priv->response, 0, priv->response->len); g_byte_array_remove_range (priv->response, 0, consumed);
if (!g_queue_is_empty (priv->queue)) if (!g_queue_is_empty (priv->queue))
mm_serial_port_schedule_queue_process (self); mm_serial_port_schedule_queue_process (self);
} }

View File

@@ -74,9 +74,10 @@ struct _MMSerialPortClass {
GError **error); GError **error);
/* Called after parsing to allow the command response to be delivered to /* 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, GByteArray *response,
GError *error, GError *error,
GCallback callback, GCallback callback,