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