Path: blob/main/usr.sbin/bluetooth/sdpd/audio_source.c
102616 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2019 Hans Petter Selasky <[email protected]>4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*/2728#include <sys/queue.h>29#define L2CAP_SOCKET_CHECKED30#include <bluetooth.h>31#include <sdp.h>32#include <string.h>33#include "profile.h"34#include "provider.h"3536static int32_t37audio_source_profile_create_service_class_id_list(38uint8_t *buf, uint8_t const *const eob,39uint8_t const *data, uint32_t datalen)40{41static const uint16_t service_classes[] = {42SDP_SERVICE_CLASS_AUDIO_SOURCE,43};4445return (common_profile_create_service_class_id_list(46buf, eob,47(uint8_t const *)service_classes,48sizeof(service_classes)));49}5051static int32_t52audio_source_profile_create_protocol_descriptor_list(53uint8_t *buf, uint8_t const *const eob,54uint8_t const *data, uint32_t datalen)55{56provider_p provider = (provider_p) data;57sdp_audio_source_profile_p audio_source = (sdp_audio_source_profile_p) provider->data;5859if (buf + 18 > eob)60return (-1);6162SDP_PUT8(SDP_DATA_SEQ8, buf);63SDP_PUT8(16, buf);6465SDP_PUT8(SDP_DATA_SEQ8, buf);66SDP_PUT8(6, buf);6768SDP_PUT8(SDP_DATA_UUID16, buf);69SDP_PUT16(SDP_UUID_PROTOCOL_L2CAP, buf);7071SDP_PUT8(SDP_DATA_UINT16, buf);72SDP_PUT16(audio_source->psm, buf);7374SDP_PUT8(SDP_DATA_SEQ8, buf);75SDP_PUT8(6, buf);7677SDP_PUT8(SDP_DATA_UUID16, buf);78SDP_PUT16(SDP_UUID_PROTOCOL_AVDTP, buf);7980SDP_PUT8(SDP_DATA_UINT16, buf);81SDP_PUT16(audio_source->protover, buf);8283return (18);84}8586static int32_t87audio_source_profile_create_browse_group_list(88uint8_t *buf, uint8_t const *const eob,89uint8_t const *data, uint32_t datalen)90{9192if (buf + 5 > eob)93return (-1);9495SDP_PUT8(SDP_DATA_SEQ8, buf);96SDP_PUT8(3, buf);9798SDP_PUT8(SDP_DATA_UUID16, buf);99SDP_PUT16(SDP_SERVICE_CLASS_PUBLIC_BROWSE_GROUP, buf);100101return (5);102}103104static int32_t105audio_source_profile_create_bluetooth_profile_descriptor_list(106uint8_t *buf, uint8_t const *const eob,107uint8_t const *data, uint32_t datalen)108{109static const uint16_t profile_descriptor_list[] = {110SDP_SERVICE_CLASS_ADVANCED_AUDIO_DISTRIBUTION,1110x0100112};113114return (common_profile_create_bluetooth_profile_descriptor_list(115buf, eob,116(uint8_t const *)profile_descriptor_list,117sizeof(profile_descriptor_list)));118}119120static int32_t121audio_source_profile_create_service_name(122uint8_t *buf, uint8_t const *const eob,123uint8_t const *data, uint32_t datalen)124{125static const char service_name[] = "Audio SRC";126127return (common_profile_create_string8(128buf, eob,129(uint8_t const *)service_name, strlen(service_name)));130}131132static int32_t133audio_source_create_supported_features(134uint8_t *buf, uint8_t const *const eob,135uint8_t const *data, uint32_t datalen)136{137provider_p provider = (provider_p) data;138sdp_audio_source_profile_p audio_source = (sdp_audio_source_profile_p) provider->data;139140if (buf + 3 > eob)141return (-1);142143SDP_PUT8(SDP_DATA_UINT16, buf);144SDP_PUT16(audio_source->features, buf);145146return (3);147}148149static int32_t150audio_source_profile_valid(uint8_t const *data, uint32_t datalen)151{152153if (datalen < sizeof(struct sdp_audio_source_profile))154return (0);155return (1);156}157158static const attr_t audio_source_profile_attrs[] = {159{SDP_ATTR_SERVICE_RECORD_HANDLE,160common_profile_create_service_record_handle},161{SDP_ATTR_SERVICE_CLASS_ID_LIST,162audio_source_profile_create_service_class_id_list},163{SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST,164audio_source_profile_create_protocol_descriptor_list},165{SDP_ATTR_BROWSE_GROUP_LIST,166audio_source_profile_create_browse_group_list},167{SDP_ATTR_LANGUAGE_BASE_ATTRIBUTE_ID_LIST,168common_profile_create_language_base_attribute_id_list},169{SDP_ATTR_BLUETOOTH_PROFILE_DESCRIPTOR_LIST,170audio_source_profile_create_bluetooth_profile_descriptor_list},171{SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_SERVICE_NAME_OFFSET,172audio_source_profile_create_service_name},173{SDP_ATTR_PRIMARY_LANGUAGE_BASE_ID + SDP_ATTR_PROVIDER_NAME_OFFSET,174common_profile_create_service_provider_name},175{SDP_ATTR_SUPPORTED_FEATURES,176audio_source_create_supported_features},177{} /* end entry */178};179180profile_t audio_source_profile_descriptor = {181SDP_SERVICE_CLASS_AUDIO_SOURCE,182sizeof(sdp_audio_source_profile_t),183audio_source_profile_valid,184(attr_t const *const)&audio_source_profile_attrs185};186187188