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 /** 54 * construct HCI Event based on template 55 * 56 * Format: 57 * 1,2,3,4: one to four byte value 58 * H: HCI connection handle 59 * B: Bluetooth Baseband Address (BD_ADDR) 60 * D: 8 byte data block 61 * P: 16 byte data block. 62 * Q: 32 byte data block, e.g. for X and Y coordinates of P-256 public key 63 * J: 1-byte lenght of following variable-length data blob 'V' 64 * K: 1-byte length of following variable-length data blob 'V', length is not included in packet 65 * V: variable-length data blob of len provided in 'J' field 66 */ 67 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){ 68 69 UNUSED(buffer_size); 70 71 hci_event_buffer[0] = event->event_code; 72 uint16_t pos = 2; 73 74 // store subevent code if set 75 if (event->subevent_code != 0){ 76 hci_event_buffer[pos++] = event->subevent_code; 77 } 78 79 const char *format = event->format; 80 uint16_t word; 81 uint32_t longword; 82 uint8_t * ptr; 83 uint16_t length_j = 0xffff; 84 while (*format) { 85 switch(*format) { 86 case '1': // 8 bit value 87 case '2': // 16 bit value 88 case 'H': // hci_handle 89 word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs 90 hci_event_buffer[pos++] = word & 0xff; 91 if (*format != '1') { 92 hci_event_buffer[pos++] = word >> 8; 93 } 94 break; 95 case '3': 96 case '4': 97 longword = va_arg(argptr, uint32_t); 98 // longword = va_arg(argptr, int); 99 hci_event_buffer[pos++] = longword; 100 hci_event_buffer[pos++] = longword >> 8; 101 hci_event_buffer[pos++] = longword >> 16; 102 if (*format == '4'){ 103 hci_event_buffer[pos++] = longword >> 24; 104 } 105 break; 106 case 'B': // bt-addr 107 ptr = va_arg(argptr, uint8_t *); 108 hci_event_buffer[pos++] = ptr[5]; 109 hci_event_buffer[pos++] = ptr[4]; 110 hci_event_buffer[pos++] = ptr[3]; 111 hci_event_buffer[pos++] = ptr[2]; 112 hci_event_buffer[pos++] = ptr[1]; 113 hci_event_buffer[pos++] = ptr[0]; 114 break; 115 case 'D': // 8 byte data block 116 ptr = va_arg(argptr, uint8_t *); 117 (void)memcpy(&hci_event_buffer[pos], ptr, 8); 118 pos += 8; 119 break; 120 case 'P': // 16 byte block 121 ptr = va_arg(argptr, uint8_t *); 122 (void)memcpy(&hci_event_buffer[pos], ptr, 16); 123 pos += 16; 124 break; 125 case 'Q': 126 ptr = va_arg(argptr, uint8_t *); 127 reverse_bytes(ptr, &hci_event_buffer[pos], 32); 128 pos += 32; 129 break; 130 case 'J': 131 word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs 132 length_j = word & 0xff; 133 hci_event_buffer[pos++] = length_j; 134 break; 135 case 'K': 136 word = va_arg(argptr, int); // minimal va_arg is int: 2 bytes on 8+16 bit CPUs 137 length_j = word & 0xff; 138 break; 139 case 'V': 140 btstack_assert(length_j < 0x100); 141 ptr = va_arg(argptr, uint8_t *); 142 (void)memcpy(&hci_event_buffer[pos], ptr, length_j); 143 pos += length_j; 144 break; 145 default: 146 btstack_assert(false); 147 break; 148 } 149 format++; 150 }; 151 hci_event_buffer[1] = pos - 2; 152 return pos; 153 } 154 155 uint16_t hci_event_create_from_template_and_arguments(uint8_t *hci_buffer, uint16_t buffer_size, const hci_event_t *event, ...){ 156 va_list argptr; 157 va_start(argptr, event); 158 uint16_t length = hci_event_create_from_template_and_arglist(hci_buffer, buffer_size, event, argptr); 159 va_end(argptr); 160 return length; 161 } 162 163 /* HCI Events */ 164 165 const hci_event_t hci_event_hardware_error = { 166 HCI_EVENT_HARDWARE_ERROR, 0, "1" 167 }; 168 169 const hci_event_t hci_event_transport_packet_sent = { 170 HCI_EVENT_TRANSPORT_PACKET_SENT, 0, "" 171 }; 172 173 const hci_event_t hci_event_command_complete = { 174 HCI_EVENT_COMMAND_COMPLETE, 0, "121KV" 175 }; 176 177 const hci_event_t hci_event_disconnection_complete = { 178 HCI_EVENT_DISCONNECTION_COMPLETE, 0, "1H1" 179 }; 180 181 const hci_event_t hci_event_number_of_completed_packets_1 = { 182 HCI_EVENT_NUMBER_OF_COMPLETED_PACKETS, 0, "1H2" 183 }; 184 185 /* LE Subevents */ 186 187 const hci_event_t hci_subevent_le_connection_complete = { 188 HCI_EVENT_LE_META, HCI_SUBEVENT_LE_CONNECTION_COMPLETE, "1H11B2221" 189 }; 190