summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2021-10-24 15:03:31 +0200
committerAleksander Morgado <aleksander@aleksander.es>2021-10-25 12:48:51 +0200
commite980523babf3bcc508557a4a113d91330fdee433 (patch)
tree9d147d3aea8c716b48761b88520236365300b786
parentee9eea63160664c4e28ae73e112ca582f0c4621f (diff)
libmbim-glib,tlv: parsers for wake command and wake packet types
-rw-r--r--build-aux/mbim-codegen/utils.py1
-rw-r--r--data/mbim-service-ms-basic-connect-extensions-v3.json4
-rwxr-xr-xdocs/reference/libmbim-glib/libmbim-glib-common.sections4
-rw-r--r--src/libmbim-glib/mbim-tlv.c151
-rw-r--r--src/libmbim-glib/mbim-tlv.h63
-rw-r--r--src/libmbim-glib/test/test-message-parser.c244
-rw-r--r--src/mbimcli/mbimcli-ms-basic-connect-extensions.c89
7 files changed, 544 insertions, 12 deletions
diff --git a/build-aux/mbim-codegen/utils.py b/build-aux/mbim-codegen/utils.py
index 5ed3ff0..6722269 100644
--- a/build-aux/mbim-codegen/utils.py
+++ b/build-aux/mbim-codegen/utils.py
@@ -46,6 +46,7 @@ def add_header_start(f, output_name):
"#include \"mbim-message.h\"\n"
"#include \"mbim-device.h\"\n"
"#include \"mbim-enums.h\"\n"
+ "#include \"mbim-tlv.h\"\n"
"\n"
"#ifndef ${guard}\n"
"#define ${guard}\n"
diff --git a/data/mbim-service-ms-basic-connect-extensions-v3.json b/data/mbim-service-ms-basic-connect-extensions-v3.json
index 02e06e4..71ed7aa 100644
--- a/data/mbim-service-ms-basic-connect-extensions-v3.json
+++ b/data/mbim-service-ms-basic-connect-extensions-v3.json
@@ -274,7 +274,7 @@
"public-format" : "MbimWakeType" },
{ "name" : "SessionId",
"format" : "guint32" },
- { "name" : "DataBuffer",
- "format" : "unsized-byte-array" } ] }
+ { "name" : "WakeTlv",
+ "format" : "tlv" } ] }
]
diff --git a/docs/reference/libmbim-glib/libmbim-glib-common.sections b/docs/reference/libmbim-glib/libmbim-glib-common.sections
index 6a07b4c..ab4585e 100755
--- a/docs/reference/libmbim-glib/libmbim-glib-common.sections
+++ b/docs/reference/libmbim-glib/libmbim-glib-common.sections
@@ -788,6 +788,10 @@ mbim_tlv_string_new
mbim_tlv_string_get
<SUBSECTION TlvUint16Array>
mbim_tlv_guint16_array_get
+<SUBSECTION TlvWakeCommand>
+mbim_tlv_wake_command_get
+<SUBSECTION TlvWakePacket>
+mbim_tlv_wake_packet_get
<SUBSECTION Private>
mbim_tlv_type_build_string_from_mask
<SUBSECTION Standard>
diff --git a/src/libmbim-glib/mbim-tlv.c b/src/libmbim-glib/mbim-tlv.c
index b347d0f..8058836 100644
--- a/src/libmbim-glib/mbim-tlv.c
+++ b/src/libmbim-glib/mbim-tlv.c
@@ -323,3 +323,154 @@ mbim_tlv_guint16_array_get (const MbimTlv *self,
return TRUE;
}
+
+/*****************************************************************************/
+
+gboolean
+mbim_tlv_wake_command_get (const MbimTlv *self,
+ const MbimUuid **service,
+ guint32 *cid,
+ guint32 *payload_size,
+ guint8 **payload,
+ GError **error)
+{
+ const guint8 *tlv_data;
+ guint32 tlv_data_size;
+ guint32 buffer_offset;
+ guint32 buffer_size;
+ guint32 offset = 0;
+ guint64 required_size;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (MBIM_TLV_GET_TLV_TYPE (self) != MBIM_TLV_TYPE_WAKE_COMMAND) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "TLV is not a wake command");
+ return FALSE;
+ }
+
+ tlv_data = mbim_tlv_get_tlv_data (self, &tlv_data_size);
+ tlv_data_size = MBIM_TLV_GET_DATA_LENGTH (self);
+
+ required_size = 28;
+ if (tlv_data_size < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake command TLV (%u < %" G_GUINT64_FORMAT ")",
+ tlv_data_size, required_size);
+ return FALSE;
+ }
+
+ if (service)
+ *service = (const MbimUuid *) G_STRUCT_MEMBER_P (tlv_data, offset);
+ offset += 16;
+
+ if (cid)
+ *cid = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ buffer_offset = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ buffer_size = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ if (buffer_size > 0) {
+ if (buffer_offset != required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake command TLV: invalid payload offset (%u)",
+ buffer_offset);
+ return FALSE;
+ }
+
+ required_size += buffer_size;
+ if (tlv_data_size < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake command TLV payload (%u bytes) (%u < %" G_GUINT64_FORMAT ")",
+ buffer_size, tlv_data_size, required_size);
+ return FALSE;
+ }
+ }
+
+ if (payload_size)
+ *payload_size = buffer_size;
+ if (payload)
+ *payload = (buffer_size ? g_memdup (&tlv_data[offset], buffer_size) : NULL);
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+gboolean
+mbim_tlv_wake_packet_get (const MbimTlv *self,
+ guint32 *filter_id,
+ guint32 *original_packet_size,
+ guint32 *packet_size,
+ guint8 **packet,
+ GError **error)
+{
+
+ const guint8 *tlv_data;
+ guint32 tlv_data_size;
+ guint32 buffer_offset;
+ guint32 buffer_size;
+ guint32 offset = 0;
+ guint64 required_size;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (MBIM_TLV_GET_TLV_TYPE (self) != MBIM_TLV_TYPE_WAKE_PACKET) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "TLV is not a wake packet");
+ return FALSE;
+ }
+
+ tlv_data = mbim_tlv_get_tlv_data (self, &tlv_data_size);
+ tlv_data_size = MBIM_TLV_GET_DATA_LENGTH (self);
+
+ required_size = 16;
+ if (tlv_data_size < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake packet TLV (%u < %" G_GUINT64_FORMAT ")",
+ tlv_data_size, required_size);
+ return FALSE;
+ }
+
+ if (filter_id)
+ *filter_id = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ if (original_packet_size)
+ *original_packet_size = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ buffer_offset = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ buffer_size = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ if (buffer_size > 0) {
+ if (buffer_offset != offset) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake packet TLV: invalid saved packet offset (%u)",
+ buffer_offset);
+ return FALSE;
+ }
+
+ required_size += buffer_size;
+ if (tlv_data_size < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake packet TLV payload (%u bytes) (%u < %" G_GUINT64_FORMAT ")",
+ buffer_size, tlv_data_size, required_size);
+ return FALSE;
+ }
+ }
+
+ if (packet_size)
+ *packet_size = buffer_size;
+ if (packet)
+ *packet = (buffer_size ? g_memdup (&tlv_data[offset], buffer_size) : NULL);
+
+ return TRUE;
+}
diff --git a/src/libmbim-glib/mbim-tlv.h b/src/libmbim-glib/mbim-tlv.h
index cfafb4a..64b9c8b 100644
--- a/src/libmbim-glib/mbim-tlv.h
+++ b/src/libmbim-glib/mbim-tlv.h
@@ -17,6 +17,8 @@
#include <glib.h>
#include <glib-object.h>
+#include "mbim-uuid.h"
+
G_BEGIN_DECLS
/**
@@ -247,6 +249,67 @@ gboolean mbim_tlv_guint16_array_get (const MbimTlv *self,
guint16 **array,
GError **error);
+/*****************************************************************************/
+/* wake command type helpers */
+
+/**
+ * mbim_tlv_wake_command_get:
+ * @self: a #MbimTlv of type %MBIM_TLV_TYPE_WAKE_COMMAND.
+ * @service: (out)(optional)(transfer none): return location for a #MbimUuid
+ * specifying the service that triggered the wake.
+ * @cid: (out)(optional)(transfer none): return location for the command id that
+ * triggered the wake.
+ * @payload_size: (out)(optional)(transfer none): return location for a #guint32,
+ * or %NULL if the field is not needed.
+ * @payload: (out)(optional)(transfer full)(type guint8): return location for a
+ * newly allocated array of #guint8 values, or %NULL if the field is not
+ * needed. Free the returned value with g_free().
+ *
+ * Get the contents of a wake command TLV.
+ *
+ * The method may return a successful return even with on empty payload (i.e.
+ * with @payload_size set to 0 and @payload set to %NULL).
+ *
+ * Returns: %TRUE if on success, %FALSE if @error is set.
+ *
+ * Since: 1.28
+ */
+gboolean mbim_tlv_wake_command_get (const MbimTlv *self,
+ const MbimUuid **service,
+ guint32 *cid,
+ guint32 *payload_size,
+ guint8 **payload,
+ GError **error);
+
+/*****************************************************************************/
+/* wake packet type helpers */
+
+/**
+ * mbim_tlv_wake_packet_get:
+ * @self: a #MbimTlv of type %MBIM_TLV_TYPE_WAKE_PACKET.
+ * @filter_id: (out)(optional)(transfer none): return location for a #guint32
+ * specifying the filter id.
+ * @original_packet_size: (out)(optional)(transfer none): return location for a
+ * #guint32, or %NULL if the field is not needed.
+ * @packet_size: (out)(optional)(transfer none): return location for a #guint32,
+ * or %NULL if the field is not needed.
+ * @packet: (out)(optional)(transfer full)(type guint8): return location for a
+ * newly allocated array of #guint8 values, or %NULL if the field is not
+ * needed. Free the returned value with g_free().
+ *
+ * Get the contents of a wake packet TLV.
+ *
+ * Returns: %TRUE if on success, %FALSE if @error is set.
+ *
+ * Since: 1.28
+ */
+gboolean mbim_tlv_wake_packet_get (const MbimTlv *self,
+ guint32 *filter_id,
+ guint32 *original_packet_size,
+ guint32 *packet_size,
+ guint8 **packet,
+ GError **error);
+
G_END_DECLS
#endif /* _LIBMBIM_GLIB_MBIM_TLV_H_ */
diff --git a/src/libmbim-glib/test/test-message-parser.c b/src/libmbim-glib/test/test-message-parser.c
index aad01ea..f5690cc 100644
--- a/src/libmbim-glib/test/test-message-parser.c
+++ b/src/libmbim-glib/test/test-message-parser.c
@@ -2582,6 +2582,247 @@ test_message_parser_ms_basic_connect_v3_connect_3_unnamed_tlvs (void)
g_list_free_full (unnamed_ies, (GDestroyNotify)mbim_tlv_unref);
}
+static void
+test_message_parser_ms_basic_connect_extensions_wake_reason_command (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimWakeType wake_type;
+ guint32 session_id;
+ g_autoptr(MbimTlv) wake_tlv = NULL;
+ const MbimUuid *service = NULL;
+ guint32 cid = 0;
+ guint32 payload_size = 0;
+ g_autofree guint8 *payload = NULL;
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x5C, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x13, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x2C, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x01, 0x00, 0x00, 0x00, /* wake type: cid indication */
+ 0x02, 0x00, 0x00, 0x00, /* session id */
+ /* TLV */
+ 0x10, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WAKE_COMMAND, padding 0 */
+ 0x1C, 0x00, 0x00, 0x00, /* TLV data length */
+ 0xA2, 0x89, 0xCC, 0x33, /* service id: basic connect */
+ 0xBC, 0xBB, 0x8B, 0x4F,
+ 0xB6, 0xB0, 0x13, 0x3E,
+ 0xC2, 0xAA, 0xE6, 0xDF,
+ 0x0B, 0x00, 0x00, 0x00, /* command id: signal state */
+ 0x00, 0x00, 0x00, 0x00, /* payload offset: none */
+ 0x00, 0x00, 0x00, 0x00, /* payload size: none */
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_wake_reason_response_parse (
+ response,
+ &wake_type,
+ &session_id,
+ &wake_tlv,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (wake_type, ==, MBIM_WAKE_TYPE_CID_INDICATION);
+ g_assert_cmpuint (session_id, ==, 2);
+ g_assert_nonnull (wake_tlv);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (wake_tlv), ==, MBIM_TLV_TYPE_WAKE_COMMAND);
+
+ result = (mbim_tlv_wake_command_get (wake_tlv,
+ &service,
+ &cid,
+ &payload_size,
+ &payload,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (mbim_uuid_to_service (service), ==, MBIM_SERVICE_BASIC_CONNECT);
+ g_assert_cmpuint (cid, ==, MBIM_CID_BASIC_CONNECT_SIGNAL_STATE);
+ g_assert_cmpuint (payload_size, ==, 0);
+ g_assert_null (payload);
+}
+
+static void
+test_message_parser_ms_basic_connect_extensions_wake_reason_command_payload (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimWakeType wake_type;
+ guint32 session_id;
+ g_autoptr(MbimTlv) wake_tlv = NULL;
+ const MbimUuid *service = NULL;
+ guint32 cid = 0;
+ guint32 payload_size = 0;
+ g_autofree guint8 *payload = NULL;
+ guint32 payload_uint;
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x60, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x13, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x30, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x00, 0x00, 0x00, 0x00, /* wake type: cid response */
+ 0x02, 0x00, 0x00, 0x00, /* session id */
+ /* TLV */
+ 0x10, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WAKE_COMMAND, padding 0 */
+ 0x20, 0x00, 0x00, 0x00, /* TLV data length */
+ 0xA2, 0x89, 0xCC, 0x33, /* service id: basic connect */
+ 0xBC, 0xBB, 0x8B, 0x4F,
+ 0xB6, 0xB0, 0x13, 0x3E,
+ 0xC2, 0xAA, 0xE6, 0xDF,
+ 0x0C, 0x00, 0x00, 0x00, /* command id: connect */
+ 0x1C, 0x00, 0x00, 0x00, /* payload offset: 28 */
+ 0x04, 0x00, 0x00, 0x00, /* payload size: 4 */
+ 0x01, 0x00, 0x00, 0x00, /* payload: a guint32 */
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_wake_reason_response_parse (
+ response,
+ &wake_type,
+ &session_id,
+ &wake_tlv,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (wake_type, ==, MBIM_WAKE_TYPE_CID_RESPONSE);
+ g_assert_cmpuint (session_id, ==, 2);
+ g_assert_nonnull (wake_tlv);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (wake_tlv), ==, MBIM_TLV_TYPE_WAKE_COMMAND);
+
+ result = (mbim_tlv_wake_command_get (wake_tlv,
+ &service,
+ &cid,
+ &payload_size,
+ &payload,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (mbim_uuid_to_service (service), ==, MBIM_SERVICE_BASIC_CONNECT);
+ g_assert_cmpuint (cid, ==, MBIM_CID_BASIC_CONNECT_CONNECT);
+ g_assert_cmpuint (payload_size, ==, 4);
+ g_assert_nonnull (payload);
+
+ memcpy (&payload_uint, payload, payload_size);
+ payload_uint = GUINT32_FROM_LE (payload_uint);
+ g_assert_cmpuint (payload_uint, ==, 1);
+}
+
+static void
+test_message_parser_ms_basic_connect_extensions_wake_reason_packet (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimWakeType wake_type;
+ guint32 session_id;
+ g_autoptr(MbimTlv) wake_tlv = NULL;
+ guint32 filter_id = 0;
+ guint32 original_packet_size = 0;
+ guint32 packet_size = 0;
+ g_autofree guint8 *packet = NULL;
+ const guint8 expected_packet[] = { 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A };
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x5C, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x13, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x2C, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x02, 0x00, 0x00, 0x00, /* wake type: packet */
+ 0x02, 0x00, 0x00, 0x00, /* session id */
+ /* TLV */
+ 0x11, 0x00, 0x00, 0x02, /* TLV type MBIM_TLV_TYPE_WAKE_PACKET, padding 2 */
+ 0x1A, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x0B, 0x00, 0x00, 0x00, /* filter id */
+ 0x0C, 0x00, 0x00, 0x00, /* original packet size: 12 */
+ 0x10, 0x00, 0x00, 0x00, /* packet offset: 16 */
+ 0x0A, 0x00, 0x00, 0x00, /* packet size: 10 */
+ 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x00, 0x00, /* last 2 bytes padding */
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_wake_reason_response_parse (
+ response,
+ &wake_type,
+ &session_id,
+ &wake_tlv,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (wake_type, ==, MBIM_WAKE_TYPE_PACKET);
+ g_assert_cmpuint (session_id, ==, 2);
+ g_assert_nonnull (wake_tlv);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (wake_tlv), ==, MBIM_TLV_TYPE_WAKE_PACKET);
+
+ result = (mbim_tlv_wake_packet_get (wake_tlv,
+ &filter_id,
+ &original_packet_size,
+ &packet_size,
+ &packet,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (filter_id, ==, 0x0B);
+ g_assert_cmpuint (original_packet_size, ==, 12);
+ g_assert_cmpuint (packet_size, ==, sizeof (expected_packet));
+ g_assert_nonnull (packet);
+ g_assert (memcmp (packet, expected_packet, sizeof (expected_packet)) == 0);
+}
+
int main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
@@ -2615,6 +2856,9 @@ int main (int argc, char **argv)
g_test_add_func ("/libmbim-glib/message/parser/basic-connect-v3/connect/0-unnamed-tlvs", test_message_parser_ms_basic_connect_v3_connect_0_unnamed_tlvs);
g_test_add_func ("/libmbim-glib/message/parser/basic-connect-v3/connect/1-unnamed-tlv", test_message_parser_ms_basic_connect_v3_connect_1_unnamed_tlv);
g_test_add_func ("/libmbim-glib/message/parser/basic-connect-v3/connect/3-unnamed-tlvs", test_message_parser_ms_basic_connect_v3_connect_3_unnamed_tlvs);
+ g_test_add_func ("/libmbim-glib/message/parser/basic-connect-extensions/wake-reason/command", test_message_parser_ms_basic_connect_extensions_wake_reason_command);
+ g_test_add_func ("/libmbim-glib/message/parser/basic-connect-extensions/wake-reason/command/payload", test_message_parser_ms_basic_connect_extensions_wake_reason_command_payload);
+ g_test_add_func ("/libmbim-glib/message/parser/basic-connect-extensions/wake-reason/packet", test_message_parser_ms_basic_connect_extensions_wake_reason_packet);
return g_test_run ();
}
diff --git a/src/mbimcli/mbimcli-ms-basic-connect-extensions.c b/src/mbimcli/mbimcli-ms-basic-connect-extensions.c
index e7cbe62..3149b70 100644
--- a/src/mbimcli/mbimcli-ms-basic-connect-extensions.c
+++ b/src/mbimcli/mbimcli-ms-basic-connect-extensions.c
@@ -1548,9 +1548,7 @@ query_wake_reason_ready (MbimDevice *device,
g_autoptr(GError) error = NULL;
MbimWakeType wake_type;
guint32 session_id;
- const guint8 *data_buffer;
- guint32 data_buffer_size;
- g_autofree gchar *data_buffer_str = NULL;
+ MbimTlv *wake_tlv = NULL;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
@@ -1563,8 +1561,7 @@ query_wake_reason_ready (MbimDevice *device,
response,
&wake_type,
&session_id,
- &data_buffer_size,
- &data_buffer,
+ &wake_tlv,
&error)) {
g_printerr ("error: couldn't parse response message: %s\n", error->message);
shutdown (FALSE);
@@ -1574,12 +1571,84 @@ query_wake_reason_ready (MbimDevice *device,
g_print ("[%s] Successfully queried wake reason\n",
mbim_device_get_path_display (device));
- data_buffer_str = mbim_common_str_hex (data_buffer, data_buffer_size, ':');
- g_print ("\t Wake type: '%s'\n", mbim_wake_type_get_string (wake_type));
- g_print ("\t Session ID: '%u'\n", session_id);
- g_print ("\tData buffer: '%s'\n", data_buffer_str);
+ g_print ("\t Wake type: '%s'\n", mbim_wake_type_get_string (wake_type));
+ g_print ("\tSession ID: '%u'\n", session_id);
+
+ if ((wake_type == MBIM_WAKE_TYPE_CID_RESPONSE) ||
+ (wake_type == MBIM_WAKE_TYPE_CID_INDICATION)) {
+ const MbimUuid *service = NULL;
+ g_autofree gchar *service_str = NULL;
+ guint32 cid = 0;
+ guint32 payload_size = 0;
+ g_autofree guint8 *payload = NULL;
+ g_autofree gchar *payload_str = NULL;
+
+ if (!mbim_tlv_wake_command_get (wake_tlv,
+ &service,
+ &cid,
+ &payload_size,
+ &payload,
+ &error)) {
+ g_printerr ("error: couldn't parse wake command TLV: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
- shutdown (TRUE);
+ /* Known payload defined right now only for the Connect CID */
+ if ((mbim_uuid_to_service (service) == MBIM_SERVICE_BASIC_CONNECT) &&
+ (cid == MBIM_CID_BASIC_CONNECT_CONNECT) &&
+ (payload_size == 4)) {
+ guint32 activate;
+
+ memcpy (&activate, payload, payload_size);
+ activate = GUINT32_FROM_LE (activate);
+ if (activate == 0x00000001 || activate == 0x00000000)
+ payload_str = g_strdup (activate ? "activate" : "deactivate");
+ }
+
+ if (!payload_str)
+ payload_str = mbim_common_str_hex (payload, payload_size, ':');
+
+ service_str = mbim_uuid_get_printable (service);
+
+ g_print ("\t Service: '%s'\n", service_str);
+ g_print ("\t CID: '0x%08x'\n", cid);
+ g_print ("\t Payload: '%s'\n", payload_str);
+ shutdown (TRUE);
+ return;
+ }
+
+ if (wake_type == MBIM_WAKE_TYPE_PACKET) {
+ guint32 filter_id = 0;
+ guint32 original_packet_size = 0;
+ guint32 packet_size = 0;
+ g_autofree guint8 *packet = NULL;
+ g_autofree gchar *packet_str = NULL;
+
+ if (!mbim_tlv_wake_packet_get (wake_tlv,
+ &filter_id,
+ &original_packet_size,
+ &packet_size,
+ &packet,
+ &error)) {
+ g_printerr ("error: couldn't parse wake packet TLV: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ packet_str = mbim_common_str_hex (packet, packet_size, ':');
+
+ g_print ("\t Filter ID: '%u'\n", filter_id);
+ g_print ("\tOriginal size: '%u'\n", original_packet_size);
+ g_print ("\t Saved size: '%u'\n", packet_size);
+ g_print ("\t Packet: '%s'\n", packet_str);
+
+ shutdown (TRUE);
+ return;
+ }
+
+ g_printerr ("error: unknown wake type: 0x%08x\n", wake_type);
+ shutdown (FALSE);
}
void