Skip to content

Commit bae9a64

Browse files
committed
Add NimBLE HCI driver and transport layers with overrides
This adds the transport and HCI driver layers and the necessary override functions to allow the NimBLE host to communicate with the controller when bluedroid was enabled in Arduino.
1 parent 4c77b34 commit bae9a64

File tree

5 files changed

+274
-4
lines changed

5 files changed

+274
-4
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifdef ESP_PLATFORM
8+
#include "syscfg/syscfg.h"
9+
#if CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT
10+
11+
#include <string.h>
12+
#include <stdio.h>
13+
#include "esp_hci_internal.h"
14+
#include "esp_hci_driver.h"
15+
16+
typedef struct {
17+
hci_driver_forward_fn *forward_cb;
18+
} hci_driver_vhci_env_t;
19+
20+
static hci_driver_vhci_env_t s_hci_driver_vhci_env;
21+
22+
static int
23+
hci_driver_vhci_controller_tx(hci_driver_data_type_t data_type, uint8_t *data)
24+
{
25+
/* The length is contained in the data. */
26+
return s_hci_driver_vhci_env.forward_cb(data_type, data, 0, HCI_DRIVER_DIR_C2H);
27+
}
28+
29+
static int
30+
hci_driver_vhci_host_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length)
31+
{
32+
return s_hci_driver_vhci_env.forward_cb(data_type, data, length, HCI_DRIVER_DIR_H2C);
33+
}
34+
35+
static int
36+
hci_driver_vhci_tx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
37+
hci_driver_direction_t dir)
38+
{
39+
int rc;
40+
41+
if (dir == HCI_DRIVER_DIR_C2H) {
42+
rc = hci_driver_vhci_controller_tx(data_type, data);
43+
} else {
44+
rc = hci_driver_vhci_host_tx(data_type, data, length);
45+
}
46+
return rc;
47+
}
48+
49+
static int
50+
hci_driver_vhci_init(hci_driver_forward_fn *cb)
51+
{
52+
s_hci_driver_vhci_env.forward_cb = cb;
53+
return 0;
54+
}
55+
56+
static void
57+
hci_driver_vhci_deinit(void)
58+
{
59+
memset(&s_hci_driver_vhci_env, 0, sizeof(hci_driver_vhci_env_t));
60+
}
61+
62+
hci_driver_ops_t hci_driver_vhci_ops = {
63+
.hci_driver_tx = hci_driver_vhci_tx,
64+
.hci_driver_init = hci_driver_vhci_init,
65+
.hci_driver_deinit = hci_driver_vhci_deinit,
66+
};
67+
68+
#endif
69+
#endif
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifdef ESP_PLATFORM
8+
#include "syscfg/syscfg.h"
9+
#if CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT
10+
11+
#include <stdio.h>
12+
#include <string.h>
13+
#include "esp_log.h"
14+
#include "nimble/esp_port/port/transport/include/esp_hci_transport.h"
15+
#include "esp_hci_internal.h"
16+
#include "esp_bt.h"
17+
18+
typedef struct hci_transport_env
19+
{
20+
hci_transport_host_recv_fn *host_recv_cb;
21+
hci_driver_ops_t *driver_ops;
22+
} hci_transport_env_t;
23+
24+
static hci_transport_env_t s_hci_transport_env;
25+
26+
/* Functions for packets Rx. */
27+
static int
28+
hci_transport_controller_packet_rx(hci_driver_data_type_t data_type, uint8_t *data)
29+
{
30+
if (data_type == HCI_DRIVER_TYPE_CMD) {
31+
r_ble_hci_trans_hs_cmd_tx(data);
32+
}
33+
34+
if (data_type == HCI_DRIVER_TYPE_ACL) {
35+
r_ble_hci_trans_hs_acl_tx((struct os_mbuf *) data);
36+
}
37+
return 0;
38+
}
39+
40+
static int
41+
hci_transport_host_packet_rx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length)
42+
{
43+
if (!s_hci_transport_env.host_recv_cb) {
44+
return -1;
45+
}
46+
return s_hci_transport_env.host_recv_cb((hci_trans_pkt_ind_t)data_type, data, length);
47+
}
48+
49+
static int
50+
hci_transport_packet_rx(hci_driver_data_type_t data_type, uint8_t *data, uint32_t length,
51+
hci_driver_direction_t dir)
52+
{
53+
int rc;
54+
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
55+
return -1;
56+
}
57+
58+
if (dir == HCI_DRIVER_DIR_C2H) {
59+
rc = hci_transport_host_packet_rx(data_type, data, length);
60+
} else {
61+
rc = hci_transport_controller_packet_rx(data_type, data);
62+
}
63+
64+
return rc;
65+
}
66+
67+
/* Functions for controller Tx. */
68+
static int
69+
hci_transport_controller_tx_dummy(void *data, void *arg)
70+
{
71+
return -1;
72+
}
73+
74+
static int
75+
hci_transport_controller_evt_tx(uint8_t *hci_ev, void *arg)
76+
{
77+
uint32_t len;
78+
79+
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
80+
r_ble_hci_trans_buf_free(hci_ev);
81+
return -1;
82+
}
83+
84+
len = hci_ev[1] + 2;
85+
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_EVT, hci_ev, len,
86+
HCI_DRIVER_DIR_C2H);
87+
}
88+
89+
static int
90+
hci_transport_controller_acl_tx(struct os_mbuf *om, void *arg)
91+
{
92+
uint16_t len;
93+
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
94+
os_mbuf_free_chain(om);
95+
return -1;
96+
}
97+
98+
len = OS_MBUF_PKTHDR(om)->omp_len;
99+
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_ACL, (uint8_t *)om, len,
100+
HCI_DRIVER_DIR_C2H);
101+
}
102+
103+
/* Functions for host Tx. */
104+
int
105+
na_hci_transport_host_cmd_tx(uint8_t *data, uint32_t length)
106+
{
107+
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_CMD, data, length,
108+
HCI_DRIVER_DIR_H2C);
109+
}
110+
111+
int
112+
na_hci_transport_host_acl_tx(uint8_t *data, uint32_t length)
113+
{
114+
return s_hci_transport_env.driver_ops->hci_driver_tx(HCI_DRIVER_TYPE_ACL, data, length,
115+
HCI_DRIVER_DIR_H2C);
116+
}
117+
118+
int
119+
na_hci_transport_host_callback_register(hci_transport_host_recv_fn *callback)
120+
{
121+
s_hci_transport_env.host_recv_cb = callback;
122+
return 0;
123+
}
124+
125+
int
126+
na_hci_transport_init(uint8_t hci_transport_mode)
127+
{
128+
int rc;
129+
hci_driver_ops_t *ops;
130+
131+
memset(&s_hci_transport_env, 0, sizeof(hci_transport_env_t));
132+
133+
switch(hci_transport_mode) {
134+
#if CONFIG_BT_LE_HCI_INTERFACE_USE_RAM
135+
case HCI_TRANSPORT_VHCI:
136+
ops = &hci_driver_vhci_ops;
137+
break;
138+
#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_RAM
139+
#if CONFIG_BT_LE_HCI_INTERFACE_USE_UART
140+
#if CONFIG_BT_LE_UART_HCI_DMA_MODE
141+
case HCI_TRANSPORT_UART_UHCI:
142+
ops = &hci_driver_uart_dma_ops;
143+
break;
144+
#else
145+
case HCI_TRANSPORT_UART_NO_DMA:
146+
ops = &hci_driver_uart_ops;
147+
break;
148+
#endif // CONFIG_BT_LE_UART_HCI_DMA_MODE
149+
#endif // CONFIG_BT_LE_HCI_INTERFACE_USE_UART
150+
default:
151+
assert(0);
152+
}
153+
154+
rc = ops->hci_driver_init(hci_transport_packet_rx);
155+
if (rc) {
156+
goto error;
157+
}
158+
159+
s_hci_transport_env.driver_ops = ops;
160+
r_ble_hci_trans_cfg_hs(hci_transport_controller_evt_tx, NULL, hci_transport_controller_acl_tx, NULL);
161+
162+
return 0;
163+
164+
error:
165+
na_hci_transport_deinit();
166+
return rc;
167+
}
168+
169+
void
170+
na_hci_transport_deinit(void)
171+
{
172+
hci_driver_ops_t *ops;
173+
174+
r_ble_hci_trans_cfg_hs((esp_hci_internal_rx_cmd_fn *)hci_transport_controller_tx_dummy, NULL,
175+
(esp_hci_internal_rx_acl_fn *)hci_transport_controller_tx_dummy, NULL);
176+
177+
ops = s_hci_transport_env.driver_ops;
178+
if (ops) {
179+
ops->hci_driver_deinit();
180+
}
181+
memset(&s_hci_transport_env, 0, sizeof(hci_transport_env_t));
182+
}
183+
184+
#endif
185+
#endif

