12bef0250SMatthias Ringwald /* 22bef0250SMatthias Ringwald * Copyright (C) 2024 BlueKitchen GmbH 32bef0250SMatthias Ringwald * 42bef0250SMatthias Ringwald * Redistribution and use in source and binary forms, with or without 52bef0250SMatthias Ringwald * modification, are permitted provided that the following conditions 62bef0250SMatthias Ringwald * are met: 72bef0250SMatthias Ringwald * 82bef0250SMatthias Ringwald * 1. Redistributions of source code must retain the above copyright 92bef0250SMatthias Ringwald * notice, this list of conditions and the following disclaimer. 102bef0250SMatthias Ringwald * 2. Redistributions in binary form must reproduce the above copyright 112bef0250SMatthias Ringwald * notice, this list of conditions and the following disclaimer in the 122bef0250SMatthias Ringwald * documentation and/or other materials provided with the distribution. 132bef0250SMatthias Ringwald * 3. Neither the name of the copyright holders nor the names of 142bef0250SMatthias Ringwald * contributors may be used to endorse or promote products derived 152bef0250SMatthias Ringwald * from this software without specific prior written permission. 162bef0250SMatthias Ringwald * 4. Any redistribution, use, or modification is done solely for 172bef0250SMatthias Ringwald * personal benefit and not for any commercial purpose or for 182bef0250SMatthias Ringwald * monetary gain. 192bef0250SMatthias Ringwald * 202bef0250SMatthias Ringwald * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 212bef0250SMatthias Ringwald * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 222bef0250SMatthias Ringwald * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 232bef0250SMatthias Ringwald * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 242bef0250SMatthias Ringwald * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 252bef0250SMatthias Ringwald * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 262bef0250SMatthias Ringwald * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 272bef0250SMatthias Ringwald * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 282bef0250SMatthias Ringwald * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 292bef0250SMatthias Ringwald * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 302bef0250SMatthias Ringwald * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 312bef0250SMatthias Ringwald * SUCH DAMAGE. 322bef0250SMatthias Ringwald * 332bef0250SMatthias Ringwald * Please inquire about commercial licensing options at 342bef0250SMatthias Ringwald * [email protected] 352bef0250SMatthias Ringwald * 362bef0250SMatthias Ringwald */ 372bef0250SMatthias Ringwald 382bef0250SMatthias Ringwald #define BTSTACK_FILE__ "hci_event_builder.c" 392bef0250SMatthias Ringwald 402bef0250SMatthias Ringwald #include "hci_event_builder.h" 412bef0250SMatthias Ringwald 422bef0250SMatthias Ringwald #include "btstack_debug.h" 432bef0250SMatthias Ringwald #include "btstack_util.h" 442bef0250SMatthias Ringwald 452bef0250SMatthias Ringwald #include <stdint.h> 462bef0250SMatthias Ringwald #include <stddef.h> 472bef0250SMatthias Ringwald 482bef0250SMatthias Ringwald static void hci_event_builder_increment_pos(hci_event_builder_context_t * context, uint16_t size){ 492bef0250SMatthias Ringwald btstack_assert((context->pos + size) < context->size); 502bef0250SMatthias Ringwald context->pos += size; 512bef0250SMatthias Ringwald context->buffer[1] = (uint8_t) (context->pos - 2); 522bef0250SMatthias Ringwald } 532bef0250SMatthias Ringwald 542bef0250SMatthias 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){ 552bef0250SMatthias Ringwald uint16_t subevent_overhead = subevent_type == 0 ? 0 : 1; 562bef0250SMatthias Ringwald btstack_assert(buffer != NULL); 572bef0250SMatthias Ringwald btstack_assert(size + subevent_overhead >= 2); 582bef0250SMatthias Ringwald context->buffer = buffer; 592bef0250SMatthias Ringwald context->size = size; 602bef0250SMatthias Ringwald context->pos = 0; 612bef0250SMatthias Ringwald hci_event_builder_add_08(context, event_type); 622bef0250SMatthias Ringwald context->pos += 1; 632bef0250SMatthias Ringwald if (subevent_type != 0){ 642bef0250SMatthias Ringwald hci_event_builder_add_08(context, subevent_type); 652bef0250SMatthias Ringwald } 662bef0250SMatthias Ringwald } 672bef0250SMatthias Ringwald 682bef0250SMatthias Ringwald uint16_t hci_event_builder_remaining_space(hci_event_builder_context_t * context){ 692bef0250SMatthias Ringwald return context->size - context->pos; 702bef0250SMatthias Ringwald } 712bef0250SMatthias Ringwald 722bef0250SMatthias Ringwald uint16_t hci_event_builder_get_length(hci_event_builder_context_t * context){ 732bef0250SMatthias Ringwald return context->pos; 742bef0250SMatthias Ringwald } 752bef0250SMatthias Ringwald 762bef0250SMatthias Ringwald void hci_event_builder_add_08(hci_event_builder_context_t * context, uint8_t value){ 772bef0250SMatthias Ringwald uint16_t pos = context->pos; 782bef0250SMatthias Ringwald hci_event_builder_increment_pos(context, 1); 792bef0250SMatthias Ringwald context->buffer[pos] = value; 802bef0250SMatthias Ringwald } 812bef0250SMatthias Ringwald 822bef0250SMatthias Ringwald void hci_event_builder_add_16(hci_event_builder_context_t * context, uint16_t value){ 832bef0250SMatthias Ringwald uint16_t pos = context->pos; 842bef0250SMatthias Ringwald hci_event_builder_increment_pos(context, 2); 852bef0250SMatthias Ringwald little_endian_store_16(context->buffer, pos, value); 862bef0250SMatthias Ringwald } 872bef0250SMatthias Ringwald 882bef0250SMatthias Ringwald void hci_event_builder_add_24(hci_event_builder_context_t * context, uint32_t value){ 892bef0250SMatthias Ringwald uint16_t pos = context->pos; 902bef0250SMatthias Ringwald hci_event_builder_increment_pos(context, 3); 912bef0250SMatthias Ringwald little_endian_store_24(context->buffer, pos, value); 922bef0250SMatthias Ringwald } 932bef0250SMatthias Ringwald 942bef0250SMatthias Ringwald void hci_event_builder_add_32(hci_event_builder_context_t * context, uint32_t value){ 952bef0250SMatthias Ringwald uint16_t pos = context->pos; 962bef0250SMatthias Ringwald hci_event_builder_increment_pos(context, 4); 972bef0250SMatthias Ringwald little_endian_store_32(context->buffer, pos, value); 982bef0250SMatthias Ringwald } 992bef0250SMatthias Ringwald 1002bef0250SMatthias Ringwald void hci_event_builder_add_bd_addr(hci_event_builder_context_t * context, bd_addr_t addr){ 1012bef0250SMatthias Ringwald uint16_t pos = context->pos; 1022bef0250SMatthias Ringwald hci_event_builder_increment_pos(context, 6); 1032bef0250SMatthias Ringwald reverse_bd_addr(addr, &context->buffer[pos]); 1042bef0250SMatthias Ringwald } 1052bef0250SMatthias Ringwald 1062bef0250SMatthias Ringwald void hci_event_builder_add_con_handle(hci_event_builder_context_t * context, hci_con_handle_t con_handle){ 1072bef0250SMatthias Ringwald hci_event_builder_add_16(context, (uint16_t) con_handle); 1082bef0250SMatthias Ringwald } 1092bef0250SMatthias Ringwald 1102bef0250SMatthias Ringwald void hci_event_builder_add_string(hci_event_builder_context_t * context, const char * text){ 111*f7acdd51SMatthias Ringwald uint16_t length = (uint16_t) strlen(text); 1122bef0250SMatthias Ringwald uint16_t pos = context->pos; 1132bef0250SMatthias Ringwald hci_event_builder_increment_pos(context, length); 1142bef0250SMatthias Ringwald memcpy(&context->buffer[pos], text, length); 1152bef0250SMatthias Ringwald } 1162bef0250SMatthias Ringwald 1172bef0250SMatthias Ringwald void hci_event_builder_add_bytes(hci_event_builder_context_t * context, const uint8_t * data, uint16_t length){ 1182bef0250SMatthias Ringwald uint16_t pos = context->pos; 1192bef0250SMatthias Ringwald hci_event_builder_increment_pos(context, length); 1202bef0250SMatthias Ringwald memcpy(&context->buffer[pos], data, length); 1212bef0250SMatthias Ringwald } 122