1 /*
2 * Copyright (C) 2023 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__ "main.c"
39
40 #include "sdkconfig.h"
41
42 #if CONFIG_BT_ENABLED
43
44 #include <stdint.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48
49 #include "btstack_config.h"
50 #include "btstack_event.h"
51 #include "btstack_memory.h"
52 #include "btstack_run_loop.h"
53 #include "btstack_run_loop_freertos.h"
54 #include "btstack_ring_buffer.h"
55 #include "btstack_tlv.h"
56 #include "btstack_tlv_esp32.h"
57 #include "ble/le_device_db_tlv.h"
58 #include "classic/btstack_link_key_db.h"
59 #include "classic/btstack_link_key_db_tlv.h"
60 #include "hci.h"
61 #include "hci_dump.h"
62 #include "esp_bt.h"
63 #include "btstack_debug.h"
64 #include "btstack_audio.h"
65 #include "btstack_port_esp32.h"
66
67 #include "freertos/FreeRTOS.h"
68 #include "freertos/task.h"
69 #include "freertos/semphr.h"
70
71 uint32_t esp_log_timestamp();
72
hal_time_ms(void)73 uint32_t hal_time_ms(void) {
74 // super hacky way to get ms
75 return esp_log_timestamp();
76 }
77
78 #ifdef CONFIG_BT_ENABLED
79
80 // ESP32 and next generation ESP32-C3 + ESP32-S3 provide an asynchronous VHCI interface with
81 // a callback when the packet was accepted by the Controller.
82 // Newer Controller only rely on the regular Host to Controller Flow Control and can be
83 // considered synchronous
84
85 #if defined(CONFIG_IDF_TARGET_ESP32) || defined (CONFIG_IDF_TARGET_ESP32C3) || defined (CONFIG_IDF_TARGET_ESP32S3)
86 #define ENABLE_ESP32_VHCI_ASYNCHRONOUS
87 #endif
88
89 // assert pre-buffer for packet type is available
90 #if !defined(HCI_OUTGOING_PRE_BUFFER_SIZE) || (HCI_OUTGOING_PRE_BUFFER_SIZE < 1)
91 #error HCI_OUTGOING_PRE_BUFFER_SIZE not defined or smaller than 1. Please update hci.h
92 #endif
93
94 static void (*transport_packet_handler)(uint8_t packet_type, uint8_t *packet, uint16_t size);
95
96 // ring buffer for incoming HCI packets. Each packet has 2 byte len tag + H4 packet type + packet itself
97 #define MAX_NR_HOST_EVENT_PACKETS 4
98 static uint8_t hci_ringbuffer_storage[HCI_HOST_ACL_PACKET_NUM * (2 + 1 + HCI_ACL_HEADER_SIZE + HCI_HOST_ACL_PACKET_LEN) +
99 HCI_HOST_SCO_PACKET_NUM * (2 + 1 + HCI_SCO_HEADER_SIZE + HCI_HOST_SCO_PACKET_LEN) +
100 MAX_NR_HOST_EVENT_PACKETS * (2 + 1 + HCI_EVENT_BUFFER_SIZE)];
101
102 static btstack_ring_buffer_t hci_ringbuffer;
103
104 // incoming packet buffer
105 static uint8_t hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE + HCI_INCOMING_PACKET_BUFFER_SIZE]; // packet type + max(acl header + acl payload, event header + event data)
106 static uint8_t * hci_receive_buffer = &hci_packet_with_pre_buffer[HCI_INCOMING_PRE_BUFFER_SIZE];
107
108 static SemaphoreHandle_t ring_buffer_mutex;
109
110 static void transport_notify_packet_send(void *context);
111 static btstack_context_callback_registration_t packet_send_callback_context = {
112 .callback = transport_notify_packet_send,
113 .context = NULL,
114 };
115
116 static void transport_deliver_packets(void *context);
117 static btstack_context_callback_registration_t packet_receive_callback_context = {
118 .callback = transport_deliver_packets,
119 .context = NULL,
120 };
121
122 // never supposed to happen, just panic if it does happen anyway
panic_recv_called_from_isr(void)123 static void panic_recv_called_from_isr(void) {
124 btstack_assert(0);
125 printf("host_recv_pkt_cb called from ISR!\n");
126 }
127
panic_sent_called_from_isr(void)128 static void panic_sent_called_from_isr(void) {
129 btstack_assert(0);
130 printf("host_send_pkt_available_cb called from ISR!\n");
131 }
132
133 // VHCI callbacks, run from VHCI Task "BT Controller"
134
host_send_pkt_available_cb(void)135 static void host_send_pkt_available_cb(void){
136
137 if (xPortInIsrContext()) {
138 panic_sent_called_from_isr();
139 return;
140 }
141
142 btstack_run_loop_execute_on_main_thread(&packet_send_callback_context);
143 }
144
host_recv_pkt_cb(uint8_t * data,uint16_t len)145 static int host_recv_pkt_cb(uint8_t *data, uint16_t len){
146
147 if (xPortInIsrContext()){
148 panic_recv_called_from_isr();
149 return 0;
150 }
151
152 xSemaphoreTake(ring_buffer_mutex, portMAX_DELAY);
153
154 // check space
155 uint16_t space = btstack_ring_buffer_bytes_free(&hci_ringbuffer);
156 if (space < len){
157 xSemaphoreGive(ring_buffer_mutex);
158 log_error("transport_recv_pkt_cb packet %u, space %u -> dropping packet", len, space);
159 return 0;
160 }
161
162 // store size in ringbuffer
163 uint8_t len_tag[2];
164 little_endian_store_16(len_tag, 0, len);
165 btstack_ring_buffer_write(&hci_ringbuffer, len_tag, sizeof(len_tag));
166
167 // store in ringbuffer
168 btstack_ring_buffer_write(&hci_ringbuffer, data, len);
169
170 xSemaphoreGive(ring_buffer_mutex);
171
172 btstack_run_loop_execute_on_main_thread(&packet_receive_callback_context);
173 return 0;
174 }
175
176 static const esp_vhci_host_callback_t vhci_host_cb = {
177 .notify_host_send_available = host_send_pkt_available_cb,
178 .notify_host_recv = host_recv_pkt_cb,
179 };
180
181 // run from main thread
182
transport_notify_packet_send(void * context)183 static void transport_notify_packet_send(void *context){
184 UNUSED(context);
185 // notify upper stack that it might be possible to send again
186 uint8_t event[] = { HCI_EVENT_TRANSPORT_PACKET_SENT, 0};
187 transport_packet_handler(HCI_EVENT_PACKET, &event[0], sizeof(event));
188 }
189
transport_deliver_packets(void * context)190 static void transport_deliver_packets(void *context){
191 UNUSED(context);
192 xSemaphoreTake(ring_buffer_mutex, portMAX_DELAY);
193 while (btstack_ring_buffer_bytes_available(&hci_ringbuffer)){
194 uint32_t number_read;
195 uint8_t len_tag[2];
196 btstack_ring_buffer_read(&hci_ringbuffer, len_tag, 2, &number_read);
197 uint32_t len = little_endian_read_16(len_tag, 0);
198 btstack_ring_buffer_read(&hci_ringbuffer, hci_receive_buffer, len, &number_read);
199 xSemaphoreGive(ring_buffer_mutex);
200 transport_packet_handler(hci_receive_buffer[0], &hci_receive_buffer[1], len-1);
201 xSemaphoreTake(ring_buffer_mutex, portMAX_DELAY);
202 }
203 xSemaphoreGive(ring_buffer_mutex);
204 }
205
206
207 /**
208 * init transport
209 * @param transport_config
210 */
transport_init(const void * transport_config)211 static void transport_init(const void *transport_config){
212 log_info("transport_init");
213 ring_buffer_mutex = xSemaphoreCreateMutex();
214 }
215
216 /**
217 * open transport connection
218 */
219 static int bt_controller_initialized;
transport_open(void)220 static int transport_open(void){
221 esp_err_t ret;
222
223 #ifdef ENABLE_ESP32_VHCI_ASYNCHRONOUS
224 log_info("transport_open: using asynchronous VHCI");
225 #else
226 log_info("transport_open: using synchronous VHCI");
227 #endif
228
229 btstack_ring_buffer_init(&hci_ringbuffer, hci_ringbuffer_storage, sizeof(hci_ringbuffer_storage));
230
231 // http://esp-idf.readthedocs.io/en/latest/api-reference/bluetooth/controller_vhci.html (2017104)
232 // - "esp_bt_controller_init: ... This function should be called only once, before any other BT functions are called."
233 // - "esp_bt_controller_deinit" .. This function should be called only once, after any other BT functions are called.
234 // This function is not whole completed, esp_bt_controller_init cannot called after this function."
235 // -> esp_bt_controller_init can only be called once after boot
236 if (!bt_controller_initialized){
237 bt_controller_initialized = 1;
238
239
240 #if CONFIG_IDF_TARGET_ESP32
241 #ifndef ENABLE_CLASSIC
242 // LE-only on ESP32 - release memory used for classic mode
243 ret = esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
244 if (ret) {
245 log_error("Bluetooth controller release classic bt memory failed: %s", esp_err_to_name(ret));
246 return -1;
247 }
248 #endif
249 #endif
250
251 esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
252 ret = esp_bt_controller_init(&bt_cfg);
253 if (ret) {
254 log_error("transport: esp_bt_controller_init failed");
255 return -1;
256 }
257
258 }
259
260 // Enable LE mode by default
261 esp_bt_mode_t bt_mode = ESP_BT_MODE_BLE;
262 #if CONFIG_IDF_TARGET_ESP32
263 #if CONFIG_BTDM_CTRL_MODE_BTDM
264 bt_mode = ESP_BT_MODE_BTDM;
265 #elif CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY
266 bt_mode = ESP_BT_MODE_CLASSIC_BT;
267 #endif
268 #endif
269
270 ret = esp_bt_controller_enable(bt_mode);
271 if (ret) {
272 log_error("transport: esp_bt_controller_enable failed");
273 return -1;
274 }
275
276 esp_vhci_host_register_callback(&vhci_host_cb);
277
278 return 0;
279 }
280
281 /**
282 * close transport connection
283 */
transport_close(void)284 static int transport_close(void){
285 log_info("transport_close");
286
287 // disable controller
288 esp_bt_controller_disable();
289 return 0;
290 }
291
292 /**
293 * register packet handler for HCI packets: ACL, SCO, and Events
294 */
transport_register_packet_handler(void (* handler)(uint8_t packet_type,uint8_t * packet,uint16_t size))295 static void transport_register_packet_handler(void (*handler)(uint8_t packet_type, uint8_t *packet, uint16_t size)){
296 log_info("transport_register_packet_handler");
297 transport_packet_handler = handler;
298 }
299
300 #ifdef ENABLE_ESP32_VHCI_ASYNCHRONOUS
transport_can_send_packet_now(uint8_t packet_type)301 static int transport_can_send_packet_now(uint8_t packet_type) {
302 return esp_vhci_host_check_send_available();
303 }
304 #endif
305
transport_send_packet(uint8_t packet_type,uint8_t * packet,int size)306 static int transport_send_packet(uint8_t packet_type, uint8_t *packet, int size){
307 // store packet type before actual data and increase size
308 size++;
309 packet--;
310 *packet = packet_type;
311
312 // send packet
313 esp_vhci_host_send_packet(packet, size);
314 return 0;
315 }
316
317 static const hci_transport_t transport = {
318 .name = "esp32-vhci",
319 .init = &transport_init,
320 .open = &transport_open,
321 .close = &transport_close,
322 .register_packet_handler = &transport_register_packet_handler,
323 #ifdef ENABLE_ESP32_VHCI_ASYNCHRONOUS
324 // asynchronous
325 .can_send_packet_now = &transport_can_send_packet_now,
326 #else
327 // synchronous <=> can_send_packet_now == NULL
328 #endif
329 .send_packet = &transport_send_packet,
330 };
331
332 #else
333
334 // this port requires the ESP32 Bluetooth to be enabled in the sdkconfig
335 // try to tell the user
336
337 #include "esp_log.h"
transport_init(const void * transport_config)338 static void transport_init(const void *transport_config){
339 while (1){
340 ESP_LOGE("BTstack", "ESP32 Transport Init called, but Bluetooth support not enabled in sdkconfig.");
341 ESP_LOGE("BTstack", "Please enable CONFIG_BT_ENABLED with 'make menuconfig and compile again.");
342 ESP_LOGE("BTstack", "");
343 }
344 }
345
346 static const hci_transport_t transport = {
347 .name = "none",
348 .init = &transport_init,
349 };
350 #endif
351
352
transport_get_instance(void)353 static const hci_transport_t * transport_get_instance(void){
354 return &transport;
355 }
356
357 static btstack_packet_callback_registration_t hci_event_callback_registration;
358
packet_handler(uint8_t packet_type,uint16_t channel,uint8_t * packet,uint16_t size)359 static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size){
360 if (packet_type != HCI_EVENT_PACKET) return;
361 switch(hci_event_packet_get_type(packet)){
362 case BTSTACK_EVENT_STATE:
363 if (btstack_event_state_get_state(packet) == HCI_STATE_WORKING) {
364 #ifdef ENABLE_SCO_OVER_HCI
365 esp_err_t ret = esp_bredr_sco_datapath_set(ESP_SCO_DATA_PATH_HCI);
366 log_info("transport: configure SCO over HCI, result 0x%04x", ret);
367 #endif
368 bd_addr_t addr;
369 gap_local_bd_addr(addr);
370 printf("BTstack up and running at %s\n", bd_addr_to_str(addr));
371 }
372 break;
373 case HCI_EVENT_COMMAND_COMPLETE:
374 if (hci_event_command_complete_get_command_opcode(packet) == HCI_OPCODE_HCI_READ_LOCAL_VERSION_INFORMATION){
375 // @TODO
376 }
377 break;
378 default:
379 break;
380 }
381 }
382
btstack_init(void)383 uint8_t btstack_init(void){
384 // Setup memory pools and run loop
385 btstack_memory_init();
386 btstack_run_loop_init(btstack_run_loop_freertos_get_instance());
387
388 // init HCI
389 hci_init(transport_get_instance(), NULL);
390
391 // setup TLV ESP32 implementation and register with system
392 const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_esp32_get_instance();
393 btstack_tlv_set_instance(btstack_tlv_impl, NULL);
394
395 #ifdef ENABLE_CLASSIC
396 // setup Link Key DB using TLV
397 const btstack_link_key_db_t * btstack_link_key_db = btstack_link_key_db_tlv_get_instance(btstack_tlv_impl, NULL);
398 hci_set_link_key_db(btstack_link_key_db);
399 #endif
400
401 #ifdef ENABLE_BLE
402 // setup LE Device DB using TLV
403 le_device_db_tlv_configure(btstack_tlv_impl, NULL);
404 #endif
405
406 // inform about BTstack state
407 hci_event_callback_registration.callback = &packet_handler;
408 hci_add_event_handler(&hci_event_callback_registration);
409
410 #if CONFIG_BTSTACK_AUDIO
411 // setup i2s audio for sink and source
412 btstack_audio_sink_set_instance(btstack_audio_esp32_sink_get_instance());
413 btstack_audio_source_set_instance(btstack_audio_esp32_source_get_instance());
414 #endif
415
416 return ERROR_CODE_SUCCESS;
417 }
418
419 #endif
420