pinebuds/services/ble_stack/hci/src/hci_int.h

455 lines
14 KiB
C

#ifndef HCI_INT_H_
#define HCI_INT_H_
/**
****************************************************************************************
* @addtogroup HCI Host Controller Interface
*@{
****************************************************************************************
*/
/*
* INCLUDE FILES
****************************************************************************************
*/
#include "rwip_config.h" // SW configuration
#if (HCI_PRESENT)
#include <stddef.h> // standard definition
#include <stdint.h> // standard integer
#include "co_bt.h" // BT standard definitions
#include "hci_ble.h"
#include "ke_msg.h" // Kernel message definitions
/*
* DEFINES
****************************************************************************************
*/
/// Macro to get OCF of a known command
#define OCF(cmd) (HCI_OP2OCF(HCI_##cmd##_CMD_OPCODE))
/// Unknown opcode identifier
#define HCI_OPCODE_UNKNOWN 0xFFFF
/**
* Destination field decoding
*
* bit | 7 6 | 5 4 | 3..0 |
* def | Rsvd (pkupk) | HL | LL |
*/
#define HCI_CMD_DEST_LL_POS 0
#define HCI_CMD_DEST_LL_MASK 0x0F
#define HCI_CMD_DEST_HL_POS 4
#define HCI_CMD_DEST_HL_MASK 0x30
/**
* Destination field decoding
*
* bit | 7..2 | 1 0 |
* def | Rsvd | HL |
*/
#define HCI_EVT_DEST_HL_POS 0
#define HCI_EVT_DEST_HL_MASK 0x03
#if (HCI_TL_SUPPORT)
/// Special Pack-Unpack settings for HCI commands (parameters and return parameters)
/**
* Special Pack-Unpack settings for HCI commands (parameters and return parameters)
*
* bit | 7 | 6 | 5..0 |
* def | RET PAR | PAR | Rsvd |
*/
#define HCI_CMD_DEST_SPEC_PAR_PK_POS 6
#define HCI_CMD_DEST_SPEC_PAR_PK_MSK 0x40
#define HCI_CMD_DEST_SPEC_RET_PAR_PK_POS 7
#define HCI_CMD_DEST_SPEC_RET_PAR_PK_MSK 0x80
#define PK_GEN_GEN (0x00)
#define PK_GEN_SPE (HCI_CMD_DEST_SPEC_RET_PAR_PK_MSK)
#define PK_SPE_GEN (HCI_CMD_DEST_SPEC_PAR_PK_MSK)
#define PK_SPE_SPE (HCI_CMD_DEST_SPEC_RET_PAR_PK_MSK | HCI_CMD_DEST_SPEC_PAR_PK_MSK)
/// Special Pack settings for HCI events
#define PK_GEN 0x00
#define PK_SPE 0x01
/// Macro for building a command descriptor in split mode (with parameters packing/unpacking)
#define CMD(opcode, dest_ll, dest_hl, pkupk, par_size_max, par_fmt, ret_fmt) {HCI_##opcode##_CMD_OPCODE, (dest_ll<<HCI_CMD_DEST_LL_POS) | (dest_hl<<HCI_CMD_DEST_HL_POS) | pkupk, par_size_max, (void*)par_fmt, (void*)ret_fmt}
/// Macro for building an event descriptor in split mode (with parameters packing/unpacking)
#define EVT(code, dest_hl, pkupk, par_fmt) {HCI_##code##_EVT_CODE, (dest_hl<<HCI_EVT_DEST_HL_POS), pkupk, (void*)par_fmt}
/// Macro for building an event descriptor in split mode (with parameters packing/unpacking)
#define LE_EVT(subcode, dest_hl, pkupk, par_fmt) {HCI_##subcode##_EVT_SUBCODE, (dest_hl<<HCI_EVT_DEST_HL_POS), pkupk, (void*)par_fmt}
/// Macro for building an event descriptor in split mode (with parameters packing/unpacking)
#define DBG_EVT(subcode, dest_hl, pkupk, par_fmt) {HCI_##subcode##_EVT_SUBCODE, (dest_hl<<HCI_EVT_DEST_HL_POS), pkupk, (void*)par_fmt}
#else //(HCI_TL_SUPPORT)
/// Macro for building a command descriptor in full mode (without parameters packing/unpacking)
#define CMD(opcode, dest_ll, dest_hl, pkupk, par_size_max, par_fmt, ret_fmt) {HCI_##opcode##_CMD_OPCODE, (dest_ll<<HCI_CMD_DEST_LL_POS) | (dest_hl<<HCI_CMD_DEST_HL_POS)}
/// Macro for building an event descriptor in full mode (without parameters packing/unpacking)
#define EVT(code, dest_hl, pkupk, par_fmt) {HCI_##code##_EVT_CODE, (dest_hl<<HCI_EVT_DEST_HL_POS)}
/// Macro for building an event descriptor in full mode (without parameters packing/unpacking)
#define LE_EVT(subcode, dest_hl, pkupk, par_fmt) {HCI_##subcode##_EVT_SUBCODE, (dest_hl<<HCI_EVT_DEST_HL_POS)}
/// Macro for building an event descriptor in full mode (without parameters packing/unpacking)
#define DBG_EVT(subcode, dest_hl, pkupk, par_fmt) {HCI_##subcode##_EVT_SUBCODE, (dest_hl<<HCI_EVT_DEST_HL_POS)}
#endif //(HCI_TL_SUPPORT)
/*
* ENUMERATIONS DEFINITIONS
****************************************************************************************
*/
/// Possible destination field values within lower layers
enum HCI_MSG_DEST_LL
{
MNG,
CTRL,
BLE_MNG,
BLE_CTRL,
BT_MNG,
BT_CTRL_CONHDL,
BT_CTRL_BD_ADDR,
BT_BCST,
DBG,
LL_UNDEF,
};
/// Possible destination field values within higher layers
enum HCI_MSG_DEST_HL
{
HL_MNG,
HL_CTRL,
HL_DATA,
HL_UNDEF,
};
#if (HCI_TL_SUPPORT)
/// Status returned by generic packer-unpacker
enum HCI_PACK_STATUS
{
HCI_PACK_OK,
HCI_PACK_IN_BUF_OVFLW,
HCI_PACK_OUT_BUF_OVFLW,
HCI_PACK_WRONG_FORMAT,
HCI_PACK_ERROR,
};
#endif //(HCI_TL_SUPPORT)
#if (BT_EMB_PRESENT)
/// Status of BT ACL connection at HCI level
enum HCI_BT_ACL_CON_STATUS
{
/// ACL link not active
HCI_BT_ACL_STATUS_NOT_ACTIVE,
/// ACL link ID associated with BD address
HCI_BT_ACL_STATUS_BD_ADDR,
/// ACL link ID associated with BD address + connection handle
HCI_BT_ACL_STATUS_BD_ADDR_CONHDL,
};
#endif //(BT_EMB_PRESENT)
/*
* STRUCTURES DEFINITIONS
****************************************************************************************
*/
/// HCI command descriptor structure
struct hci_cmd_desc_tab_ref
{
/// OpCode Group Field (OGF)
uint8_t ogf;
/// Number of commands supported in this group
uint16_t nb_cmds;
/// Command descriptor table
const struct hci_cmd_desc_tag* cmd_desc_tab;
};
/// HCI command descriptor structure
struct hci_cmd_desc_tag
{
/// Command opcode with flags indicating if a special packing or unpacking is needed
uint16_t opcode;
/// Destination field (used to find the internal destination task)
uint8_t dest_field;
#if (HCI_TL_SUPPORT)
/// Maximum size of the parameters
uint8_t par_size_max;
/// Parameters format string (or special unpacker)
void* par_fmt;
/// Return parameters format string (or special unpacker)
void* ret_par_fmt;
#endif //(HCI_TL_SUPPORT)
};
/// HCI event descriptor structure
struct hci_evt_desc_tag
{
/// Event opcode
uint8_t code;
/// Destination field (used to find the internal destination task)
uint8_t dest_field;
#if (HCI_TL_SUPPORT)
/// Flag indicating if a special packing is needed
uint8_t special_pack;
/// Parameters format string (or special unpacker)
void* par_fmt;
#endif //(HCI_TL_SUPPORT)
};
#if (HCI_TL_SUPPORT)
/// HCI pack/unpack function pointer type definition
typedef uint16_t (*hci_pkupk_func_t)(uint8_t *out, uint8_t *in, uint16_t* out_len, uint16_t in_len);
#endif //(HCI_TL_SUPPORT)
#if (BT_EMB_PRESENT)
/// HCI Environment context structure
struct hci_bt_acl_con_tag
{
/**
* BT ACL connection status
* - 0x00: Not active
* - 0x01: link ID associated with BD address
* - 0x02: link ID associated with BD address + connection handle
*/
uint8_t state;
/// BD address associated with link ID
struct bd_addr bd_addr;
};
/// Condition based on class of device
struct classofdevcondition
{
/// Class of device
struct devclass classofdev;
/// Device mask
struct devclass class_mask;
};
/// Condition based on device class
union cond
{
/// Device class
struct classofdevcondition device_class;
/// BD address
struct bd_addr bdaddr;
};
/// Event Filter Record
struct hci_evt_filter_tag
{
bool in_use;
uint8_t type;
uint8_t condition;
uint8_t auto_accept;
union cond param;
};
#elif (BLE_HOST_PRESENT && !BLE_EMB_PRESENT)
/// HCI Environment context structure
struct hci_ble_acl_con_tag
{
/// Code
uint8_t code;
};
#endif //(BT_EMB_PRESENT || (BLE_HOST_PRESENT && !BLE_EMB_PRESENT))
/// HCI Environment context structure
struct hci_env_tag
{
/// Event mask
struct evt_mask evt_msk;
/// Event mask page 2
struct evt_mask evt_msk_page_2;
#if (BLE_EMB_PRESENT)
/// LE Event mask
struct evt_mask le_evt_msk;
#endif // (BLE_EMB_PRESENT)
#if (BLE_EMB_PRESENT && HCI_BLE_CON_SUPPORT)
/// Link association table for BLE link-oriented messages routing
bool ble_con_state[BLE_CONNECTION_MAX];
#endif //(BLE_EMB_PRESENT && !BLE_HOST_PRESENT && HCI_BLE_CON_SUPPORT)
#if (BT_EMB_PRESENT)
/// Link association table for BT link-oriented messages routing
struct hci_bt_acl_con_tag bt_acl_con_tab[MAX_NB_ACTIVE_ACL];
/// Event filters
struct hci_evt_filter_tag evt_filter[HCI_FILTER_NB];
/**
* Current auto-accept command opcode, used to filter the associated CS event
* Note: assume that there would be 1 auto accept command at the same time
* Note: could be HCI_Accept_Con, HCI_Accept_sync_Con
*/
uint16_t auto_accept_opcode;
#if (MAX_NB_SYNC > 0)
/**
* Voice settings used when SCO connection is auto-accepted
*/
uint16_t voice_settings;
#endif //(MAX_NB_SYNC > 0)
/**
* Auto-reject flag, used to filter the complete event when a request has been auto-rejected
*/
bool auto_reject;
#elif (BLE_HOST_PRESENT && !BLE_EMB_PRESENT && (BLE_CENTRAL || BLE_PERIPHERAL))
/// Link association table for BLE link-oriented messages routing
struct hci_ble_acl_con_tag ble_acl_con_tab[BLE_CONNECTION_MAX];
#endif //(BT_EMB_PRESENT)
};
/*
* GLOBAL VARIABLE DECLARATIONS
****************************************************************************************
*/
#if BLE_HOST_PRESENT
extern const uint8_t hl_task_type[];
#endif //BLE_HOST_PRESENT
///HCI environment context
extern struct hci_env_tag hci_env;
/*
* FUNCTION DECLARATIONS
****************************************************************************************
*/
/**
****************************************************************************************
* @brief Look for a command descriptor that could match with the specified opcode
*
* @param[in] opcode Command opcode
*
* @return Pointer the command descriptor (NULL if not found)
*****************************************************************************************
*/
const struct hci_cmd_desc_tag* hci_look_for_cmd_desc(uint16_t opcode);
/**
****************************************************************************************
* @brief Look for an event descriptor that could match with the specified event code
*
* @param[in] code event code
*
* @return Pointer the event descriptor (NULL if not found)
*****************************************************************************************
*/
const struct hci_evt_desc_tag* hci_look_for_evt_desc(uint8_t code);
/**
****************************************************************************************
* @brief Look for an event descriptor that could match with the specified DBG subcode
*
* @param[in] subcode DBG event subcode
*
* @return Pointer the event descriptor (NULL if not found)
*****************************************************************************************
*/
const struct hci_evt_desc_tag* hci_look_for_dbg_evt_desc(uint8_t subcode);
#if (BLE_EMB_PRESENT || BLE_HOST_PRESENT)
/**
****************************************************************************************
* @brief Look for an event descriptor that could match with the specified LE subcode
*
* @param[in] subcode LE event subcode
*
* @return Pointer the event descriptor (NULL if not found)
*****************************************************************************************
*/
const struct hci_evt_desc_tag* hci_look_for_le_evt_desc(uint8_t subcode);
#endif //(BLE_EMB_PRESENT || BLE_HOST_PRESENT)
#if (HCI_TL_SUPPORT)
/**
****************************************************************************************
* @brief Initialize HIC TL part
*****************************************************************************************
*/
void hci_tl_init(bool reset);
/**
****************************************************************************************
* @brief Send an HCI message over TL
*
* @param[in] msg Kernel message carrying the HCI message
*****************************************************************************************
*/
void hci_tl_send(struct ke_msg *msg);
#endif //(HCI_TL_SUPPORT)
/**
****************************************************************************************
* @brief Initialize Flow Control Structure
*
*****************************************************************************************
*/
void hci_fc_init(void);
/**
****************************************************************************************
* @brief count ACL packets sent to Host
*
*****************************************************************************************
*/
void hci_fc_acl_packet_sent(void);
/**
****************************************************************************************
* @brief count SCO packets sent to Host
*
*****************************************************************************************
*/
void hci_fc_sync_packet_sent(void);
/**
****************************************************************************************
* @brief Calculate number of ACL packets slots available on Host side
*
* @return number of packets available
*****************************************************************************************
*/
uint16_t hci_fc_check_host_available_nb_acl_packets(void);
/**
****************************************************************************************
* @brief Calculate number of SCO packets slots available on Host side
*
* @return number of packets available
*****************************************************************************************
*/
uint16_t hci_fc_check_host_available_nb_sync_packets(void);
#endif //HCI_PRESENT
/// @} HCI
#endif // HCI_INT_H_