/* * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #ifndef H_HCI_TRANSPORT_ #define H_HCI_TRANSPORT_ #ifdef __cplusplus extern "C" { #endif #include <inttypes.h> #include "os/os_mempool.h" #define BLE_HCI_TRANS_CMD_SZ 260 /*** Type of buffers for holding commands and events. */ /** * Controller-to-host event buffers. Events have one of two priorities: * o Low-priority (BLE_HCI_TRANS_BUF_EVT_LO) * o High-priority (BLE_HCI_TRANS_BUF_EVT_HI) * * Low-priority event buffers are only used for advertising reports. If there * are no free low-priority event buffers, then an incoming advertising report * will get dropped. * * High-priority event buffers are for everything except advertising reports. * If there are no free high-priority event buffers, a request to allocate one * will try to allocate a low-priority buffer instead. * * If you want all events to be given equal treatment, then you should allocate * low-priority events only. * * Event priorities solve the problem of critical events getting dropped due to * a flood of advertising reports. This solution is likely temporary: when * HCI flow control is added, event priorities may become obsolete. * * Not all transports distinguish between low and high priority events. If the * transport does not have separate settings for low and high buffer counts, * then it treats all events with equal priority. */ #define BLE_HCI_TRANS_BUF_EVT_LO 1 #define BLE_HCI_TRANS_BUF_EVT_HI 2 /* Host-to-controller command. */ #define BLE_HCI_TRANS_BUF_CMD 3 /** Callback function types; executed when HCI packets are received. */ typedef int ble_hci_trans_rx_cmd_fn(uint8_t *cmd, void *arg); typedef int ble_hci_trans_rx_acl_fn(struct os_mbuf *om, void *arg); #if SOC_ESP_NIMBLE_CONTROLLER && CONFIG_BT_CONTROLLER_ENABLED #define ble_transport_alloc_cmd() ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD) #define ble_transport_alloc_event(X) ble_hci_trans_buf_alloc(X ? BLE_HCI_TRANS_BUF_EVT_LO : BLE_HCI_TRANS_BUF_EVT_HI) #define ble_transport_free ble_hci_trans_buf_free struct ble_hci_trans_funcs_t { int(*_ble_hci_trans_hs_acl_tx)(struct os_mbuf *om); int(*_ble_hci_trans_hs_cmd_tx)(uint8_t *cmd); int(*_ble_hci_trans_ll_acl_tx)(struct os_mbuf *om); int(*_ble_hci_trans_ll_evt_tx)(uint8_t *hci_ev); int(*_ble_hci_trans_reset)(void); int(*_ble_hci_trans_set_acl_free_cb)(os_mempool_put_fn *cb, void *arg); }; extern struct ble_hci_trans_funcs_t *ble_hci_trans_funcs_ptr; /** * Sends an HCI event from the controller to the host. * * @param cmd The HCI event to send. This buffer must be * allocated via ble_hci_trans_buf_alloc(). * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ extern int r_ble_hci_trans_ll_evt_tx(uint8_t *hci_ev); #define ble_hci_trans_ll_evt_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_ll_evt_tx /** * Sends ACL data from controller to host. * * @param om The ACL data packet to send. * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ extern int r_ble_hci_trans_ll_acl_tx(struct os_mbuf *om); #define ble_hci_trans_ll_acl_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_ll_acl_tx /** * Sends an HCI command from the host to the controller. * * @param cmd The HCI command to send. This buffer must be * allocated via ble_hci_trans_buf_alloc(). * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ extern int r_ble_hci_trans_hs_cmd_tx(uint8_t *cmd); #define ble_hci_trans_hs_cmd_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_hs_cmd_tx /** * Sends ACL data from host to controller. * * @param om The ACL data packet to send. * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ extern int r_ble_hci_trans_hs_acl_tx(struct os_mbuf *om); #define ble_hci_trans_hs_acl_tx ble_hci_trans_funcs_ptr->_ble_hci_trans_hs_acl_tx /** * Allocates a flat buffer of the specified type. * * @param type The type of buffer to allocate; one of the * BLE_HCI_TRANS_BUF_[...] constants. * * @return The allocated buffer on success; * NULL on buffer exhaustion. */ extern uint8_t *r_ble_hci_trans_buf_alloc(int type); #define ble_hci_trans_buf_alloc r_ble_hci_trans_buf_alloc /** * Frees the specified flat buffer. The buffer must have been allocated via * ble_hci_trans_buf_alloc(). * * @param buf The buffer to free. */ extern void r_ble_hci_trans_buf_free(uint8_t *buf); #define ble_hci_trans_buf_free r_ble_hci_trans_buf_free /** * Configures a callback to get executed whenever an ACL data packet is freed. * The function is called immediately before the free occurs. * * @param cb The callback to configure. * @param arg An optional argument to pass to the callback. * * @return 0 on success; * BLE_ERR_UNSUPPORTED if the transport does not * support this operation. */ extern int r_ble_hci_trans_set_acl_free_cb(os_mempool_put_fn *cb, void *arg); #define ble_hci_trans_set_acl_free_cb ble_hci_trans_funcs_ptr->_ble_hci_trans_set_acl_free_cb /** * Configures the HCI transport to operate with a controller. The transport * will execute specified callbacks upon receiving HCI packets from the host. * * @param cmd_cb The callback to execute upon receiving an HCI * command. * @param cmd_arg Optional argument to pass to the command * callback. * @param acl_cb The callback to execute upon receiving ACL * data. * @param acl_arg Optional argument to pass to the ACL * callback. */ extern void r_ble_hci_trans_cfg_ll(ble_hci_trans_rx_cmd_fn *cmd_cb, void *cmd_arg, ble_hci_trans_rx_acl_fn *acl_cb, void *acl_arg); #define ble_hci_trans_cfg_ll r_ble_hci_trans_cfg_ll /** * Configures the HCI transport to operate with a host. The transport will * execute specified callbacks upon receiving HCI packets from the controller. * * @param evt_cb The callback to execute upon receiving an HCI * event. * @param evt_arg Optional argument to pass to the event * callback. * @param acl_cb The callback to execute upon receiving ACL * data. * @param acl_arg Optional argument to pass to the ACL * callback. */ extern void r_ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, void *evt_arg, ble_hci_trans_rx_acl_fn *acl_cb, void *acl_arg); #define ble_hci_trans_cfg_hs r_ble_hci_trans_cfg_hs /** * Resets the HCI module to a clean state. Frees all buffers and reinitializes * the underlying transport. * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ extern int r_ble_hci_trans_reset(void); #define ble_hci_trans_reset ble_hci_trans_funcs_ptr->_ble_hci_trans_reset void esp_ble_hci_trans_init(uint8_t); #else /** * Sends an HCI event from the controller to the host. * * @param cmd The HCI event to send. This buffer must be * allocated via ble_hci_trans_buf_alloc(). * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ int ble_hci_trans_ll_evt_tx(uint8_t *hci_ev); /** * Sends ACL data from controller to host. * * @param om The ACL data packet to send. * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ int ble_hci_trans_ll_acl_tx(struct os_mbuf *om); /** * Sends an HCI command from the host to the controller. * * @param cmd The HCI command to send. This buffer must be * allocated via ble_hci_trans_buf_alloc(). * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ int ble_hci_trans_hs_cmd_tx(uint8_t *cmd); /** * Sends ACL data from host to controller. * * @param om The ACL data packet to send. * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om); /** * Allocates a flat buffer of the specified type. * * @param type The type of buffer to allocate; one of the * BLE_HCI_TRANS_BUF_[...] constants. * * @return The allocated buffer on success; * NULL on buffer exhaustion. */ int esp_ble_hci_trans_hs_cmd_tx(uint8_t *cmd); /** * Sends ACL data from host to controller. * * @param om The ACL data packet to send. * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ int esp_ble_hci_trans_hs_acl_tx(struct os_mbuf *om); /** * Allocates a flat buffer of the specified type. * * @param type The type of buffer to allocate; one of the * BLE_HCI_TRANS_BUF_[...] constants. * * @return The allocated buffer on success; * NULL on buffer exhaustion. */ uint8_t *esp_ble_hci_trans_buf_alloc(int type); /** * Frees the specified flat buffer. The buffer must have been allocated via * ble_hci_trans_buf_alloc(). * * @param buf The buffer to free. */ void esp_ble_hci_trans_buf_free(uint8_t *buf); /** * Configures the HCI transport to operate with a host. The transport will * execute specified callbacks upon receiving HCI packets from the controller. * * @param evt_cb The callback to execute upon receiving an HCI * event. * @param evt_arg Optional argument to pass to the event * callback. * @param acl_cb The callback to execute upon receiving ACL * data. * @param acl_arg Optional argument to pass to the ACL * callback. */ void esp_ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *evt_cb, void *evt_arg, ble_hci_trans_rx_acl_fn *acl_cb, void *acl_arg); /** * Resets the HCI module to a clean state. Frees all buffers and reinitializes * the underlying transport. * * @return 0 on success; * A BLE_ERR_[...] error code on failure. */ int esp_ble_hci_trans_reset(void); #endif #ifdef __cplusplus } #endif #endif /* H_HCI_TRANSPORT_ */