Skip to content

Commit

Permalink
Bluetooth: include: Add initial HCI driver API definition
Browse files Browse the repository at this point in the history
Add the initial HCI driver header file and driver API definition. This
is distinct from drivers/bluetooth/hci_driver.h in order to support
legacy (unconverted) drivers for the time being.

Signed-off-by: Johan Hedberg <[email protected]>
  • Loading branch information
jhedberg committed May 5, 2024
1 parent 9f562eb commit 77f82b4
Showing 1 changed file with 194 additions and 0 deletions.
194 changes: 194 additions & 0 deletions include/zephyr/drivers/bluetooth.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/** @file
* @brief Bluetooth HCI driver API.
*
* Copyright (c) 2024 Johan Hedberg
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_H_
#define ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_H_

/**
* @brief Bluetooth HCI drivers
* @defgroup bt_hci_driver HCI drivers
* @ingroup bluetooth
* @{
*/

#include <stdbool.h>
#include <zephyr/net/buf.h>
#include <zephyr/bluetooth/buf.h>
#include <zephyr/bluetooth/hci_vs.h>
#include <zephyr/device.h>
#include <zephyr/dt-bindings/bluetooth/hci.h>

#ifdef __cplusplus
extern "C" {
#endif

#if defined(CONFIG_BT_HCI_SETUP) || defined(__DOXYGEN__)
struct bt_hci_setup_params {
/** The public identity address to give to the controller. This field is used when the
* driver selects @kconfig{CONFIG_BT_HCI_SET_PUBLIC_ADDR} to indicate that it supports
* setting the controller's public address.
*/
bt_addr_t public_addr;
};
#endif

/** Name of the driver */
struct bt_hci_info {
/** Name of the HCI transport. This is purely for informational purposes, e.g. to
* be used in logging.
*/
char name[20];

/** Bus of the transport (BT_HCI_BUS_*) */
enum bt_hci_bus bus;

/** Specific controller quirks. These are set by the HCI driver
* and acted upon by the host. They can either be statically
* set at buildtime, or set at runtime before the HCI driver's
* open() callback returns.
*/
uint32_t quirks;
};

#define BT_DT_HCI_INFO_GET(node_id) \
{ \
.name = DT_PROP_OR(node_id, name, "HCI"), \
.bus = DT_STRING_TOKEN_OR(node_id, bus, BT_HCI_BUS_VIRTUAL), \
.quirks = DT_PROP_OR(node_id, quirks, 0), \
}

#define BT_DT_HCI_INFO_INST_GET(inst) BT_DT_HCI_INFO_GET(DT_DRV_INST(inst))

typedef int (*bt_hci_recv_t)(const struct device *dev, struct net_buf *buf);

__subsystem struct bt_hci_driver_api {
void (*get_info)(const struct device *dev, struct bt_hci_info *info);
int (*open)(const struct device *dev, bt_hci_recv_t recv);
int (*close)(const struct device *dev);
int (*send)(const struct device *dev, struct net_buf *buf);

#if defined(CONFIG_BT_HCI_SETUP) || defined(__DOXYGEN__)
/**
* @brief HCI vendor-specific setup
*
* Executes vendor-specific commands sequence to initialize
* BT Controller before BT Host executes Reset sequence.
*
* @note @kconfig{CONFIG_BT_HCI_SETUP} must be selected for this
* field to be available.
*
* @param dev HCI device
* @param dev Setup parameters
*
* @return 0 on success or negative error number on failure.
*/
int (*setup)(const struct device *dev,
struct bt_hci_setup_params *param);
#endif /* defined(CONFIG_BT_HCI_SETUP) || defined(__DOXYGEN__)*/
};

/**
* @brief Get information about a given HCI device.
*
* Get basic information about a given HCI device.
*
* @param dev HCI device
* @param info Structure to copy the information into.
*
* @return 0 on success or negative error number on failure.
*/
static inline void bt_hci_get_info(const struct device *dev, struct bt_hci_info *info)
{
const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api;

return api->get_info(dev, info);
}

/**
* @brief Open the HCI transport.
*
* Opens the HCI transport for operation. This function must not
* return until the transport is ready for operation, meaning it
* is safe to start calling the send() handler.
*
* @param dev HCI device
* @param recv Callback to receive data from the controller
*
* @return 0 on success or negative error number on failure.
*/
static inline int bt_hci_open(const struct device *dev, bt_hci_recv_t recv)
{
const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api;

return api->open(dev, recv);
}

/**
* @brief Close the HCI transport.
*
* Closes the HCI transport. This function must not return until the
* transport is closed.
*
* @param dev HCI device
*
* @return 0 on success or negative error number on failure.
*/
static inline int bt_hci_close(const struct device *dev)
{
const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api;

if (api->close == NULL) {
return -ENOSYS;
}

return api->close(dev);
}

/**
* @brief Send HCI buffer to controller.
*
* Send an HCI command or ACL data to the controller. The exact
* type of the data can be checked with the help of bt_buf_get_type().
*
* @note This function must only be called from a cooperative thread.
*
* @param dev HCI device
* @param buf Buffer containing data to be sent to the controller.
*
* @return 0 on success or negative error number on failure.
*/
static inline int bt_hci_send(const struct device *dev, struct net_buf *buf)
{
const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api;

return api->send(dev, buf);
}

#if defined(CONFIG_BT_HCI_SETUP) || defined(__DOXYGEN__)
/**
* @brief HCI vendor-specific setup
*
* Executes vendor-specific commands sequence to initialize
* BT Controller before BT Host executes Reset sequence.
*
* @note @kconfig{CONFIG_BT_HCI_SETUP} must be selected for this
* field to be available.
*
* @return 0 on success or negative error number on failure.
*/
static inline int bt_hci_setup(const struct device *dev, struct bt_hci_setup_params *params)
{
const struct bt_hci_driver_api *api = (const struct bt_hci_driver_api *)dev->api;

if (api->setup == NULL) {
return -ENOSYS;
}

return api->setup(dev, params);
}
#endif
#endif /* ZEPHYR_INCLUDE_DRIVERS_BLUETOOTH_H_ */

0 comments on commit 77f82b4

Please sign in to comment.