1 /* 2 * Copyright (C) 2020 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 * 4. Any redistribution, use, or modification is done solely for 17 * personal benefit and not for any commercial purpose or for 18 * monetary gain. 19 * 20 * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN 24 * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 27 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 30 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * Please inquire about commercial licensing options at 34 * [email protected] 35 * 36 */ 37 38 #define BTSTACK_FILE__ "hci_event.c" 39 40 /* 41 * hci_event.c 42 */ 43 44 #include "btstack_config.h" 45 46 #include "hci.h" 47 #include "hci_event.h" 48 #include "btstack_defines.h" 49 #include "btstack_debug.h" 50 51 #include <string.h> 52 53 static inline bool hci_event_can_store(uint16_t pos, uint16_t size, uint16_t to_store, bool *overrun) { 54 if ((pos + to_store) > size) { 55 *overrun = true; 56 return false; 57 } else { 58 return true; 59 } 60 } 61 62 /** 63 * construct HCI Event based on template 64 * 65 * Format: 66 * 1,2,3,4: one to four byte value 67 * H: HCI connection handle 68 * B: Bluetooth Baseband Address (BD_ADDR) 69 * D: 8 byte data block 70 * P: 16 byte data block. 71 * Q: 32 byte data block, e.g. for X and Y coordinates of P-256 public key 72 * J: 1-byte lenght of following variable-length data blob 'V' 73 * K: 1-byte length of following variable-length data blob 'V', length is not included in packet 74 * V: variable-length data blob of len provided in 'J' field 75 */ 76 uint16_t hci_event_create_from_template_and_arglist(uint8_t *hci_event_buffer, uint16_t buffer_size, const hci_event_t *event, va_list argptr){ 77 78 hci_event_buffer[0] = event->event_code; 79 hci_event_buffer[1] = 0; 80 81 uint16_t pos = 2; 82 83 // store subevent code if set 84 if (event->subevent_code != 0){ 85 hci_event_buffer[pos++] = event->subevent_code; 86 } 87 88 const char *format = event->format; 89 uint16_t word; 90 uint32_t longword; 91 uint8_t * ptr; 92 uint16_t length_j = 0xffff; 93 bool overrun = false; 94 while (*format != 0) { 95 switch(*format) { 96 case '1': // 8 bit value 97 if (!hci_event_can_store(pos, buffer_size, 1, &overrun)) break; 98 word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs 99 hci_event_buffer[pos++] = word & 0xff; 100 break; 101 case '2': // 16 bit value 102 case 'H': // hci_handle 103 if (!hci_event_can_store(pos, buffer_size, 2, &overrun)) break; 104 word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs 105 little_endian_store_16(hci_event_buffer, pos, word); 106 pos += 2; 107 break; 108 case '3': 109 if (!hci_event_can_store(pos, buffer_size, 3, &overrun)) break; 110 longword = va_arg(argptr, uint32_t); 111 little_endian_store_24(hci_event_buffer, pos, longword); 112 pos += 3; 113 break; 114 case '4': 115 if (!hci_event_can_store(pos, buffer_size, 4, &overrun)) break; 116 longword = va_arg(argptr, uint32_t); 117 little_endian_store_32(hci_event_buffer, pos, longword); 118 pos += 4; 119 break; 120 case 'B': // bt-addr 121 if (!hci_event_can_store(pos, buffer_size, 6, &overrun)) break; 122 ptr = va_arg(argptr, uint8_t *); 123 reverse_bytes(ptr, &hci_event_buffer[pos], 6); 124 pos += 6; 125 break; 126 case 'Q': 127 if (!hci_event_can_store(pos, buffer_size, 32, &overrun)) break; 128 ptr = va_arg(argptr, uint8_t *); 129 reverse_bytes(ptr, &hci_event_buffer[pos], 32); 130 pos += 32; 131 break; 132 case 'J': 133 if (!hci_event_can_store(pos, buffer_size, 1, &overrun)) break; 134 word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs 135 length_j = word & 0xff; 136 hci_event_buffer[pos++] = (uint8_t) length_j; 137 break; 138 case 'K': 139 word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs 140 length_j = word & 0xff; 141 break; 142 case 'V': 143 btstack_assert(length_j < 0x100); 144 if (!hci_event_can_store(pos, buffer_size, length_j, &overrun)) break; 145 ptr = va_arg(argptr, uint8_t *); 146 (void)memcpy(&hci_event_buffer[pos], ptr, length_j); 147 pos += length_j; 148 break; 149 default: 150 btstack_assert(false); 151 break; 152 } 153 if (overrun){ 154 return 0; 155 } 156 format++; 157 }; 158 159 // store final event len 160 hci_event_buffer[1] = pos - 2; 161 return pos; 162 } 163 164 uint16_t hci_event_create_from_template_and_arguments(uint8_t *hci_buffer, uint16_t buffer_size, const hci_event_t *event, ...){ 165 va_list argptr; 166 va_start(argptr, event); 167 uint16_t length = hci_event_create_from_template_and_arglist(hci_buffer, buffer_size, event, argptr); 168 va_end(argptr); 169 return length; 170 } 171 172 /* HCI Events */ 173 174 const hci_event_t hci_event_hardware_error = { 175 HCI_EVENT_HARDWARE_ERROR, 0, "1" 176 }; 177 178 const hci_event_t hci_event_transport_packet_sent = { 179 HCI_EVENT_TRANSPORT_PACKET_SENT, 0, "" 180 }; 181 182 const hci_event_t hci_event_command_complete = { 183 HCI_EVENT_COMMAND_COMPLETE, 0, "121KV" 184 }; 185 186 const hci_event_t hci_event_disconnection_complete = { 187 HCI_EVENT_DISCONNECTION_COMPLETE, 0, "1H1" 188 }; 189 190 const hci_event_t hci_event_number_of_completed_packets_1 = { 191 HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS, 0, "1H2" 192 }; 193 194 /* LE Subevents */ 195 196 const hci_event_t hci_subevent_le_connection_complete = { 197 HCI_EVENT_LE_META, HCI_SUBEVENT_LE_CONNECTION_COMPLETE, "1H11B2221" 198 }; 199