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