diff options
author | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2013-12-17 17:26:16 +0200 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2013-12-18 12:17:00 +0200 |
commit | 1a564b5b2b25d431b32fa1a7196d20ff5a5465b0 (patch) | |
tree | c0681c3b4f11e8d12008ce7cbb7307902aa50cf9 /unit | |
parent | efe7bd03faddef604ceeee895b1a1fcc4c1c7ef1 (diff) | |
download | bluez-1a564b5b2b25d431b32fa1a7196d20ff5a5465b0.tar.gz |
unit/AVDTP: Add /TP/SIG/FRA/BV-01-C test
Verify that the IUT (INT and ACP) fragments the signaling messages that
cannot fit in a single L2CAP packet.
Diffstat (limited to 'unit')
-rw-r--r-- | unit/test-avdtp.c | 109 |
1 files changed, 105 insertions, 4 deletions
diff --git a/unit/test-avdtp.c b/unit/test-avdtp.c index fb555b806..5458d446d 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(); } |