xref: /btstack/src/hci_event.c (revision 6897da5c53aac5b1f90f41b5b15d0bd43d61dfff)
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