1 /* 2 * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef H_HCI_TRANSPORT_ 8 #define H_HCI_TRANSPORT_ 9 10 #ifdef __cplusplus 11 extern "C" { 12 #endif 13 14 #include <inttypes.h> 15 #include "os/os_mempool.h" 16 17 #define BLE_HCI_TRANS_CMD_SZ 260 18 /*** Type of buffers for holding commands and events. */ 19 /** 20 * Controller-to-host event buffers. Events have one of two priorities: 21 * o Low-priority (BLE_HCI_TRANS_BUF_EVT_LO) 22 * o High-priority (BLE_HCI_TRANS_BUF_EVT_HI) 23 * 24 * Low-priority event buffers are only used for advertising reports. If there 25 * are no free low-priority event buffers, then an incoming advertising report 26 * will get dropped. 27 * 28 * High-priority event buffers are for everything except advertising reports. 29 * If there are no free high-priority event buffers, a request to allocate one 30 * will try to allocate a low-priority buffer instead. 31 * 32 * If you want all events to be given equal treatment, then you should allocate 33 * low-priority events only. 34 * 35 * Event priorities solve the problem of critical events getting dropped due to 36 * a flood of advertising reports. This solution is likely temporary: when 37 * HCI flow control is added, event priorities may become obsolete. 38 * 39 * Not all transports distinguish between low and high priority events. If the 40 * transport does not have separate settings for low and high buffer counts, 41 * then it treats all events with equal priority. 42 */ 43 #define BLE_HCI_TRANS_BUF_EVT_LO 1 44 #define BLE_HCI_TRANS_BUF_EVT_HI 2 45 46 /* Host-to-controller command. */ 47 #define BLE_HCI_TRANS_BUF_CMD 3 48 49 /** Callback function types; executed when HCI packets are received. */ 50 typedef int ble_hci_trans_rx_cmd_fn(uint8_t *cmd, void *arg); 51 typedef int ble_hci_trans_rx_acl_fn(struct os_mbuf *om, void *arg); 52 53 #if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED 54 #define ble_transport_alloc_cmd() ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD) 55 #define ble_transport_alloc_event(X) ble_hci_trans_buf_alloc(X ? BLE_HCI_TRANS_BUF_EVT_LO : BLE_HCI_TRANS_BUF_EVT_HI) 56 #define ble_transport_free ble_hci_trans_buf_free 57 58 struct ble_hci_trans_funcs_t { 59 int(*_ble_hci_trans_hs_acl_tx)(struct os_mbuf *om); 60 int(*_ble_hci_trans_hs_cmd_tx)(uint8_t *cmd); 61 int(*_ble_hci_trans_ll_acl_tx)(struct os_mbuf *om); 62 int(*_ble_hci_trans_ll_evt_tx)(uint8_t *hci_ev); 63 int(*_ble_hci_trans_reset)(void); 64 int(*_ble_hci_trans_set_acl_free_cb)(os_mempool_put_fn *cb, void *arg); 65 }; 66 67 extern struct ble_hci_trans_funcs_t *ble_hci_trans_funcs_ptr; 68 69 /** 70 * Sends an HCI event from the controller to the host. 71 * 72 * @param cmd The HCI event to send. This buffer must be 73 * allocated via ble_hci_trans_buf_alloc(). 74 * 75 * @return 0 on success; 76 * A BLE_ERR_[...] error code on failure. 77 */ 78 extern int r_ble_hci_trans_ll_evt_tx(uint8_t *hci_ev); 79 #define ble_hci_trans_ll_evt_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_ll_evt_tx 80 81 /** 82 * Sends ACL data from controller to host. 83 * 84 * @param om The ACL data packet to send. 85 * 86 * @return 0 on success; 87 * A BLE_ERR_[...] error code on failure. 88 */ 89 extern int r_ble_hci_trans_ll_acl_tx(struct os_mbuf *om); 90 #define ble_hci_trans_ll_acl_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_ll_acl_tx 91 92 /** 93 * Sends an HCI command from the host to the controller. 94 * 95 * @param cmd The HCI command to send. This buffer must be 96 * allocated via ble_hci_trans_buf_alloc(). 97 * 98 * @return 0 on success; 99 * A BLE_ERR_[...] error code on failure. 100 */ 101 extern int r_ble_hci_trans_hs_cmd_tx(uint8_t *cmd); 102 #define ble_hci_trans_hs_cmd_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_hs_cmd_tx 103 104 /** 105 * Sends ACL data from host to controller. 106 * 107 * @param om The ACL data packet to send. 108 * 109 * @return 0 on success; 110 * A BLE_ERR_[...] error code on failure. 111 */ 112 extern int r_ble_hci_trans_hs_acl_tx(struct os_mbuf *om); 113 #define ble_hci_trans_hs_acl_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_hs_acl_tx 114 115 /** 116 * Allocates a flat buffer of the specified type. 117 * 118 * @param type The type of buffer to allocate; one of the 119 * BLE_HCI_TRANS_BUF_[...] constants. 120 * 121 * @return The allocated buffer on success; 122 * NULL on buffer exhaustion. 123 */ 124 extern uint8_t *r_ble_hci_trans_buf_alloc(int type); 125 #define ble_hci_trans_buf_alloc r_ble_hci_trans_buf_alloc 126 127 /** 128 * Frees the specified flat buffer. The buffer must have been allocated via 129 * ble_hci_trans_buf_alloc(). 130 * 131 * @param buf The buffer to free. 132 */ 133 extern void r_ble_hci_trans_buf_free(uint8_t *buf); 134 #define ble_hci_trans_buf_free r_ble_hci_trans_buf_free 135 136 /** 137 * Configures a callback to get executed whenever an ACL data packet is freed. 138 * The function is called immediately before the free occurs. 139 * 140 * @param cb The callback to configure. 141 * @param arg An optional argument to pass to the callback. 142 * 143 * @return 0 on success; 144 * BLE_ERR_UNSUPPORTED if the transport does not 145 * support this operation. 146 */ 147 extern int r_ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg); 148 #define ble_hci_trans_set_acl_free_cb ble_hci_trans_funcs_ptr->_ble_hci_trans_set_acl_free_cb 149 150 /** 151 * Configures the HCI transport to operate with a controller. The transport 152 * will execute specified callbacks upon receiving HCI packets from the host. 153 * 154 * @param cmd_cb The callback to execute upon receiving an HCI 155 * command. 156 * @param cmd_arg Optional argument to pass to the command 157 * callback. 158 * @param acl_cb The callback to execute upon receiving ACL 159 * data. 160 * @param acl_arg Optional argument to pass to the ACL 161 * callback. 162 */ 163 extern void r_ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, 164 void *cmd_arg, 165 ble_hci_trans_rx_acl_fn *acl_cb, 166 void *acl_arg); 167 #define ble_hci_trans_cfg_ll r_ble_hci_trans_cfg_ll 168 169 /** 170 * Configures the HCI transport to operate with a host. The transport will 171 * execute specified callbacks upon receiving HCI packets from the controller. 172 * 173 * @param evt_cb The callback to execute upon receiving an HCI 174 * event. 175 * @param evt_arg Optional argument to pass to the event 176 * callback. 177 * @param acl_cb The callback to execute upon receiving ACL 178 * data. 179 * @param acl_arg Optional argument to pass to the ACL 180 * callback. 181 */ 182 extern void r_ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, 183 void *evt_arg, 184 ble_hci_trans_rx_acl_fn *acl_cb, 185 void *acl_arg); 186 #define ble_hci_trans_cfg_hs r_ble_hci_trans_cfg_hs 187 188 /** 189 * Resets the HCI module to a clean state. Frees all buffers and reinitializes 190 * the underlying transport. 191 * 192 * @return 0 on success; 193 * A BLE_ERR_[...] error code on failure. 194 */ 195 extern int r_ble_hci_trans_reset(void); 196 #define ble_hci_trans_reset ble_hci_trans_funcs_ptr->_ble_hci_trans_reset 197 198 void esp_ble_hci_trans_init(uint8_t); 199 200 #else 201 /** 202 * Sends an HCI event from the controller to the host. 203 * 204 * @param cmd The HCI event to send. This buffer must be 205 * allocated via ble_hci_trans_buf_alloc(). 206 * 207 * @return 0 on success; 208 * A BLE_ERR_[...] error code on failure. 209 */ 210 int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev); 211 212 /** 213 * Sends ACL data from controller to host. 214 * 215 * @param om The ACL data packet to send. 216 * 217 * @return 0 on success; 218 * A BLE_ERR_[...] error code on failure. 219 */ 220 int ble_hci_trans_ll_acl_tx(struct os_mbuf *om); 221 222 /** 223 * Sends an HCI command from the host to the controller. 224 * 225 * @param cmd The HCI command to send. This buffer must be 226 * allocated via ble_hci_trans_buf_alloc(). 227 * 228 * @return 0 on success; 229 * A BLE_ERR_[...] error code on failure. 230 */ 231 int ble_hci_trans_hs_cmd_tx(uint8_t *cmd); 232 233 /** 234 * Sends ACL data from host to controller. 235 * 236 * @param om The ACL data packet to send. 237 * 238 * @return 0 on success; 239 * A BLE_ERR_[...] error code on failure. 240 */ 241 int ble_hci_trans_hs_acl_tx(struct os_mbuf *om); 242 243 /** 244 * Allocates a flat buffer of the specified type. 245 * 246 * @param type The type of buffer to allocate; one of the 247 * BLE_HCI_TRANS_BUF_[...] constants. 248 * 249 * @return The allocated buffer on success; 250 * NULL on buffer exhaustion. 251 */ 252 int esp_ble_hci_trans_hs_cmd_tx(uint8_t *cmd); 253 254 /** 255 * Sends ACL data from host to controller. 256 * 257 * @param om The ACL data packet to send. 258 * 259 * @return 0 on success; 260 * A BLE_ERR_[...] error code on failure. 261 */ 262 int esp_ble_hci_trans_hs_acl_tx(struct os_mbuf *om); 263 264 /** 265 * Allocates a flat buffer of the specified type. 266 * 267 * @param type The type of buffer to allocate; one of the 268 * BLE_HCI_TRANS_BUF_[...] constants. 269 * 270 * @return The allocated buffer on success; 271 * NULL on buffer exhaustion. 272 */ 273 uint8_t *esp_ble_hci_trans_buf_alloc(int type); 274 275 /** 276 * Frees the specified flat buffer. The buffer must have been allocated via 277 * ble_hci_trans_buf_alloc(). 278 * 279 * @param buf The buffer to free. 280 */ 281 void esp_ble_hci_trans_buf_free(uint8_t *buf); 282 283 /** 284 * Configures the HCI transport to operate with a host. The transport will 285 * execute specified callbacks upon receiving HCI packets from the controller. 286 * 287 * @param evt_cb The callback to execute upon receiving an HCI 288 * event. 289 * @param evt_arg Optional argument to pass to the event 290 * callback. 291 * @param acl_cb The callback to execute upon receiving ACL 292 * data. 293 * @param acl_arg Optional argument to pass to the ACL 294 * callback. 295 */ 296 void esp_ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, 297 void *evt_arg, 298 ble_hci_trans_rx_acl_fn *acl_cb, 299 void *acl_arg); 300 301 /** 302 * Resets the HCI module to a clean state. Frees all buffers and reinitializes 303 * the underlying transport. 304 * 305 * @return 0 on success; 306 * A BLE_ERR_[...] error code on failure. 307 */ 308 int esp_ble_hci_trans_reset(void); 309 #endif 310 311 #ifdef __cplusplus 312 } 313 #endif 314 315 #endif /* H_HCI_TRANSPORT_ */ 316