src/nimble/esp_port/port/transport/include/esp_hci_transport.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,22 @@ typedef int hci_transport_host_recv_fn(hci_trans_pkt_ind_t type, uint8_t *data,
4848
* @return int Returns 0 on success, or a non-zero error code on failure.
4949
*/
5050
int hci_transport_init(uint8_t hci_transport_mode);
51+
int na_hci_transport_init(uint8_t hci_transport_mode);
52+
5153

5254
/**
5355
* @brief Deinitialize the HCI transport layer for releasing any allocated resources.
5456
*/
5557
void hci_transport_deinit(void);
58+
void na_hci_transport_deinit(void);
5659

5760
/**
5861
* @brief Set the host's HCI callback which will be invoked when receiving ACL/Events from controller.
5962
* @param callback hci_transport_host_recv_fn type variable
6063
* @return int 0 on success, non-zero error code on failure.
6164
*/
6265
int hci_transport_host_callback_register(hci_transport_host_recv_fn *callback);
66+
int na_hci_transport_host_callback_register(hci_transport_host_recv_fn *callback);
6367

6468
/**
6569
* @brief Called to send HCI commands form host to controller.
@@ -68,6 +72,7 @@ int hci_transport_host_callback_register(hci_transport_host_recv_fn *callback);
6872
* @return int 0 on success, non-zero error code on failure.
6973
*/
7074
int hci_transport_host_cmd_tx(uint8_t *data, uint32_t length);
75+
int na_hci_transport_host_cmd_tx(uint8_t *data, uint32_t length);
7176

7277
/**
7378
* @brief Called to send HCI ACL form host to controller.
@@ -76,6 +81,7 @@ int hci_transport_host_cmd_tx(uint8_t *data, uint32_t length);
7681
* @return int 0 on success, non-zero error code on failure.
7782
*/
7883
int hci_transport_host_acl_tx(uint8_t *data, uint32_t length);
84+
int na_hci_transport_host_acl_tx(uint8_t *data, uint32_t length);
7985

8086
#ifdef __cplusplus
8187
}

