25
26
#include <config.h>
35
#include <sys/socket.h>
36
#include <netinet/in.h>
38
#include <bluetooth/bluetooth.h>
39
#include <bluetooth/hci.h>
40
#include <bluetooth/hci_lib.h>
41
#include <bluetooth/l2cap.h>
42
#include <bluetooth/sdp.h>
44
#define AVDTP_PKT_TYPE_SINGLE 0x00
45
#define AVDTP_PKT_TYPE_START 0x01
46
#define AVDTP_PKT_TYPE_CONTINUE 0x02
47
#define AVDTP_PKT_TYPE_END 0x03
49
#define AVDTP_MSG_TYPE_COMMAND 0x00
50
#define AVDTP_MSG_TYPE_GEN_REJECT 0x01
51
#define AVDTP_MSG_TYPE_ACCEPT 0x02
52
#define AVDTP_MSG_TYPE_REJECT 0x03
54
#define AVDTP_DISCOVER 0x01
55
#define AVDTP_GET_CAPABILITIES 0x02
56
#define AVDTP_SET_CONFIGURATION 0x03
57
#define AVDTP_GET_CONFIGURATION 0x04
58
#define AVDTP_RECONFIGURE 0x05
59
#define AVDTP_OPEN 0x06
60
#define AVDTP_START 0x07
61
#define AVDTP_CLOSE 0x08
62
#define AVDTP_SUSPEND 0x09
63
#define AVDTP_ABORT 0x0A
65
#define AVDTP_SEP_TYPE_SOURCE 0x00
66
#define AVDTP_SEP_TYPE_SINK 0x01
68
#define AVDTP_MEDIA_TYPE_AUDIO 0x00
69
#define AVDTP_MEDIA_TYPE_VIDEO 0x01
70
#define AVDTP_MEDIA_TYPE_MULTIMEDIA 0x02
72
#if __BYTE_ORDER == __LITTLE_ENDIAN
75
uint8_t message_type:2;
76
uint8_t packet_type:2;
77
uint8_t transaction:4;
80
} __attribute__ ((packed));
89
} __attribute__ ((packed));
91
struct avdtp_start_header {
92
uint8_t message_type:2;
93
uint8_t packet_type:2;
94
uint8_t transaction:4;
95
uint8_t no_of_packets;
98
} __attribute__ ((packed));
100
struct avdtp_continue_header {
101
uint8_t message_type:2;
102
uint8_t packet_type:2;
103
uint8_t transaction:4;
104
} __attribute__ ((packed));
106
struct avctp_header {
109
uint8_t packet_type:2;
110
uint8_t transaction:4;
112
} __attribute__ ((packed));
113
#define AVCTP_HEADER_LENGTH 3
115
#elif __BYTE_ORDER == __BIG_ENDIAN
117
struct avdtp_header {
118
uint8_t transaction:4;
119
uint8_t packet_type:2;
120
uint8_t message_type:2;
123
} __attribute__ ((packed));
129
uint8_t media_type:4;
132
} __attribute__ ((packed));
134
struct avdtp_start_header {
135
uint8_t transaction:4;
136
uint8_t packet_type:2;
137
uint8_t message_type:2;
138
uint8_t no_of_packets;
141
} __attribute__ ((packed));
143
struct avdtp_continue_header {
144
uint8_t transaction:4;
145
uint8_t packet_type:2;
146
uint8_t message_type:2;
147
} __attribute__ ((packed));
149
struct avctp_header {
150
uint8_t transaction:4;
151
uint8_t packet_type:2;
155
} __attribute__ ((packed));
156
#define AVCTP_HEADER_LENGTH 3
159
#error "Unknown byte order"
162
#define AVCTP_COMMAND 0
163
#define AVCTP_RESPONSE 1
165
#define AVCTP_PACKET_SINGLE 0
167
static const unsigned char media_transport[] = {
168
0x01, /* Media transport category */
170
0x07, /* Media codec category */
172
0x00, /* Media type audio */
173
0x00, /* Codec SBC */
174
0x22, /* 44.1 kHz, stereo */
175
0x15, /* 16 blocks, 8 subbands */
180
static int media_sock = -1;
182
static void dump_avctp_header(struct avctp_header *hdr)
184
printf("TL %d PT %d CR %d IPID %d PID 0x%04x\n", hdr->transaction,
185
hdr->packet_type, hdr->cr, hdr->ipid, ntohs(hdr->pid));
188
static void dump_avdtp_header(struct avdtp_header *hdr)
190
printf("TL %d PT %d MT %d SI %d\n", hdr->transaction,
191
hdr->packet_type, hdr->message_type, hdr->signal_id);
194
static void dump_buffer(const unsigned char *buf, int len)
198
for (i = 0; i < len; i++)
199
printf("%02x ", buf[i]);
203
static void process_avdtp(int srv_sk, int sk, unsigned char reject,
206
unsigned char buf[672];
210
struct avdtp_header *hdr = (void *) buf;
212
len = read(sk, buf, sizeof(buf));
214
perror("Read failed");
218
dump_buffer(buf, len);
219
dump_avdtp_header(hdr);
221
if (hdr->packet_type != AVDTP_PKT_TYPE_SINGLE) {
222
fprintf(stderr, "Only single packets are supported\n");
226
if (hdr->message_type != AVDTP_MSG_TYPE_COMMAND) {
227
fprintf(stderr, "Ignoring non-command messages\n");
231
switch (hdr->signal_id) {
233
if (reject == AVDTP_DISCOVER) {
234
hdr->message_type = AVDTP_MSG_TYPE_REJECT;
235
buf[2] = 0x29; /* Unsupported configuration */
236
printf("Rejecting discover command\n");
237
len = write(sk, buf, 3);
239
struct seid_info *sei = (void *) (buf + 2);
240
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
244
sei->type = AVDTP_SEP_TYPE_SINK;
245
sei->media_type = AVDTP_MEDIA_TYPE_AUDIO;
246
printf("Accepting discover command\n");
247
len = write(sk, buf, 4);
251
case AVDTP_GET_CAPABILITIES:
252
if (reject == AVDTP_GET_CAPABILITIES) {
253
hdr->message_type = AVDTP_MSG_TYPE_REJECT;
254
buf[2] = 0x29; /* Unsupported configuration */
255
printf("Rejecting get capabilties command\n");
256
len = write(sk, buf, 3);
257
} else if (fragment) {
258
struct avdtp_start_header *start = (void *) buf;
260
printf("Sending fragmented reply to getcap\n");
262
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
265
hdr->packet_type = AVDTP_PKT_TYPE_START;
266
start->signal_id = AVDTP_GET_CAPABILITIES;
267
start->no_of_packets = 3;
268
memcpy(&buf[3], media_transport,
269
sizeof(media_transport));
271
3 + sizeof(media_transport));
273
/* Continue packet */
274
hdr->packet_type = AVDTP_PKT_TYPE_CONTINUE;
275
memcpy(&buf[1], media_transport,
276
sizeof(media_transport));
278
1 + sizeof(media_transport));
281
hdr->packet_type = AVDTP_PKT_TYPE_END;
282
memcpy(&buf[1], media_transport,
283
sizeof(media_transport));
285
1 + sizeof(media_transport));
287
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
288
memcpy(&buf[2], media_transport,
289
sizeof(media_transport));
290
printf("Accepting get capabilities command\n");
292
2 + sizeof(media_transport));
296
case AVDTP_SET_CONFIGURATION:
297
if (reject == AVDTP_SET_CONFIGURATION) {
298
hdr->message_type = AVDTP_MSG_TYPE_REJECT;
300
buf[3] = 0x13; /* SEP In Use */
301
printf("Rejecting set configuration command\n");
302
len = write(sk, buf, 4);
304
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
305
printf("Accepting set configuration command\n");
306
len = write(sk, buf, 2);
310
case AVDTP_GET_CONFIGURATION:
311
if (reject == AVDTP_GET_CONFIGURATION) {
312
hdr->message_type = AVDTP_MSG_TYPE_REJECT;
313
buf[2] = 0x12; /* Bad ACP SEID */
314
printf("Rejecting get configuration command\n");
315
len = write(sk, buf, 3);
317
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
318
printf("Accepting get configuration command\n");
319
len = write(sk, buf, 2);
324
if (reject == AVDTP_OPEN) {
325
hdr->message_type = AVDTP_MSG_TYPE_REJECT;
326
buf[2] = 0x31; /* Bad State */
327
printf("Rejecting open command\n");
328
len = write(sk, buf, 3);
330
struct sockaddr_l2 addr;
333
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
334
printf("Accepting open command\n");
335
len = write(sk, buf, 2);
337
memset(&addr, 0, sizeof(addr));
338
optlen = sizeof(addr);
340
media_sock = accept(srv_sk,
341
(struct sockaddr *) &addr,
343
if (media_sock < 0) {
344
perror("Accept failed");
351
if (reject == AVDTP_ABORT)
352
printf("Ignoring start to cause abort");
353
else if (reject == AVDTP_START) {
354
hdr->message_type = AVDTP_MSG_TYPE_REJECT;
355
buf[3] = 0x31; /* Bad State */
356
printf("Rejecting start command\n");
357
len = write(sk, buf, 4);
359
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
360
printf("Accepting start command\n");
361
len = write(sk, buf, 2);
366
if (reject == AVDTP_CLOSE) {
367
hdr->message_type = AVDTP_MSG_TYPE_REJECT;
368
buf[2] = 0x31; /* Bad State */
369
printf("Rejecting close command\n");
370
len = write(sk, buf, 3);
372
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
373
printf("Accepting close command\n");
374
len = write(sk, buf, 2);
375
if (media_sock >= 0) {
383
if (reject == AVDTP_SUSPEND) {
384
hdr->message_type = AVDTP_MSG_TYPE_REJECT;
385
buf[3] = 0x31; /* Bad State */
386
printf("Rejecting suspend command\n");
387
len = write(sk, buf, 4);
389
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
390
printf("Accepting suspend command\n");
391
len = write(sk, buf, 2);
396
hdr->message_type = AVDTP_MSG_TYPE_ACCEPT;
397
printf("Accepting abort command\n");
398
len = write(sk, buf, 2);
399
if (media_sock >= 0) {
407
printf("Unknown command\n");
408
len = write(sk, buf, 2);
414
static void process_avctp(int sk, int reject)
416
unsigned char buf[672];
420
struct avctp_header *hdr = (void *) buf;
422
len = read(sk, buf, sizeof(buf));
424
perror("Read failed");
428
dump_buffer(buf, len);
430
if (len >= AVCTP_HEADER_LENGTH)
431
dump_avctp_header(hdr);
435
static int set_minimum_mtu(int sk)
437
struct l2cap_options l2o;
440
memset(&l2o, 0, sizeof(l2o));
441
optlen = sizeof(l2o);
443
if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &optlen) < 0) {
444
perror("getsockopt");
451
if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) {
452
perror("setsockopt");
459
static void do_listen(const bdaddr_t *src, unsigned char reject, int fragment)
461
struct sockaddr_l2 addr;
465
sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
467
perror("Can't create socket");
471
memset(&addr, 0, sizeof(addr));
472
addr.l2_family = AF_BLUETOOTH;
473
bacpy(&addr.l2_bdaddr, src);
474
addr.l2_psm = htobs(25);
476
if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
477
perror("Can't bind socket");
484
if (listen(sk, 10)) {
485
perror("Can't listen on the socket");
490
memset(&addr, 0, sizeof(addr));
491
optlen = sizeof(addr);
493
nsk = accept(sk, (struct sockaddr *) &addr, &optlen);
495
perror("Accept failed");
499
process_avdtp(sk, nsk, reject, fragment);
501
if (media_sock >= 0) {
513
static int do_connect(const bdaddr_t *src, const bdaddr_t *dst, int avctp,
516
struct sockaddr_l2 addr;
519
sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
521
perror("Can't create socket");
525
memset(&addr, 0, sizeof(addr));
526
addr.l2_family = AF_BLUETOOTH;
527
bacpy(&addr.l2_bdaddr, src);
529
if (bind(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
530
perror("Can't bind socket");
537
memset(&addr, 0, sizeof(addr));
538
addr.l2_family = AF_BLUETOOTH;
539
bacpy(&addr.l2_bdaddr, dst);
540
addr.l2_psm = htobs(avctp ? 23 : 25);
542
err = connect(sk, (struct sockaddr *) &addr, sizeof(addr));
544
perror("Unable to connect");
555
static void do_avdtp_send(int sk, const bdaddr_t *src, const bdaddr_t *dst,
556
unsigned char cmd, int invalid, int preconf)
558
unsigned char buf[672];
559
struct avdtp_header *hdr = (void *) buf;
562
memset(buf, 0, sizeof(buf));
567
hdr->message_type = 0x01;
569
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
570
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
571
hdr->signal_id = AVDTP_DISCOVER;
572
len = write(sk, buf, 2);
575
case AVDTP_GET_CAPABILITIES:
576
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
577
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
578
hdr->signal_id = AVDTP_GET_CAPABILITIES;
579
buf[2] = 1 << 2; /* SEID 1 */
580
len = write(sk, buf, invalid ? 2 : 3);
583
case AVDTP_SET_CONFIGURATION:
585
do_avdtp_send(sk, src, dst, cmd, 0, 0);
586
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
587
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
588
hdr->signal_id = AVDTP_SET_CONFIGURATION;
589
buf[2] = 1 << 2; /* ACP SEID */
590
buf[3] = 1 << 2; /* INT SEID */
591
memcpy(&buf[4], media_transport, sizeof(media_transport));
593
buf[5] = 0x01; /* LOSC != 0 */
594
len = write(sk, buf, 4 + sizeof(media_transport));
597
case AVDTP_GET_CONFIGURATION:
599
do_avdtp_send(sk, src, dst, AVDTP_SET_CONFIGURATION, 0, 0);
600
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
601
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
602
hdr->signal_id = AVDTP_GET_CONFIGURATION;
604
buf[2] = 13 << 2; /* Invalid ACP SEID */
606
buf[2] = 1 << 2; /* Valid ACP SEID */
607
len = write(sk, buf, 3);
612
do_avdtp_send(sk, src, dst, AVDTP_SET_CONFIGURATION, 0, 0);
613
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
614
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
615
hdr->signal_id = AVDTP_OPEN;
616
buf[2] = 1 << 2; /* ACP SEID */
617
len = write(sk, buf, 3);
622
do_avdtp_send(sk, src, dst, AVDTP_SET_CONFIGURATION, 0, 0);
624
do_avdtp_send(sk, src, dst, AVDTP_OPEN, 0, 0);
625
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
626
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
627
hdr->signal_id = AVDTP_START;
628
buf[2] = 1 << 2; /* ACP SEID */
629
len = write(sk, buf, 3);
634
do_avdtp_send(sk, src, dst, AVDTP_SET_CONFIGURATION, 0, 0);
635
do_avdtp_send(sk, src, dst, AVDTP_OPEN, 0, 0);
637
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
638
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
639
hdr->signal_id = AVDTP_CLOSE;
641
buf[2] = 13 << 2; /* Invalid ACP SEID */
643
buf[2] = 1 << 2; /* Valid ACP SEID */
644
len = write(sk, buf, 3);
649
do_avdtp_send(sk, src, dst, AVDTP_OPEN, 0, preconf);
651
do_avdtp_send(sk, src, dst, AVDTP_START, 0, preconf);
652
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
653
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
654
hdr->signal_id = AVDTP_SUSPEND;
655
buf[2] = 1 << 2; /* ACP SEID */
656
len = write(sk, buf, 3);
660
do_avdtp_send(sk, src, dst, AVDTP_OPEN, 0, 1);
661
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
662
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
663
hdr->signal_id = AVDTP_ABORT;
664
buf[2] = 1 << 2; /* ACP SEID */
665
len = write(sk, buf, 3);
669
hdr->message_type = AVDTP_MSG_TYPE_COMMAND;
670
hdr->packet_type = AVDTP_PKT_TYPE_SINGLE;
671
hdr->signal_id = cmd;
672
len = write(sk, buf, 2);
677
len = read(sk, buf, sizeof(buf));
679
dump_buffer(buf, len);
680
dump_avdtp_header(hdr);
681
} while (len < 2 || (hdr->message_type != AVDTP_MSG_TYPE_ACCEPT &&
682
hdr->message_type != AVDTP_MSG_TYPE_REJECT &&
683
hdr->message_type != AVDTP_MSG_TYPE_GEN_REJECT));
685
if (cmd == AVDTP_OPEN && len >= 2 &&
686
hdr->message_type == AVDTP_MSG_TYPE_ACCEPT)
687
media_sock = do_connect(src, dst, 0, 0);
690
static void do_avctp_send(int sk, int invalid)
692
unsigned char buf[672];
693
struct avctp_header *hdr = (void *) buf;
694
unsigned char play_pressed[] = { 0x00, 0x48, 0x7c, 0x44, 0x00 };
697
memset(buf, 0, sizeof(buf));
699
hdr->packet_type = AVCTP_PACKET_SINGLE;
700
hdr->cr = AVCTP_COMMAND;
704
hdr->pid = htons(AV_REMOTE_SVCLASS_ID);
706
memcpy(&buf[AVCTP_HEADER_LENGTH], play_pressed, sizeof(play_pressed));
708
len = write(sk, buf, AVCTP_HEADER_LENGTH + sizeof(play_pressed));
710
len = read(sk, buf, sizeof(buf));
712
dump_buffer(buf, len);
713
if (len >= AVCTP_HEADER_LENGTH)
714
dump_avctp_header(hdr);
719
printf("avtest - Audio/Video testing ver %s\n", VERSION);
721
"\tavtest [options] [remote address]\n");
723
"\t--device <hcidev> HCI device\n"
724
"\t--reject <command> Reject command\n"
725
"\t--send <command> Send command\n"
726
"\t--preconf Configure stream before actual command\n"
727
"\t--wait <N> Wait N seconds before exiting\n"
728
"\t--fragment Use minimum MTU and fragmented messages\n"
729
"\t--invalid <command> Send invalid command\n");
732
static struct option main_options[] = {
733
{ "help", 0, 0, 'h' },
734
{ "device", 1, 0, 'i' },
735
{ "reject", 1, 0, 'r' },
736
{ "send", 1, 0, 's' },
737
{ "invalid", 1, 0, 'f' },
738
{ "preconf", 0, 0, 'c' },
739
{ "fragment", 0, 0, 'F' },
740
{ "avctp", 0, 0, 'C' },
741
{ "wait", 1, 0, 'w' },
745
static unsigned char parse_cmd(const char *arg)
747
if (!strncmp(arg, "discov", 6))
748
return AVDTP_DISCOVER;
749
else if (!strncmp(arg, "capa", 4))
750
return AVDTP_GET_CAPABILITIES;
751
else if (!strncmp(arg, "getcapa", 7))
752
return AVDTP_GET_CAPABILITIES;
753
else if (!strncmp(arg, "setconf", 7))
754
return AVDTP_SET_CONFIGURATION;
755
else if (!strncmp(arg, "getconf", 7))
756
return AVDTP_GET_CONFIGURATION;
757
else if (!strncmp(arg, "open", 4))
759
else if (!strncmp(arg, "start", 5))
761
else if (!strncmp(arg, "close", 5))
763
else if (!strncmp(arg, "suspend", 7))
764
return AVDTP_SUSPEND;
765
else if (!strncmp(arg, "abort", 7))
772
MODE_NONE, MODE_REJECT, MODE_SEND,
28
775
int main(int argc, char *argv[])
777
unsigned char cmd = 0x00;
779
int opt, mode = MODE_NONE, sk, invalid = 0, preconf = 0, fragment = 0;
780
int avctp = 0, wait_before_exit = 0;
782
bacpy(&src, BDADDR_ANY);
783
bacpy(&dst, BDADDR_ANY);
785
while ((opt = getopt_long(argc, argv, "+i:r:s:f:hcFCw:",
786
main_options, NULL)) != EOF) {
789
if (!strncmp(optarg, "hci", 3))
790
hci_devba(atoi(optarg + 3), &src);
792
str2ba(optarg, &src);
797
cmd = parse_cmd(optarg);
802
/* Intentionally missing break */
806
cmd = parse_cmd(optarg);
822
wait_before_exit = atoi(optarg);
833
str2ba(argv[optind], &dst);
842
do_listen(&src, cmd, fragment);
845
sk = do_connect(&src, &dst, avctp, fragment);
849
if (avctp == MODE_SEND)
850
do_avctp_send(sk, invalid);
852
process_avctp(sk, cmd);
854
do_avdtp_send(sk, &src, &dst, cmd, invalid, preconf);
855
if (wait_before_exit) {
856
printf("Waiting %d seconds before exiting\n", wait_before_exit);
857
sleep(wait_before_exit);
864
fprintf(stderr, "No operating mode specified!\n");