xref: /freebsd/lib/virtual_oss/bt/avdtp.c (revision 9cab9fde5edad9b409dd2317a2aec7815e6d6bed)
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