mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
Bluetooth HCI common components.
Separate Bluetooth HCI component example which adds some macros and functions used by HCI Layer defined by the spec.
This commit is contained in:
@@ -17,3 +17,7 @@ See the [README.md](./controller_hci_uart/README.md) file in the example [contro
|
||||
Demonstrates interaction with controller though virtual HCI layer. In this example, simple BLE advertising is done.
|
||||
|
||||
See the [README.md](./controller_vhci_ble_adv/README.md) file in the example [controller_vhci_ble_adv](./controller_vhci_ble_adv).
|
||||
|
||||
## hci_common_component
|
||||
|
||||
This is separate component adding functionalities for HCI Layer. Since this component is just used by HCI examples, it is not placed in global components.
|
||||
|
@@ -2,5 +2,8 @@
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# This example uses an extra component for common functions for Bluetooth HCI layer.
|
||||
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/bluetooth/hci/hci_common_component)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(ble_adv)
|
||||
|
@@ -5,4 +5,6 @@
|
||||
|
||||
PROJECT_NAME := ble_adv
|
||||
|
||||
EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/bluetooth/hci/hci_common_component
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
@@ -13,39 +13,10 @@
|
||||
#include "esp_bt.h"
|
||||
#include "esp_log.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "bt_hci_common.h"
|
||||
|
||||
static const char *tag = "BLE_ADV";
|
||||
|
||||
#define HCI_H4_CMD_PREAMBLE_SIZE (4)
|
||||
|
||||
/* HCI Command opcode group field(OGF) */
|
||||
#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */
|
||||
#define HCI_GRP_BLE_CMDS (0x08 << 10)
|
||||
|
||||
#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
|
||||
#define HCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS)
|
||||
#define HCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS)
|
||||
#define HCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS)
|
||||
|
||||
#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE (1)
|
||||
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS (15)
|
||||
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA (31)
|
||||
|
||||
#define BD_ADDR_LEN (6) /* Device address length */
|
||||
typedef uint8_t bd_addr_t[BD_ADDR_LEN]; /* Device address */
|
||||
|
||||
#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
|
||||
#define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);}
|
||||
#define BDADDR_TO_STREAM(p, a) {int ijk; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *(p)++ = (uint8_t) a[BD_ADDR_LEN - 1 - ijk];}
|
||||
#define ARRAY_TO_STREAM(p, a, len) {int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (uint8_t) a[ijk];}
|
||||
|
||||
enum {
|
||||
H4_TYPE_COMMAND = 1,
|
||||
H4_TYPE_ACL = 2,
|
||||
H4_TYPE_SCO = 3,
|
||||
H4_TYPE_EVENT = 4
|
||||
};
|
||||
|
||||
static uint8_t hci_cmd_buf[128];
|
||||
|
||||
/*
|
||||
@@ -75,65 +46,6 @@ static esp_vhci_host_callback_t vhci_host_cb = {
|
||||
controller_rcv_pkt_ready,
|
||||
host_rcv_pkt
|
||||
};
|
||||
|
||||
static uint16_t make_cmd_reset(uint8_t *buf)
|
||||
{
|
||||
UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
|
||||
UINT16_TO_STREAM (buf, HCI_RESET);
|
||||
UINT8_TO_STREAM (buf, 0);
|
||||
return HCI_H4_CMD_PREAMBLE_SIZE;
|
||||
}
|
||||
|
||||
static uint16_t make_cmd_ble_set_adv_enable (uint8_t *buf, uint8_t adv_enable)
|
||||
{
|
||||
UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
|
||||
UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_ENABLE);
|
||||
UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
|
||||
UINT8_TO_STREAM (buf, adv_enable);
|
||||
return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_ADV_ENABLE;
|
||||
}
|
||||
|
||||
static uint16_t make_cmd_ble_set_adv_param (uint8_t *buf, uint16_t adv_int_min, uint16_t adv_int_max,
|
||||
uint8_t adv_type, uint8_t addr_type_own,
|
||||
uint8_t addr_type_dir, bd_addr_t direct_bda,
|
||||
uint8_t channel_map, uint8_t adv_filter_policy)
|
||||
{
|
||||
UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
|
||||
UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_PARAMS);
|
||||
UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS );
|
||||
|
||||
UINT16_TO_STREAM (buf, adv_int_min);
|
||||
UINT16_TO_STREAM (buf, adv_int_max);
|
||||
UINT8_TO_STREAM (buf, adv_type);
|
||||
UINT8_TO_STREAM (buf, addr_type_own);
|
||||
UINT8_TO_STREAM (buf, addr_type_dir);
|
||||
BDADDR_TO_STREAM (buf, direct_bda);
|
||||
UINT8_TO_STREAM (buf, channel_map);
|
||||
UINT8_TO_STREAM (buf, adv_filter_policy);
|
||||
return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS;
|
||||
}
|
||||
|
||||
|
||||
static uint16_t make_cmd_ble_set_adv_data(uint8_t *buf, uint8_t data_len, uint8_t *p_data)
|
||||
{
|
||||
UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
|
||||
UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_DATA);
|
||||
UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
|
||||
|
||||
memset(buf, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA);
|
||||
|
||||
if (p_data != NULL && data_len > 0) {
|
||||
if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA) {
|
||||
data_len = HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA;
|
||||
}
|
||||
|
||||
UINT8_TO_STREAM (buf, data_len);
|
||||
|
||||
ARRAY_TO_STREAM (buf, p_data, data_len);
|
||||
}
|
||||
return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1;
|
||||
}
|
||||
|
||||
static void hci_cmd_send_reset(void)
|
||||
{
|
||||
uint16_t sz = make_cmd_reset (hci_cmd_buf);
|
||||
|
@@ -0,0 +1,3 @@
|
||||
idf_component_register(SRCS "bt_hci_common.c"
|
||||
INCLUDE_DIRS "include"
|
||||
)
|
70
examples/bluetooth/hci/hci_common_component/bt_hci_common.c
Normal file
70
examples/bluetooth/hci/hci_common_component/bt_hci_common.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/* Basic functionality for Bluetooth Host Controller Interface Layer.
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include "bt_hci_common.h"
|
||||
|
||||
|
||||
uint16_t make_cmd_ble_set_adv_enable (uint8_t *buf, uint8_t adv_enable)
|
||||
{
|
||||
UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
|
||||
UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_ENABLE);
|
||||
UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
|
||||
UINT8_TO_STREAM (buf, adv_enable);
|
||||
return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_ADV_ENABLE;
|
||||
}
|
||||
|
||||
uint16_t make_cmd_ble_set_adv_param (uint8_t *buf, uint16_t adv_int_min, uint16_t adv_int_max,
|
||||
uint8_t adv_type, uint8_t addr_type_own,
|
||||
uint8_t addr_type_dir, bd_addr_t direct_bda,
|
||||
uint8_t channel_map, uint8_t adv_filter_policy)
|
||||
{
|
||||
UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
|
||||
UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_PARAMS);
|
||||
UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS );
|
||||
|
||||
UINT16_TO_STREAM (buf, adv_int_min);
|
||||
UINT16_TO_STREAM (buf, adv_int_max);
|
||||
UINT8_TO_STREAM (buf, adv_type);
|
||||
UINT8_TO_STREAM (buf, addr_type_own);
|
||||
UINT8_TO_STREAM (buf, addr_type_dir);
|
||||
BDADDR_TO_STREAM (buf, direct_bda);
|
||||
UINT8_TO_STREAM (buf, channel_map);
|
||||
UINT8_TO_STREAM (buf, adv_filter_policy);
|
||||
return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS;
|
||||
}
|
||||
|
||||
uint16_t make_cmd_reset(uint8_t *buf)
|
||||
{
|
||||
UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
|
||||
UINT16_TO_STREAM (buf, HCI_RESET);
|
||||
UINT8_TO_STREAM (buf, 0);
|
||||
return HCI_H4_CMD_PREAMBLE_SIZE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint16_t make_cmd_ble_set_adv_data(uint8_t *buf, uint8_t data_len, uint8_t *p_data)
|
||||
{
|
||||
UINT8_TO_STREAM (buf, H4_TYPE_COMMAND);
|
||||
UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_DATA);
|
||||
UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
|
||||
|
||||
memset(buf, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA);
|
||||
|
||||
if (p_data != NULL && data_len > 0) {
|
||||
if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA) {
|
||||
data_len = HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA;
|
||||
}
|
||||
|
||||
UINT8_TO_STREAM (buf, data_len);
|
||||
|
||||
ARRAY_TO_STREAM (buf, p_data, data_len);
|
||||
}
|
||||
return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1;
|
||||
}
|
@@ -0,0 +1,104 @@
|
||||
/* Baisc macros and functions for Bluetooth Host Controller Interface Layer.
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
|
||||
#define HCI_H4_CMD_PREAMBLE_SIZE (4)
|
||||
|
||||
/* HCI Command Opcode group Field (OGF) */
|
||||
#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */
|
||||
#define HCI_GRP_BLE_CMDS (0x08 << 10)
|
||||
|
||||
/* HCI Command Opcode Command Field (OCF) */
|
||||
#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS)
|
||||
#define HCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS)
|
||||
#define HCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS)
|
||||
#define HCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS)
|
||||
|
||||
/* HCI Command length. */
|
||||
#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE 1
|
||||
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS 15
|
||||
#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA 31
|
||||
|
||||
#define BD_ADDR_LEN (6) /* Device address length */
|
||||
typedef uint8_t bd_addr_t[BD_ADDR_LEN]; /* Device address */
|
||||
|
||||
#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);}
|
||||
#define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);}
|
||||
#define BDADDR_TO_STREAM(p, a) {int ijk; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *(p)++ = (uint8_t) a[BD_ADDR_LEN - 1 - ijk];}
|
||||
#define ARRAY_TO_STREAM(p, a, len) {int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (uint8_t) a[ijk];}
|
||||
|
||||
enum {
|
||||
H4_TYPE_COMMAND = 1,
|
||||
H4_TYPE_ACL = 2,
|
||||
H4_TYPE_SCO = 3,
|
||||
H4_TYPE_EVENT = 4
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Writes reset bit in buf and returns size of input buffer after
|
||||
* writing in it.
|
||||
*
|
||||
* @param buf Input buffer to write which will be sent to controller.
|
||||
*
|
||||
* @return Size of buf after writing into it.
|
||||
*/
|
||||
uint16_t make_cmd_reset(uint8_t *buf);
|
||||
|
||||
/**
|
||||
* @brief This function is used to request the Controller to start or stop advertising.
|
||||
*
|
||||
* @param buf Input buffer to write which will be sent to controller.
|
||||
* @param adv_enable 1 to enable advertising and 0 to disable.
|
||||
*
|
||||
* @return Size of buf after writing into it.
|
||||
*/
|
||||
uint16_t make_cmd_ble_set_adv_enable (uint8_t *buf, uint8_t adv_enable);
|
||||
|
||||
/**
|
||||
* @brief This function is used by the Host to set the advertising parameters.
|
||||
*
|
||||
* @param buf Input buffer to write which will be sent to controller.
|
||||
* @param adv_int_min Minimum advertising interval.
|
||||
* @param adv_int_max Maximum advertising interval.
|
||||
* @param adv_type Advertising type.
|
||||
* @param addr_type_own Own advertising type.
|
||||
* @param addr_type_peer Peer device's address type.
|
||||
* @param peer_addr Peer device's BD address.
|
||||
* @param channel_map Advertising channel map.
|
||||
* @param adv_filter_policy Advertising Filter Policy.
|
||||
*
|
||||
* @return Size of buf after writing into it.
|
||||
*/
|
||||
uint16_t make_cmd_ble_set_adv_param (uint8_t *buf, uint16_t adv_int_min, uint16_t adv_int_max,
|
||||
uint8_t adv_type, uint8_t addr_type_own,
|
||||
uint8_t addr_type_peer, bd_addr_t peer_addr,
|
||||
uint8_t channel_map, uint8_t adv_filter_policy);
|
||||
|
||||
/**
|
||||
* @brief This function is used to set the data used in advertising packets that have a data field.
|
||||
*
|
||||
* @param buf Input buffer to write which will be sent to controller.
|
||||
* @param data_len Length of p_data.
|
||||
* @param p_data Data to be set.
|
||||
*
|
||||
* @return Size of buf after writing into it.
|
||||
*/
|
||||
uint16_t make_cmd_ble_set_adv_data(uint8_t *buf, uint8_t data_len, uint8_t *p_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user