mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
Merge branch 'bugfix/nimble_issues_02062026_v6.0' into 'release/v6.0'
fix(nimble): Fix few nimble issues 02062026 (v6.0) See merge request espressif/esp-idf!49153
This commit is contained in:
@@ -109,6 +109,12 @@ menu "Bluetooth"
|
||||
This option is to configure the buffer size of the hci adv report cache in hci debug mode.
|
||||
This is a ring buffer, the new data will overwrite the oldest data if the buffer is full.
|
||||
|
||||
config BT_HCI_LOG_INSIGHTS_ENABLE
|
||||
depends on BT_HCI_LOG_DEBUG_EN
|
||||
bool "Enable Insights for HCI LOGS BT Stack"
|
||||
help
|
||||
Enable this to allow the BT stack to send diagnostic events.
|
||||
|
||||
endmenu
|
||||
|
||||
menuconfig BLE_MESH
|
||||
|
||||
@@ -94,7 +94,7 @@ list(APPEND bt_common_srcs
|
||||
"${CMAKE_CURRENT_LIST_DIR}/api/esp_blufi_api.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/hci_log/bt_hci_log.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/btc/core/btc_manage.c"
|
||||
# "${CMAKE_CURRENT_LIST_DIR}/hci_log/bt_hci_log_insights.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/hci_log/bt_hci_log_insights.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/btc/core/btc_task.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/btc/profile/esp/blufi/blufi_prf.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/btc/profile/esp/blufi/blufi_protocol.c"
|
||||
|
||||
@@ -6,6 +6,21 @@ config BT_ALARM_MAX_NUM
|
||||
This option decides the maximum number of alarms which
|
||||
could be used by Bluetooth host.
|
||||
|
||||
config BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT
|
||||
bool "Allow BLE connection interval below Bluetooth Core Spec minimum (disable host check)"
|
||||
depends on BT_BLE_ENABLED || BT_NIMBLE_ENABLED
|
||||
default n
|
||||
help
|
||||
When enabled, BLE host-side validation accepts connection interval
|
||||
values below the Bluetooth Core Specification minimum of 0x0006
|
||||
(7.5 ms), down to non-zero values. The BLE controller still enforces
|
||||
what is actually supported in hardware and firmware.
|
||||
|
||||
End users should NOT set this option directly. In typical IDF builds it
|
||||
follows the active Controller integration when that Controller supports
|
||||
this mode; use the Controller's own configuration instead of toggling
|
||||
this host symbol manually.
|
||||
|
||||
choice BT_SMP_CRYPTO_STACK
|
||||
prompt "SMP cryptographic stack"
|
||||
depends on (BT_BLE_SMP_ENABLE || BT_SMP_ENABLE || BT_NIMBLE_SECURITY_ENABLE || BT_LE_SECURITY_ENABLE)
|
||||
|
||||
@@ -40,6 +40,16 @@ static const char s_hex_to_char_mapping[16] = {
|
||||
static bt_hci_log_t g_bt_hci_log_data_ctl = {0};
|
||||
static bt_hci_log_t g_bt_hci_log_adv_ctl = {0};
|
||||
|
||||
uint8_t bt_hci_log_h4_type_to_data_type(uint8_t h4_type)
|
||||
{
|
||||
switch (h4_type) {
|
||||
case 0x05:
|
||||
return HCI_LOG_DATA_TYPE_ISO_DATA;
|
||||
default:
|
||||
return h4_type;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bt_hci_log_init(void)
|
||||
{
|
||||
uint8_t *g_bt_hci_log_data_buffer = NULL;
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/portmacro.h"
|
||||
|
||||
#include "esp_timer.h"
|
||||
#include "bt_ble_insights.h"
|
||||
#include "bt_common.h"
|
||||
#include "hci_log/bt_hci_log.h"
|
||||
|
||||
#if (BT_HCI_LOG_INCLUDED == TRUE) && BT_HCI_INSIGHTS_INCLUDED
|
||||
static uint8_t s_hci_log_seq_num = 0;
|
||||
static portMUX_TYPE s_hci_log_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
#define HCI_LOG_INSIGHTS_LINE_SIZE 128U
|
||||
#define HCI_LOG_INSIGHTS_TS_LEN 8U
|
||||
|
||||
static const char *bt_hci_log_insights_label(uint8_t data_type)
|
||||
{
|
||||
switch (data_type) {
|
||||
case HCI_LOG_DATA_TYPE_COMMAND:
|
||||
return "C";
|
||||
case HCI_LOG_DATA_TYPE_H2C_ACL:
|
||||
return "H";
|
||||
case HCI_LOG_DATA_TYPE_SCO:
|
||||
return "S";
|
||||
case HCI_LOG_DATA_TYPE_EVENT:
|
||||
return "E";
|
||||
case HCI_LOG_DATA_TYPE_ADV:
|
||||
return "ADV";
|
||||
case HCI_LOG_DATA_TYPE_C2H_ACL:
|
||||
return "D";
|
||||
case HCI_LOG_DATA_TYPE_ISO_DATA:
|
||||
return "I";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void bt_hci_log_record_insights(uint8_t data_type, const uint8_t *data, uint16_t data_len)
|
||||
{
|
||||
const char *label = bt_hci_log_insights_label(data_type);
|
||||
char line[HCI_LOG_INSIGHTS_LINE_SIZE];
|
||||
uint8_t ts_bytes[HCI_LOG_INSIGHTS_TS_LEN];
|
||||
uint64_t timestamp;
|
||||
uint8_t seq_num;
|
||||
int offset;
|
||||
|
||||
if (!BT_BLE_INSIGHTS_AVAILABLE || label == NULL || data == NULL || data_len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
portENTER_CRITICAL(&s_hci_log_mux);
|
||||
seq_num = ++s_hci_log_seq_num;
|
||||
portEXIT_CRITICAL(&s_hci_log_mux);
|
||||
|
||||
timestamp = esp_timer_get_time();
|
||||
memcpy(ts_bytes, ×tamp, sizeof(ts_bytes));
|
||||
|
||||
offset = snprintf(line, sizeof(line), "%02x %s:", (unsigned int)seq_num, label);
|
||||
if (offset < 0 || (size_t)offset >= sizeof(line) - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(ts_bytes) && offset <= (int)sizeof(line) - 3; i++) {
|
||||
offset += snprintf(&line[offset], sizeof(line) - offset, "%02x", ts_bytes[i]);
|
||||
}
|
||||
|
||||
if (offset < 0 || (size_t)offset >= sizeof(line) - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
line[offset++] = ' ';
|
||||
line[offset] = '\0';
|
||||
|
||||
for (uint16_t i = 0; i < data_len && offset <= (int)sizeof(line) - 3; i++) {
|
||||
offset += snprintf(&line[offset], sizeof(line) - offset, "%02X", data[i]);
|
||||
}
|
||||
|
||||
ble_insights_log(line);
|
||||
}
|
||||
#endif
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -102,6 +102,17 @@ esp_err_t bt_hci_log_record_hci_data(uint8_t data_type, uint8_t *data, uint16_t
|
||||
*/
|
||||
esp_err_t bt_hci_log_record_hci_adv(uint8_t data_type, uint8_t *data, uint8_t data_len);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Convert HCI H4 packet type to HCI log data type.
|
||||
*
|
||||
* @param h4_type : HCI H4 packet type byte
|
||||
*
|
||||
* @return corresponding HCI log data type
|
||||
*
|
||||
*/
|
||||
uint8_t bt_hci_log_h4_type_to_data_type(uint8_t h4_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __BT_BLE_INSIGHTS_H__
|
||||
#define __BT_BLE_INSIGHTS_H__
|
||||
|
||||
#if __has_include("ble_insights.h")
|
||||
#include "ble_insights.h"
|
||||
#define BT_BLE_INSIGHTS_AVAILABLE 1
|
||||
#else
|
||||
#define BT_BLE_INSIGHTS_AVAILABLE 0
|
||||
static inline void ble_insights_log(const char *log)
|
||||
{
|
||||
(void)log;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BT_BLE_INSIGHTS_H__ */
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -100,6 +100,13 @@
|
||||
#define BT_HCI_LOG_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
// HCI INSIGHTS LOG
|
||||
#if UC_BT_HCI_LOG_INSIGHTS_ENABLE
|
||||
#define BT_HCI_INSIGHTS_INCLUDED UC_BT_HCI_LOG_INSIGHTS_ENABLE
|
||||
#else
|
||||
#define BT_HCI_INSIGHTS_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
// HCI LOG TO SPI
|
||||
#if UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
|
||||
#define BT_BLE_LOG_SPI_OUT_HCI_ENABLED UC_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
|
||||
@@ -117,10 +124,10 @@
|
||||
#if UC_BT_HCI_LOG_DATA_BUFFER_SIZE
|
||||
#define HCI_LOG_DATA_BUFFER_SIZE UC_BT_HCI_LOG_DATA_BUFFER_SIZE
|
||||
#else
|
||||
#define HCI_BUFFER_SIZE (5)
|
||||
#define HCI_LOG_DATA_BUFFER_SIZE (5)
|
||||
#endif
|
||||
|
||||
#if UC_BT_HCI_ADV_BUFFER_SIZE
|
||||
#if UC_BT_HCI_LOG_ADV_BUFFER_SIZE
|
||||
#define HCI_LOG_ADV_BUFFER_SIZE UC_BT_HCI_LOG_ADV_BUFFER_SIZE
|
||||
#else
|
||||
#define HCI_LOG_ADV_BUFFER_SIZE (5)
|
||||
@@ -277,4 +284,8 @@ typedef struct {
|
||||
#define BD_ADDR_LEN 6 /* Device address length */
|
||||
typedef UINT8 BD_ADDR[BD_ADDR_LEN]; /* Device address */
|
||||
|
||||
#if (BT_HCI_LOG_INCLUDED == TRUE) && BT_HCI_INSIGHTS_INCLUDED
|
||||
void bt_hci_log_record_insights(uint8_t data_type, const uint8_t *data, uint16_t data_len);
|
||||
#endif
|
||||
|
||||
#endif /* _BT_COMMON_H_ */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -176,4 +176,12 @@
|
||||
#define UC_BT_HCI_LOG_ADV_BUFFER_SIZE (5)
|
||||
#endif
|
||||
|
||||
|
||||
// HCI LOG INSIGHTS
|
||||
#ifdef CONFIG_BT_HCI_LOG_INSIGHTS_ENABLE
|
||||
#define UC_BT_HCI_LOG_INSIGHTS_ENABLE TRUE
|
||||
#else
|
||||
#define UC_BT_HCI_LOG_INSIGHTS_ENABLE FALSE
|
||||
#endif
|
||||
|
||||
#endif /* __BT_USER_CONFIG_H__ */
|
||||
|
||||
@@ -575,7 +575,7 @@ config BT_CTRL_CHECK_CONNECT_IND_ACCESS_ADDRESS
|
||||
config BT_CTRL_BLE_MIN_CONN_INTERVAL_ENABLE
|
||||
bool "Allow BLE connection interval below the spec minimum"
|
||||
default y
|
||||
select BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT if BT_BLUEDROID_ENABLED
|
||||
select BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT if BT_BLUEDROID_ENABLED || BT_NIMBLE_ENABLED
|
||||
help
|
||||
Enabling this option allows the BLE controller to use a connection interval
|
||||
smaller than the Bluetooth Core specification minimum of 7.5 ms. On
|
||||
@@ -590,12 +590,9 @@ config BT_CTRL_BLE_MIN_CONN_INTERVAL_ENABLE
|
||||
This option is enabled by default. Disable it to stay compliant with the BLE
|
||||
specification (minimum connection interval 7.5 ms).
|
||||
|
||||
Host stack: When Bluedroid is the BLE host, enabling this option also selects
|
||||
BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT so the host accepts connection
|
||||
intervals below the spec minimum. NimBLE host does not provide equivalent
|
||||
support yet; it is planned for a future release. Until then, use Bluedroid
|
||||
if you need coordinated host and controller behavior for sub-minimum
|
||||
intervals.
|
||||
Host stack: Enabling this option also selects
|
||||
BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT so the active BLE host accepts
|
||||
connection intervals below the spec minimum.
|
||||
|
||||
menu "Controller debug log Options (Experimental)"
|
||||
config BT_CTRL_LE_LOG_EN
|
||||
|
||||
@@ -1388,23 +1388,6 @@ config BT_BLE_RPA_TIMEOUT
|
||||
This set RPA timeout of Controller and Host.
|
||||
Default is 900 s (15 minutes). Range is 1 s to 1 hour (3600 s).
|
||||
|
||||
config BT_BLE_HOST_ALLOW_SUB_SPEC_MIN_CONN_INT
|
||||
bool "Allow BLE connection interval below Bluetooth Core Spec minimum (disable host check)"
|
||||
depends on BT_BLE_ENABLED
|
||||
default n
|
||||
help
|
||||
When enabled, the Bluedroid host skips the minimum BLE connection
|
||||
interval validation (Bluetooth Core Spec minimum is 0x0006 / 7.5 ms)
|
||||
and accepts any non-zero interval value from the application. The
|
||||
BLE controller then enforces what is actually allowed; how small the
|
||||
connection interval may be depends on controller capability and its
|
||||
own configuration, not on this host option text.
|
||||
|
||||
End users should NOT set this option directly. In typical IDF builds it
|
||||
follows the active Controller integration when that Controller supports
|
||||
this mode; use the Controller's own configuration (menu entries and symbol
|
||||
names differ by chip) instead of toggling this host symbol manually.
|
||||
|
||||
menuconfig BT_BLE_50_FEATURES_SUPPORTED
|
||||
bool "Enable BLE 5.0 and above features(please disable BLE 4.2 if enable BLE 5.0)"
|
||||
depends on (BT_BLE_ENABLED && ((BT_CONTROLLER_ENABLED && SOC_BLE_50_SUPPORTED) || BT_CONTROLLER_DISABLED))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_bluedroid_hci.h"
|
||||
#include "common/bt_target.h"
|
||||
#include "bt_common.h"
|
||||
#include "hci/hci_trans_int.h"
|
||||
#if (BT_CONTROLLER_INCLUDED == TRUE)
|
||||
#include "esp_bt.h"
|
||||
@@ -69,7 +70,11 @@ void hci_host_send_packet(uint8_t *data, uint16_t len)
|
||||
{
|
||||
#if (BT_HCI_LOG_INCLUDED == TRUE)
|
||||
if (data != NULL && len > 1) {
|
||||
bt_hci_log_record_hci_data(data[0], &data[1], (uint16_t)(len - 1));
|
||||
uint8_t data_type = bt_hci_log_h4_type_to_data_type(data[0]);
|
||||
bt_hci_log_record_hci_data(data_type, &data[1], (uint16_t)(len - 1));
|
||||
#if BT_HCI_INSIGHTS_INCLUDED
|
||||
bt_hci_log_record_insights(data_type, &data[1], (uint16_t)(len - 1));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "esp_bt.h"
|
||||
#endif
|
||||
#include "esp_bluedroid_hci.h"
|
||||
#include "bt_common.h"
|
||||
|
||||
#if (C2H_FLOW_CONTROL_INCLUDED == TRUE)
|
||||
#include "l2c_int.h"
|
||||
@@ -601,14 +602,20 @@ void bt_record_hci_data(uint8_t *data, uint16_t len)
|
||||
#endif // (BLE_50_FEATURE_SUPPORT == TRUE)
|
||||
)) {
|
||||
bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2);
|
||||
#if BT_HCI_INSIGHTS_INCLUDED
|
||||
bt_hci_log_record_insights(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2);
|
||||
#endif
|
||||
} else {
|
||||
uint8_t data_type;
|
||||
if (data[0] == HCI_LOG_DATA_TYPE_ISO_DATA) {
|
||||
if (data[0] == DATA_TYPE_ISO) {
|
||||
data_type = HCI_LOG_DATA_TYPE_ISO_DATA;
|
||||
} else {
|
||||
data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]);
|
||||
}
|
||||
bt_hci_log_record_hci_data(data_type, &data[1], len - 1);
|
||||
#if BT_HCI_INSIGHTS_INCLUDED
|
||||
bt_hci_log_record_insights(data_type, &data[1], len - 1);
|
||||
#endif
|
||||
}
|
||||
#endif // (BT_HCI_LOG_INCLUDED == TRUE)
|
||||
}
|
||||
|
||||
@@ -917,6 +917,14 @@ menu "Services"
|
||||
help
|
||||
Defines maximum number of report characteristics per service instance
|
||||
|
||||
config BT_NIMBLE_RAS_SERVICE
|
||||
depends on BT_NIMBLE_CHANNEL_SOUNDING
|
||||
bool "RAS service"
|
||||
default y
|
||||
help
|
||||
Enable RAS Service
|
||||
|
||||
|
||||
menuconfig BT_NIMBLE_BAS_SERVICE
|
||||
bool "Battery service"
|
||||
default y
|
||||
|
||||
@@ -78,7 +78,11 @@ void ble_hci_trans_cfg_hs(ble_hci_trans_rx_cmd_fn *cmd_cb,
|
||||
void esp_vhci_host_send_packet_wrapper(uint8_t *data, uint16_t len)
|
||||
{
|
||||
#if (BT_HCI_LOG_INCLUDED == TRUE)
|
||||
bt_hci_log_record_hci_data(data[0], &data[1], len - 1);
|
||||
uint8_t data_type = bt_hci_log_h4_type_to_data_type(data[0]);
|
||||
bt_hci_log_record_hci_data(data_type, &data[1], len - 1);
|
||||
#if BT_HCI_INSIGHTS_INCLUDED
|
||||
bt_hci_log_record_insights(data_type, &data[1], len - 1);
|
||||
#endif
|
||||
#endif
|
||||
#if CONFIG_BT_BLE_LOG_SPI_OUT_HCI_ENABLED
|
||||
ble_log_spi_out_hci_write(BLE_LOG_SPI_OUT_SOURCE_HCI_DOWNSTREAM, data, len);
|
||||
@@ -178,7 +182,6 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
|
||||
{
|
||||
struct os_mbuf *m = NULL;
|
||||
int rc;
|
||||
int sr;
|
||||
|
||||
int retry_count = 1;
|
||||
|
||||
@@ -212,9 +215,7 @@ static void ble_hci_rx_acl(uint8_t *data, uint16_t len)
|
||||
os_mbuf_free_chain(m);
|
||||
return;
|
||||
}
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
ble_transport_to_hs_acl(m);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -237,18 +238,24 @@ static void dummy_controller_rcv_pkt_ready(void)
|
||||
void bt_record_hci_data(uint8_t *data, uint16_t len)
|
||||
{
|
||||
#if (BT_HCI_LOG_INCLUDED == TRUE)
|
||||
if ((data[0] == BLE_HCI_UART_H4_EVT) && (data[1] == BLE_HCI_EVCODE_LE_META) && ((data[3] == BLE_HCI_LE_SUBEV_ADV_RPT) || (data[3] == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT)
|
||||
if (len < 2) {
|
||||
return;
|
||||
}
|
||||
if ((len >= 4) && (data[0] == BLE_HCI_UART_H4_EVT) && (data[1] == BLE_HCI_EVCODE_LE_META) && ((data[3] == BLE_HCI_LE_SUBEV_ADV_RPT) || (data[3] == BLE_HCI_LE_SUBEV_DIRECT_ADV_RPT)
|
||||
|| (data[3] == BLE_HCI_LE_SUBEV_EXT_ADV_RPT) || (data[3] == BLE_HCI_LE_SUBEV_PERIODIC_ADV_RPT))) {
|
||||
bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2);
|
||||
#if BT_HCI_INSIGHTS_INCLUDED
|
||||
bt_hci_log_record_insights(HCI_LOG_DATA_TYPE_ADV, &data[2], len - 2);
|
||||
#endif
|
||||
} else {
|
||||
uint8_t data_type;
|
||||
if (data[0] == HCI_LOG_DATA_TYPE_ISO_DATA) {
|
||||
data_type = HCI_LOG_DATA_TYPE_ISO_DATA;
|
||||
} else {
|
||||
data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]);
|
||||
}
|
||||
data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : bt_hci_log_h4_type_to_data_type(data[0]));
|
||||
bt_hci_log_record_hci_data(data_type, &data[1], len - 1);
|
||||
#if BT_HCI_INSIGHTS_INCLUDED
|
||||
bt_hci_log_record_insights(data_type, &data[1], len - 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // (BT_HCI_LOG_INCLUDED == TRUE)
|
||||
}
|
||||
|
||||
|
||||
Submodule components/bt/host/nimble/nimble updated: 5d8b70207a...bdc5010548
@@ -2382,4 +2382,12 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BT_NIMBLE_INSIGHTS_ENABLE
|
||||
#ifdef CONFIG_BT_NIMBLE_INSIGHTS_ENABLE
|
||||
#define MYNEWT_VAL_BT_NIMBLE_INSIGHTS_ENABLE CONFIG_BT_NIMBLE_INSIGHTS_ENABLE
|
||||
#else
|
||||
#define MYNEWT_VAL_BT_NIMBLE_INSIGHTS_ENABLE (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
portMUX_TYPE ble_port_mutex = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static SemaphoreHandle_t npl_eventq_sync;
|
||||
|
||||
#if BLE_NPL_USE_ESP_TIMER
|
||||
static const char *TAG = "Timer";
|
||||
#endif
|
||||
@@ -197,6 +199,115 @@ IRAM_ATTR in_isr(void)
|
||||
return xPortInIsrContext() != 0;
|
||||
}
|
||||
|
||||
static void
|
||||
npl_eventq_sync_init(void)
|
||||
{
|
||||
if (npl_eventq_sync == NULL) {
|
||||
npl_eventq_sync = xSemaphoreCreateMutex();
|
||||
BLE_LL_ASSERT(npl_eventq_sync);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
npl_eventq_lock(void)
|
||||
{
|
||||
if (!in_isr()) {
|
||||
BLE_LL_ASSERT(npl_eventq_sync);
|
||||
xSemaphoreTake(npl_eventq_sync, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
npl_eventq_unlock(void)
|
||||
{
|
||||
if (!in_isr()) {
|
||||
xSemaphoreGive(npl_eventq_sync);
|
||||
}
|
||||
}
|
||||
|
||||
static bool IRAM_ATTR
|
||||
npl_eventq_queued_get_isr(struct ble_npl_event_freertos *event)
|
||||
{
|
||||
bool queued;
|
||||
|
||||
portENTER_CRITICAL_ISR(&ble_port_mutex);
|
||||
queued = event->queued;
|
||||
portEXIT_CRITICAL_ISR(&ble_port_mutex);
|
||||
return queued;
|
||||
}
|
||||
|
||||
static void IRAM_ATTR
|
||||
npl_eventq_queued_set_isr(struct ble_npl_event_freertos *event, bool queued)
|
||||
{
|
||||
portENTER_CRITICAL_ISR(&ble_port_mutex);
|
||||
event->queued = queued;
|
||||
portEXIT_CRITICAL_ISR(&ble_port_mutex);
|
||||
}
|
||||
|
||||
static bool IRAM_ATTR
|
||||
npl_eventq_queued_claim_isr(struct ble_npl_event_freertos *event)
|
||||
{
|
||||
bool already;
|
||||
|
||||
portENTER_CRITICAL_ISR(&ble_port_mutex);
|
||||
already = event->queued;
|
||||
if (!already) {
|
||||
event->queued = true;
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&ble_port_mutex);
|
||||
return already;
|
||||
}
|
||||
|
||||
static void IRAM_ATTR
|
||||
npl_eventq_queued_set_task(struct ble_npl_event_freertos *event, bool queued)
|
||||
{
|
||||
portENTER_CRITICAL(&ble_port_mutex);
|
||||
event->queued = queued;
|
||||
portEXIT_CRITICAL(&ble_port_mutex);
|
||||
}
|
||||
|
||||
static bool IRAM_ATTR
|
||||
npl_eventq_queued_get_task(struct ble_npl_event_freertos *event)
|
||||
{
|
||||
bool queued;
|
||||
|
||||
portENTER_CRITICAL(&ble_port_mutex);
|
||||
queued = event->queued;
|
||||
portEXIT_CRITICAL(&ble_port_mutex);
|
||||
return queued;
|
||||
}
|
||||
|
||||
static bool IRAM_ATTR
|
||||
npl_eventq_queued_claim(struct ble_npl_event_freertos *event)
|
||||
{
|
||||
bool already;
|
||||
|
||||
portENTER_CRITICAL(&ble_port_mutex);
|
||||
already = event->queued;
|
||||
if (!already) {
|
||||
event->queued = true;
|
||||
}
|
||||
portEXIT_CRITICAL(&ble_port_mutex);
|
||||
return already;
|
||||
}
|
||||
|
||||
static void IRAM_ATTR
|
||||
npl_eventq_lost_event_clear(struct ble_npl_event *ev)
|
||||
{
|
||||
struct ble_npl_event_freertos *lost;
|
||||
|
||||
if (ev == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
lost = (struct ble_npl_event_freertos *)ev->event;
|
||||
if (lost == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
lost->queued = false;
|
||||
}
|
||||
|
||||
struct ble_npl_event *
|
||||
IRAM_ATTR npl_freertos_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo)
|
||||
{
|
||||
@@ -211,16 +322,63 @@ IRAM_ATTR npl_freertos_eventq_get(struct ble_npl_eventq *evq, ble_npl_time_t tmo
|
||||
if( woken == pdTRUE ) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
} else {
|
||||
ret = xQueueReceive(eventq->q, &ev, tmo);
|
||||
}
|
||||
BLE_LL_ASSERT(ret == pdPASS || ret == errQUEUE_EMPTY);
|
||||
BLE_LL_ASSERT(ret == pdPASS || ret == errQUEUE_EMPTY);
|
||||
|
||||
if (ev) {
|
||||
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
|
||||
if (event) {
|
||||
event->queued = false;
|
||||
}
|
||||
if (ev) {
|
||||
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
|
||||
if (event) {
|
||||
npl_eventq_queued_set_isr(event, false);
|
||||
}
|
||||
}
|
||||
} else if (tmo == 0) {
|
||||
npl_eventq_lock();
|
||||
portENTER_CRITICAL(&ble_port_mutex);
|
||||
ret = xQueueReceive(eventq->q, &ev, 0);
|
||||
if (ret == pdPASS && ev != NULL) {
|
||||
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
|
||||
if (event) {
|
||||
event->queued = false;
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL(&ble_port_mutex);
|
||||
npl_eventq_unlock();
|
||||
} else {
|
||||
TickType_t deadline = 0;
|
||||
TickType_t remaining;
|
||||
|
||||
if (tmo != portMAX_DELAY) {
|
||||
deadline = xTaskGetTickCount() + tmo;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (tmo == portMAX_DELAY) {
|
||||
ret = xQueuePeek(eventq->q, &ev, portMAX_DELAY);
|
||||
} else {
|
||||
remaining = deadline - xTaskGetTickCount();
|
||||
if (remaining > tmo) {
|
||||
return NULL;
|
||||
}
|
||||
ret = xQueuePeek(eventq->q, &ev, remaining);
|
||||
}
|
||||
if (ret != pdPASS) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
npl_eventq_lock();
|
||||
portENTER_CRITICAL(&ble_port_mutex);
|
||||
ret = xQueueReceive(eventq->q, &ev, 0);
|
||||
if (ret == pdPASS && ev != NULL) {
|
||||
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
|
||||
if (event) {
|
||||
event->queued = false;
|
||||
}
|
||||
portEXIT_CRITICAL(&ble_port_mutex);
|
||||
npl_eventq_unlock();
|
||||
break;
|
||||
}
|
||||
portEXIT_CRITICAL(&ble_port_mutex);
|
||||
npl_eventq_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
return ev;
|
||||
@@ -234,22 +392,35 @@ IRAM_ATTR npl_freertos_eventq_put(struct ble_npl_eventq *evq, struct ble_npl_eve
|
||||
struct ble_npl_eventq_freertos *eventq = (struct ble_npl_eventq_freertos *)evq->eventq;
|
||||
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
|
||||
|
||||
if (event->queued) {
|
||||
return;
|
||||
}
|
||||
|
||||
event->queued = true;
|
||||
|
||||
if (in_isr()) {
|
||||
if (npl_eventq_queued_claim_isr(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = xQueueSendToBackFromISR(eventq->q, &ev, &woken);
|
||||
if (ret != pdPASS) {
|
||||
npl_eventq_queued_set_isr(event, false);
|
||||
return;
|
||||
}
|
||||
if( woken == pdTRUE ) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
ret = xQueueSendToBack(eventq->q, &ev, portMAX_DELAY);
|
||||
}
|
||||
npl_eventq_lock();
|
||||
|
||||
BLE_LL_ASSERT(ret == pdPASS);
|
||||
if (npl_eventq_queued_claim(event)) {
|
||||
npl_eventq_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
ret = xQueueSendToBack(eventq->q, &ev, 0);
|
||||
if (ret != pdPASS) {
|
||||
ESP_LOGW("NimBLE", "eventq put: queue full, event dropped");
|
||||
npl_eventq_queued_set_task(event, false);
|
||||
}
|
||||
npl_eventq_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -260,22 +431,35 @@ IRAM_ATTR npl_freertos_eventq_put_to_front(struct ble_npl_eventq *evq, struct bl
|
||||
struct ble_npl_eventq_freertos *eventq = (struct ble_npl_eventq_freertos *)evq->eventq;
|
||||
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
|
||||
|
||||
if (event->queued) {
|
||||
return;
|
||||
}
|
||||
|
||||
event->queued = true;
|
||||
|
||||
if (in_isr()) {
|
||||
if (npl_eventq_queued_claim_isr(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ret = xQueueSendToFrontFromISR(eventq->q, &ev, &woken);
|
||||
if (ret != pdPASS) {
|
||||
npl_eventq_queued_set_isr(event, false);
|
||||
return;
|
||||
}
|
||||
if( woken == pdTRUE ) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
ret = xQueueSendToFront(eventq->q, &ev, portMAX_DELAY);
|
||||
}
|
||||
npl_eventq_lock();
|
||||
|
||||
BLE_LL_ASSERT(ret == pdPASS);
|
||||
if (npl_eventq_queued_claim(event)) {
|
||||
npl_eventq_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
ret = xQueueSendToFront(eventq->q, &ev, 0);
|
||||
if (ret != pdPASS) {
|
||||
ESP_LOGW("NimBLE", "eventq put_to_front: queue full, event dropped");
|
||||
npl_eventq_queued_set_task(event, false);
|
||||
}
|
||||
npl_eventq_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -286,14 +470,11 @@ IRAM_ATTR npl_freertos_eventq_remove(struct ble_npl_eventq *evq,
|
||||
BaseType_t ret;
|
||||
int i;
|
||||
int count;
|
||||
bool removed;
|
||||
BaseType_t woken, woken2;
|
||||
struct ble_npl_eventq_freertos *eventq = (struct ble_npl_eventq_freertos *)evq->eventq;
|
||||
struct ble_npl_event_freertos *event = (struct ble_npl_event_freertos *)ev->event;
|
||||
|
||||
if (!event->queued) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX We cannot extract element from inside FreeRTOS queue so as a quick
|
||||
* workaround we'll just remove all elements and add them back except the
|
||||
@@ -302,46 +483,77 @@ IRAM_ATTR npl_freertos_eventq_remove(struct ble_npl_eventq *evq,
|
||||
*/
|
||||
|
||||
if (in_isr()) {
|
||||
if (!npl_eventq_queued_get_isr(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
removed = false;
|
||||
woken = pdFALSE;
|
||||
|
||||
portENTER_CRITICAL_ISR(&ble_port_mutex);
|
||||
count = uxQueueMessagesWaitingFromISR(eventq->q);
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = xQueueReceiveFromISR(eventq->q, &tmp_ev, &woken2);
|
||||
BLE_LL_ASSERT(ret == pdPASS);
|
||||
if (ret != pdPASS) {
|
||||
break;
|
||||
}
|
||||
woken |= woken2;
|
||||
|
||||
if (tmp_ev == ev) {
|
||||
removed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = xQueueSendToBackFromISR(eventq->q, &tmp_ev, &woken2);
|
||||
BLE_LL_ASSERT(ret == pdPASS);
|
||||
if (ret != pdPASS) {
|
||||
npl_eventq_lost_event_clear(tmp_ev);
|
||||
break;
|
||||
}
|
||||
woken |= woken2;
|
||||
}
|
||||
if (removed) {
|
||||
event->queued = false;
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&ble_port_mutex);
|
||||
|
||||
if( woken == pdTRUE ) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
} else {
|
||||
portENTER_CRITICAL(&ble_port_mutex);
|
||||
removed = false;
|
||||
|
||||
npl_eventq_lock();
|
||||
if (!npl_eventq_queued_get_task(event)) {
|
||||
npl_eventq_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
portENTER_CRITICAL(&ble_port_mutex);
|
||||
count = uxQueueMessagesWaiting(eventq->q);
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = xQueueReceive(eventq->q, &tmp_ev, 0);
|
||||
BLE_LL_ASSERT(ret == pdPASS);
|
||||
if (ret != pdPASS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmp_ev == ev) {
|
||||
removed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = xQueueSendToBack(eventq->q, &tmp_ev, 0);
|
||||
BLE_LL_ASSERT(ret == pdPASS);
|
||||
if (ret != pdPASS) {
|
||||
npl_eventq_lost_event_clear(tmp_ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (removed) {
|
||||
event->queued = 0;
|
||||
}
|
||||
|
||||
portEXIT_CRITICAL(&ble_port_mutex);
|
||||
}
|
||||
|
||||
event->queued = 0;
|
||||
npl_eventq_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
ble_npl_error_t
|
||||
@@ -1116,6 +1328,9 @@ int npl_freertos_set_controller_npl_info(ble_npl_count_info_t *ctrl_npl_info)
|
||||
int npl_freertos_mempool_init(void)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
npl_eventq_sync_init();
|
||||
|
||||
uint16_t ble_total_evt_count = 0;
|
||||
uint16_t ble_total_co_count = 0;
|
||||
uint16_t ble_total_evtq_count = 0;
|
||||
@@ -1205,6 +1420,11 @@ int npl_freertos_mempool_init(void)
|
||||
|
||||
return 0;
|
||||
_error:
|
||||
if (npl_eventq_sync) {
|
||||
vSemaphoreDelete(npl_eventq_sync);
|
||||
npl_eventq_sync = NULL;
|
||||
}
|
||||
|
||||
if (ble_freertos_ev_buf) {
|
||||
bt_osi_mem_free_internal(ble_freertos_ev_buf);
|
||||
ble_freertos_ev_buf = NULL;
|
||||
@@ -1234,6 +1454,11 @@ _error:
|
||||
|
||||
void npl_freertos_mempool_deinit(void)
|
||||
{
|
||||
if (npl_eventq_sync) {
|
||||
vSemaphoreDelete(npl_eventq_sync);
|
||||
npl_eventq_sync = NULL;
|
||||
}
|
||||
|
||||
if (ble_freertos_ev_buf) {
|
||||
bt_osi_mem_free_internal(ble_freertos_ev_buf);
|
||||
ble_freertos_ev_buf = NULL;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -302,6 +302,21 @@ static void attach_report_listeners(esp_gatt_if_t gattc_if, esp_hidh_dev_t *dev)
|
||||
|
||||
//subscribe to battery notifications
|
||||
if (dev->ble.battery_handle) {
|
||||
uint8_t *rdata = NULL;
|
||||
uint16_t rlen = 0;
|
||||
|
||||
if (event_loop_handle &&
|
||||
read_char(gattc_if, dev->ble.conn_id, dev->ble.battery_handle,
|
||||
ESP_GATT_AUTH_REQ_NO_MITM, &rdata, &rlen) == ESP_GATT_OK &&
|
||||
rlen >= 1 && rdata != NULL) {
|
||||
esp_hidh_event_data_t p = {0};
|
||||
p.battery.dev = dev;
|
||||
p.battery.level = rdata[0];
|
||||
esp_event_post_to(event_loop_handle, ESP_HIDH_EVENTS, ESP_HIDH_BATTERY_EVENT,
|
||||
&p, sizeof(esp_hidh_event_data_t), portMAX_DELAY);
|
||||
}
|
||||
free(rdata);
|
||||
|
||||
register_for_notify(gattc_if, dev->addr.bda, dev->ble.battery_handle);
|
||||
if (dev->ble.battery_ccc_handle) {
|
||||
//Write CCC descr to enable notifications
|
||||
|
||||
@@ -43,6 +43,9 @@ static void (*s_prev_sync_cb)(void) = NULL;
|
||||
static struct ble_gap_event_listener nimble_gap_event_listener;
|
||||
static void nimble_host_synced(void);
|
||||
void nimble_host_reset(int reason);
|
||||
static void nimble_report_write_cb(uint16_t attr_handle, uint8_t report_type, uint8_t report_id,
|
||||
const uint8_t *data, uint16_t len);
|
||||
static void nimble_char_write_cb(uint16_t attr_handle, uint16_t char_uuid16, uint8_t value);
|
||||
|
||||
static inline void lock_hidd(void)
|
||||
{
|
||||
@@ -349,6 +352,8 @@ static int nimble_hidd_dev_deinit(void *devp)
|
||||
ble_hs_cfg.sync_cb = s_prev_sync_cb;
|
||||
}
|
||||
ble_hs_cfg.gatts_register_cb = NULL;
|
||||
ble_svc_hid_register_report_write_cb(NULL);
|
||||
ble_svc_hid_register_char_write_cb(NULL);
|
||||
unlock_hidd();
|
||||
|
||||
/* Known timing issue: STOP_EVENT is posted here but ble_hid_free_config (called
|
||||
@@ -425,6 +430,129 @@ static hidd_le_report_item_t* find_report_by_usage_and_type(uint8_t dev_index, u
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void nimble_report_write_cb(uint16_t attr_handle, uint8_t report_type, uint8_t report_id,
|
||||
const uint8_t *data, uint16_t len)
|
||||
{
|
||||
lock_hidd();
|
||||
if (s_dev == NULL || s_dev->event_loop_handle == NULL || data == NULL) {
|
||||
unlock_hidd();
|
||||
return;
|
||||
}
|
||||
|
||||
hidd_le_report_item_t *match = NULL;
|
||||
uint8_t map_index = 0;
|
||||
for (uint8_t d = 0; d < s_dev->devices_len && match == NULL; d++) {
|
||||
for (uint8_t r = 0; r < s_dev->devices[d].reports_len; r++) {
|
||||
hidd_le_report_item_t *item = &s_dev->devices[d].reports[r];
|
||||
if (item->handle == attr_handle) {
|
||||
match = item;
|
||||
map_index = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match == NULL) {
|
||||
unlock_hidd();
|
||||
return;
|
||||
}
|
||||
|
||||
if (report_type != ESP_HID_REPORT_TYPE_OUTPUT &&
|
||||
report_type != ESP_HID_REPORT_TYPE_FEATURE) {
|
||||
ESP_LOGD(TAG, "Ignoring host write for unsupported report type=%u, id=%u, handle=%u",
|
||||
report_type, report_id, attr_handle);
|
||||
unlock_hidd();
|
||||
return;
|
||||
}
|
||||
|
||||
size_t event_data_size = sizeof(esp_hidd_event_data_t);
|
||||
if (len > 0) {
|
||||
event_data_size += len;
|
||||
}
|
||||
esp_hidd_event_data_t *p_cb_param = (esp_hidd_event_data_t *)calloc(1, event_data_size);
|
||||
if (p_cb_param == NULL) {
|
||||
ESP_LOGE(TAG, "%s malloc event data failed!", __func__);
|
||||
unlock_hidd();
|
||||
return;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
memcpy(((uint8_t *)p_cb_param) + sizeof(esp_hidd_event_data_t), data, len);
|
||||
}
|
||||
|
||||
if (report_type == ESP_HID_REPORT_TYPE_OUTPUT) {
|
||||
p_cb_param->output.dev = s_dev->dev;
|
||||
p_cb_param->output.usage = match->usage;
|
||||
p_cb_param->output.report_id = report_id;
|
||||
p_cb_param->output.length = len;
|
||||
p_cb_param->output.data = (len > 0) ? (uint8_t *)data : NULL; /* fixed by esp_hidd_process_event_data_handler */
|
||||
p_cb_param->output.map_index = map_index;
|
||||
esp_event_post_to(s_dev->event_loop_handle, ESP_HIDD_EVENTS, ESP_HIDD_OUTPUT_EVENT,
|
||||
p_cb_param, event_data_size, portMAX_DELAY);
|
||||
} else if (report_type == ESP_HID_REPORT_TYPE_FEATURE) {
|
||||
p_cb_param->feature.dev = s_dev->dev;
|
||||
p_cb_param->feature.usage = match->usage;
|
||||
p_cb_param->feature.report_id = report_id;
|
||||
p_cb_param->feature.length = len;
|
||||
p_cb_param->feature.data = (len > 0) ? (uint8_t *)data : NULL; /* fixed by esp_hidd_process_event_data_handler */
|
||||
p_cb_param->feature.map_index = map_index;
|
||||
esp_event_post_to(s_dev->event_loop_handle, ESP_HIDD_EVENTS, ESP_HIDD_FEATURE_EVENT,
|
||||
p_cb_param, event_data_size, portMAX_DELAY);
|
||||
}
|
||||
free(p_cb_param);
|
||||
unlock_hidd();
|
||||
}
|
||||
|
||||
static void nimble_char_write_cb(uint16_t attr_handle, uint16_t char_uuid16, uint8_t value)
|
||||
{
|
||||
lock_hidd();
|
||||
if (s_dev == NULL || s_dev->event_loop_handle == NULL) {
|
||||
unlock_hidd();
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t map_index = 0;
|
||||
bool found = false;
|
||||
|
||||
for (uint8_t d = 0; d < s_dev->devices_len; d++) {
|
||||
if (char_uuid16 == BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE &&
|
||||
s_dev->devices[d].hid_protocol_handle == attr_handle) {
|
||||
found = true;
|
||||
map_index = d;
|
||||
break;
|
||||
}
|
||||
if (char_uuid16 == BLE_SVC_HID_CHR_UUID16_HID_CTRL_PT &&
|
||||
s_dev->devices[d].hid_control_handle == attr_handle) {
|
||||
found = true;
|
||||
map_index = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
unlock_hidd();
|
||||
return;
|
||||
}
|
||||
|
||||
esp_hidd_event_data_t cb_param = {0};
|
||||
if (char_uuid16 == BLE_SVC_HID_CHR_UUID16_PROTOCOL_MODE) {
|
||||
s_dev->protocol = value;
|
||||
cb_param.protocol_mode.dev = s_dev->dev;
|
||||
cb_param.protocol_mode.protocol_mode = value;
|
||||
cb_param.protocol_mode.map_index = map_index;
|
||||
esp_event_post_to(s_dev->event_loop_handle, ESP_HIDD_EVENTS, ESP_HIDD_PROTOCOL_MODE_EVENT,
|
||||
&cb_param, sizeof(esp_hidd_event_data_t), portMAX_DELAY);
|
||||
} else if (char_uuid16 == BLE_SVC_HID_CHR_UUID16_HID_CTRL_PT) {
|
||||
s_dev->control = value;
|
||||
cb_param.control.dev = s_dev->dev;
|
||||
cb_param.control.control = value;
|
||||
cb_param.control.map_index = map_index;
|
||||
esp_event_post_to(s_dev->event_loop_handle, ESP_HIDD_EVENTS, ESP_HIDD_CONTROL_EVENT,
|
||||
&cb_param, sizeof(esp_hidd_event_data_t), portMAX_DELAY);
|
||||
}
|
||||
unlock_hidd();
|
||||
}
|
||||
|
||||
static int nimble_hidd_dev_input_set(void *devp, size_t index, size_t id, uint8_t *data, size_t length)
|
||||
{
|
||||
hidd_le_report_item_t *p_rpt;
|
||||
@@ -843,6 +971,8 @@ esp_err_t esp_ble_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_conf
|
||||
ble_hs_cfg.reset_cb = nimble_host_reset;
|
||||
ble_hs_cfg.sync_cb = nimble_host_synced;
|
||||
ble_hs_cfg.gatts_register_cb = nimble_gatt_svr_register_cb;
|
||||
ble_svc_hid_register_report_write_cb(nimble_report_write_cb);
|
||||
ble_svc_hid_register_char_write_cb(nimble_char_write_cb);
|
||||
rc = nimble_hid_start_gatts();
|
||||
if (rc != ESP_OK) {
|
||||
if (ble_hs_cfg.reset_cb == nimble_host_reset) {
|
||||
@@ -852,6 +982,8 @@ esp_err_t esp_ble_hidd_dev_init(esp_hidd_dev_t *dev_p, const esp_hid_device_conf
|
||||
ble_hs_cfg.sync_cb = s_prev_sync_cb;
|
||||
}
|
||||
ble_hs_cfg.gatts_register_cb = NULL;
|
||||
ble_svc_hid_register_report_write_cb(NULL);
|
||||
ble_svc_hid_register_char_write_cb(NULL);
|
||||
ble_hidd_dev_free();
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -70,14 +70,14 @@ static inline void SEND_CB(void)
|
||||
static inline void LOCK_OPS(void)
|
||||
{
|
||||
if (s_ble_hidh_op_mutex) {
|
||||
xSemaphoreTake(s_ble_hidh_op_mutex, portMAX_DELAY);
|
||||
xSemaphoreTakeRecursive(s_ble_hidh_op_mutex, portMAX_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void UNLOCK_OPS(void)
|
||||
{
|
||||
if (s_ble_hidh_op_mutex) {
|
||||
xSemaphoreGive(s_ble_hidh_op_mutex);
|
||||
xSemaphoreGiveRecursive(s_ble_hidh_op_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -789,6 +789,20 @@ static void attach_report_listeners(esp_hidh_dev_t *dev)
|
||||
report = dev->reports;
|
||||
|
||||
if (dev->ble.battery_handle) {
|
||||
uint8_t *rdata = NULL;
|
||||
uint16_t rlen = 0;
|
||||
|
||||
if (event_loop_handle &&
|
||||
read_char(dev->ble.conn_id, dev->ble.battery_handle, &rdata, &rlen) == 0 &&
|
||||
rlen >= 1 && rdata != NULL) {
|
||||
esp_hidh_event_data_t p = {0};
|
||||
p.battery.dev = dev;
|
||||
p.battery.level = rdata[0];
|
||||
esp_event_post_to(event_loop_handle, ESP_HIDH_EVENTS, ESP_HIDH_BATTERY_EVENT,
|
||||
&p, sizeof(esp_hidh_event_data_t), portMAX_DELAY);
|
||||
}
|
||||
free(rdata);
|
||||
|
||||
register_for_notify(dev->ble.conn_id, dev->ble.battery_handle);
|
||||
if (dev->ble.battery_ccc_handle && dev->ble.conn_id >= 0 && dev->connected) {
|
||||
write_char_descr(dev, dev->ble.battery_ccc_handle, 2, (uint8_t *)&ccc_data);
|
||||
@@ -1174,7 +1188,7 @@ esp_err_t esp_ble_hidh_init(const esp_hidh_config_t *config)
|
||||
s_ble_hidh_cb_semaphore = xSemaphoreCreateBinary();
|
||||
ESP_RETURN_ON_FALSE(s_ble_hidh_cb_semaphore,
|
||||
ESP_ERR_NO_MEM, TAG, "Allocation failed");
|
||||
s_ble_hidh_op_mutex = xSemaphoreCreateMutex();
|
||||
s_ble_hidh_op_mutex = xSemaphoreCreateRecursiveMutex();
|
||||
if (s_ble_hidh_op_mutex == NULL) {
|
||||
vSemaphoreDelete(s_ble_hidh_cb_semaphore);
|
||||
s_ble_hidh_cb_semaphore = NULL;
|
||||
|
||||
Reference in New Issue
Block a user