1 /* 2 * Copyright (C) 2022 BlueKitchen GmbH 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the copyright holders nor the names of 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 21 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 27 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32 #define BTSTACK_FILE__ "le_audio_base_builder.c" 33 34 /** 35 * @title Broadcast Audio Source Endpoint AD Builder 36 */ 37 38 #include <string.h> 39 40 #include "bluetooth.h" 41 #include "bluetooth_data_types.h" 42 #include "bluetooth_gatt.h" 43 #include "btstack_util.h" 44 #include "btstack_debug.h" 45 #include "le-audio/le_audio_base_builder.h" 46 47 void le_audio_base_builder_init(le_audio_base_builder_t * builder, uint8_t * buffer, uint16_t size, uint32_t presentation_delay_us){ 48 btstack_assert(size >= 8); 49 // default init 50 memset(builder, 0, sizeof(le_audio_base_builder_t)); 51 builder->buffer = buffer; 52 builder->size = size; 53 builder->len = 0; 54 builder->buffer[builder->len++] = 7; 55 builder->buffer[builder->len++] = BLUETOOTH_DATA_TYPE_SERVICE_DATA_16_BIT_UUID; 56 little_endian_store_16(builder->buffer, 2, ORG_BLUETOOTH_SERVICE_BASIC_AUDIO_ANNOUNCEMENT_SERVICE); 57 builder->len += 2; 58 little_endian_store_24(builder->buffer, 4, presentation_delay_us); 59 builder->len += 3; 60 builder->buffer[builder->len++] = 0; 61 builder->subgroup_offset = builder->len; 62 } 63 64 void le_audio_base_builder_add_subgroup(le_audio_base_builder_t * builder, 65 const uint8_t * codec_id, 66 uint8_t codec_specific_configuration_length, const uint8_t * codec_specific_configuration, 67 uint8_t metadata_length, const uint8_t * metadata){ 68 // check len 69 uint16_t additional_len = 1 + 5 + 1 + codec_specific_configuration_length + 1 + metadata_length; 70 btstack_assert((builder->len + additional_len) <= builder->size); 71 72 builder->buffer[builder->len++] = 0; 73 memcpy(&builder->buffer[builder->len], codec_id, 5); 74 builder->len += 5; 75 builder->buffer[builder->len++] = codec_specific_configuration_length; 76 memcpy(&builder->buffer[builder->len], codec_specific_configuration, codec_specific_configuration_length); 77 builder->len += codec_specific_configuration_length; 78 builder->buffer[builder->len++] = metadata_length; 79 memcpy(&builder->buffer[builder->len], metadata, metadata_length); 80 builder->len += metadata_length; 81 builder->bis_offset = builder->len; 82 83 // update num subgroups 84 builder->buffer[7]++; 85 86 // update total len 87 builder->buffer[0] = builder->len - 1; 88 } 89 90 /** 91 * Add BIS to current BASE 92 * @param builder 93 * @param bis_index 94 * @param codec_specific_configuration_length 95 * @param codec_specific_configuration 96 */ 97 void le_audio_base_builder_add_bis(le_audio_base_builder_t * builder, 98 uint8_t bis_index, 99 uint8_t codec_specific_configuration_length, 100 const uint8_t * codec_specific_configuration){ 101 // check len 102 uint16_t additional_len = 1 + 1 + codec_specific_configuration_length; 103 btstack_assert((builder->len + additional_len) <= builder->size); 104 105 // append data 106 builder->buffer[builder->len++] = bis_index; 107 builder->buffer[builder->len++] = codec_specific_configuration_length; 108 memcpy(&builder->buffer[builder->len], codec_specific_configuration, codec_specific_configuration_length); 109 builder->len += codec_specific_configuration_length; 110 111 // update num bis 112 builder->buffer[builder->subgroup_offset]++; 113 114 // update total len 115 builder->buffer[0] = builder->len - 1; 116 } 117 118 uint16_t le_audio_base_builder_get_ad_data_size(const le_audio_base_builder_t * builder){ 119 return builder->len; 120 } 121