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
le_audio_base_builder_init(le_audio_base_builder_t * builder,uint8_t * buffer,uint16_t size,uint32_t presentation_delay_us)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
le_audio_base_builder_add_subgroup(le_audio_base_builder_t * builder,const uint8_t * codec_id,uint8_t codec_specific_configuration_length,const uint8_t * codec_specific_configuration,uint8_t metadata_length,const uint8_t * metadata)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 */
le_audio_base_builder_add_bis(le_audio_base_builder_t * builder,uint8_t bis_index,uint8_t codec_specific_configuration_length,const uint8_t * codec_specific_configuration)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
le_audio_base_builder_get_ad_data_size(const le_audio_base_builder_t * builder)118 uint16_t le_audio_base_builder_get_ad_data_size(const le_audio_base_builder_t * builder){
119 return builder->len;
120 }
121