diff options
author | Aleksander Morgado <aleksander@lanedo.com> | 2012-09-24 17:08:37 +0200 |
---|---|---|
committer | Aleksander Morgado <aleksander@lanedo.com> | 2012-09-26 09:25:06 +0200 |
commit | 2947d4f6e53a39bdd800b208a2da5488f4a84797 (patch) | |
tree | 16e78d934b19eb71cc6859fb6f478800d38fbdeb | |
parent | c3c3acb3e6acd6782f81ef246e94beedc8eb8f0b (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.c | 41 | ||||
-rw-r--r-- | libqmi-glib/qmi-message.c | 30 | ||||
-rw-r--r-- | libqmi-glib/qmi-message.h | 4 |
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); |