avdtp.c revision 1.4
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