1 /* $NetBSD$ */
2
3 /*-
4 * Copyright (c) 2015-2016 Nathanial Sloss <nathanialsloss@yahoo.com.au>
5 * Copyright (c) 2016-2019 Hans Petter Selasky <hps@selasky.org>
6 * Copyright (c) 2019 Google LLC, written by Richard Kralovic <riso@google.com>
7 *
8 * This software is dedicated to the memory of -
9 * Baron James Anlezark (Barry) - 1 Jan 1949 - 13 May 2012.
10 *
11 * Barry was a man who loved his music.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include <sys/uio.h>
36
37 #include <stdio.h>
38 #include <errno.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42
43 #include "avdtp_signal.h"
44 #include "bt.h"
45
46 #define DPRINTF(...) printf("backend_bt: " __VA_ARGS__)
47
48 struct avdtpGetPacketInfo {
49 uint8_t buffer_data[512];
50 uint16_t buffer_len;
51 uint8_t trans;
52 uint8_t signalID;
53 };
54
55 static int avdtpAutoConfig(struct bt_config *);
56
57 /* Return received message type if success, < 0 if failure. */
58 static int
avdtpGetPacket(int fd,struct avdtpGetPacketInfo * info)59 avdtpGetPacket(int fd, struct avdtpGetPacketInfo *info)
60 {
61 uint8_t *pos = info->buffer_data;
62 uint8_t *end = info->buffer_data + sizeof(info->buffer_data);
63 uint8_t message_type;
64 int len;
65
66 memset(info, 0, sizeof(*info));
67
68 /* Handle fragmented packets */
69 for (int remaining = 1; remaining > 0; --remaining) {
70 len = read(fd, pos, end - pos);
71
72 if (len < AVDTP_LEN_SUCCESS)
73 return (-1);
74 if (len == (int)(end - pos))
75 return (-1); /* buffer too small */
76
77 uint8_t trans = (pos[0] & TRANSACTIONLABEL) >> TRANSACTIONLABEL_S;
78 uint8_t packet_type = (pos[0] & PACKETTYPE) >> PACKETTYPE_S;
79 uint8_t current_message_type = (info->buffer_data[0] & MESSAGETYPE);
80 uint8_t shift;
81 if (pos == info->buffer_data) {
82 info->trans = trans;
83 message_type = current_message_type;
84 if (packet_type == singlePacket) {
85 info->signalID = (pos[1] & SIGNALID_MASK);
86 shift = 2;
87 } else {
88 if (packet_type != startPacket)
89 return (-1);
90 remaining = pos[1];
91 info->signalID = (pos[2] & SIGNALID_MASK);
92 shift = 3;
93 }
94 } else {
95 if (info->trans != trans ||
96 message_type != current_message_type ||
97 (remaining == 1 && packet_type != endPacket) ||
98 (remaining > 1 && packet_type != continuePacket)) {
99 return (-1);
100 }
101 shift = 1;
102 }
103 memmove(pos, pos + shift, len);
104 pos += len;
105 }
106 info->buffer_len = pos - info->buffer_data;
107 return (message_type);
108 }
109
110 /* Returns 0 on success, < 0 on failure. */
111 static int
avdtpSendPacket(int fd,uint8_t command,uint8_t trans,uint8_t type,uint8_t * data0,int datasize0,uint8_t * data1,int datasize1)112 avdtpSendPacket(int fd, uint8_t command, uint8_t trans, uint8_t type,
113 uint8_t * data0, int datasize0, uint8_t * data1,
114 int datasize1)
115 {
116 struct iovec iov[3];
117 uint8_t header[2];
118 int retval;
119
120 /* fill out command header */
121 header[0] = (trans << 4) | (type & 3);
122 if (command != 0)
123 header[1] = command & 0x3f;
124 else
125 header[1] = 3;
126
127 iov[0].iov_base = header;
128 iov[0].iov_len = 2;
129 iov[1].iov_base = data0;
130 iov[1].iov_len = datasize0;
131 iov[2].iov_base = data1;
132 iov[2].iov_len = datasize1;
133
134 retval = writev(fd, iov, 3);
135 if (retval != (2 + datasize0 + datasize1))
136 return (-EINVAL);
137 else
138 return (0);
139 }
140
141 /* Returns 0 on success, < 0 on failure. */
142 static int
avdtpSendSyncCommand(int fd,struct avdtpGetPacketInfo * info,uint8_t command,uint8_t type,uint8_t * data0,int datasize0,uint8_t * data1,int datasize1)143 avdtpSendSyncCommand(int fd, struct avdtpGetPacketInfo *info,
144 uint8_t command, uint8_t type, uint8_t * data0,
145 int datasize0, uint8_t * data1, int datasize1)
146 {
147 static uint8_t transLabel;
148 uint8_t trans;
149 int retval;
150
151 alarm(8); /* set timeout */
152
153 trans = (transLabel++) & 0xF;
154
155 retval = avdtpSendPacket(fd, command, trans, type,
156 data0, datasize0, data1, datasize1);
157 if (retval)
158 goto done;
159 retry:
160 switch (avdtpGetPacket(fd, info)) {
161 case RESPONSEACCEPT:
162 if (info->trans != trans)
163 goto retry;
164 retval = 0;
165 break;
166 case RESPONSEREJECT:
167 if (info->trans != trans)
168 goto retry;
169 retval = -EINVAL;
170 break;
171 case COMMAND:
172 retval = avdtpSendReject(fd, info->trans, info->signalID);
173 if (retval == 0)
174 goto retry;
175 break;
176 default:
177 retval = -ENXIO;
178 break;
179 }
180 done:
181 alarm(0); /* clear timeout */
182
183 return (retval);
184 }
185
186 /*
187 * Variant for acceptor role: We support any frequency, blocks, bands, and
188 * allocation. Returns 0 on success, < 0 on failure.
189 */
190 static int
avdtpSendCapabilitiesResponseSBCForACP(int fd,int trans)191 avdtpSendCapabilitiesResponseSBCForACP(int fd, int trans)
192 {
193 uint8_t data[10];
194
195 data[0] = mediaTransport;
196 data[1] = 0;
197 data[2] = mediaCodec;
198 data[3] = 0x6;
199 data[4] = mediaTypeAudio;
200 data[5] = SBC_CODEC_ID;
201 data[6] =
202 (1 << (3 - MODE_STEREO)) |
203 (1 << (3 - MODE_JOINT)) |
204 (1 << (3 - MODE_DUAL)) |
205 (1 << (3 - MODE_MONO)) |
206 (1 << (7 - FREQ_44_1K)) |
207 (1 << (7 - FREQ_48K)) |
208 (1 << (7 - FREQ_32K)) |
209 (1 << (7 - FREQ_16K));
210 data[7] =
211 (1 << (7 - BLOCKS_4)) |
212 (1 << (7 - BLOCKS_8)) |
213 (1 << (7 - BLOCKS_12)) |
214 (1 << (7 - BLOCKS_16)) |
215 (1 << (3 - BANDS_4)) |
216 (1 << (3 - BANDS_8)) | (1 << ALLOC_LOUDNESS) | (1 << ALLOC_SNR);
217 data[8] = MIN_BITPOOL;
218 data[9] = DEFAULT_MAXBPOOL;
219
220 return (avdtpSendPacket(fd, AVDTP_GET_CAPABILITIES, trans,
221 RESPONSEACCEPT, data, sizeof(data), NULL, 0));
222 }
223
224 /* Returns 0 on success, < 0 on failure. */
225 int
avdtpSendAccept(int fd,uint8_t trans,uint8_t myCommand)226 avdtpSendAccept(int fd, uint8_t trans, uint8_t myCommand)
227 {
228 return (avdtpSendPacket(fd, myCommand, trans, RESPONSEACCEPT,
229 NULL, 0, NULL, 0));
230 }
231
232 /* Returns 0 on success, < 0 on failure. */
233 int
avdtpSendReject(int fd,uint8_t trans,uint8_t myCommand)234 avdtpSendReject(int fd, uint8_t trans, uint8_t myCommand)
235 {
236 uint8_t value = 0;
237
238 return (avdtpSendPacket(fd, myCommand, trans, RESPONSEREJECT,
239 &value, 1, NULL, 0));
240 }
241
242 /* Returns 0 on success, < 0 on failure. */
243 int
avdtpSendDiscResponseAudio(int fd,uint8_t trans,uint8_t mySep,uint8_t is_sink)244 avdtpSendDiscResponseAudio(int fd, uint8_t trans,
245 uint8_t mySep, uint8_t is_sink)
246 {
247 uint8_t data[2];
248
249 data[0] = mySep << 2;
250 data[1] = mediaTypeAudio << 4 | (is_sink ? (1 << 3) : 0);
251
252 return (avdtpSendPacket(fd, AVDTP_DISCOVER, trans, RESPONSEACCEPT,
253 data, 2, NULL, 0));
254 }
255
256 /* Returns 0 on success, < 0 on failure. */
257 int
avdtpDiscoverAndConfig(struct bt_config * cfg,bool isSink)258 avdtpDiscoverAndConfig(struct bt_config *cfg, bool isSink)
259 {
260 struct avdtpGetPacketInfo info;
261 uint16_t offset;
262 uint8_t chmode = cfg->chmode;
263 uint8_t aacMode1 = cfg->aacMode1;
264 uint8_t aacMode2 = cfg->aacMode2;
265 int retval;
266
267 retval = avdtpSendSyncCommand(cfg->hc, &info, AVDTP_DISCOVER, 0,
268 NULL, 0, NULL, 0);
269 if (retval)
270 return (retval);
271
272 retval = -EBUSY;
273 for (offset = 0; offset + 2 <= info.buffer_len; offset += 2) {
274 cfg->sep = info.buffer_data[offset] >> 2;
275 cfg->media_Type = info.buffer_data[offset + 1] >> 4;
276 cfg->chmode = chmode;
277 cfg->aacMode1 = aacMode1;
278 cfg->aacMode2 = aacMode2;
279 if (info.buffer_data[offset] & DISCOVER_SEP_IN_USE)
280 continue;
281 if (info.buffer_data[offset + 1] & DISCOVER_IS_SINK) {
282 if (!isSink)
283 continue;
284 } else {
285 if (isSink)
286 continue;
287 }
288 /* try to configure SBC */
289 retval = avdtpAutoConfig(cfg);
290 if (retval == 0)
291 return (0);
292 }
293 return (retval);
294 }
295
296 /* Returns 0 on success, < 0 on failure. */
297 static int
avdtpGetCapabilities(int fd,uint8_t sep,struct avdtpGetPacketInfo * info)298 avdtpGetCapabilities(int fd, uint8_t sep, struct avdtpGetPacketInfo *info)
299 {
300 uint8_t address = (sep << 2);
301
302 return (avdtpSendSyncCommand(fd, info,
303 AVDTP_GET_CAPABILITIES, 0, &address, 1,
304 NULL, 0));
305 }
306
307 /* Returns 0 on success, < 0 on failure. */
308 int
avdtpSetConfiguration(int fd,uint8_t sep,uint8_t * data,int datasize)309 avdtpSetConfiguration(int fd, uint8_t sep, uint8_t * data, int datasize)
310 {
311 struct avdtpGetPacketInfo info;
312 uint8_t configAddresses[2];
313
314 configAddresses[0] = sep << 2;
315 configAddresses[1] = INTSEP << 2;
316
317 return (avdtpSendSyncCommand(fd, &info, AVDTP_SET_CONFIGURATION, 0,
318 configAddresses, 2, data, datasize));
319 }
320
321 /* Returns 0 on success, < 0 on failure. */
322 int
avdtpOpen(int fd,uint8_t sep)323 avdtpOpen(int fd, uint8_t sep)
324 {
325 struct avdtpGetPacketInfo info;
326 uint8_t address = sep << 2;
327
328 return (avdtpSendSyncCommand(fd, &info, AVDTP_OPEN, 0,
329 &address, 1, NULL, 0));
330 }
331
332 /* Returns 0 on success, < 0 on failure. */
333 int
avdtpStart(int fd,uint8_t sep)334 avdtpStart(int fd, uint8_t sep)
335 {
336 struct avdtpGetPacketInfo info;
337 uint8_t address = sep << 2;
338
339 return (avdtpSendSyncCommand(fd, &info, AVDTP_START, 0,
340 &address, 1, NULL, 0));
341 }
342
343 /* Returns 0 on success, < 0 on failure. */
344 int
avdtpClose(int fd,uint8_t sep)345 avdtpClose(int fd, uint8_t sep)
346 {
347 struct avdtpGetPacketInfo info;
348 uint8_t address = sep << 2;
349
350 return (avdtpSendSyncCommand(fd, &info, AVDTP_CLOSE, 0,
351 &address, 1, NULL, 0));
352 }
353
354 /* Returns 0 on success, < 0 on failure. */
355 int
avdtpSuspend(int fd,uint8_t sep)356 avdtpSuspend(int fd, uint8_t sep)
357 {
358 struct avdtpGetPacketInfo info;
359 uint8_t address = sep << 2;
360
361 return (avdtpSendSyncCommand(fd, &info, AVDTP_SUSPEND, 0,
362 &address, 1, NULL, 0));
363 }
364
365 /* Returns 0 on success, < 0 on failure. */
366 int
avdtpAbort(int fd,uint8_t sep)367 avdtpAbort(int fd, uint8_t sep)
368 {
369 struct avdtpGetPacketInfo info;
370 uint8_t address = sep << 2;
371
372 return (avdtpSendSyncCommand(fd, &info, AVDTP_ABORT, 0,
373 &address, 1, NULL, 0));
374 }
375
376 static int
avdtpAutoConfig(struct bt_config * cfg)377 avdtpAutoConfig(struct bt_config *cfg)
378 {
379 struct avdtpGetPacketInfo info;
380 uint8_t freqmode;
381 uint8_t blk_len_sb_alloc;
382 uint8_t availFreqMode = 0;
383 uint8_t availConfig = 0;
384 uint8_t supBitpoolMin = 0;
385 uint8_t supBitpoolMax = 0;
386 uint8_t aacMode1 = 0;
387 uint8_t aacMode2 = 0;
388 #ifdef HAVE_LIBAV
389 uint8_t aacBitrate3 = 0;
390 uint8_t aacBitrate4 = 0;
391 uint8_t aacBitrate5 = 0;
392 #endif
393 int retval;
394 int i;
395
396 retval = avdtpGetCapabilities(cfg->hc, cfg->sep, &info);
397 if (retval) {
398 DPRINTF("Cannot get capabilities\n");
399 return (retval);
400 }
401 retry:
402 for (i = 0; (i + 1) < info.buffer_len;) {
403 #if 0
404 DPRINTF("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
405 info.buffer_data[i + 0],
406 info.buffer_data[i + 1],
407 info.buffer_data[i + 2],
408 info.buffer_data[i + 3],
409 info.buffer_data[i + 4], info.buffer_data[i + 5]);
410 #endif
411 if (i + 2 + info.buffer_data[i + 1] > info.buffer_len)
412 break;
413 switch (info.buffer_data[i]) {
414 case mediaTransport:
415 break;
416 case mediaCodec:
417 if (info.buffer_data[i + 1] < 2)
418 break;
419 /* check codec */
420 switch (info.buffer_data[i + 3]) {
421 case 0: /* SBC */
422 if (info.buffer_data[i + 1] < 6)
423 break;
424 availFreqMode = info.buffer_data[i + 4];
425 availConfig = info.buffer_data[i + 5];
426 supBitpoolMin = info.buffer_data[i + 6];
427 supBitpoolMax = info.buffer_data[i + 7];
428 break;
429 case 2: /* MPEG2/4 AAC */
430 if (info.buffer_data[i + 1] < 8)
431 break;
432 aacMode1 = info.buffer_data[i + 5];
433 aacMode2 = info.buffer_data[i + 6];
434 #ifdef HAVE_LIBAV
435 aacBitrate3 = info.buffer_data[i + 7];
436 aacBitrate4 = info.buffer_data[i + 8];
437 aacBitrate5 = info.buffer_data[i + 9];
438 #endif
439 break;
440 default:
441 break;
442 }
443 }
444 /* jump to next information element */
445 i += 2 + info.buffer_data[i + 1];
446 }
447 aacMode1 &= cfg->aacMode1;
448 aacMode2 &= cfg->aacMode2;
449
450 /* Try AAC first */
451 if (aacMode1 == cfg->aacMode1 && aacMode2 == cfg->aacMode2) {
452 #ifdef HAVE_LIBAV
453 uint8_t config[12] = { mediaTransport, 0x0, mediaCodec,
454 0x8, 0x0, 0x02, 0x80, aacMode1, aacMode2, aacBitrate3,
455 aacBitrate4, aacBitrate5
456 };
457
458 if (avdtpSetConfiguration
459 (cfg->hc, cfg->sep, config, sizeof(config)) == 0) {
460 cfg->codec = CODEC_AAC;
461 return (0);
462 }
463 #endif
464 }
465 /* Try SBC second */
466 if (cfg->freq == FREQ_UNDEFINED)
467 goto auto_config_failed;
468
469 freqmode = (1 << (3 - cfg->freq + 4)) | (1 << (3 - cfg->chmode));
470
471 if ((availFreqMode & freqmode) != freqmode) {
472 DPRINTF("No frequency and mode match\n");
473 goto auto_config_failed;
474 }
475 for (i = 0; i != 4; i++) {
476 blk_len_sb_alloc = (1 << (i + 4)) |
477 (1 << (1 - cfg->bands + 2)) | (1 << cfg->allocm);
478
479 if ((availConfig & blk_len_sb_alloc) == blk_len_sb_alloc)
480 break;
481 }
482 if (i == 4) {
483 DPRINTF("No bands available\n");
484 goto auto_config_failed;
485 }
486 cfg->blocks = (3 - i);
487
488 if (cfg->allocm == ALLOC_SNR)
489 supBitpoolMax &= ~1;
490
491 if (cfg->chmode == MODE_DUAL || cfg->chmode == MODE_MONO)
492 supBitpoolMax /= 2;
493
494 if (cfg->bands == BANDS_4)
495 supBitpoolMax /= 2;
496
497 if (supBitpoolMax > cfg->bitpool)
498 supBitpoolMax = cfg->bitpool;
499 else
500 cfg->bitpool = supBitpoolMax;
501
502 do {
503 uint8_t config[10] = { mediaTransport, 0x0, mediaCodec, 0x6,
504 0x0, 0x0, freqmode, blk_len_sb_alloc, supBitpoolMin,
505 supBitpoolMax
506 };
507
508 if (avdtpSetConfiguration
509 (cfg->hc, cfg->sep, config, sizeof(config)) == 0) {
510 cfg->codec = CODEC_SBC;
511 return (0);
512 }
513 } while (0);
514
515 auto_config_failed:
516 if (cfg->chmode == MODE_STEREO) {
517 cfg->chmode = MODE_MONO;
518 cfg->aacMode2 ^= 0x0C;
519 goto retry;
520 }
521 return (-EINVAL);
522 }
523
524 void
avdtpACPFree(struct bt_config * cfg)525 avdtpACPFree(struct bt_config *cfg)
526 {
527 if (cfg->handle.sbc_enc) {
528 free(cfg->handle.sbc_enc);
529 cfg->handle.sbc_enc = NULL;
530 }
531 }
532
533 /* Returns 0 on success, < 0 on failure. */
534 static int
avdtpParseSBCConfig(uint8_t * data,struct bt_config * cfg)535 avdtpParseSBCConfig(uint8_t * data, struct bt_config *cfg)
536 {
537 if (data[0] & (1 << (7 - FREQ_48K))) {
538 cfg->freq = FREQ_48K;
539 } else if (data[0] & (1 << (7 - FREQ_44_1K))) {
540 cfg->freq = FREQ_44_1K;
541 } else if (data[0] & (1 << (7 - FREQ_32K))) {
542 cfg->freq = FREQ_32K;
543 } else if (data[0] & (1 << (7 - FREQ_16K))) {
544 cfg->freq = FREQ_16K;
545 } else {
546 return -EINVAL;
547 }
548
549 if (data[0] & (1 << (3 - MODE_STEREO))) {
550 cfg->chmode = MODE_STEREO;
551 } else if (data[0] & (1 << (3 - MODE_JOINT))) {
552 cfg->chmode = MODE_JOINT;
553 } else if (data[0] & (1 << (3 - MODE_DUAL))) {
554 cfg->chmode = MODE_DUAL;
555 } else if (data[0] & (1 << (3 - MODE_MONO))) {
556 cfg->chmode = MODE_MONO;
557 } else {
558 return -EINVAL;
559 }
560
561 if (data[1] & (1 << (7 - BLOCKS_16))) {
562 cfg->blocks = BLOCKS_16;
563 } else if (data[1] & (1 << (7 - BLOCKS_12))) {
564 cfg->blocks = BLOCKS_12;
565 } else if (data[1] & (1 << (7 - BLOCKS_8))) {
566 cfg->blocks = BLOCKS_8;
567 } else if (data[1] & (1 << (7 - BLOCKS_4))) {
568 cfg->blocks = BLOCKS_4;
569 } else {
570 return -EINVAL;
571 }
572
573 if (data[1] & (1 << (3 - BANDS_8))) {
574 cfg->bands = BANDS_8;
575 } else if (data[1] & (1 << (3 - BANDS_4))) {
576 cfg->bands = BANDS_4;
577 } else {
578 return -EINVAL;
579 }
580
581 if (data[1] & (1 << ALLOC_LOUDNESS)) {
582 cfg->allocm = ALLOC_LOUDNESS;
583 } else if (data[1] & (1 << ALLOC_SNR)) {
584 cfg->allocm = ALLOC_SNR;
585 } else {
586 return -EINVAL;
587 }
588 cfg->bitpool = data[3];
589 return 0;
590 }
591
592 int
avdtpACPHandlePacket(struct bt_config * cfg)593 avdtpACPHandlePacket(struct bt_config *cfg)
594 {
595 struct avdtpGetPacketInfo info;
596 int retval;
597
598 if (avdtpGetPacket(cfg->hc, &info) != COMMAND)
599 return (-ENXIO);
600
601 switch (info.signalID) {
602 case AVDTP_DISCOVER:
603 retval =
604 avdtpSendDiscResponseAudio(cfg->hc, info.trans, ACPSEP, 1);
605 if (!retval)
606 retval = AVDTP_DISCOVER;
607 break;
608 case AVDTP_GET_CAPABILITIES:
609 retval =
610 avdtpSendCapabilitiesResponseSBCForACP(cfg->hc, info.trans);
611 if (!retval)
612 retval = AVDTP_GET_CAPABILITIES;
613 break;
614 case AVDTP_SET_CONFIGURATION:
615 if (cfg->acceptor_state != acpInitial)
616 goto err;
617 cfg->sep = info.buffer_data[1] >> 2;
618 int is_configured = 0;
619 for (int i = 2; (i + 1) < info.buffer_len;) {
620 if (i + 2 + info.buffer_data[i + 1] > info.buffer_len)
621 break;
622 switch (info.buffer_data[i]) {
623 case mediaTransport:
624 break;
625 case mediaCodec:
626 if (info.buffer_data[i + 1] < 2)
627 break;
628 /* check codec */
629 switch (info.buffer_data[i + 3]) {
630 case 0: /* SBC */
631 if (info.buffer_data[i + 1] < 6)
632 break;
633 retval =
634 avdtpParseSBCConfig(info.buffer_data + i + 4, cfg);
635 if (retval)
636 return retval;
637 is_configured = 1;
638 break;
639 case 2: /* MPEG2/4 AAC */
640 /* TODO: Add support */
641 default:
642 break;
643 }
644 }
645 /* jump to next information element */
646 i += 2 + info.buffer_data[i + 1];
647 }
648 if (!is_configured)
649 goto err;
650
651 retval =
652 avdtpSendAccept(cfg->hc, info.trans, AVDTP_SET_CONFIGURATION);
653 if (retval)
654 return (retval);
655
656 /* TODO: Handle other codecs */
657 if (cfg->handle.sbc_enc == NULL) {
658 cfg->handle.sbc_enc = malloc(sizeof(*cfg->handle.sbc_enc));
659 if (cfg->handle.sbc_enc == NULL)
660 return (-ENOMEM);
661 }
662 memset(cfg->handle.sbc_enc, 0, sizeof(*cfg->handle.sbc_enc));
663
664 retval = AVDTP_SET_CONFIGURATION;
665 cfg->acceptor_state = acpConfigurationSet;
666 break;
667 case AVDTP_OPEN:
668 if (cfg->acceptor_state != acpConfigurationSet)
669 goto err;
670 retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID);
671 if (retval)
672 return (retval);
673 retval = info.signalID;
674 cfg->acceptor_state = acpStreamOpened;
675 break;
676 case AVDTP_START:
677 if (cfg->acceptor_state != acpStreamOpened &&
678 cfg->acceptor_state != acpStreamSuspended) {
679 goto err;
680 }
681 retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID);
682 if (retval)
683 return retval;
684 retval = info.signalID;
685 cfg->acceptor_state = acpStreamStarted;
686 break;
687 case AVDTP_CLOSE:
688 if (cfg->acceptor_state != acpStreamOpened &&
689 cfg->acceptor_state != acpStreamStarted &&
690 cfg->acceptor_state != acpStreamSuspended) {
691 goto err;
692 }
693 retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID);
694 if (retval)
695 return (retval);
696 retval = info.signalID;
697 cfg->acceptor_state = acpStreamClosed;
698 break;
699 case AVDTP_SUSPEND:
700 if (cfg->acceptor_state != acpStreamOpened &&
701 cfg->acceptor_state != acpStreamStarted) {
702 goto err;
703 }
704 retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID);
705 if (retval)
706 return (retval);
707 retval = info.signalID;
708 cfg->acceptor_state = acpStreamSuspended;
709 break;
710 case AVDTP_GET_CONFIGURATION:
711 case AVDTP_RECONFIGURE:
712 case AVDTP_ABORT:
713 /* TODO: Implement this. */
714 default:
715 err:
716 avdtpSendReject(cfg->hc, info.trans, info.signalID);
717 return (-ENXIO);
718 }
719 return (retval);
720 }
721