xref: /btstack/src/hci_event_builder.c (revision 2bef0250cf8373c865269c8ac10859284e105ff5)
1*2bef0250SMatthias Ringwald /*
2*2bef0250SMatthias Ringwald  * Copyright (C) 2024 BlueKitchen GmbH
3*2bef0250SMatthias Ringwald  *
4*2bef0250SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
5*2bef0250SMatthias Ringwald  * modification, are permitted provided that the following conditions
6*2bef0250SMatthias Ringwald  * are met:
7*2bef0250SMatthias Ringwald  *
8*2bef0250SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright
9*2bef0250SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
10*2bef0250SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*2bef0250SMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*2bef0250SMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
13*2bef0250SMatthias Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*2bef0250SMatthias Ringwald  *    contributors may be used to endorse or promote products derived
15*2bef0250SMatthias Ringwald  *    from this software without specific prior written permission.
16*2bef0250SMatthias Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*2bef0250SMatthias Ringwald  *    personal benefit and not for any commercial purpose or for
18*2bef0250SMatthias Ringwald  *    monetary gain.
19*2bef0250SMatthias Ringwald  *
20*2bef0250SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*2bef0250SMatthias Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*2bef0250SMatthias Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*2bef0250SMatthias Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN
24*2bef0250SMatthias Ringwald  * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*2bef0250SMatthias Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*2bef0250SMatthias Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*2bef0250SMatthias Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*2bef0250SMatthias Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*2bef0250SMatthias Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*2bef0250SMatthias Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*2bef0250SMatthias Ringwald  * SUCH DAMAGE.
32*2bef0250SMatthias Ringwald  *
33*2bef0250SMatthias Ringwald  * Please inquire about commercial licensing options at
34*2bef0250SMatthias Ringwald  * [email protected]
35*2bef0250SMatthias Ringwald  *
36*2bef0250SMatthias Ringwald  */
37*2bef0250SMatthias Ringwald 
38*2bef0250SMatthias Ringwald #define BTSTACK_FILE__ "hci_event_builder.c"
39*2bef0250SMatthias Ringwald 
40*2bef0250SMatthias Ringwald #include "hci_event_builder.h"
41*2bef0250SMatthias Ringwald 
42*2bef0250SMatthias Ringwald #include "btstack_debug.h"
43*2bef0250SMatthias Ringwald #include "btstack_util.h"
44*2bef0250SMatthias Ringwald 
45*2bef0250SMatthias Ringwald #include <stdint.h>
46*2bef0250SMatthias Ringwald #include <stddef.h>
47*2bef0250SMatthias Ringwald 
48*2bef0250SMatthias Ringwald static void hci_event_builder_increment_pos(hci_event_builder_context_t * context, uint16_t size){
49*2bef0250SMatthias Ringwald     btstack_assert((context->pos + size) < context->size);
50*2bef0250SMatthias Ringwald     context->pos += size;
51*2bef0250SMatthias Ringwald     context->buffer[1] = (uint8_t) (context->pos - 2);
52*2bef0250SMatthias Ringwald }
53*2bef0250SMatthias Ringwald 
54*2bef0250SMatthias Ringwald void hci_event_builder_init(hci_event_builder_context_t * context, uint8_t * buffer, uint16_t size, uint8_t event_type, uint8_t subevent_type){
55*2bef0250SMatthias Ringwald     uint16_t subevent_overhead = subevent_type == 0 ? 0 : 1;
56*2bef0250SMatthias Ringwald     btstack_assert(buffer != NULL);
57*2bef0250SMatthias Ringwald     btstack_assert(size + subevent_overhead >= 2);
58*2bef0250SMatthias Ringwald     context->buffer = buffer;
59*2bef0250SMatthias Ringwald     context->size = size;
60*2bef0250SMatthias Ringwald     context->pos = 0;
61*2bef0250SMatthias Ringwald     hci_event_builder_add_08(context, event_type);
62*2bef0250SMatthias Ringwald     context->pos += 1;
63*2bef0250SMatthias Ringwald     if (subevent_type != 0){
64*2bef0250SMatthias Ringwald         hci_event_builder_add_08(context, subevent_type);
65*2bef0250SMatthias Ringwald     }
66*2bef0250SMatthias Ringwald }
67*2bef0250SMatthias Ringwald 
68*2bef0250SMatthias Ringwald uint16_t hci_event_builder_remaining_space(hci_event_builder_context_t * context){
69*2bef0250SMatthias Ringwald     return context->size - context->pos;
70*2bef0250SMatthias Ringwald }
71*2bef0250SMatthias Ringwald 
72*2bef0250SMatthias Ringwald uint16_t hci_event_builder_get_length(hci_event_builder_context_t * context){
73*2bef0250SMatthias Ringwald     return context->pos;
74*2bef0250SMatthias Ringwald }
75*2bef0250SMatthias Ringwald 
76*2bef0250SMatthias Ringwald void hci_event_builder_add_08(hci_event_builder_context_t * context, uint8_t value){
77*2bef0250SMatthias Ringwald     uint16_t pos = context->pos;
78*2bef0250SMatthias Ringwald     hci_event_builder_increment_pos(context, 1);
79*2bef0250SMatthias Ringwald     context->buffer[pos] = value;
80*2bef0250SMatthias Ringwald }
81*2bef0250SMatthias Ringwald 
82*2bef0250SMatthias Ringwald void hci_event_builder_add_16(hci_event_builder_context_t * context, uint16_t value){
83*2bef0250SMatthias Ringwald     uint16_t pos = context->pos;
84*2bef0250SMatthias Ringwald     hci_event_builder_increment_pos(context, 2);
85*2bef0250SMatthias Ringwald     little_endian_store_16(context->buffer, pos, value);
86*2bef0250SMatthias Ringwald }
87*2bef0250SMatthias Ringwald 
88*2bef0250SMatthias Ringwald void hci_event_builder_add_24(hci_event_builder_context_t * context, uint32_t value){
89*2bef0250SMatthias Ringwald     uint16_t pos = context->pos;
90*2bef0250SMatthias Ringwald     hci_event_builder_increment_pos(context, 3);
91*2bef0250SMatthias Ringwald     little_endian_store_24(context->buffer, pos, value);
92*2bef0250SMatthias Ringwald }
93*2bef0250SMatthias Ringwald 
94*2bef0250SMatthias Ringwald void hci_event_builder_add_32(hci_event_builder_context_t * context, uint32_t value){
95*2bef0250SMatthias Ringwald     uint16_t pos = context->pos;
96*2bef0250SMatthias Ringwald     hci_event_builder_increment_pos(context, 4);
97*2bef0250SMatthias Ringwald     little_endian_store_32(context->buffer, pos, value);
98*2bef0250SMatthias Ringwald }
99*2bef0250SMatthias Ringwald 
100*2bef0250SMatthias Ringwald void hci_event_builder_add_bd_addr(hci_event_builder_context_t * context, bd_addr_t addr){
101*2bef0250SMatthias Ringwald     uint16_t pos = context->pos;
102*2bef0250SMatthias Ringwald     hci_event_builder_increment_pos(context, 6);
103*2bef0250SMatthias Ringwald     reverse_bd_addr(addr, &context->buffer[pos]);
104*2bef0250SMatthias Ringwald }
105*2bef0250SMatthias Ringwald 
106*2bef0250SMatthias Ringwald void hci_event_builder_add_con_handle(hci_event_builder_context_t * context, hci_con_handle_t con_handle){
107*2bef0250SMatthias Ringwald     hci_event_builder_add_16(context, (uint16_t) con_handle);
108*2bef0250SMatthias Ringwald }
109*2bef0250SMatthias Ringwald 
110*2bef0250SMatthias Ringwald void hci_event_builder_add_string(hci_event_builder_context_t * context, const char * text){
111*2bef0250SMatthias Ringwald     uint16_t length = strlen(text);
112*2bef0250SMatthias Ringwald     uint16_t pos = context->pos;
113*2bef0250SMatthias Ringwald     hci_event_builder_increment_pos(context, length);
114*2bef0250SMatthias Ringwald     memcpy(&context->buffer[pos], text, length);
115*2bef0250SMatthias Ringwald }
116*2bef0250SMatthias Ringwald 
117*2bef0250SMatthias Ringwald void hci_event_builder_add_bytes(hci_event_builder_context_t * context, const uint8_t * data, uint16_t length){
118*2bef0250SMatthias Ringwald     uint16_t pos = context->pos;
119*2bef0250SMatthias Ringwald     hci_event_builder_increment_pos(context, length);
120*2bef0250SMatthias Ringwald     memcpy(&context->buffer[pos], data, length);
121*2bef0250SMatthias Ringwald }
122