11.4Smsaitoh/* $NetBSD: avdtp.c,v 1.4 2020/05/14 08:34:19 msaitoh Exp $ */
21.1Snat
31.1Snat/*-
41.1Snat * Copyright (c) 2015 - 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au>
51.1Snat * All rights reserved.
61.1Snat *
71.1Snat *		This software is dedicated to the memory of -
81.1Snat *	   Baron James Anlezark (Barry) - 1 Jan 1949 - 13 May 2012.
91.1Snat *
101.1Snat *		Barry was a man who loved his music.
111.1Snat *
121.1Snat * Redistribution and use in source and binary forms, with or without
131.1Snat * modification, are permitted provided that the following conditions
141.1Snat * are met:
151.1Snat * 1. Redistributions of source code must retain the above copyright
161.1Snat *    notice, this list of conditions and the following disclaimer.
171.1Snat * 2. Redistributions in binary form must reproduce the above copyright
181.1Snat *    notice, this list of conditions and the following disclaimer in the
191.1Snat *    documentation and/or other materials provided with the distribution.
201.1Snat *
211.1Snat * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
221.1Snat * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
231.1Snat * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
241.1Snat * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
251.1Snat * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
261.1Snat * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
271.1Snat * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
281.1Snat * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
291.1Snat * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
301.1Snat * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
311.1Snat * POSSIBILITY OF SUCH DAMAGE.
321.1Snat */
331.1Snat
341.1Snat#include <errno.h>
351.1Snat#include <malloc.h>
361.1Snat#include <string.h>
371.1Snat#include <unistd.h>
381.1Snat
391.1Snat#include "avdtp_signal.h"
401.1Snat#include "sbc_encode.h"
411.1Snat
421.1Snatstatic uint8_t transLabel = 1;
431.1Snatint
441.1SnatavdtpSendCommand(int fd, uint8_t command, uint8_t type, uint8_t *data,
451.1Snat    size_t datasize)
461.1Snat{
471.1Snat#define SINGLE_PACKET 0
481.1Snat#define START_PACKET 1
491.1Snat#define CONTINUE_PACKET 2
501.1Snat#define END_PACKET 3
511.1Snat#define signalID 3
521.1Snat
531.1Snat	uint8_t header[64];
541.1Snat	size_t extra_size = 0;
551.1Snat	const uint8_t packetType = (SINGLE_PACKET & 3) << 2;
561.1Snat	const uint8_t messageType = (type & 3);
571.1Snat
581.1Snat	transLabel &= 0xf;
591.1Snat
601.1Snat	header[0] = (uint8_t)((transLabel << 4) | packetType | messageType);
611.1Snat	if (command != 0)
621.1Snat		header[1] = command & 0x3f;
631.1Snat	else
641.1Snat		header[1] = signalID & 0x3f; /* Bits 7/6 Reserved */
651.1Snat
661.1Snat	transLabel++;
671.1Snat	if (data != NULL) {
681.1Snat		extra_size = datasize;
691.1Snat		memcpy(header + 2, data, extra_size);
701.1Snat	}
711.1Snat	write(fd, &header, extra_size + 2);
721.1Snat
731.1Snat	return transLabel - 1;
741.1Snat}
751.1Snat
761.1Snatint
771.1SnatavdtpCheckResponse(int recvfd, bool *isCommand, uint8_t *trans, uint8_t
781.1Snat    *signalId, uint8_t *pkt_type, uint8_t *data, size_t *datasize, uint8_t *sep)
791.1Snat{
801.1Snat	uint8_t buffer[1024];
811.1Snat	size_t len;
821.1Snat
831.1Snat	*isCommand = false;
841.1Snat	len = (size_t)read(recvfd, buffer, sizeof(buffer));
851.1Snat
861.1Snat	if (datasize)
871.1Snat		*datasize = 0;
881.1Snat
891.1Snat	if (len < AVDTP_LEN_SUCCESS)
901.1Snat		return ENOMEM;
911.1Snat
921.2Skamil	*trans = (uint8_t)((buffer[0] & TRANSACTIONLABEL) >> TRANSACTIONLABEL_S);
931.1Snat	*signalId = buffer[1] & SIGNALID_MASK;
941.1Snat	if ((buffer[0] & MESSAGETYPE) == COMMAND) {
951.1Snat		if (datasize)
961.1Snat			*datasize = 0;
971.1Snat		if (sep && len > 2)
981.1Snat			*sep = buffer[2] >> 2;
991.1Snat		*isCommand = true;
1001.1Snat	}
1011.1Snat
1021.1Snat	if (len == AVDTP_LEN_ERROR)
1031.1Snat		return buffer[2];
1041.1Snat	else if ((len % AVDTP_LEN_SUCCESS) == 0 &&
1051.1Snat	    buffer[0] & RESPONSEACCEPT) {
1061.1Snat		if (len == AVDTP_LEN_SUCCESS)
1071.1Snat			return 0;
1081.1Snat	}
1091.1Snat	if (datasize && data && len > AVDTP_LEN_SUCCESS &&
1101.1Snat	    buffer[0] & RESPONSEACCEPT) {
1111.1Snat		memcpy(data, buffer + 2, len - 2);
1121.1Snat		*datasize = len - 2;
1131.1Snat
1141.1Snat		return 0;
1151.1Snat	}
1161.1Snat
1171.1Snat	if (isCommand)
1181.1Snat		return 0;
1191.1Snat
1201.1Snat	return EINVAL;
1211.1Snat}
1221.1Snat
1231.1Snatint
1241.1SnatavdtpSendCapabilitiesResponseSBC(int fd, int recvfd, int trans, uint8_t mySep,
1251.1Snat    uint8_t bitpool, uint8_t freq, uint8_t mode, uint8_t bands, uint8_t blocks,
1261.1Snat    uint8_t alloc_method)
1271.1Snat{
1281.1Snat	uint8_t data[12], freqmode, blk_len_sb_alloc, freq_dat, mode_dat;
1291.1Snat	uint8_t bands_dat, blocks_dat, alloc_dat;
1301.1Snat
1311.1Snat
1321.1Snat	freq_dat = (uint8_t)(freq << 4);
1331.1Snat	mode_dat = mode;
1341.1Snat	freqmode = freq_dat | mode_dat;
1351.1Snat
1361.1Snat	blocks_dat = (uint8_t)(blocks << 4);
1371.1Snat	bands_dat = (uint8_t)(bands << 2);
1381.1Snat	alloc_dat = alloc_method;
1391.1Snat	blk_len_sb_alloc = blocks_dat| bands_dat | alloc_dat;
1401.1Snat
1411.1Snat	data[0] = (uint8_t)(trans << 4 | RESPONSEACCEPT);
1421.1Snat	data[1] = AVDTP_GET_CAPABILITIES;
1431.1Snat	data[2] = mediaTransport;
1441.1Snat	data[3] = 0;
1451.1Snat	data[4] = mediaCodec;
1461.1Snat	data[5] = 0x6;
1471.1Snat	data[6] = mediaTypeAudio;
1481.1Snat	data[7] = SBC_CODEC_ID;
1491.1Snat	data[8] = freqmode;
1501.1Snat	data[9] = blk_len_sb_alloc;
1511.1Snat	data[10] = MIN_BITPOOL;
1521.1Snat	if (bitpool > MIN_BITPOOL)
1531.1Snat		data[11] = bitpool;
1541.1Snat	else
1551.1Snat		data[11] = DEFAULT_MAXBPOOL;
1561.1Snat
1571.1Snat	write(fd, data, sizeof(data));
1581.1Snat
1591.1Snat	return 0;
1601.1Snat}
1611.1Snat
1621.1Snatint
1631.1SnatavdtpSendAccept(int fd, int recvfd, uint8_t trans, uint8_t myCommand)
1641.1Snat{
1651.1Snat	uint8_t data[2];
1661.1Snat
1671.1Snat	data[0] = (uint8_t)(trans << 4 | RESPONSEACCEPT);
1681.4Smsaitoh	data[1] = myCommand;
1691.1Snat
1701.1Snat	write(fd, data, sizeof(data));
1711.1Snat
1721.1Snat	return 0;
1731.1Snat}
1741.1Snat
1751.1Snatint
1761.1SnatavdtpSendReject(int fd, int recvfd, uint8_t trans, uint8_t myCommand)
1771.1Snat{
1781.1Snat	uint8_t data[4];
1791.1Snat
1801.1Snat	data[0] = (uint8_t)(trans << 4 | RESPONSEREJECT);
1811.1Snat	data[1] = myCommand;
1821.1Snat	data[2] = 0;
1831.1Snat
1841.1Snat	write(fd, data, sizeof(data));
1851.1Snat
1861.1Snat	return 0;
1871.1Snat}
1881.1Snat
1891.1Snatint
1901.1SnatavdtpSendDiscResponseAudio(int fd, int recvfd, uint8_t trans, uint8_t mySep,
1911.1Snat    bool sink)
1921.1Snat{
1931.1Snat	uint8_t data[4];
1941.1Snat
1951.1Snat	data[0] = (uint8_t)(trans << 4 | RESPONSEACCEPT);
1961.1Snat	data[1] = AVDTP_DISCOVER;
1971.1Snat	data[2] = (uint8_t)(mySep << 2);
1981.1Snat	data[3] = (uint8_t)((sink ? 1 : 0) << 3);
1991.1Snat
2001.1Snat	write(fd, data, sizeof(data));
2011.1Snat
2021.1Snat	return 0;
2031.1Snat}
2041.1Snat
2051.1Snatint
2061.1SnatavdtpDiscover(uint8_t *buffer, size_t recvsize,  struct avdtp_sepInfo *sepInfo,
2071.1Snat    bool sink)
2081.1Snat{
2091.1Snat	size_t offset;
2101.1Snat	bool isSink;
2111.1Snat
2121.1Snat	if (recvsize >= 2) {
2131.3Smaya		for (offset = 0; offset < recvsize - 1; offset += 2) {
2141.1Snat			sepInfo->sep = buffer[offset] >> 2;
2151.1Snat			sepInfo->media_Type = buffer[offset+1] >> 4;
2161.1Snat			isSink = (buffer[offset+1] >> 3) & 1;
2171.1Snat			if (buffer[offset] & DISCOVER_SEP_IN_USE ||
2181.1Snat			     isSink != sink)
2191.1Snat				continue;
2201.1Snat			else
2211.1Snat				break;
2221.1Snat		}
2231.1Snat		if (offset > recvsize)
2241.1Snat			return EINVAL;
2251.1Snat
2261.1Snat		return 0;
2271.1Snat	}
2281.1Snat
2291.1Snat	return EINVAL;
2301.1Snat}
2311.1Snat
2321.1Snatvoid
2331.1SnatavdtpGetCapabilities(int fd, int recvfd, uint8_t sep)
2341.1Snat{
2351.1Snat	uint8_t address = (uint8_t)(sep << 2);
2361.1Snat
2371.1Snat	avdtpSendCommand(fd, AVDTP_GET_CAPABILITIES, 0, &address, 1);
2381.1Snat}
2391.1Snat
2401.1Snatint
2411.1SnatavdtpSetConfiguration(int fd, int recvfd, uint8_t sep, uint8_t *data,
2421.1Snat    size_t datasize, int srcsep)
2431.1Snat{
2441.1Snat	uint8_t configAddresses[2];
2451.1Snat	uint8_t *configData;
2461.1Snat
2471.1Snat	if (data == NULL || datasize == 0)
2481.1Snat		return EINVAL;
2491.1Snat
2501.1Snat	configData = malloc(datasize + 2);
2511.1Snat	if (configData == NULL)
2521.1Snat		return ENOMEM;
2531.1Snat	configAddresses[0] = (uint8_t)(sep << 2);
2541.1Snat	configAddresses[1] = (uint8_t)(srcsep << 2);
2551.1Snat
2561.1Snat	memcpy(configData, configAddresses, 2);
2571.1Snat	memcpy(configData + 2, data, datasize);
2581.1Snat
2591.1Snat	avdtpSendCommand(fd, AVDTP_SET_CONFIGURATION, 0,
2601.1Snat	    configData, datasize + 2);
2611.1Snat	free(configData);
2621.1Snat
2631.1Snat	return 0;
2641.1Snat
2651.1Snat}
2661.1Snat
2671.1Snatvoid
2681.1SnatavdtpOpen(int fd, int recvfd, uint8_t sep)
2691.1Snat{
2701.1Snat	uint8_t address = (uint8_t)(sep << 2);
2711.1Snat
2721.1Snat	avdtpSendCommand(fd, AVDTP_OPEN, 0, &address, 1);
2731.1Snat}
2741.1Snat
2751.1Snatvoid
2761.1SnatavdtpStart(int fd, int recvfd, uint8_t sep)
2771.1Snat{
2781.1Snat	uint8_t address = (uint8_t)(sep << 2);
2791.1Snat
2801.1Snat	avdtpSendCommand(fd, AVDTP_START, 0, &address, 1);
2811.1Snat}
2821.1Snat
2831.1Snatvoid
2841.1SnatavdtpClose(int fd, int recvfd, uint8_t sep)
2851.1Snat{
2861.1Snat	uint8_t address = (uint8_t)(sep << 2);
2871.1Snat
2881.1Snat	avdtpSendCommand(fd, AVDTP_CLOSE, 0, &address, 1);
2891.1Snat}
2901.1Snat
2911.1Snatvoid
2921.1SnatavdtpSuspend(int fd, int recvfd, uint8_t sep)
2931.1Snat{
2941.1Snat	uint8_t address = (uint8_t)(sep << 2);
2951.1Snat
2961.1Snat	avdtpSendCommand(fd, AVDTP_SUSPEND, 0, &address, 1);
2971.1Snat}
2981.1Snat
2991.1Snatvoid
3001.1SnatavdtpAbort(int fd, int recvfd, uint8_t sep)
3011.1Snat{
3021.1Snat	uint8_t address = (uint8_t)(sep << 2);
3031.1Snat
3041.1Snat	avdtpSendCommand(fd, AVDTP_ABORT, 0, &address, 1);
3051.1Snat}
3061.1Snat
3071.1Snatint
3081.1SnatavdtpAutoConfigSBC(int fd, int recvfd, uint8_t *capabilities, size_t cap_len,
3091.1Snat    uint8_t sep, uint8_t *freq, uint8_t *mode, uint8_t *alloc_method, uint8_t
3101.1Snat    *bitpool, uint8_t* bands, uint8_t *blocks, uint8_t srcsep)
3111.1Snat{
3121.1Snat	uint8_t freqmode, blk_len_sb_alloc, availFreqMode, availConfig;
3131.1Snat	uint8_t supBitpoolMin, supBitpoolMax, tmp_mask;
3141.1Snat	size_t i;
3151.1Snat
3161.3Smaya	for (i = 0; i < cap_len - 5; i++) {
3171.1Snat		if (capabilities[i] == mediaTransport &&
3181.1Snat		    capabilities[i + 1] == 0 &&
3191.1Snat		    capabilities[i + 2] == mediaCodec &&
3201.1Snat		    capabilities[i + 4] == mediaTypeAudio &&
3211.1Snat		    capabilities[i + 5] == SBC_CODEC_ID)
3221.1Snat			break;
3231.1Snat	}
3241.3Smaya	if (i >= cap_len - 9)
3251.1Snat		goto auto_config_failed;
3261.1Snat
3271.1Snat	availFreqMode = capabilities[i + 6];
3281.1Snat	availConfig = capabilities[i + 7];
3291.1Snat	supBitpoolMin = capabilities[i + 8];
3301.1Snat	supBitpoolMax = capabilities[i + 9];
3311.1Snat
3321.1Snat	freqmode = (uint8_t)(*freq << 4 | *mode);
3331.1Snat	tmp_mask = availFreqMode & freqmode;
3341.1Snat	*mode = (uint8_t)(1 << FLS(tmp_mask & 0xf));
3351.1Snat	*freq = (uint8_t)(1 << FLS(tmp_mask >> 4));
3361.1Snat
3371.1Snat	freqmode = (uint8_t)(*freq << 4 | *mode);
3381.1Snat	if ((availFreqMode & freqmode) != freqmode)
3391.1Snat		goto auto_config_failed;
3401.1Snat
3411.1Snat	blk_len_sb_alloc = (uint8_t)(*blocks << 4 | *bands << 2 |
3421.1Snat	    *alloc_method);
3431.1Snat
3441.1Snat	tmp_mask = availConfig & blk_len_sb_alloc;
3451.1Snat	*blocks = (uint8_t)(1 << FLS(tmp_mask >> 4));
3461.1Snat	*bands = (uint8_t)(1 << FLS((tmp_mask >> 2) & 3));
3471.1Snat	*alloc_method = (uint8_t)(1 << FLS(tmp_mask & 3));
3481.1Snat
3491.1Snat	blk_len_sb_alloc = (uint8_t)(*blocks << 4 | *bands << 2 |
3501.1Snat	    *alloc_method);
3511.1Snat
3521.1Snat	if ((availConfig & blk_len_sb_alloc) != blk_len_sb_alloc)
3531.1Snat		goto auto_config_failed;
3541.1Snat
3551.1Snat	if (*alloc_method == ALLOC_SNR)
3561.1Snat		supBitpoolMax &= (uint8_t)~1;
3571.1Snat
3581.1Snat	if (*mode == MODE_DUAL || *mode == MODE_MONO)
3591.1Snat		supBitpoolMax /= 2;
3601.1Snat
3611.1Snat	if (*bands == BANDS_4)
3621.1Snat		supBitpoolMax /= 2;
3631.1Snat
3641.1Snat	if (supBitpoolMax > *bitpool)
3651.1Snat		supBitpoolMax = *bitpool;
3661.1Snat	else
3671.1Snat		*bitpool = supBitpoolMax;
3681.1Snat
3691.1Snat	uint8_t config[] = {mediaTransport, 0x0, mediaCodec, 0x6,
3701.1Snat	    mediaTypeAudio, SBC_CODEC_ID, freqmode, blk_len_sb_alloc,
3711.1Snat	    supBitpoolMin, supBitpoolMax};
3721.1Snat
3731.1Snat	if (avdtpSetConfiguration(fd, fd, sep, config, sizeof(config),
3741.1Snat	    srcsep) == 0)
3751.1Snat		return 0;
3761.1Snat
3771.1Snatauto_config_failed:
3781.1Snat	return EINVAL;
3791.1Snat}
380