src/nimble/nimble/transport/esp_ipc/src/hci_esp_ipc.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,25 +41,25 @@ ble_transport_host_recv_cb(hci_trans_pkt_ind_t type, uint8_t *data, uint16_t len
4141
int
4242
ble_transport_to_ll_cmd_impl(void *buf)
4343
{
44-
return hci_transport_host_cmd_tx(buf, 0);
44+
return na_hci_transport_host_cmd_tx(buf, 0);
4545
}
4646

4747
int
4848
ble_transport_to_ll_acl_impl(struct os_mbuf *om)
4949
{
50-
return hci_transport_host_acl_tx((uint8_t *)om, 0);
50+
return na_hci_transport_host_acl_tx((uint8_t *)om, 0);
5151
}
5252

5353
void
5454
ble_transport_ll_init(void)
5555
{
56-
hci_transport_host_callback_register(ble_transport_host_recv_cb);
56+
na_hci_transport_host_callback_register(ble_transport_host_recv_cb);
5757
}
5858

5959
void
6060
ble_transport_ll_deinit(void)
6161
{
62-
hci_transport_host_callback_register(ble_transport_dummy_host_recv_cb);
62+
na_hci_transport_host_callback_register(ble_transport_dummy_host_recv_cb);
6363
}
6464

6565
void *

src/nimble/porting/nimble/src/nimble_port.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
#if !CONFIG_BT_CONTROLLER_ENABLED
4343
#include "nimble/nimble/transport/include/nimble/transport.h"
4444
#endif
45+
#if CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT
46+
#include "nimble/esp_port/port/transport/include/esp_hci_transport.h"
47+
#endif
4548
// #if (BT_HCI_LOG_INCLUDED == TRUE)
4649
// #include "hci_log/bt_hci_log.h"
4750
// #endif // (BT_HCI_LOG_INCLUDED == TRUE)
@@ -120,6 +123,9 @@ esp_err_t esp_nimble_init(void)
120123
os_mempool_module_init();
121124
os_msys_init();
122125

126+
#elif CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT
127+
hci_transport_deinit();
128+
na_hci_transport_init(HCI_TRANSPORT_VHCI);
123129
#endif
124130

125131
ble_transport_ll_init();
@@ -253,6 +259,10 @@ nimble_port_deinit(void)
253259
}
254260
#endif
255261

262+
#if CONFIG_BT_LE_CONTROLLER_NPL_OS_PORTING_SUPPORT
263+
na_hci_transport_deinit();
264+
#endif
265+
256266
#if (BT_HCI_LOG_INCLUDED == TRUE)
257267
//bt_hci_log_deinit();
258268
#endif // (BT_HCI_LOG_INCLUDED == TRUE)

0 commit comments

Comments
 (0)