summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@lanedo.com>2012-09-24 17:08:37 +0200
committerAleksander Morgado <aleksander@lanedo.com>2012-09-26 09:25:06 +0200
commit2947d4f6e53a39bdd800b208a2da5488f4a84797 (patch)
tree16e78d934b19eb71cc6859fb6f478800d38fbdeb
parentc3c3acb3e6acd6782f81ef246e94beedc8eb8f0b (diff)
message: use a modifiable `GByteArray' in `qmi_message_new_from_raw ()'
Passing a modifiable `GByteArray' allows us to run the validity check as soon as we create the `QmiMessage', given that we can remove the read chunk of data from the input buffer directly. This removal takes place both when the QMI message is valid and invalid.
-rw-r--r--libqmi-glib/qmi-device.c41
-rw-r--r--libqmi-glib/qmi-message.c30
-rw-r--r--libqmi-glib/qmi-message.h4
3 files changed, 38 insertions, 37 deletions
diff --git a/libqmi-glib/qmi-device.c b/libqmi-glib/qmi-device.c
index 04b963d..8625d99 100644
--- a/libqmi-glib/qmi-device.c
+++ b/libqmi-glib/qmi-device.c
@@ -1055,17 +1055,6 @@ static void
process_message (QmiDevice *self,
QmiMessage *message)
{
- GError *error = NULL;
-
- /* Ensure the read message is valid */
- if (!qmi_message_check (message, &error)) {
- g_warning ("[%s] Invalid QMI message received: %s",
- self->priv->path_display,
- error->message);
- g_error_free (error);
- return;
- }
-
#ifdef MESSAGE_ENABLE_TRACE
{
gchar *printable;
@@ -1125,6 +1114,7 @@ static void
parse_response (QmiDevice *self)
{
do {
+ GError *error = NULL;
QmiMessage *message;
/* Every message received must start with the QMUX marker.
@@ -1139,21 +1129,22 @@ parse_response (QmiDevice *self)
return;
}
- message = qmi_message_new_from_raw (self->priv->response->data,
- self->priv->response->len);
- if (!message)
- /* More data we need */
- return;
-
- /* Remove the read data from the response buffer */
- g_byte_array_remove_range (self->priv->response,
- 0,
- qmi_message_get_length (message));
-
- /* Play with the received message */
- process_message (self, message);
+ message = qmi_message_new_from_raw (self->priv->response, &error);
+ if (!message) {
+ if (!error)
+ /* More data we need */
+ return;
- qmi_message_unref (message);
+ /* Warn about the issue */
+ g_warning ("[%s] Invalid QMI message received: '%s'",
+ self->priv->path_display,
+ error->message);
+ g_error_free (error);
+ } else {
+ /* Play with the received message */
+ process_message (self, message);
+ qmi_message_unref (message);
+ }
} while (self->priv->response->len > 0);
}
diff --git a/libqmi-glib/qmi-message.c b/libqmi-glib/qmi-message.c
index 26118f5..fbab2ec 100644
--- a/libqmi-glib/qmi-message.c
+++ b/libqmi-glib/qmi-message.c
@@ -689,16 +689,18 @@ qmi_message_add_raw_tlv (QmiMessage *self,
/**
* qmi_message_new_from_raw:
- * @raw: raw data buffer.
- * @length: length of the raw data buffer.
+ * @raw: (inout): raw data buffer.
+ * @error: return location for error or %NULL.
*
* Create a new #QmiMessage from the given raw data buffer.
*
- * Returns: (transfer full): a newly created #QmiMessage or #NULL if @raw doesn't contain a valid complete QMI message. The returned value should be freed with qmi_message_unref().
+ * Whenever a complete QMI message is read, its raw data gets removed from the @raw buffer.
+ *
+ * Returns: (transfer full): a newly created #QmiMessage, which should be freed with qmi_message_unref(). If @raw doesn't contain a complete QMI message #NULL is returned. If there is a complete QMI message but it appears not to be valid, #NULL is returned and @error is set.
*/
QmiMessage *
-qmi_message_new_from_raw (const guint8 *raw,
- gsize length)
+qmi_message_new_from_raw (GByteArray *raw,
+ GError **error)
{
QmiMessage *self;
gsize message_len;
@@ -707,13 +709,13 @@ qmi_message_new_from_raw (const guint8 *raw,
/* If we didn't even read the QMUX header (comes after the 1-byte marker),
* leave */
- if (length < (sizeof (struct qmux) + 1))
+ if (raw->len < (sizeof (struct qmux) + 1))
return NULL;
/* We need to have read the length reported by the QMUX header (plus the
* initial 1-byte marker) */
- message_len = GUINT16_FROM_LE (((struct full_message *)raw)->qmux.length);
- if (length < (message_len + 1))
+ message_len = GUINT16_FROM_LE (((struct full_message *)raw->data)->qmux.length);
+ if (raw->len < (message_len + 1))
return NULL;
/* Ok, so we should have all the data available already */
@@ -721,9 +723,17 @@ qmi_message_new_from_raw (const guint8 *raw,
self->ref_count = 1;
self->len = message_len + 1;
self->buf = g_malloc (self->len);
- memcpy (self->buf, raw, self->len);
+ memcpy (self->buf, raw->data, self->len);
+
+ /* We got a complete QMI message, remove from input buffer */
+ g_byte_array_remove_range (raw, 0, self->len);
- /* NOTE: we don't check if the message is valid here, let the caller do it */
+ /* Check input message validity as soon as we create the QmiMessage */
+ if (!qmi_message_check (self, error)) {
+ /* Yes, we lose the whole message here */
+ qmi_message_unref (self);
+ return NULL;
+ }
return self;
}
diff --git a/libqmi-glib/qmi-message.h b/libqmi-glib/qmi-message.h
index d147bcf..b9934b0 100644
--- a/libqmi-glib/qmi-message.h
+++ b/libqmi-glib/qmi-message.h
@@ -52,8 +52,8 @@ QmiMessage *qmi_message_new (QmiService service,
guint8 client_id,
guint16 transaction_id,
guint16 message_id);
-QmiMessage *qmi_message_new_from_raw (const guint8 *raw,
- gsize length);
+QmiMessage *qmi_message_new_from_raw (GByteArray *raw,
+ GError **error);
QmiMessage *qmi_message_ref (QmiMessage *self);
void qmi_message_unref (QmiMessage *self);