Diff between efe7bd03faddef604ceeee895b1a1fcc4c1c7ef1 and 1a564b5b2b25d431b32fa1a7196d20ff5a5465b0

Changed Files

File Additions Deletions Status
unit/test-avdtp.c +105 -4 modified

Full Patch

diff --git a/unit/test-avdtp.c b/unit/test-avdtp.c
index fb555b8..5458d44 100644
--- a/unit/test-avdtp.c
+++ b/unit/test-avdtp.c
@@ -41,6 +41,7 @@
 
 struct test_pdu {
 	bool valid;
+	bool fragmented;
 	const uint8_t *data;
 	size_t size;
 };
@@ -59,6 +60,14 @@ struct test_data {
 		.size = sizeof(data(args)),			\
 	}
 
+#define frg_pdu(args...) \
+	{							\
+		.valid = true,					\
+		.fragmented = true,				\
+		.data = data(args),				\
+		.size = sizeof(data(args)),			\
+	}
+
 #define define_test(name, function, args...) \
 	do {								\
 		const struct test_pdu pdus[] = {			\
@@ -174,7 +183,7 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
 	if (g_test_verbose())
 		util_hexdump('>', buf, len, test_debug, "AVDTP: ");
 
-	g_assert((size_t) len == pdu->size);
+	g_assert_cmpint(len, ==, pdu->size);
 
 	g_assert(memcmp(buf, pdu->data, pdu->size) == 0);
 
@@ -191,12 +200,15 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
 		g_assert_cmpint(ret, ==, 0);
 	}
 
-	context_process(context);
+	if (!pdu->fragmented)
+		context_process(context);
 
 	return TRUE;
 }
 
-static struct context *create_context(uint16_t version, gconstpointer data)
+
+static struct context *context_new(uint16_t version, uint16_t imtu,
+					uint16_t omtu, gconstpointer data)
 {
 	struct context *context = g_new0(struct context, 1);
 	GIOChannel *channel;
@@ -208,7 +220,7 @@ static struct context *create_context(uint16_t version, gconstpointer data)
 	err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
 	g_assert(err == 0);
 
-	context->session = avdtp_new(sv[0], 672, 672, version);
+	context->session = avdtp_new(sv[0], imtu, omtu, version);
 	g_assert(context->session != NULL);
 
 	channel = g_io_channel_unix_new(sv[1]);
@@ -230,6 +242,11 @@ static struct context *create_context(uint16_t version, gconstpointer data)
 	return context;
 }
 
+static struct context *create_context(uint16_t version, gconstpointer data)
+{
+	return context_new(version, 672, 672, data);
+}
+
 static void execute_context(struct context *context)
 {
 	g_main_loop_run(context->main_loop);
@@ -509,6 +526,62 @@ static void test_server_0_sep(gconstpointer data)
 	execute_context(context);
 }
 
+static gboolean sep_getcap_ind_frg(struct avdtp *session,
+					struct avdtp_local_sep *sep,
+					gboolean get_all, GSList **caps,
+					uint8_t *err, void *user_data)
+{
+	struct avdtp_service_capability *media_transport, *media_codec;
+	struct avdtp_service_capability *content_protection;
+	struct avdtp_media_codec_capability *codec_caps;
+	uint8_t cap[4] = { 0xff, 0xff, 2, 64 };
+	uint8_t frg_cap[96] = {};
+
+	*caps = NULL;
+
+	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
+						NULL, 0);
+
+	*caps = g_slist_append(*caps, media_transport);
+
+	codec_caps = g_malloc0(sizeof(*codec_caps) + sizeof(cap));
+	codec_caps->media_type = AVDTP_MEDIA_TYPE_AUDIO;
+	codec_caps->media_codec_type = 0x00;
+	memcpy(codec_caps->data, cap, sizeof(cap));
+
+	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec_caps,
+					sizeof(*codec_caps) + sizeof(cap));
+
+	*caps = g_slist_append(*caps, media_codec);
+	g_free(codec_caps);
+
+	content_protection = avdtp_service_cap_new(AVDTP_CONTENT_PROTECTION,
+						frg_cap, sizeof(frg_cap));
+	*caps = g_slist_append(*caps, content_protection);
+
+	return TRUE;
+}
+
+static struct avdtp_sep_ind sep_ind_frg = {
+	.get_capability		= sep_getcap_ind_frg,
+};
+
+static void test_server_frg(gconstpointer data)
+{
+	struct context *context = context_new(0x0100, 48, 48, data);
+	struct avdtp_local_sep *sep;
+
+	sep = avdtp_register_sep(AVDTP_SEP_TYPE_SOURCE, AVDTP_MEDIA_TYPE_AUDIO,
+						0x00, TRUE, &sep_ind_frg,
+						NULL, context);
+
+	g_idle_add(send_pdu, context);
+
+	execute_context(context);
+
+	avdtp_unregister_sep(sep);
+}
+
 static void discover_cb(struct avdtp *session, GSList *seps,
 				struct avdtp_error *err, void *user_data)
 {
@@ -1086,5 +1159,33 @@ int main(int argc, char *argv[])
 			raw_pdu(0xa0, 0x03, 0x04, 0x04, 0x01, 0x00, 0x07, 0x06,
 				0x00, 0x00, 0x21, 0x02, 0x02, 0x20));
 
+	/*
+	 * Signaling Message Fragmentation Service
+	 *
+	 * verify that the IUT (INT and ACP) fragments the signaling messages
+	 * that cannot fit in a single L2CAP packet.
+	 */
+	define_test("/TP/SIG/FRA/BV-01-C", test_server_frg,
+			raw_pdu(0x00, 0x01),
+			raw_pdu(0x02, 0x01, 0x04, 0x00),
+			raw_pdu(0x10, 0x02, 0x04),
+			frg_pdu(0x16, 0x03, 0x02, 0x01, 0x00, 0x07, 0x06, 0x00,
+				0x00, 0xff, 0xff, 0x02, 0x40, 0x04, 0x60, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00),
+			frg_pdu(0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00),
+			raw_pdu(0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+				0x00));
+
 	return g_test_run();
 }