15f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz/*
25f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *
35f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  BlueZ - Bluetooth protocol stack for Linux
45f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *
55592142cb9383df0556b27ac59e96547b380310bJohan Hedberg *  Copyright (C) 2006-2010  Nokia Corporation
69184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
75f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *
85f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *
95f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  This program is free software; you can redistribute it and/or modify
105f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  it under the terms of the GNU General Public License as published by
115f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  the Free Software Foundation; either version 2 of the License, or
125f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  (at your option) any later version.
135f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *
145f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  This program is distributed in the hope that it will be useful,
155f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  but WITHOUT ANY WARRANTY; without even the implied warranty of
165f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
175f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  GNU General Public License for more details.
185f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *
195f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  You should have received a copy of the GNU General Public License
205f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  along with this program; if not, write to the Free Software
215f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
225f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz *
235f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz */
245f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
255f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#ifdef HAVE_CONFIG_H
265f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <config.h>
275f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#endif
285f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
295f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <stdio.h>
305f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <errno.h>
315f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <ctype.h>
325f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <fcntl.h>
335f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <unistd.h>
345f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <stdlib.h>
355f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <string.h>
365f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <getopt.h>
375f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <stdint.h>
385f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <sys/param.h>
395f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <sys/ioctl.h>
405f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <sys/socket.h>
415f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
425f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <bluetooth/bluetooth.h>
435f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <bluetooth/hci.h>
445f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <bluetooth/hci_lib.h>
455f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#include <bluetooth/l2cap.h>
465f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
475f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_PSM			25
485f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
495f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz/* Commands */
505f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_DISCOVER			0x01
515f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_GET_CAPABILITIES		0x02
525f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
535f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_PKT_TYPE_SINGLE		0x00
545f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
555f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_MSG_TYPE_COMMAND		0x00
565f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
575f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz/* SEP capability categories */
585f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_MEDIA_TRANSPORT		0x01
595f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_REPORTING			0x02
605f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_RECOVERY			0x03
615f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_CONTENT_PROTECTION	0x04
625f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_HEADER_COMPRESSION	0x05
635f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_MULTIPLEXING		0x06
645f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_MEDIA_CODEC		0x07
655f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
665f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz/* SEP types definitions */
675f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_SEP_TYPE_SOURCE		0x00
685f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_SEP_TYPE_SINK		0x01
695f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
705f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz/* Media types definitions */
715f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_MEDIA_TYPE_AUDIO		0x00
725f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_MEDIA_TYPE_VIDEO		0x01
735f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define AVDTP_MEDIA_TYPE_MULTIMEDIA	0x02
745f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
755f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define A2DP_CODEC_SBC			0x00
765f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define A2DP_CODEC_MPEG12		0x01
775f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define A2DP_CODEC_MPEG24		0x02
785f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define A2DP_CODEC_ATRAC		0x03
795f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
805f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_SAMPLING_FREQ_16000		(1 << 3)
815f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_SAMPLING_FREQ_32000		(1 << 2)
825f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_SAMPLING_FREQ_44100		(1 << 1)
8317ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann#define SBC_SAMPLING_FREQ_48000		(1 << 0)
845f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
855f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_CHANNEL_MODE_MONO		(1 << 3)
865f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_CHANNEL_MODE_DUAL_CHANNEL	(1 << 2)
875f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_CHANNEL_MODE_STEREO		(1 << 1)
8817ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann#define SBC_CHANNEL_MODE_JOINT_STEREO	(1 << 0)
895f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
905f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_BLOCK_LENGTH_4		(1 << 3)
915f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_BLOCK_LENGTH_8		(1 << 2)
925f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_BLOCK_LENGTH_12		(1 << 1)
9317ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann#define SBC_BLOCK_LENGTH_16		(1 << 0)
945f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
955f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_SUBBANDS_4			(1 << 1)
9617ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann#define SBC_SUBBANDS_8			(1 << 0)
975f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
985f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define SBC_ALLOCATION_SNR		(1 << 1)
9917ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann#define SBC_ALLOCATION_LOUDNESS		(1 << 0)
1005f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1015f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_CHANNEL_MODE_MONO		(1 << 3)
1025f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_CHANNEL_MODE_DUAL_CHANNEL	(1 << 2)
1035f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_CHANNEL_MODE_STEREO	(1 << 1)
10417ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann#define MPEG_CHANNEL_MODE_JOINT_STEREO	(1 << 0)
1055f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1065f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_LAYER_MP1			(1 << 2)
1075f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_LAYER_MP2			(1 << 1)
10817ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann#define MPEG_LAYER_MP3			(1 << 0)
1095f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1105f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_SAMPLING_FREQ_16000	(1 << 5)
1115f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_SAMPLING_FREQ_22050	(1 << 4)
1125f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_SAMPLING_FREQ_24000	(1 << 3)
1135f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_SAMPLING_FREQ_32000	(1 << 2)
1145f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#define MPEG_SAMPLING_FREQ_44100	(1 << 1)
11517ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann#define MPEG_SAMPLING_FREQ_48000	(1 << 0)
1165f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
117326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_VBR		0x8000
118326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_320000		0x4000
119326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_256000		0x2000
120326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_224000		0x1000
121326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_192000		0x0800
122326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_160000		0x0400
123326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_128000		0x0200
124326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_112000		0x0100
125326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_96000		0x0080
126326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_80000		0x0040
127326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_64000		0x0020
128326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_56000		0x0010
129326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_48000		0x0008
130326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_40000		0x0004
131326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_32000		0x0002
132326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz#define MPEG_BIT_RATE_FREE		0x0001
133326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz
1345f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct avdtp_service_capability {
1355f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t category;
1365f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t length;
1375f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t data[0];
1385f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
1395f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1405f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#if __BYTE_ORDER == __LITTLE_ENDIAN
1415f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1425f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct avdtp_header {
1435f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t message_type:2;
1445f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t packet_type:2;
1455f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t transaction:4;
1465f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t signal_id:6;
1475f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa0:2;
1485f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
1495f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1505f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct seid_info {
1515f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa0:1;
1525f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t inuse:1;
1535f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t seid:6;
1545f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa2:3;
1555f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t type:1;
1565f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t media_type:4;
1575f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
1585f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1595f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct seid_req {
1605f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct avdtp_header header;
1615f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa0:2;
1625f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t acp_seid:6;
1635f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
1645f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1655f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct avdtp_media_codec_capability {
1665f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa0:4;
1675f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t media_type:4;
1685f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t media_codec_type;
1695f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t data[0];
1705f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
1715f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1725f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct sbc_codec_cap {
1735f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct avdtp_media_codec_capability cap;
1745f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t channel_mode:4;
1755f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t frequency:4;
1765f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t allocation_method:2;
1775f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t subbands:2;
1785f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t block_length:4;
1795f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t min_bitpool;
1805f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t max_bitpool;
1815f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
1825f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1835f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct mpeg_codec_cap {
1845f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct avdtp_media_codec_capability cap;
1855f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t channel_mode:4;
1865f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t crc:1;
1875f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t layer:3;
1885f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t frequency:6;
1895f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t mpf:1;
1905f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa:1;
1915f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint16_t bitrate;
1925f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
1935f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1945f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#elif __BYTE_ORDER == __BIG_ENDIAN
1955f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
1965f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct avdtp_header {
1975f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t transaction:4;
1985f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t packet_type:2;
1995f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t message_type:2;
2005f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa0:2;
2015f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t signal_id:6;
2025f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
2035f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2045f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct seid_info {
2055f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t seid:6;
2065f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t inuse:1;
2075f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa0:1;
2085f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t media_type:4;
2095f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t type:1;
2105f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa2:3;
2115f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
2125f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2135f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct seid_req {
2145f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct avdtp_header header;
2155f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t acp_seid:6;
2165f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa0:2;
2175f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
2185f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2195f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct avdtp_media_codec_capability {
2205f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t media_type:4;
2215f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa0:4;
2225f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t media_codec_type;
2235f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t data[0];
2245f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
2255f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2265f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct sbc_codec_cap {
2275f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct avdtp_media_codec_capability cap;
2285f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t frequency:4;
2295f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t channel_mode:4;
2305f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t block_length:4;
2315f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t subbands:2;
2325f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t allocation_method:2;
2335f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t min_bitpool;
2345f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t max_bitpool;
2355f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
2365f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2375f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct mpeg_codec_cap {
2385f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct avdtp_media_codec_capability cap;
2395f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t layer:3;
2405f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t crc:1;
2415f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t channel_mode:4;
2425f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t rfa:1;
2435f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t mpf:1;
2445f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t frequency:6;
2455f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint16_t bitrate;
2465f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
2475f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2485f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#else
2495f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#error "Unknown byte order"
2505f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz#endif
2515f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2525f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct discover_resp {
2535f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct avdtp_header header;
2545f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct seid_info seps[0];
2555f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
2565f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2575f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstruct getcap_resp {
2585f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct avdtp_header header;
2595f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	uint8_t caps[0];
2605f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz} __attribute__ ((packed));
2615f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2625f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
2635f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstatic void print_mpeg12(struct mpeg_codec_cap *mpeg)
2645f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
265326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	printf("\tMedia Codec: MPEG12\n\t\tChannel Modes: ");
266326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz
267326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->channel_mode & MPEG_CHANNEL_MODE_MONO)
268326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("Mono ");
269326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->channel_mode & MPEG_CHANNEL_MODE_DUAL_CHANNEL)
270326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("DualChannel ");
271326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->channel_mode & MPEG_CHANNEL_MODE_STEREO)
272326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("Stereo ");
273326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->channel_mode & MPEG_CHANNEL_MODE_JOINT_STEREO)
274326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("JointStereo");
275326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz
276326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	printf("\n\t\tFrequencies: ");
277326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->frequency & MPEG_SAMPLING_FREQ_16000)
278326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("16Khz ");
279326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->frequency & MPEG_SAMPLING_FREQ_22050)
280326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("22.05Khz ");
281326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->frequency & MPEG_SAMPLING_FREQ_24000)
282326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("24Khz ");
283326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->frequency & MPEG_SAMPLING_FREQ_32000)
284326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("32Khz ");
285326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->frequency & MPEG_SAMPLING_FREQ_44100)
286326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("44.1Khz ");
287326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->frequency & MPEG_SAMPLING_FREQ_48000)
288326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("48Khz ");
289326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz
290326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	printf("\n\t\tCRC: %s", mpeg->crc ? "Yes" : "No");
291326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz
292326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	printf("\n\t\tLayer: ");
293326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->layer & MPEG_LAYER_MP1)
294326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("1 ");
295326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->layer & MPEG_LAYER_MP2)
296326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("2 ");
297326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->layer & MPEG_LAYER_MP3)
298326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("3 ");
299326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz
300326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	printf("\n\t\tBit Rate: ");
301326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->bitrate & MPEG_BIT_RATE_FREE)
302326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("Free format");
303326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	else {
304326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_32000)
305326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("32kbps ");
306326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_40000)
307326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("40kbps ");
308326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_48000)
309326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("48kbps ");
310326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_56000)
311326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("56kbps ");
312326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_64000)
313326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("64kbps ");
314326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_80000)
315326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("80kbps ");
316326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_96000)
317326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("96kbps ");
318326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_112000)
319326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("112kbps ");
320326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_128000)
321326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("128kbps ");
322326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_160000)
323326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("160kbps ");
324326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_192000)
325326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("192kbps ");
326326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_224000)
327326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("224kbps ");
328326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_256000)
329326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("256kbps ");
330326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		if (mpeg->bitrate & MPEG_BIT_RATE_320000)
331326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz			printf("320kbps ");
332326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	}
333326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz
334326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	printf("\n\t\tVBR: %s", mpeg->bitrate & MPEG_BIT_RATE_VBR ? "Yes" :
335326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		"No");
336326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz
337326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	printf("\n\t\tPayload Format: ");
338326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	if (mpeg->mpf)
339326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("RFC-2250 RFC-3119\n");
340326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz	else
341326c4aedcfa9f7087b9c87614901f41a32f71c63Luiz Augusto von Dentz		printf("RFC-2250\n");
3425f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
3435f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
3445f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstatic void print_sbc(struct sbc_codec_cap *sbc)
3455f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
3465f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	printf("\tMedia Codec: SBC\n\t\tChannel Modes: ");
3475f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
3485f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->channel_mode & SBC_CHANNEL_MODE_MONO)
3495f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("Mono ");
3505f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
3515f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("DualChannel ");
3525f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->channel_mode & SBC_CHANNEL_MODE_STEREO)
3535f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("Stereo ");
3545f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
3555f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("JointStereo");
3565f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
3575f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	printf("\n\t\tFrequencies: ");
3585f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->frequency & SBC_SAMPLING_FREQ_16000)
3595f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("16Khz ");
3605f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->frequency & SBC_SAMPLING_FREQ_32000)
3615f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("32Khz ");
3625f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->frequency & SBC_SAMPLING_FREQ_44100)
3635f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("44.1Khz ");
3645f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->frequency & SBC_SAMPLING_FREQ_48000)
3655f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("48Khz ");
3665f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
3675f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	printf("\n\t\tSubbands: ");
3685f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->allocation_method & SBC_SUBBANDS_4)
3695f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("4 ");
3705f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->allocation_method & SBC_SUBBANDS_8)
3715f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("8");
3725f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
3735f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	printf("\n\t\tBlocks: ");
3745f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->block_length & SBC_BLOCK_LENGTH_4)
3755f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("4 ");
3765f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->block_length & SBC_BLOCK_LENGTH_8)
3775f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("8 ");
3785f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->block_length & SBC_BLOCK_LENGTH_12)
3795f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("12 ");
3805f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sbc->block_length & SBC_BLOCK_LENGTH_16)
3815f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("16 ");
3825f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
38317ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann	printf("\n\t\tBitpool Range: %d-%d\n",
38417ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann				sbc->min_bitpool, sbc->max_bitpool);
3855f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
3865f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
3875f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstatic void print_media_codec(struct avdtp_media_codec_capability *cap)
3885f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
3895f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	switch (cap->media_codec_type) {
3905f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	case A2DP_CODEC_SBC:
3915f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		print_sbc((void *) cap);
3925f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		break;
3935f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	case A2DP_CODEC_MPEG12:
3945f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		print_mpeg12((void *) cap);
3955f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		break;
3965f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	default:
3975f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("\tMedia Codec: Unknown\n");
3985f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
3995f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
4005f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4015f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstatic void print_caps(void *data, int size)
4025f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
4035f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	int processed;
4045f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4055f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	for (processed = 0; processed + 2 < size;) {
4065f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		struct avdtp_service_capability *cap;
4075f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4085f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		cap = data;
4095f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4105f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		if (processed + 2 + cap->length > size) {
4115f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			printf("Invalid capability data in getcap resp\n");
4125f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			break;
4135f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		}
4145f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4155f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		switch (cap->category) {
4165f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_MEDIA_TRANSPORT:
4175f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_REPORTING:
4185f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_RECOVERY:
4195f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_CONTENT_PROTECTION:
4205f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_MULTIPLEXING:
4215f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			/* FIXME: Add proper functions */
4225f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			break;
4235f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_MEDIA_CODEC:
4245f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			print_media_codec((void *) cap->data);
4255f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			break;
4265f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		}
42717ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann
4285f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		processed += 2 + cap->length;
4295f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		data += 2 + cap->length;
4305f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
4315f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
4325f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4335f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstatic void init_request(struct avdtp_header *header, int request_id)
4345f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
4355f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	static int transaction = 0;
4365f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4375f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	header->packet_type = AVDTP_PKT_TYPE_SINGLE;
4385f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	header->message_type = AVDTP_MSG_TYPE_COMMAND;
4395f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	header->transaction = transaction;
4405f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	header->signal_id = request_id;
4415f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4425f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	/* clear rfa bits */
4435f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	header->rfa0 = 0;
4445f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4455f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	transaction = (transaction + 1) % 16;
4465f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
4475f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4487c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedbergstatic ssize_t avdtp_send(int sk, void *data, int len)
4495f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
4507c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedberg	ssize_t ret;
4515f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4525f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	ret = send(sk, data, len, 0);
4535f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4545f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (ret < 0)
4555f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		ret = -errno;
4565f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	else if (ret != len)
4575f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		ret = -EIO;
4585f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4595f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (ret < 0) {
4607c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedberg		printf("Unable to send message: %s (%zd)\n",
46117ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann						strerror(-ret), -ret);
4625f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return ret;
4635f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
4645f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4655f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	return ret;
4665f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
4675f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4687c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedbergstatic ssize_t avdtp_receive(int sk, void *data, int len)
4695f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
4707c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedberg	ssize_t ret;
4715f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4725f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	ret = recv(sk, data, len, 0);
4735f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4745f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (ret < 0) {
47517ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann		printf("Unable to receive message: %s (%d)\n",
47617ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann						strerror(errno), errno);
4775f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return -errno;
4785f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
4795f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4805f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	return ret;
4815f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
4825f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4837c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedbergstatic ssize_t avdtp_get_caps(int sk, int seid)
4845f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
4855f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct seid_req req;
4865f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	char buffer[1024];
4875f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct getcap_resp *caps = (void *) buffer;
4887c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedberg	ssize_t ret;
4895f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4905f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	memset(&req, 0, sizeof(req));
4915f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	init_request(&req.header, AVDTP_GET_CAPABILITIES);
4925f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	req.acp_seid = seid;
4935f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4945f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	ret = avdtp_send(sk, &req, sizeof(req));
4955f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (ret < 0)
4965f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return ret;
4975f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
4985f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	memset(&buffer, 0, sizeof(buffer));
4995f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	ret = avdtp_receive(sk, caps, sizeof(buffer));
5005f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (ret < 0)
5015f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return ret;
5025f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5037c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedberg	if ((size_t) ret < (sizeof(struct getcap_resp) + 4 +
5047c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedberg			sizeof(struct avdtp_media_codec_capability))) {
5055f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("Invalid capabilities\n");
5065f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return -1;
5075f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
5085f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5095f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	print_caps(caps, ret);
5105f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5115f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	return 0;
5125f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
5135f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5147c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedbergstatic ssize_t avdtp_discover(int sk)
5155f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
5165f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct avdtp_header req;
5175f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	char buffer[256];
5185f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct discover_resp *discover = (void *) buffer;
5197c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedberg	int seps, i;
5207c27b3e218470ba0bc2beaad39635f7b3548e53aJohan Hedberg	ssize_t ret;
5215f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5225f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	memset(&req, 0, sizeof(req));
5235f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	init_request(&req, AVDTP_DISCOVER);
5245f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5255f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	ret = avdtp_send(sk, &req, sizeof(req));
5265f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (ret < 0)
5275f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return ret;
5285f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5295f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	memset(&buffer, 0, sizeof(buffer));
5305f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	ret = avdtp_receive(sk, discover, sizeof(buffer));
5315f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (ret < 0)
5325f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return ret;
5335f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5345f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	seps = (ret - sizeof(struct avdtp_header)) / sizeof(struct seid_info);
5355f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	for (i = 0; i < seps; i++) {
5365f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		const char *type, *media;
5375f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5385f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		switch (discover->seps[i].type) {
5395f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_SEP_TYPE_SOURCE:
5405f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			type = "Source";
5415f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			break;
5425f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_SEP_TYPE_SINK:
5435f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			type = "Sink";
5445f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			break;
5455f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		default:
5465f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			type = "Invalid";
5475f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		}
5485f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5495f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		switch (discover->seps[i].media_type) {
5505f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_MEDIA_TYPE_AUDIO:
5515f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			media = "Audio";
5525f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			break;
5535f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_MEDIA_TYPE_VIDEO:
55417ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann			media = "Video";
5555f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			break;
5565f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case AVDTP_MEDIA_TYPE_MULTIMEDIA:
55717ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann			media = "Multimedia";
5585f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			break;
5595f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		default:
5605f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			media = "Invalid";
5615f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		}
5625f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
56317ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann		printf("Stream End-Point #%d: %s %s %s\n",
56417ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann					discover->seps[i].seid, media, type,
56517ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann					discover->seps[i].inuse ? "*" : "");
56617ec2826d313495aff0e16cf5330317b6c4f61c5Marcel Holtmann
5675f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		avdtp_get_caps(sk, discover->seps[i].seid);
5685f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
5695f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5705f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	return 0;
5715f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
5725f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5735f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstatic int l2cap_connect(bdaddr_t *src, bdaddr_t *dst)
5745f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
5755f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	struct sockaddr_l2 l2a;
5765f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	int sk;
5775f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5785f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	memset(&l2a, 0, sizeof(l2a));
5795f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	l2a.l2_family = AF_BLUETOOTH;
5805f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	bacpy(&l2a.l2_bdaddr, src);
5815f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5825f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
5835f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sk < 0) {
5845f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("Cannot create L2CAP socket. %s(%d)\n", strerror(errno),
5855f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz				errno);
5865f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return -errno;
5875f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
5885f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5895f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) {
5905f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("Bind failed. %s (%d)\n", strerror(errno), errno);
5915f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return -errno;
5925f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
5935f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5945f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	memset(&l2a, 0, sizeof(l2a));
5955f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	l2a.l2_family = AF_BLUETOOTH;
5965f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	bacpy(&l2a.l2_bdaddr, dst);
5975f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	l2a.l2_psm = htobs(AVDTP_PSM);
5985f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
5995f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) {
6005f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("Connect failed. %s(%d)\n", strerror(errno), errno);
6015f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		return -errno;
6025f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
6035f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
6045f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	return sk;
6055f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
6065f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
6078af5f43a6988e8f9eb2df0d43decfde23a168980Szymon Jancstatic void usage(void)
6085f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
6095f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	printf("avinfo - Audio/Video Info Tool ver %s\n", VERSION);
6105f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	printf("Usage:\n"
61175b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz		"\tavinfo [options] <remote address>\n");
61275b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz	printf("Options:\n"
61375b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz		"\t-h\t\tDisplay help\n"
61475b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz		"\t-i\t\tSpecify source interface\n");
6155f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
6165f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
6175f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzstatic struct option main_options[] = {
6185f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	{ "help",	0, 0, 'h' },
61975b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz	{ "device",	1, 0, 'i' },
6205f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	{ 0, 0, 0, 0 }
6215f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz};
6225f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
6235f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentzint main(int argc, char *argv[])
6245f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz{
6255f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	bdaddr_t src, dst;
6265f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	int opt, sk, dev_id;
6275f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
6285f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (argc < 2) {
6295f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		usage();
6305f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		exit(0);
6315f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
6325f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
63375b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz	bacpy(&src, BDADDR_ANY);
63475b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz	dev_id = hci_get_route(&src);
63575b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz	if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0)) {
63675b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz		printf("Cannot find any local adapter\n");
63775b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz		exit(-1);
63875b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz	}
63975b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz
64075b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz	while ((opt = getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
6415f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		switch (opt) {
64275b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz		case 'i':
64375b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz			if (!strncmp(optarg, "hci", 3))
64475b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz				hci_devba(atoi(optarg + 3), &src);
64575b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz			else
64675b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz				str2ba(optarg, &src);
64775b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz			break;
64875b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz
6495f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		case 'h':
6505f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		default:
6515f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			usage();
6525f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz			exit(0);
6535f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		}
6545f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
6555f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
6565f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	printf("Connecting ... \n");
6575f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
65875b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz	if (bachk(argv[optind]) < 0) {
6595f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		printf("Invalid argument\n");
6605f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		exit(1);
6615f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	}
6625f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
66375b61c0a4f415fdb6518b9cf99f9b5d4b8072c5fLuiz Augusto von Dentz	str2ba(argv[optind], &dst);
6645f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	sk = l2cap_connect(&src, &dst);
6655f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (sk < 0)
6665f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		exit(1);
6675f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
6685f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	if (avdtp_discover(sk) < 0)
6695f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz		exit(1);
6705f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz
6715f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz	return 0;
6725f1075f2f9ec9c5d18f09497bd6b0f14511621eaLuiz Augusto von Dentz}
673