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