Merge branch 'bugfix/fix_nimble_issue_310826_v6.1' into 'release/v6.1'

fix(nimble): Fix few nimble issues 31082026

See merge request espressif/esp-idf!52224
This commit is contained in:
Rahul Tank
2026-09-02 13:31:33 +05:30
245 changed files with 2028 additions and 1306 deletions
@@ -1,48 +1,69 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_tinycrypt_port.h"
#include <string.h>
#include "esp_crypto_lock.h"
#include "esp_private/esp_crypto_lock_internal.h"
#include "esp_crypto_periph_clk.h"
#include <tinycrypt/ecc.h>
#if SOC_ECC_SUPPORTED
#include "hal/ecc_hal.h"
#include "hal/ecc_ll.h"
#endif /* SOC_ECC_SUPPORTED */
#define ECC_MAX_PARAM_BYTES 48
#if SOC_ECC_SUPPORTED
static void esp_tinycrypt_acquire_ecc_hardware(void)
static void uecc_vli_native_to_le(uint8_t *le, const uECC_word_t *native, uint16_t len)
{
uint8_t be[ECC_MAX_PARAM_BYTES];
uECC_vli_nativeToBytes(be, len, native);
for (uint16_t i = 0; i < len; i++) {
le[i] = be[len - 1 - i];
}
}
static void uecc_vli_le_to_native(uECC_word_t *native, const uint8_t *le, uint16_t len)
{
uint8_t be[ECC_MAX_PARAM_BYTES];
for (uint16_t i = 0; i < len; i++) {
be[i] = le[len - 1 - i];
}
uECC_vli_bytesToNative(native, be, len);
}
static void esp_tinycrypt_acquire_ecc_hardware(void)
{
esp_crypto_ecc_lock_acquire();
ECC_RCC_ATOMIC() {
ecc_ll_enable_bus_clock(true);
ecc_ll_power_up();
ecc_ll_reset_register();
}
esp_crypto_ecc_enable_periph_clk(true);
}
static void esp_tinycrypt_release_ecc_hardware(void)
static void esp_tinycrypt_release_ecc_hardware(void)
{
ECC_RCC_ATOMIC() {
ecc_ll_enable_bus_clock(false);
ecc_ll_power_down();
}
esp_crypto_ecc_enable_periph_clk(false);
esp_crypto_ecc_lock_release();
}
#endif /* SOC_ECC_SUPPORTED */
int esp_tinycrypt_verify_ecc_point(const uint8_t *pk_x, const uint8_t *pk_y, uint8_t length)
{
#if SOC_ECC_SUPPORTED
int result;
uint8_t px_le[ECC_MAX_PARAM_BYTES];
uint8_t py_le[ECC_MAX_PARAM_BYTES];
uecc_vli_native_to_le(px_le, (const uECC_word_t *)pk_x, length);
uecc_vli_native_to_le(py_le, (const uECC_word_t *)pk_y, length);
esp_tinycrypt_acquire_ecc_hardware();
ecc_hal_write_verify_param(pk_x, pk_y, length);
ecc_hal_write_verify_param(px_le, py_le, length);
ecc_hal_set_mode(ECC_MODE_VERIFY);
ecc_hal_start_calc();
while (!ecc_hal_is_calc_finished());
@@ -55,17 +76,40 @@ int esp_tinycrypt_verify_ecc_point(const uint8_t *pk_x, const uint8_t *pk_y, uin
} else {
return -1;
}
#else
(void)pk_x;
(void)pk_y;
(void)length;
return -1;
#endif /* SOC_ECC_SUPPORTED */
}
int esp_tinycrypt_calc_ecc_mult(const uint8_t *p_x, const uint8_t *p_y, const uint8_t *scalar,
uint8_t *r_x, uint8_t *r_y, uint8_t num_bytes, bool verify_first)
int esp_tinycrypt_calc_ecc_mult(const uECC_word_t *point_x, const uECC_word_t *point_y,
const uECC_word_t *scalar, uECC_word_t *result_x,
uECC_word_t *result_y, uint8_t num_bytes, bool verify_first)
{
int ret = -1;
#if SOC_ECC_SUPPORTED
int ret;
ecc_mode_t work_mode = verify_first ? ECC_MODE_VERIFY_THEN_POINT_MUL : ECC_MODE_POINT_MUL;
uint8_t k_le[ECC_MAX_PARAM_BYTES];
uint8_t px_le[ECC_MAX_PARAM_BYTES];
uint8_t py_le[ECC_MAX_PARAM_BYTES];
uint8_t rx_le[ECC_MAX_PARAM_BYTES];
uint8_t ry_le[ECC_MAX_PARAM_BYTES];
memset(k_le, 0, sizeof(k_le));
memset(px_le, 0, sizeof(px_le));
memset(py_le, 0, sizeof(py_le));
memset(rx_le, 0, sizeof(rx_le));
memset(ry_le, 0, sizeof(ry_le));
uecc_vli_native_to_le(k_le, scalar, num_bytes);
uecc_vli_native_to_le(px_le, point_x, num_bytes);
uecc_vli_native_to_le(py_le, point_y, num_bytes);
esp_tinycrypt_acquire_ecc_hardware();
ecc_hal_write_mul_param(scalar, p_x, p_y, num_bytes);
ecc_hal_write_mul_param(k_le, px_le, py_le, num_bytes);
ecc_hal_set_mode(work_mode);
/*
* Enable constant-time point multiplication operations for the ECC hardware accelerator,
@@ -78,10 +122,25 @@ int esp_tinycrypt_calc_ecc_mult(const uint8_t *p_x, const uint8_t *p_y, const ui
while (!ecc_hal_is_calc_finished());
ret = ecc_hal_read_mul_result(r_x, r_y, num_bytes);
ret = ecc_hal_read_mul_result(rx_le, ry_le, num_bytes);
esp_tinycrypt_release_ecc_hardware();
return ret;
}
if (ret != 0) {
return -1;
}
uecc_vli_le_to_native(result_x, rx_le, num_bytes);
uecc_vli_le_to_native(result_y, ry_le, num_bytes);
return 0;
#else
(void)point_x;
(void)point_y;
(void)scalar;
(void)result_x;
(void)result_y;
(void)num_bytes;
(void)verify_first;
return -1;
#endif /* SOC_ECC_SUPPORTED */
}
@@ -1,15 +1,20 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc_caps.h"
#if SOC_ECC_SUPPORTED
#include <tinycrypt/ecc.h>
int esp_tinycrypt_verify_ecc_point(const uint8_t *pk_x, const uint8_t *pk_y, uint8_t length);
int esp_tinycrypt_calc_ecc_mult(const uint8_t *p_x, const uint8_t *p_y, const uint8_t *scalar,
uint8_t *r_x, uint8_t *r_y, uint8_t num_bytes, bool verify_first);
int esp_tinycrypt_calc_ecc_mult(const uECC_word_t *point_x, const uECC_word_t *point_y,
const uECC_word_t *scalar, uECC_word_t *result_x,
uECC_word_t *result_y, uint8_t num_bytes, bool verify_first);
#endif /* SOC_ECC_SUPPORTED */
+54 -38
View File
@@ -58,7 +58,6 @@
#include <tinycrypt/ecc.h>
#include <tinycrypt/ecc_platform_specific.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
@@ -699,7 +698,6 @@ void apply_z(uECC_word_t * X1, uECC_word_t * Y1, const uECC_word_t * const Z,
uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */
}
#if !SOC_ECC_SUPPORTED || SOC_ESP_NIMBLE_CONTROLLER
/* P = (x1, y1) => 2P, (x2, y2) => P' */
static void XYcZ_initial_double(uECC_word_t * X1, uECC_word_t * Y1,
uECC_word_t * X2, uECC_word_t * Y2,
@@ -765,7 +763,6 @@ static void XYcZ_addC(uECC_word_t * X1, uECC_word_t * Y1,
uECC_vli_set(X1, t7, num_words);
}
#endif /* !SOC_ECC_SUPPORTED */
void XYcZ_add(uECC_word_t * X1, uECC_word_t * Y1,
uECC_word_t * X2, uECC_word_t * Y2,
@@ -798,20 +795,28 @@ void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point,
const uECC_word_t * initial_Z,
bitcount_t num_bits, uECC_Curve curve)
{
#if SOC_ECC_SUPPORTED && !SOC_ESP_NIMBLE_CONTROLLER
wordcount_t num_words = curve->num_words;
#if SOC_ECC_SUPPORTED
wordcount_t num_words = curve->num_words;
/* Only p256r1 and p192r1 are supported currently. */
assert(curve == uECC_secp256r1()
/*
* The ECC peripheral accepts canonical scalars only. Calls using the
* regularized software scalar use one additional bit and must stay on
* the software ladder.
*/
if (initial_Z == 0 && num_bits == curve->num_n_bits &&
(curve == uECC_secp256r1()
#if uECC_SUPPORTS_secp192r1
|| curve == uECC_secp192r1()
#endif /* #if uECC_SUPPORTS_secp192r1 */
);
esp_tinycrypt_calc_ecc_mult((const uint8_t *)&point[0], (const uint8_t *)&point[num_words],
(uint8_t *)scalar, (uint8_t *)&result[0], (uint8_t *)&result[num_words],
num_words * uECC_WORD_SIZE, false);
#else
|| curve == uECC_secp192r1()
#endif /* uECC_SUPPORTS_secp192r1 */
)) {
if (esp_tinycrypt_calc_ecc_mult(point, point + num_words, scalar,
result, result + num_words,
num_words * uECC_WORD_SIZE, false) == 0) {
return;
}
}
#endif /* SOC_ECC_SUPPORTED */
{
/* R0 and R1 */
uECC_word_t Rx[2][NUM_ECC_WORDS];
uECC_word_t Ry[2][NUM_ECC_WORDS];
@@ -850,7 +855,7 @@ void EccPoint_mult(uECC_word_t * result, const uECC_word_t * point,
uECC_vli_set(result, Rx[0], num_words);
uECC_vli_set(result + num_words, Ry[0], num_words);
#endif /* SOC_ECC_SUPPORTED */
}
}
uECC_word_t regularize_k(const uECC_word_t * const k, uECC_word_t *k0,
@@ -886,22 +891,33 @@ uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
uECC_word_t *private_key,
uECC_Curve curve)
{
#if !SOC_ECC_SUPPORTED || SOC_ESP_NIMBLE_CONTROLLER
#if SOC_ECC_SUPPORTED
/*
* The ECC peripheral requires a canonical scalar. regularize_k()
* produces k + n or k + 2n for the software constant-time ladder,
* which is mathematically equivalent but outside the HW input range.
*/
if (curve == uECC_secp256r1()
#if uECC_SUPPORTS_secp192r1
|| curve == uECC_secp192r1()
#endif /* uECC_SUPPORTS_secp192r1 */
) {
EccPoint_mult(result, curve->G, private_key, 0,
curve->num_n_bits, curve);
return !EccPoint_isZero(result, curve);
}
#endif /* SOC_ECC_SUPPORTED */
uECC_word_t tmp1[NUM_ECC_WORDS];
uECC_word_t tmp2[NUM_ECC_WORDS];
uECC_word_t tmp2[NUM_ECC_WORDS];
uECC_word_t *p2[2] = {tmp1, tmp2};
uECC_word_t carry;
#endif
#if SOC_ECC_SUPPORTED && !SOC_ESP_NIMBLE_CONTROLLER
EccPoint_mult(result, curve->G, private_key, 0, curve->num_n_bits, curve);
#else
/* Regularize the bitcount for the private key so that attackers cannot
* use a side channel attack to learn the number of leading zeros. */
carry = regularize_k(private_key, tmp1, tmp2, curve);
EccPoint_mult(result, curve->G, p2[!carry], 0, curve->num_n_bits + 1, curve);
#endif
if (EccPoint_isZero(result, curve)) {
return 0;
@@ -974,21 +990,20 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve)
return -2;
}
#if SOC_ECC_SUPPORTED && !SOC_ESP_NIMBLE_CONTROLLER
if (curve != uECC_secp256r1()
#if SOC_ECC_SUPPORTED
if (curve == uECC_secp256r1()
#if uECC_SUPPORTS_secp192r1
&& curve != uECC_secp192r1()
|| curve == uECC_secp192r1()
#endif /* uECC_SUPPORTS_secp192r1 */
) {
return -5;
}
if (esp_tinycrypt_verify_ecc_point((const uint8_t *)&point[0],
(const uint8_t *)&point[num_words],
num_words * uECC_WORD_SIZE)) {
return -3;
}
#else
) {
if (esp_tinycrypt_verify_ecc_point((const uint8_t *)&point[0],
(const uint8_t *)&point[num_words],
num_words * uECC_WORD_SIZE) == 0) {
return 0;
}
}
#endif /* SOC_ECC_SUPPORTED */
{
uECC_word_t tmp1[NUM_ECC_WORDS];
uECC_word_t tmp2[NUM_ECC_WORDS];
@@ -996,9 +1011,10 @@ int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve)
curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */
/* Make sure that y^2 == x^3 + ax + b */
if (uECC_vli_equal(tmp1, tmp2, num_words) != 0)
if (uECC_vli_equal(tmp1, tmp2, num_words) != 0) {
return -3;
#endif /* SOC_ECC_SUPPORTED */
}
}
return 0;
}
+5 -10
View File
@@ -147,11 +147,9 @@ int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
uECC_word_t _private[NUM_ECC_WORDS];
uECC_word_t tmp[NUM_ECC_WORDS];
#if !SOC_ECC_SUPPORTED || SOC_ESP_NIMBLE_CONTROLLER
uECC_word_t *p2[2] = {_private, tmp};
uECC_word_t *initial_Z = 0;
uECC_word_t carry;
#endif
wordcount_t num_words = curve->num_words;
wordcount_t num_bytes = curve->num_bytes;
int r;
@@ -167,11 +165,11 @@ int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
public_key + num_bytes,
num_bytes);
#if SOC_ECC_SUPPORTED && !SOC_ESP_NIMBLE_CONTROLLER
EccPoint_mult(_public, _public, _private, 0, curve->num_n_bits, curve);
#else
/* Regularize the bitcount for the private key so that attackers cannot use a
* side channel attack to learn the number of leading zeros. */
/*
* Use the software ladder for ECDH. Its regularized scalar is unsuitable
* for the ECC peripheral, and EccPoint_mult() can otherwise silently fall
* back to the software ladder with an unregularized scalar.
*/
carry = regularize_k(_private, _private, tmp, curve);
/* If an RNG function was specified, try to get a random initial Z value to
@@ -187,17 +185,14 @@ int uECC_shared_secret(const uint8_t *public_key, const uint8_t *private_key,
EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1,
curve);
#endif
uECC_vli_nativeToBytes(secret, num_bytes, _public);
r = !EccPoint_isZero(_public, curve);
clear_and_out:
/* erasing temporary buffer used to store secret: */
#if !SOC_ECC_SUPPORTED || SOC_ESP_NIMBLE_CONTROLLER
memset(p2, 0, sizeof(p2));
__asm__ __volatile__("" :: "g"(p2) : "memory");
#endif
memset(_public, 0, sizeof(_public));
__asm__ __volatile__("" :: "g"(_public) : "memory");
memset(tmp, 0, sizeof(tmp));
@@ -101,10 +101,8 @@ int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash,
uECC_word_t tmp[NUM_ECC_WORDS];
uECC_word_t s[NUM_ECC_WORDS];
#if !SOC_ECC_SUPPORTED || SOC_ESP_NIMBLE_CONTROLLER
uECC_word_t *k2[2] = {tmp, s};
uECC_word_t carry;
#endif
uECC_word_t p[NUM_ECC_WORDS * 2];
wordcount_t num_words = curve->num_words;
wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
@@ -116,12 +114,8 @@ int uECC_sign_with_k(const uint8_t *private_key, const uint8_t *message_hash,
return 0;
}
#if SOC_ECC_SUPPORTED && !SOC_ESP_NIMBLE_CONTROLLER
EccPoint_mult(p, curve->G, k, 0, num_n_bits, curve);
#else
carry = regularize_k(k, tmp, s, curve);
EccPoint_mult(p, curve->G, k2[!carry], 0, num_n_bits + 1, curve);
#endif
if (uECC_vli_isZero(p, num_words)) {
return 0;
}
+4 -7
View File
@@ -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
@@ -83,6 +83,7 @@ void app_main(void) {
rc = gap_init();
if (rc != 0) {
ESP_LOGE(TAG, "failed to initialize GAP service, error code: %d", rc);
nimble_port_deinit();
return;
}
#endif
@@ -35,6 +35,9 @@ static void start_advertising(void) {
/* Set device name */
name = ble_svc_gap_device_name();
if (name == NULL) {
name = DEVICE_NAME;
}
adv_fields.name = (uint8_t *)name;
adv_fields.name_len = strlen(name);
adv_fields.name_is_complete = 1;
@@ -87,6 +87,7 @@ void app_main(void) {
rc = gap_init();
if (rc != 0) {
ESP_LOGE(TAG, "failed to initialize GAP service, error code: %d", rc);
nimble_port_deinit();
return;
}
#endif
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -64,6 +64,9 @@ static void start_advertising(void) {
/* Set device name */
name = ble_svc_gap_device_name();
if (name == NULL) {
name = DEVICE_NAME;
}
adv_fields.name = (uint8_t *)name;
adv_fields.name_len = strlen(name);
adv_fields.name_is_complete = 1;
@@ -160,26 +163,29 @@ static int gap_event_handler(struct ble_gap_event *event, void *arg) {
print_conn_desc(&desc);
led_on();
/* Try to update connection parameters */
/* Try to update connection parameters.
* BT spec requires: supervision_timeout > (1+latency)*itvl/4
* Ensure the timeout satisfies this constraint when latency=3. */
uint16_t min_timeout = (uint16_t)(((1 + 3) * (uint32_t)desc.conn_itvl) / 4 + 1);
uint16_t supervision_timeout = (desc.supervision_timeout > min_timeout)
? desc.supervision_timeout : min_timeout;
struct ble_gap_upd_params params = {.itvl_min = desc.conn_itvl,
.itvl_max = desc.conn_itvl,
.latency = 3,
.supervision_timeout =
desc.supervision_timeout};
.supervision_timeout = supervision_timeout};
rc = ble_gap_update_params(event->connect.conn_handle, &params);
if (rc != 0) {
ESP_LOGE(
TAG,
"failed to update connection parameters, error code: %d",
rc);
return rc;
}
}
/* Connection failed, restart advertising */
else {
start_advertising();
}
return rc;
return 0;
/* Disconnect event */
case BLE_GAP_EVENT_DISCONNECT:
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -54,7 +54,7 @@ static void nimble_host_task(void *param) {
nimble_port_run();
/* Clean up at exit */
vTaskDelete(NULL);
nimble_port_freertos_deinit();
}
static void heart_rate_task(void *param) {
@@ -114,6 +114,7 @@ void app_main(void) {
rc = gap_init();
if (rc != 0) {
ESP_LOGE(TAG, "failed to initialize GAP service, error code: %d", rc);
nimble_port_deinit();
return;
}
#endif
@@ -122,6 +123,7 @@ void app_main(void) {
rc = gatt_svc_init();
if (rc != 0) {
ESP_LOGE(TAG, "failed to initialize GATT server, error code: %d", rc);
nimble_port_deinit();
return;
}
@@ -129,12 +131,7 @@ void app_main(void) {
nimble_host_config_init();
/* Start NimBLE host task thread and return */
rc = xTaskCreate(nimble_host_task, "NimBLE Host", 4 * 1024, NULL,
5, NULL);
if (rc != pdPASS) {
ESP_LOGE(TAG, "failed to create NimBLE host task");
return;
}
nimble_port_freertos_init(nimble_host_task);
rc = xTaskCreate(heart_rate_task, "Heart Rate", 4 * 1024, NULL, 5, NULL);
if (rc != pdPASS) {
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -64,6 +64,9 @@ static void start_advertising(void) {
/* Set device name */
name = ble_svc_gap_device_name();
if (name == NULL) {
name = DEVICE_NAME;
}
adv_fields.name = (uint8_t *)name;
adv_fields.name_len = strlen(name);
adv_fields.name_is_complete = 1;
@@ -159,26 +162,29 @@ static int gap_event_handler(struct ble_gap_event *event, void *arg) {
/* Print connection descriptor */
print_conn_desc(&desc);
/* Try to update connection parameters */
/* Try to update connection parameters.
* BT spec requires: supervision_timeout > (1+latency)*itvl/4
* Ensure the timeout satisfies this constraint when latency=3. */
uint16_t min_timeout = (uint16_t)(((1 + 3) * (uint32_t)desc.conn_itvl) / 4 + 1);
uint16_t supervision_timeout = (desc.supervision_timeout > min_timeout)
? desc.supervision_timeout : min_timeout;
struct ble_gap_upd_params params = {.itvl_min = desc.conn_itvl,
.itvl_max = desc.conn_itvl,
.latency = 3,
.supervision_timeout =
desc.supervision_timeout};
.supervision_timeout = supervision_timeout};
rc = ble_gap_update_params(event->connect.conn_handle, &params);
if (rc != 0) {
ESP_LOGE(
TAG,
"failed to update connection parameters, error code: %d",
rc);
return rc;
}
}
/* Connection failed, restart advertising */
else {
start_advertising();
}
return rc;
return 0;
/* Disconnect event */
case BLE_GAP_EVENT_DISCONNECT:
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -164,9 +164,11 @@ error:
/* Public functions */
void send_heart_rate_indication(void) {
if (heart_rate_ind_status && heart_rate_chr_conn_handle_inited) {
ble_gatts_indicate(heart_rate_chr_conn_handle,
heart_rate_chr_val_handle);
ESP_LOGI(TAG, "heart rate indication sent!");
int rc = ble_gatts_indicate(heart_rate_chr_conn_handle,
heart_rate_chr_val_handle);
if (rc != 0) {
ESP_LOGE(TAG, "failed to send heart rate indication, error code: %d", rc);
}
}
}
@@ -230,9 +232,13 @@ void gatt_svr_subscribe_cb(struct ble_gap_event *event) {
/* Check attribute handle */
if (event->subscribe.attr_handle == heart_rate_chr_val_handle) {
if (event->subscribe.conn_handle == BLE_HS_CONN_HANDLE_NONE) {
return;
}
/* Update heart rate subscription status */
heart_rate_chr_conn_handle = event->subscribe.conn_handle;
heart_rate_chr_conn_handle_inited = true;
heart_rate_chr_conn_handle_inited = event->subscribe.cur_indicate;
heart_rate_ind_status = event->subscribe.cur_indicate;
}
}
@@ -15,6 +15,7 @@
#include "host/ble_gap.h"
/* Public function declarations */
void gatt_svr_reset_heart_rate_subscription(void);
void send_heart_rate_indication(void);
void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
int gatt_svr_subscribe_cb(struct ble_gap_event *event);
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -59,7 +59,7 @@ static void nimble_host_task(void *param) {
nimble_port_run();
/* Clean up at exit */
vTaskDelete(NULL);
nimble_port_freertos_deinit();
}
static void heart_rate_task(void *param) {
@@ -123,6 +123,7 @@ void app_main(void) {
rc = gap_init();
if (rc != 0) {
ESP_LOGE(TAG, "failed to initialize GAP service, error code: %d", rc);
nimble_port_deinit();
return;
}
#endif
@@ -131,6 +132,7 @@ void app_main(void) {
rc = gatt_svc_init();
if (rc != 0) {
ESP_LOGE(TAG, "failed to initialize GATT server, error code: %d", rc);
nimble_port_deinit();
return;
}
@@ -138,7 +140,12 @@ void app_main(void) {
nimble_host_config_init();
/* Start NimBLE host task thread and return */
xTaskCreate(nimble_host_task, "NimBLE Host", 4*1024, NULL, 5, NULL);
xTaskCreate(heart_rate_task, "Heart Rate", 4*1024, NULL, 5, NULL);
nimble_port_freertos_init(nimble_host_task);
rc = xTaskCreate(heart_rate_task, "Heart Rate", 4 * 1024, NULL, 5, NULL);
if (rc != pdPASS) {
ESP_LOGE(TAG, "failed to create heart rate task");
return;
}
return;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -12,7 +12,6 @@
inline static void format_addr(char *addr_str, uint8_t addr[]);
static void print_conn_desc(struct ble_gap_conn_desc *desc);
static void start_advertising(void);
static void set_random_addr(void);
static int gap_event_handler(struct ble_gap_event *event, void *arg);
/* Private variables */
@@ -52,20 +51,6 @@ static void print_conn_desc(struct ble_gap_conn_desc *desc) {
desc->sec_state.bonded);
}
static void set_random_addr(void) {
/* Local variables */
int rc = 0;
ble_addr_t addr;
/* Generate new non-resolvable private address */
rc = ble_hs_id_gen_rnd(0, &addr);
assert(rc == 0);
/* Set address */
rc = ble_hs_id_set_rnd(addr.val);
assert(rc == 0);
}
static void start_advertising(void) {
/* Local variables */
int rc = 0;
@@ -79,6 +64,9 @@ static void start_advertising(void) {
/* Set device name */
name = ble_svc_gap_device_name();
if (name == NULL) {
name = DEVICE_NAME;
}
adv_fields.name = (uint8_t *)name;
adv_fields.name_len = strlen(name);
adv_fields.name_is_complete = 1;
@@ -201,6 +189,9 @@ static int gap_event_handler(struct ble_gap_event *event, void *arg) {
ESP_LOGI(TAG, "disconnected from peer; reason=%d",
event->disconnect.reason);
/* Reset heart rate subscription state */
gatt_svr_reset_heart_rate_subscription();
/* Restart advertising */
start_advertising();
return rc;
@@ -324,8 +315,9 @@ void adv_init(void) {
int rc = 0;
char addr_str[18] = {0};
/* Make sure we have proper BT identity address set */
set_random_addr();
/* Make sure we have proper BT identity address set.
* ble_hs_util_ensure_addr(1) safely generates a random address only if
* one is not already set, avoiding conflicts on re-sync events. */
rc = ble_hs_util_ensure_addr(1);
if (rc != 0) {
ESP_LOGE(TAG, "device does not have any available bt address!");
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -24,7 +24,7 @@ static uint8_t heart_rate_chr_val[2] = {0};
static uint16_t heart_rate_chr_val_handle;
static const ble_uuid16_t heart_rate_chr_uuid = BLE_UUID16_INIT(0x2A37);
static uint16_t heart_rate_chr_conn_handle = 0;
static uint16_t heart_rate_chr_conn_handle = BLE_HS_CONN_HANDLE_NONE;
static bool heart_rate_chr_conn_handle_inited = false;
static bool heart_rate_ind_status = false;
@@ -165,6 +165,12 @@ error:
}
/* Public functions */
void gatt_svr_reset_heart_rate_subscription(void) {
heart_rate_chr_conn_handle_inited = false;
heart_rate_ind_status = false;
heart_rate_chr_conn_handle = BLE_HS_CONN_HANDLE_NONE;
}
void send_heart_rate_indication(void) {
/* Check if connection handle is initialized */
if (!heart_rate_chr_conn_handle_inited) {
@@ -230,10 +236,19 @@ void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg) {
int gatt_svr_subscribe_cb(struct ble_gap_event *event) {
/* Check attribute handle */
if (event->subscribe.attr_handle == heart_rate_chr_val_handle) {
if (event->subscribe.conn_handle == BLE_HS_CONN_HANDLE_NONE) {
return 0;
}
if (!event->subscribe.cur_indicate) {
gatt_svr_reset_heart_rate_subscription();
return 0;
}
/* Update heart rate subscription status */
heart_rate_chr_conn_handle = event->subscribe.conn_handle;
heart_rate_chr_conn_handle_inited = true;
heart_rate_ind_status = event->subscribe.cur_indicate;
heart_rate_ind_status = true;
/* Check security status */
if (!is_connection_encrypted(event->subscribe.conn_handle)) {
@@ -0,0 +1,11 @@
# Override some defaults so BT stack is enabled
# in this example
#
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_NVS_PERSIST=y
CONFIG_BT_NIMBLE_SVC_GAP_APPEARANCE=960
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -113,7 +113,7 @@ void ble_receive_apple_notification_source(uint8_t *message, uint16_t message_le
uint8_t CategoryID = message[2];
char *Cidstr = CategoryID_to_String(CategoryID);
uint8_t CategoryCount = message[3];
uint32_t NotificationUID = (message[4]) | (message[5]<< 8) | (message[6]<< 16) | (message[7] << 24);
uint32_t NotificationUID = ((uint32_t)message[4]) | ((uint32_t)message[5] << 8) | ((uint32_t)message[6] << 16) | ((uint32_t)message[7] << 24);
ESP_LOGI(NimBLE_ANCS_TAG, "EventID:%s EventFlags:0x%x CategoryID:%s CategoryCount:%d NotificationUID:%" PRIu32, EventIDS, EventFlags, Cidstr, CategoryCount, NotificationUID);
}
@@ -131,14 +131,18 @@ void ble_receive_apple_data_source(uint8_t *message, uint16_t message_len)
message_len);
return;
}
uint32_t NotificationUID = (message[1]) | (message[2]<< 8) | (message[3]<< 16) | (message[4] << 24);
uint32_t NotificationUID = ((uint32_t)message[1]) | ((uint32_t)message[2] << 8) | ((uint32_t)message[3] << 16) | ((uint32_t)message[4] << 24);
uint32_t remain_attr_len = message_len - 5;
uint8_t *attrs = &message[5];
ESP_LOGI(NimBLE_ANCS_TAG, "recevice Notification Attributes response Command_id %d NotificationUID %" PRIu32, Command_id, NotificationUID);
while(remain_attr_len > 0) {
if (remain_attr_len < 3) {
ESP_LOGE(NimBLE_ANCS_TAG, "incomplete attribute header");
break;
}
uint8_t AttributeID = attrs[0];
uint16_t len = attrs[1] | (attrs[2] << 8);
if(len > (remain_attr_len -3)) {
if(len > (remain_attr_len - 3)) {
ESP_LOGE(NimBLE_ANCS_TAG, "data error");
break;
}
+22 -2
View File
@@ -344,7 +344,7 @@ ext_ble_ancs_advertise(void)
params.connectable = 1;
/* advertise using configured addr */
params.own_addr_type = BLE_OWN_ADDR_PUBLIC;
params.own_addr_type = own_addr_type;
params.primary_phy = BLE_HCI_LE_PHY_1M;
params.secondary_phy = BLE_HCI_LE_PHY_2M;
params.tx_power = 127;
@@ -413,11 +413,15 @@ ble_ancs_advertise(void)
fields.tx_pwr_lvl_is_present = 1;
fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
#if CONFIG_BT_NIMBLE_GAP_SERVICE
name = ble_svc_gap_device_name();
fields.name = (uint8_t *)name;
fields.name_len = strlen(name);
fields.name_is_complete = 1;
#endif
static const ble_uuid16_t adv_uuids16[] = { BLE_UUID16_INIT(0x1811) };
fields.uuids16 = adv_uuids16;
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
@@ -485,6 +489,7 @@ ble_ancs_gap_event(struct ble_gap_event *event, void *arg)
#else
ble_ancs_advertise();
#endif
return 0;
}
/** Initiate security - It will perform
@@ -544,7 +549,11 @@ ble_ancs_gap_event(struct ble_gap_event *event, void *arg)
assert(rc == 0);
ble_ancs_print_conn_desc(&desc);
MODLOG_DFLT(INFO, "\n");
rc = ble_gattc_disc_svc_by_uuid(event->connect.conn_handle, &APPLE_NC_UUID.u,
if (event->enc_change.status != 0) {
MODLOG_DFLT(ERROR, "encryption failed; status=%d\n", event->enc_change.status);
return 0;
}
rc = ble_gattc_disc_svc_by_uuid(event->enc_change.conn_handle, &APPLE_NC_UUID.u,
ancs_service_discovered_cb, NULL);
if (rc != 0) {
return rc;
@@ -563,6 +572,10 @@ ble_ancs_gap_event(struct ble_gap_event *event, void *arg)
case BLE_GAP_EVENT_NOTIFY_RX:
/* Peer sent us a notification or indication. */
if (event->notify_rx.attr_handle == notification_source_handle) {
if (event->notify_rx.om == NULL || event->notify_rx.om->om_len < 8) {
MODLOG_DFLT(ERROR, "NOTIFY_RX: short or NULL notification source packet\n");
return 0;
}
ble_receive_apple_notification_source(event->notify_rx.om->om_data, event->notify_rx.om->om_len);
uint8_t *notificationUID = &event->notify_rx.om->om_data[4];
if (event->notify_rx.om->om_data[0] == EventIDNotificationAdded &&
@@ -773,6 +786,13 @@ app_main(void)
/* XXX Need to have template for store */
ble_store_config_init();
ret = esp_timer_create(&periodic_timer_args, &periodic_timer);
if (ret != ESP_OK) {
ESP_LOGE(tag, "Failed to create periodic timer: %d", ret);
nimble_port_deinit();
return;
}
nimble_port_freertos_init(ble_ancs_host_task);
}
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_NVS_PERSIST=y
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -31,7 +31,8 @@ gatt_svr_init(void)
#if MYNEWT_VAL(BLE_GATTS)
ble_svc_gatt_init();
#endif
#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_RAS_SERVICE
ble_svc_ras_init();
#endif
return 0;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -79,6 +79,10 @@ int blecent_on_subscribe(uint16_t conn_handle,
param.cb_arg=NULL;
ble_cs_initiator_procedure_start(&param);
}
} else {
MODLOG_DFLT(ERROR, "Subscription failed; status=%d conn_handle=%d\n",
error->status, conn_handle);
ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
return 0;
@@ -180,6 +184,7 @@ blecent_on_custom_read(uint16_t conn_handle,
rc = ble_chan_ras_subsribe_by_uuid(BLE_UUID16_DECLARE(BLE_UUID_RAS_REALTIME_RD_VAL), peer, conn_handle);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Error: Peer doesn't support the RAS on demand raging data or fail to subscribe \n");
ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return -1;
} else {
MODLOG_DFLT(INFO, "Subscribed to the RAS Realtime Ranging Data characteristic\n");
@@ -189,6 +194,7 @@ blecent_on_custom_read(uint16_t conn_handle,
rc = ble_chan_ras_subsribe_by_uuid(BLE_UUID16_DECLARE(BLE_UUID_RAS_ONDEMAND_RD_VAL), peer, conn_handle);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Error: Peer doesn't support the RAS on demand ranging data or fail to subscribe \n");
ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return -1;
} else {
MODLOG_DFLT(INFO, "Subscribed to the RAS On Demand Ranging Data characteristic\n");
@@ -197,7 +203,11 @@ blecent_on_custom_read(uint16_t conn_handle,
ble_chan_ras_subscribe(peer, conn_handle);
} else if (error->status == BLE_ATT_ERR_INSUFFICIENT_AUTHEN) {
MODLOG_DFLT(INFO, "Error: Insufficient authentication to read the characteristic\n");
ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return -1;
} else {
MODLOG_DFLT(ERROR, "Error: Failed to read RAS Features; status=%d\n", error->status);
ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
return 0;
}
@@ -279,6 +289,7 @@ blecent_on_disc_complete(const struct peer *peer, int status, void *arg)
blecent_on_custom_read, (void *)peer);
if (rc != 0) {
MODLOG_DFLT(ERROR, "2 Error: Failed to read the custom subscribable characteristic; ""rc=%d\n", rc);
ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
}
@@ -289,7 +300,7 @@ static void
blecent_scan(void)
{
uint8_t own_addr_type;
struct ble_gap_disc_params disc_params;
struct ble_gap_disc_params disc_params = {0};
int rc;
/* Figure out address to use while advertising (no privacy for now) */
@@ -351,15 +362,17 @@ blecent_connect_if_interesting(void *disc)
adv_data_len = d->length_data;
#endif
for (int i = 1; i < adv_data_len - 1; i++) {
if (adv_data[i-1] == 0x03 && adv_data[i] == 0x5b && adv_data[i+1] == 0x18) {
found = 1;
MODLOG_DFLT(DEBUG, "Found 0x5b18 at index %d\n", i);
break;
struct ble_hs_adv_fields adv_fields;
if (ble_hs_adv_parse_fields(&adv_fields, adv_data, adv_data_len) == 0) {
for (int i = 0; i < adv_fields.num_uuids16; i++) {
if (adv_fields.uuids16[i].value == BLE_UUID_RANGING_SERVICE_VAL) {
found = 1;
break;
}
}
}
if (!found) {
MODLOG_DFLT(DEBUG, "0x5b18 not found in adv_data, skipping connect.\n");
MODLOG_DFLT(DEBUG, "Ranging Service UUID not found in adv_data, skipping connect.\n");
return;
}
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
@@ -374,12 +387,18 @@ blecent_connect_if_interesting(void *disc)
rc = ble_hs_id_infer_auto(0, &own_addr_type);
if (rc != 0) {
MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc);
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
blecent_scan();
#endif
return;
}
rc = ble_gap_connect(own_addr_type, addr, 30000, NULL,
blecent_gap_event, NULL);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Connection failed.\n");
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
blecent_scan();
#endif
return;
}
}
@@ -577,18 +596,19 @@ blecent_gap_event(struct ble_gap_event *event, void *arg)
rc = ble_gattc_write_no_rsp_flat(event->notify_rx.conn_handle, ble_svc_ras_cp_val_handle, &value, sizeof value);
} else if( value[0] == RASCP_RSP_OPCODE_RSP_CODE) {
MODLOG_DFLT(INFO, "Sucssefully completed the Ranging procedure\n");
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}
else if(ble_svc_ras_rd_val_handle == event->notify_rx.attr_handle){
MODLOG_DFLT(INFO, "Received Ranging Data Ready Indication\n");
if (OS_MBUF_PKTLEN(event->notify_rx.om) < sizeof(uint16_t)) {
MODLOG_DFLT(ERROR, "Error: Invalid Ranging Data Ready Indication length\n");
return 0;
}
uint16_t ranging_counter;
os_mbuf_copydata(event->notify_rx.om, 0, sizeof(uint16_t), &ranging_counter);
most_recent_peer_ranging_counter=ranging_counter;
most_recent_local_ranging_counter= ranging_counter;
most_recent_peer_ranging_counter = ranging_counter;
if (most_recent_peer_ranging_counter!=most_recent_local_ranging_counter) {
if (most_recent_peer_ranging_counter != most_recent_local_ranging_counter) {
MODLOG_DFLT(INFO, "Ranging counter mismatch : %" PRId32 " , %" PRId32,
most_recent_peer_ranging_counter,most_recent_local_ranging_counter);
return 0;
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_CONTROLLER_DISABLED=y
CONFIG_BT_NIMBLE_60_FEATURE_SUPPORT=y
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -31,7 +31,8 @@ custom_gatt_svr_init(void)
#if MYNEWT_VAL(BLE_GATTS)
ble_svc_gatt_init();
#endif
#if MYNEWT_VAL(BLE_GATTS) && CONFIG_BT_NIMBLE_RAS_SERVICE
ble_svc_ras_init();
#endif
return 0;
}
@@ -71,13 +71,17 @@ void print_cs_event(const struct ble_cs_event *event)
MODLOG_DFLT(INFO, "subev_result.num_antenna_paths = %u\n", event->subev_result.num_antenna_paths);
MODLOG_DFLT(INFO, "subev_result.num_steps_reported = %u\n", event->subev_result.num_steps_reported);
for (int i = 0; i < event->subev_result.num_steps_reported; i++) {
const struct cs_steps_data *step = &event->subev_result.steps[i];
MODLOG_DFLT(INFO, "steps[%d]: mode=%u, channel=%u, data_len=%u, data=", i, step->mode, step->channel, step->data_len);
for (int j = 0; j < step->data_len; j++) {
esp_rom_printf("%02x ", step->data[j]);
{
const uint8_t *p = (const uint8_t *)event->subev_result.steps;
for (int i = 0; i < event->subev_result.num_steps_reported; i++) {
const struct cs_steps_data *step = (const struct cs_steps_data *)p;
MODLOG_DFLT(INFO, "steps[%d]: mode=%u, channel=%u, data_len=%u, data=", i, step->mode, step->channel, step->data_len);
for (int j = 0; j < step->data_len; j++) {
esp_rom_printf("%02x ", step->data[j]);
}
esp_rom_printf("\n");
p += sizeof(struct cs_steps_data) + step->data_len;
}
esp_rom_printf("\n");
}
break;
case BLE_CS_EVENT_SUBEVET_RESULT_CONTINUE:
@@ -89,13 +93,17 @@ void print_cs_event(const struct ble_cs_event *event)
MODLOG_DFLT(INFO, "subev_result_continue.num_antenna_paths = %u\n", event->subev_result_continue.num_antenna_paths);
MODLOG_DFLT(INFO, "subev_result_continue.num_steps_reported = %u\n", event->subev_result_continue.num_steps_reported);
for (int i = 0; i < event->subev_result_continue.num_steps_reported; i++) {
const struct cs_steps_data *step = &event->subev_result_continue.steps[i];
MODLOG_DFLT(INFO, "steps[%d]: mode=%u, channel=%u, data_len=%u, data=", i, step->mode, step->channel, step->data_len);
for (int j = 0; j < step->data_len; j++) {
esp_rom_printf("%02x ", step->data[j]);
{
const uint8_t *p = (const uint8_t *)event->subev_result_continue.steps;
for (int i = 0; i < event->subev_result_continue.num_steps_reported; i++) {
const struct cs_steps_data *step = (const struct cs_steps_data *)p;
MODLOG_DFLT(INFO, "steps[%d]: mode=%u, channel=%u, data_len=%u, data=", i, step->mode, step->channel, step->data_len);
for (int j = 0; j < step->data_len; j++) {
esp_rom_printf("%02x ", step->data[j]);
}
esp_rom_printf("\n");
p += sizeof(struct cs_steps_data) + step->data_len;
}
esp_rom_printf("\n");
}
break;
@@ -124,6 +132,7 @@ static int blecs_gap_event(struct ble_cs_event *event, void *arg)
if (idx==1) {
most_recent_local_ranging_counter=event->subev_result.procedure_counter;
}
ble_gatts_store_ranging_data(ranging_subevent);
MODLOG_DFLT(INFO, "LE CS Subevent Result , status: Partial, procedure counter %d\n", event->subev_result.procedure_counter);
} else {
MODLOG_DFLT(INFO, "LE CS Subevent Result , status: Unknown\n");
@@ -135,16 +144,19 @@ static int blecs_gap_event(struct ble_cs_event *event, void *arg)
MODLOG_DFLT(INFO, "LE CS Subevent Result Continue , status: Aborted\n");
} else if ( event->subev_result_continue.procedure_done_status == BLE_HCI_LE_CS_SUBEVENT_DONE_STATUS_COMPLETE) {
MODLOG_DFLT(INFO, "LE CS Subevent Result Continue , status: Complete\n");
ranging_subevent.type = BLE_CS_EVENT_SUBEVET_RESULT_CONTINUE;
ranging_subevent.subev_result_continue = event->subev_result_continue;
/* To
* Get total number of CS procedure from CS enable event and then accordigly indicate to most recent ranging counter
Currently we are considering only one CS procedure
*/
ind ++;
if (ind==1) {
ble_gatts_store_ranging_data(ranging_subevent);
struct ble_cs_event continue_event;
continue_event.type = BLE_CS_EVENT_SUBEVET_RESULT_CONTINUE;
continue_event.subev_result_continue = event->subev_result_continue;
ble_gatts_store_ranging_data(continue_event);
ble_gatts_indicate_ranging_data_ready(most_recent_local_ranging_counter);
idx = 0;
ind = 0;
}
}
@@ -226,6 +238,9 @@ ext_bleprph_advertise(void)
/* start advertising */
rc = ble_gap_ext_adv_start(instance, 0, 0);
if (rc != 0) {
MODLOG_DFLT(ERROR, "error starting extended advertisement; rc=%d\n", rc);
}
}
#else
/**
@@ -266,9 +281,10 @@ bleprph_advertise(void)
fields.name_len = strlen(name);
fields.name_is_complete = 1;
#endif
fields.uuids16 = (ble_uuid16_t[]) {
static const ble_uuid16_t uuids16[] = {
BLE_UUID16_INIT(BLE_UUID_RANGING_SERVICE_VAL)
};
fields.uuids16 = uuids16;
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
rc = ble_gap_adv_set_fields(&fields);
@@ -335,6 +351,9 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg)
MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
bleprph_print_conn_desc(&event->disconnect.conn);
MODLOG_DFLT(INFO, "\n");
idx = 0;
ind = 0;
most_recent_local_ranging_counter = -1;
/* Connection terminated; resume advertising. */
#if CONFIG_EXAMPLE_EXTENDED_ADV
ext_bleprph_advertise();
@@ -381,7 +400,6 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg)
event->notify_tx.indication);
if (event->notify_tx.status == BLE_HS_EDONE) {
vTaskDelay(4000 / portTICK_PERIOD_MS);
ble_gatts_indicate_control_point_response(event->notify_tx.attr_handle,most_recent_local_ranging_counter);
}
return 0;
@@ -409,6 +427,9 @@ static void
bleprph_on_reset(int reason)
{
MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
idx = 0;
ind = 0;
most_recent_local_ranging_counter = -1;
}
static void
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_CONTROLLER_DISABLED=y
CONFIG_BT_NIMBLE_60_FEATURE_SUPPORT=y
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -19,6 +19,11 @@
static const char *TAG = "CTE_ADV_EXAMPLE";
static uint8_t s_periodic_adv_raw_data[] = {0x0D, BLE_HS_ADV_TYPE_COMP_NAME, 'C','T','E',' ','P','e','r','i','o','d','i','c'};
#if !(MYNEWT_VAL(BLE_EXT_ADV) && MYNEWT_VAL(BLE_PERIODIC_ADV) && MYNEWT_VAL(BLE_AOA_AOD))
#error "This example requires NimBLE Extended Advertising, Periodic Advertising, and CTE (AoA/AoD). " \
"Use a supported target from README.md (e.g. esp32h2, esp32c5, esp32c61) and run idf.py set-target before build."
#endif
/**
* @brief Configure and start periodic advertising with CTE
*/
@@ -49,10 +54,9 @@ static void start_periodic_adv_cte(uint8_t own_addr_type)
assert(rc == 0);
/* Configure advertising data */
struct ble_hs_adv_fields adv_fields = {
.name = (const uint8_t *)"CTE_Periodic_Adv",
.name_len = strlen((char *)adv_fields.name)
};
struct ble_hs_adv_fields adv_fields = {0};
adv_fields.name = (const uint8_t *)"CTE_Periodic_Adv";
adv_fields.name_len = strlen("CTE_Periodic_Adv");
struct os_mbuf *data = os_msys_get_pkthdr(BLE_HS_ADV_MAX_FIELD_SZ, 0);
assert(data);
@@ -193,7 +197,12 @@ void app_main(void)
ESP_LOGI(TAG, "%s", direction_finding_logo);
#if defined(CONFIG_EXAMPLE_ADV_DIRECTION_FINDING_AOD)
ESP_LOGI(TAG, "DIRECTION_FINDING Example Periodic Adv AOD Mode");
ble_direction_finding_antenna_init(antenna_use_gpio,CONFIG_EXAMPLE_ANT_GPIO_BIT_COUNT);
rc = ble_direction_finding_antenna_init(antenna_use_gpio, CONFIG_EXAMPLE_ANT_GPIO_BIT_COUNT);
if (rc != 0) {
ESP_LOGE(TAG, "Antenna init failed; rc=%d", rc);
nimble_port_deinit();
return;
}
#elif defined(CONFIG_EXAMPLE_ADV_DIRECTION_FINDING_AOA)
ESP_LOGI(TAG, "DIRECTION_FINDING Example Periodic Adv AOA Mode");
#endif
@@ -1,7 +1,11 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Minimal Configuration
# Minimal NimBLE config for periodic advertising with CTE (requires BLE 5.0).
#
# Supported targets: ESP32-H2, ESP32-C5, ESP32-C61, etc. (see README.md).
# Run: idf.py set-target <chip> before building.
CONFIG_BT_ENABLED=y
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_AOA_AOD=y
CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=y
CONFIG_BT_NIMBLE_EXT_ADV=y
CONFIG_BT_NIMBLE_ENABLE_PERIODIC_ADV=y
CONFIG_BT_NIMBLE_AOA_AOD=y
@@ -1,5 +1,6 @@
# This file was generated using idf.py save-defconfig. It can be edited manually.
# Espressif IoT Development Framework (ESP-IDF) 5.5.0 Project Minimal Configuration
#
CONFIG_IDF_TARGET="esp32h2"
CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
CONFIG_BT_NIMBLE_50_FEATURE_SUPPORT=y
CONFIG_BT_NIMBLE_EXT_ADV=y
CONFIG_BT_NIMBLE_ENABLE_PERIODIC_ADV=y
CONFIG_BT_NIMBLE_AOA_AOD=y
@@ -173,7 +173,7 @@ static int periodic_sync_gap_event(struct ble_gap_event *event, void *arg)
memcpy(dev_name, &adv_data[index + 2], name_len);
dev_name[name_len] = '\0';
if (strcmp(dev_name, CONFIG_SYNC_TARGET_DEVNAME) == 0) {
if (strcmp(dev_name, CONFIG_EXAMPLE_SYNC_TARGET_DEVNAME) == 0) {
should_sync = true;
break;
}
@@ -184,7 +184,7 @@ static int periodic_sync_gap_event(struct ble_gap_event *event, void *arg)
#else
#error "Please select EXAMPLE_SYNC_BY_SID or EXAMPLE_SYNC_BY_NAME in menuconfig"
#endif
if (should_sync) {
if (should_sync && disc->periodic_adv_itvl != 0) {
ble_addr_t addr;
memcpy(&addr, &disc->addr, sizeof(ble_addr_t));
@@ -249,6 +249,7 @@ static int periodic_sync_gap_event(struct ble_gap_event *event, void *arg)
static void periodic_sync_on_reset(int reason)
{
ESP_LOGE(TAG, "Resetting state; reason=%d", reason);
is_synced = 0;
}
static void periodic_sync_on_sync(void)
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -206,28 +206,17 @@ ext_ble_cts_cent_should_connect(const struct ble_gap_ext_disc_desc *disc)
{
int offset = 0;
int ad_struct_len = 0;
uint8_t test_addr[6];
uint32_t peer_addr[6];
memset(peer_addr, 0x0, sizeof peer_addr);
if (disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
uint8_t test_addr[6] = {0};
if (!(disc->props & BLE_HCI_ADV_CONN_MASK)) {
return 0;
}
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) {
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
/* Conversion */
for(int i=0; i<6; i++) {
test_addr[i] = (uint8_t )peer_addr[i];
/* Convert string to address */
if (peer_addr_parse(CONFIG_EXAMPLE_PEER_ADDR, test_addr) != 6) {
return 0;
}
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0;
}
@@ -236,17 +225,24 @@ ext_ble_cts_cent_should_connect(const struct ble_gap_ext_disc_desc *disc)
/* The device has to advertise support for the CTS
* service (0x1805).
*/
do {
while (offset < disc->length_data) {
if (offset + 1 >= disc->length_data) {
break;
}
ad_struct_len = disc->data[offset];
if (!ad_struct_len) {
break;
}
if (offset + ad_struct_len >= disc->length_data) {
break;
}
/* Search if cts UUID is advertised */
if (disc->data[offset + 1] == 0x03) {
int temp = 2;
while (temp < ad_struct_len) {
while (temp < ad_struct_len && (offset + temp + 1) < disc->length_data) {
if(disc->data[offset + temp] == 0x05 &&
disc->data[offset + temp + 1] == 0x18) {
return 1;
@@ -255,7 +251,7 @@ ext_ble_cts_cent_should_connect(const struct ble_gap_ext_disc_desc *disc)
}
}
offset += ad_struct_len + 1;
} while ( offset < disc->length_data );
}
return 0;
}
@@ -267,11 +263,7 @@ ble_cts_cent_should_connect(const struct ble_gap_disc_desc *disc)
struct ble_hs_adv_fields fields;
int rc;
int i;
uint8_t test_addr[6];
uint32_t peer_addr[6];
memset(peer_addr, 0x0, sizeof peer_addr);
uint8_t test_addr[6] = {0};
/* The device has to be advertising connectability. */
if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
@@ -287,15 +279,9 @@ ble_cts_cent_should_connect(const struct ble_gap_disc_desc *disc)
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) {
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
/* Conversion */
for (int i=0; i<6; i++) {
test_addr[i] = (uint8_t )peer_addr[i];
}
if (peer_addr_parse(CONFIG_EXAMPLE_PEER_ADDR, test_addr) != 6) {
return 0;
}
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0;
}
@@ -350,6 +336,9 @@ ble_cts_cent_connect_if_interesting(void *disc)
rc = ble_hs_id_infer_auto(0, &own_addr_type);
if (rc != 0) {
MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc);
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
ble_cts_cent_scan();
#endif
return;
}
@@ -367,6 +356,9 @@ ble_cts_cent_connect_if_interesting(void *disc)
MODLOG_DFLT(ERROR, "Error: Failed to connect to device; addr_type=%d "
"addr=%s; rc=%d\n",
addr->type, addr_str(addr->val), rc);
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
ble_cts_cent_scan();
#endif
return;
}
}
@@ -389,11 +381,13 @@ static int
ble_cts_cent_gap_event(struct ble_gap_event *event, void *arg)
{
struct ble_gap_conn_desc desc;
struct ble_hs_adv_fields fields;
int rc;
switch (event->type) {
case BLE_GAP_EVENT_DISC:
#if !CONFIG_EXAMPLE_EXTENDED_ADV
{
struct ble_hs_adv_fields fields;
rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
event->disc.length_data);
if (rc != 0) {
@@ -405,6 +399,8 @@ ble_cts_cent_gap_event(struct ble_gap_event *event, void *arg)
/* Try to connect to the advertiser if it looks interesting. */
ble_cts_cent_connect_if_interesting(&event->disc);
}
#endif
return 0;
case BLE_GAP_EVENT_CONNECT:
@@ -621,11 +617,14 @@ app_main(void)
/* Initialize data structures to track connected peers. */
#if MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)
rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64, 64);
assert(rc == 0);
#else
rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64);
assert(rc == 0);
#endif
if (rc != 0) {
ESP_LOGE(tag, "Failed to init peer tracking; rc=%d", rc);
nimble_port_deinit();
return;
}
#if CONFIG_BT_NIMBLE_GAP_SERVICE
/* Set the default device name. */
@@ -5,8 +5,5 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
@@ -68,7 +65,6 @@ CONFIG_ESP_WIFI_ENABLED=n
# Application
CONFIG_APP_COMPILE_TIME_DATE=n
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=n
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
@@ -82,7 +78,6 @@ CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=n
#Uncomment below, if security needs to be disabled
#CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
#Uncomment below, if logging needs to be disabled
#CONFIG_LOG_DEFAULT_LEVEL_NONE=y
#CONFIG_LOG_DEFAULT_LEVEL=0
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -71,9 +71,8 @@ int fetch_current_time(struct ble_svc_cts_curr_time *ctime) {
ctime->et_256.d_d_t.d_t.seconds = timeinfo.tm_sec;
/* day of week */
/* time gives day range of [0, 6], current_time_sevice
has day range of [1,7] */
ctime->et_256.d_d_t.day_of_week = timeinfo.tm_wday + 1;
/* tm_wday: 0=Sunday..6=Saturday; CTS: 1=Monday..7=Sunday */
ctime->et_256.d_d_t.day_of_week = (timeinfo.tm_wday == 0) ? 7 : timeinfo.tm_wday;
/* fractions_256 */
ctime->et_256.fractions_256 = (((uint64_t)tv_now.tv_usec * 256L )/ 1000000L);
@@ -108,7 +107,9 @@ int set_current_time(struct ble_svc_cts_curr_time ctime) {
timeinfo.tm_hour = ctime.et_256.d_d_t.d_t.hours;
timeinfo.tm_min = ctime.et_256.d_d_t.d_t.minutes;
timeinfo.tm_sec = ctime.et_256.d_d_t.d_t.seconds;
timeinfo.tm_wday = ctime.et_256.d_d_t.day_of_week - 1;
/* CTS day_of_week: 1=Monday..7=Sunday; tm_wday: 0=Sunday..6=Saturday */
timeinfo.tm_wday = (ctime.et_256.d_d_t.day_of_week == 7) ? 0 : ctime.et_256.d_d_t.day_of_week;
timeinfo.tm_isdst = -1;
now = mktime(&timeinfo);
if (now == (time_t)-1) {
ESP_LOGE(TAG, "Failed to convert current time");
@@ -137,6 +138,7 @@ int set_local_time_info(struct ble_svc_cts_local_time_info info) {
local_info.timezone = info.timezone;
local_info.dst_offset = info.dst_offset;
gettimeofday(&last_updated, NULL);
adjust_reason = (CHANGE_OF_DST_MASK | CHANGE_OF_TIME_ZONE_MASK);
return 0;
}
int fetch_reference_time_info(struct ble_svc_cts_reference_time_info *info) {
@@ -160,8 +162,6 @@ int fetch_reference_time_info(struct ble_svc_cts_reference_time_info *info) {
hours_since_update = (tv_now.tv_sec % 86400L) / 3600;
info->hours_since_update = hours_since_update;
}
adjust_reason = (CHANGE_OF_DST_MASK | CHANGE_OF_TIME_ZONE_MASK);
return 0;
}
int
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -79,8 +79,8 @@ ext_ble_cts_prph_advertise(void)
/* enable connectable advertising */
params.connectable = 1;
/* advertise using random addr */
params.own_addr_type = BLE_OWN_ADDR_PUBLIC;
/* advertise using configured addr */
params.own_addr_type = ble_cts_prph_addr_type;
params.primary_phy = BLE_HCI_LE_PHY_1M;
params.secondary_phy = BLE_HCI_LE_PHY_2M;
@@ -148,9 +148,10 @@ ble_cts_prph_advertise(void)
fields.name_len = strlen(device_name);
fields.name_is_complete = 1;
fields.uuids16 = (ble_uuid16_t[]) {
static const ble_uuid16_t adv_uuids16[] = {
BLE_UUID16_INIT(BLE_SVC_CTS_UUID16)
};
fields.uuids16 = adv_uuids16;
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
@@ -5,8 +5,5 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
@@ -36,7 +33,6 @@ CONFIG_BT_NIMBLE_SPS_SERVICE=n
CONFIG_BT_NIMBLE_HR_SERVICE=n
CONFIG_BT_NIMBLE_DIS_SERVICE=n
CONFIG_BT_ALARM_MAX_NUM=15
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=23
@@ -80,7 +76,6 @@ CONFIG_ESP_WIFI_ENABLED=n
# Application
CONFIG_APP_COMPILE_TIME_DATE=n
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=n
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
@@ -94,7 +89,6 @@ CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=n
#Uncomment below, if security needs to be disabled
#CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
#Uncomment below, if logging needs to be disabled
#CONFIG_LOG_DEFAULT_LEVEL_NONE=y
#CONFIG_LOG_DEFAULT_LEVEL=0
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -141,9 +141,11 @@ gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
sizeof(gatt_svr_chr_val),
sizeof(gatt_svr_chr_val),
&gatt_svr_chr_val, NULL);
ble_gatts_chr_updated(attr_handle);
MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
"all subscribed peers.\n");
if (rc == 0) {
ble_gatts_chr_updated(attr_handle);
MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
"all subscribed peers.\n");
}
return rc;
}
goto unknown;
@@ -160,7 +162,7 @@ gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
if (ble_uuid_cmp(uuid, &gatt_svr_dsc_uuid.u) == 0) {
rc = os_mbuf_append(ctxt->om,
&gatt_svr_dsc_val,
sizeof(gatt_svr_chr_val));
sizeof(gatt_svr_dsc_val));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
goto unknown;
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -90,9 +90,11 @@ dynamic_service_advertise(void)
fields.name_len = strlen(name);
fields.name_is_complete = 1;
fields.uuids16 = (ble_uuid16_t[]) {
BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID)
};
/* Must be static: ble_gap_adv_set_fields stores the pointer, not the data.
* A stack compound literal becomes dangling after this function returns,
* causing corruption when BLE_NIMBLE_ENABLE_CONN_REATTEMPT re-uses it. */
static const ble_uuid16_t adv_uuids16[] = { BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID) };
fields.uuids16 = adv_uuids16;
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
@@ -143,8 +145,11 @@ dynamic_service_gap_event(struct ble_gap_event *event, void *arg)
event->connect.status);
if (event->connect.status == 0) {
rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
assert(rc == 0);
dynamic_service_print_conn_desc(&desc);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to find connection; rc=%d\n", rc);
} else {
dynamic_service_print_conn_desc(&desc);
}
}
MODLOG_DFLT(INFO, "\n");
@@ -282,11 +287,19 @@ app_main(void)
#if MYNEWT_VAL(BLE_GATTS)
rc = gatt_svr_init();
assert(rc == 0);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to init GATT server; rc=%d\n", rc);
nimble_port_deinit();
return;
}
/* Set the default device name. */
rc = ble_svc_gap_device_name_set("ble-dynamic-service");
assert(rc == 0);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to set device name; rc=%d\n", rc);
nimble_port_deinit();
return;
}
#endif
nimble_port_freertos_init(dynamic_service_host_task);
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_DYNAMIC_SERVICE=y
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_DYNAMIC_SERVICE=y
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_DYNAMIC_SERVICE=y
@@ -38,7 +35,6 @@ CONFIG_BT_NIMBLE_SPS_SERVICE=n
CONFIG_BT_NIMBLE_HR_SERVICE=n
CONFIG_BT_NIMBLE_DIS_SERVICE=n
CONFIG_BT_ALARM_MAX_NUM=15
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=23
@@ -82,7 +78,6 @@ CONFIG_ESP_WIFI_ENABLED=n
# Application
CONFIG_APP_COMPILE_TIME_DATE=n
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=n
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
@@ -96,7 +91,6 @@ CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=n
#Uncomment below, if security needs to be disabled
#CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
#Uncomment below, if logging needs to be disabled
#CONFIG_LOG_DEFAULT_LEVEL_NONE=y
#CONFIG_LOG_DEFAULT_LEVEL=0
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -78,6 +78,7 @@ enc_adv_data_cent_on_read(uint16_t conn_handle,
{
int rc;
struct ble_store_value_ead value_ead = {0};
struct ble_gap_conn_desc desc;
struct peer *p;
MODLOG_DFLT(INFO, "Read complete; status=%d conn_handle=%d", error->status,
@@ -119,6 +120,10 @@ enc_adv_data_cent_on_read(uint16_t conn_handle,
print_bytes(value_ead.km.iv, BLE_EAD_IV_SIZE);
memcpy(&value_ead.peer_addr.val, &p->peer_addr, PEER_ADDR_VAL_SIZE);
rc = ble_gap_conn_find(conn_handle, &desc);
if (rc == 0) {
value_ead.peer_addr.type = desc.peer_id_addr.type;
}
rc = ble_store_write_ead(&value_ead);
if (rc == 0) {
@@ -184,6 +189,8 @@ enc_adv_data_cent_on_disc_complete(const struct peer *peer, int status, void *ar
if (!enc_adv_data_check_km_exist(peer->peer_addr)) {
/* Now perform GATT read procedures against the peer */
enc_adv_data_cent_read(peer);
} else {
ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
}
#endif
@@ -289,7 +296,17 @@ enc_adv_data_cent_decrypt(uint8_t length_data, const uint8_t *data, const uint8_
return 0;
}
uint8_t actual_dec_len = enc_payload_len - (BLE_EAD_RANDOMIZER_SIZE + BLE_EAD_MIC_SIZE);
if (actual_dec_len == 0) {
free(enc_data);
return 0;
}
dec_data_len = temp[0];
if ((uint16_t)dec_data_len + 1 > actual_dec_len) {
MODLOG_DFLT(ERROR, "Decrypted length field exceeds payload");
free(enc_data);
return 0;
}
MODLOG_DFLT(INFO, "Data after decryption:");
for (int i = 0; i < dec_data_len + 1; i++) {
@@ -318,27 +335,14 @@ enc_adv_data_cent_ext_should_connect(const struct ble_gap_ext_disc_desc *disc)
{
int offset = 0;
int ad_struct_len = 0;
uint8_t test_addr[6];
uint32_t peer_addr[6];
memset(peer_addr, 0x0, sizeof peer_addr);
if (disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
uint8_t test_addr[6] = {0};
if (!(disc->props & BLE_HCI_ADV_CONN_MASK)) {
return 0;
}
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen ("ADDR_ANY")) != 0)) {
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
/* Conversion */
for(int i=0; i<6; i++) {
test_addr[i] = (uint8_t )peer_addr[i];
}
peer_addr_parse(CONFIG_EXAMPLE_PEER_ADDR, test_addr);
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0;
}
@@ -367,6 +371,7 @@ enc_adv_data_cent_ext_should_connect(const struct ble_gap_ext_disc_desc *disc)
MODLOG_DFLT(INFO, "Adding peer addr : %s", addr_str(&disc->addr.val));
memcpy(&kmp[counter].peer_addr, &disc->addr.val, PEER_ADDR_VAL_SIZE);
kmp[counter].key_material_exist = false;
counter++;
if (counter > CONFIG_BT_NIMBLE_MAX_CONNECTIONS) {
@@ -394,11 +399,7 @@ enc_adv_data_cent_should_connect(const struct ble_gap_disc_desc *disc)
struct ble_hs_adv_fields fields;
int rc;
int i;
uint8_t test_addr[6];
uint32_t peer_addr[6];
memset(peer_addr, 0x0, sizeof peer_addr);
uint8_t test_addr[6] = {0};
if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
return 0;
@@ -412,15 +413,7 @@ enc_adv_data_cent_should_connect(const struct ble_gap_disc_desc *disc)
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen ("ADDR_ANY")) != 0)) {
MODLOG_DFLT(INFO, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
/* Conversion */
for (int i=0; i<6; i++) {
test_addr[i] = (uint8_t )peer_addr[i];
}
peer_addr_parse(CONFIG_EXAMPLE_PEER_ADDR, test_addr);
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0;
}
@@ -440,6 +433,7 @@ enc_adv_data_cent_should_connect(const struct ble_gap_disc_desc *disc)
MODLOG_DFLT(INFO, "Adding peer addr : %s", addr_str(&disc->addr.val));
memcpy(&kmp[counter].peer_addr, &disc->addr.val, PEER_ADDR_VAL_SIZE);
kmp[counter].key_material_exist = false;
counter++;
if (counter > CONFIG_BT_NIMBLE_MAX_CONNECTIONS) {
@@ -494,6 +488,9 @@ enc_adv_data_cent_connect_if_interesting(void *disc)
rc = ble_hs_id_infer_auto(0, &own_addr_type);
if (rc != 0) {
MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc);
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
enc_adv_data_cent_scan();
#endif
return;
}
@@ -512,6 +509,9 @@ enc_adv_data_cent_connect_if_interesting(void *disc)
MODLOG_DFLT(ERROR, "Error: Failed to connect to device; addr_type=%d "
"addr=%s; rc=%d\n",
addr->type, addr_str(addr->val), rc);
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
enc_adv_data_cent_scan();
#endif
return;
}
}
@@ -579,12 +579,15 @@ enc_adv_data_cent_gap_event(struct ble_gap_event *event, void *arg)
rc = peer_add(event->connect.conn_handle);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to add peer; rc=%d\n", rc);
ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return 0;
}
rc = peer_set_addr(event->connect.conn_handle, desc.peer_id_addr.val);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to set peer addr; rc=%d\n", rc);
peer_delete(event->connect.conn_handle);
ble_gap_terminate(event->connect.conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return 0;
}
@@ -751,11 +754,14 @@ app_main(void)
/* Initialize data structures to track connected peers. */
#if MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)
rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64, 64);
assert(rc == 0);
#else
rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64);
assert(rc == 0);
#endif
if (rc != 0) {
ESP_LOGE(tag, "Failed to init peer tracking; rc=%d", rc);
nimble_port_deinit();
return;
}
#if CONFIG_BT_NIMBLE_GAP_SERVICE
/* Set the default device name. */
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=n
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=n
@@ -70,7 +67,6 @@ CONFIG_ESP_WIFI_ENABLED=n
# Application
CONFIG_APP_COMPILE_TIME_DATE=n
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=n
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
@@ -84,7 +80,6 @@ CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=n
#Uncomment below, if security needs to be disabled
#CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
#Uncomment below, if logging needs to be disabled
#CONFIG_LOG_DEFAULT_LEVEL_NONE=y
#CONFIG_LOG_DEFAULT_LEVEL=0
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -150,9 +150,11 @@ gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
sizeof(gatt_svr_chr_val),
sizeof(gatt_svr_chr_val),
&gatt_svr_chr_val, NULL);
ble_gatts_chr_updated(attr_handle);
MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
"all subscribed peers.\n");
if (rc == 0) {
ble_gatts_chr_updated(attr_handle);
MODLOG_DFLT(INFO, "Notification/Indication scheduled for "
"all subscribed peers.\n");
}
return rc;
}
goto unknown;
@@ -169,7 +171,7 @@ gatt_svc_access(uint16_t conn_handle, uint16_t attr_handle,
if (ble_uuid_cmp(uuid, &gatt_svr_dsc_uuid.u) == 0) {
rc = os_mbuf_append(ctxt->om,
&gatt_svr_dsc_val,
sizeof(gatt_svr_chr_val));
sizeof(gatt_svr_dsc_val));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
goto unknown;
@@ -140,8 +140,8 @@ enc_adv_data_prph_ext_advertise(void)
/* enable connectable advertising */
params.connectable = 1;
/* advertise using random addr */
params.own_addr_type = BLE_OWN_ADDR_PUBLIC;
/* advertise using configured addr */
params.own_addr_type = own_addr_type;
params.primary_phy = BLE_HCI_LE_PHY_1M;
params.secondary_phy = BLE_HCI_LE_PHY_2M;
@@ -163,6 +163,10 @@ enc_adv_data_prph_ext_advertise(void)
/* get mbuf with adv data */
temp = malloc(sizeof(ext_adv_pattern) + 2 + encrypted_adv_data_len);
if (temp == NULL) {
MODLOG_DFLT(ERROR, "Failed to allocate temp buffer for ext adv data");
return;
}
memcpy(temp, ext_adv_pattern, sizeof(ext_adv_pattern));
temp[sizeof(ext_adv_pattern)] = 1 + encrypted_adv_data_len;
temp[sizeof(ext_adv_pattern) + 1] = BLE_GAP_ENC_ADV_DATA;
@@ -194,8 +198,11 @@ enc_adv_data_prph_advertise(void)
struct ble_hs_adv_fields fields;
int rc;
const unsigned encrypted_adv_data_len = BLE_EAD_ENCRYPTED_PAYLOAD_SIZE(sizeof(unencrypted_adv_pattern));
uint8_t encrypted_adv_data[encrypted_adv_data_len];
static const ble_uuid16_t adv_uuids16[] = {
BLE_UUID16_INIT(0x2C01) /** For the central to recognise this device */
};
static uint8_t encrypted_adv_data[BLE_EAD_ENCRYPTED_PAYLOAD_SIZE(sizeof(unencrypted_adv_pattern))];
const unsigned encrypted_adv_data_len = sizeof(encrypted_adv_data);
memset(encrypted_adv_data, 0, encrypted_adv_data_len);
/* First check if any instance is already active */
@@ -207,8 +214,6 @@ enc_adv_data_prph_advertise(void)
memset (&params, 0, sizeof(params));
memset (&fields, 0, sizeof(fields));
own_addr_type = BLE_OWN_ADDR_PUBLIC;
/* enable connectable advertising */
params.conn_mode = BLE_GAP_CONN_MODE_UND;
params.disc_mode = BLE_GAP_DISC_MODE_GEN;
@@ -222,9 +227,7 @@ enc_adv_data_prph_advertise(void)
fields.name_len = 3;
fields.name_is_complete = 1;
fields.uuids16 = (ble_uuid16_t[]) {
BLE_UUID16_INIT(0x2C01) /** For the central to recognise this device */
};
fields.uuids16 = adv_uuids16;
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
@@ -397,17 +400,22 @@ enc_adv_data_prph_on_reset(int reason)
static void
ble_app_set_addr(void)
{
ble_addr_t addr;
ble_addr_t addr = {0};
int rc;
/* generate new non-resolvable private address */
rc = ble_hs_id_gen_rnd(0, &addr);
assert(rc == 0);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to generate random address; rc=%d\n", rc);
return;
}
/* set generated address */
rc = ble_hs_id_set_rnd(addr.val);
assert(rc == 0);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to set random address; rc=%d\n", rc);
return;
}
}
#endif
@@ -5,10 +5,7 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70
CONFIG_BT_NIMBLE_EXT_ADV=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_EXT_ADV=n
@@ -39,7 +36,6 @@ CONFIG_BT_NIMBLE_SPS_SERVICE=n
CONFIG_BT_NIMBLE_HR_SERVICE=n
CONFIG_BT_NIMBLE_DIS_SERVICE=n
CONFIG_BT_ALARM_MAX_NUM=15
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=23
@@ -83,7 +79,6 @@ CONFIG_ESP_WIFI_ENABLED=n
# Application
CONFIG_APP_COMPILE_TIME_DATE=n
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=n
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
@@ -97,7 +92,6 @@ CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=n
#Uncomment below, if security needs to be disabled
#CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
#Uncomment below, if logging needs to be disabled
#CONFIG_LOG_DEFAULT_LEVEL_NONE=y
#CONFIG_LOG_DEFAULT_LEVEL=0
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -17,16 +17,16 @@ static uint8_t own_addr_type;
static int blecoex_gap_event(struct ble_gap_event *event, void *arg);
void ble_coex_advertise(void);
void ble_coex_scan(void);
static bool client_connect = 0;
static uint8_t client_connect = 0;
static int gatt_svr_access_cb(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg) {
int rc = 0;
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
static uint8_t data[1] = {42}; // Example value
os_mbuf_append(ctxt->om, data, sizeof(data));
rc = os_mbuf_append(ctxt->om, data, sizeof(data));
if (rc != 0) {
return rc;
return BLE_ATT_ERR_INSUFFICIENT_RES;
}
} else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) {
static uint8_t dsc_data[1] = {0x01}; // Example descriptor value
@@ -192,6 +192,10 @@ blecent_on_write(uint16_t conn_handle,
uint8_t value[2];
int rc;
const struct peer *peer = peer_find(conn_handle);
if (peer == NULL) {
MODLOG_DFLT(ERROR, "Peer not found for conn_handle=%d\n", conn_handle);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
dsc = peer_dsc_find_uuid(peer,
BLE_UUID16_DECLARE(BLECOEX_SVC_ALERT_UUID),
@@ -216,7 +220,7 @@ blecent_on_write(uint16_t conn_handle,
return 0;
err:
/* Terminate the connection. */
return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
@@ -241,6 +245,10 @@ blecent_on_read(uint16_t conn_handle,
uint8_t value[2];
int rc;
const struct peer *peer = peer_find(conn_handle);
if (peer == NULL) {
MODLOG_DFLT(ERROR, "Peer not found for conn_handle=%d\n", conn_handle);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
chr = peer_chr_find_uuid(peer,
BLE_UUID16_DECLARE(BLECOEX_SVC_ALERT_UUID),
@@ -263,7 +271,7 @@ blecent_on_read(uint16_t conn_handle,
return 0;
err:
/* Terminate the connection. */
return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
@@ -369,23 +377,40 @@ blecoex_gap_event(struct ble_gap_event *event, void *arg)
MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
}
if (client_connect == 1) {
client_connect = 2;
if (client_connect == 1 ) {
client_connect = 2;
/* Remember peer. */
rc = peer_add(event->connect.conn_handle);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to add peer; rc=%d\n", rc);
rc = ble_gap_terminate(event->connect.conn_handle,
BLE_ERR_REM_USER_CONN_TERM);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to terminate connection; rc=%d\n", rc);
restart_coex();
}
return 0;
}
/* Remember peer. */
rc = peer_add(event->connect.conn_handle);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to add peer; rc=%d\n", rc);
restart_coex();
/* Perform service discovery */
rc = peer_disc_all(event->connect.conn_handle,
blecent_on_disc_complete, NULL);
if(rc != 0) {
MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc);
peer_delete(event->connect.conn_handle);
rc = ble_gap_terminate(event->connect.conn_handle,
BLE_ERR_REM_USER_CONN_TERM);
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to terminate connection; rc=%d\n", rc);
restart_coex();
}
return 0;
}
}
/* Perform service discovery */
rc = peer_disc_all(event->connect.conn_handle,
blecent_on_disc_complete, NULL);
if(rc != 0) {
MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc);
} else {
if (client_connect == 1) {
MODLOG_DFLT(ERROR, "Client connection failed; status=%d\n", event->connect.status);
restart_coex();
}
}
@@ -393,6 +418,7 @@ blecoex_gap_event(struct ble_gap_event *event, void *arg)
case BLE_GAP_EVENT_DISCONNECT:
MODLOG_DFLT(INFO, "Disconnect \n");
peer_delete(event->disconnect.conn.conn_handle);
restart_coex();
return 0;
@@ -497,9 +523,10 @@ ble_coex_advertise(void)
fields.name_is_complete = 1;
}
fields.uuids16 = (ble_uuid16_t[]) {
static const ble_uuid16_t adv_uuids16[] = {
BLE_UUID16_INIT(BLECOEX_SVC_ALERT_UUID)
};
fields.uuids16 = adv_uuids16;
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
@@ -569,11 +596,17 @@ void app_main(void)
}
ble_hs_cfg.sync_cb = on_sync;
int rc;
#if MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)
peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64, 64);
rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64, 64);
#else
peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64);
rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64);
#endif
if (rc != 0) {
MODLOG_DFLT(ERROR, "Failed to init peer tracking; rc=%d\n", rc);
nimble_port_deinit();
return;
}
#if CONFIG_BT_NIMBLE_GAP_SERVICE
ble_svc_gap_init();
@@ -585,8 +618,18 @@ void app_main(void)
ble_svc_ans_init();
#endif
ble_gatts_count_cfg(gatt_svr_svcs);
ble_gatts_add_svcs(gatt_svr_svcs);
rc = ble_gatts_count_cfg(gatt_svr_svcs);
if (rc != 0) {
MODLOG_DFLT(ERROR, "ble_gatts_count_cfg failed; rc=%d\n", rc);
nimble_port_deinit();
return;
}
rc = ble_gatts_add_svcs(gatt_svr_svcs);
if (rc != 0) {
MODLOG_DFLT(ERROR, "ble_gatts_add_svcs failed; rc=%d\n", rc);
nimble_port_deinit();
return;
}
nimble_port_freertos_init(ble_hs_task);
}
@@ -5,8 +5,5 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -63,6 +63,15 @@ ble_htp_cent_on_subscribe(uint16_t conn_handle,
uint8_t value[2];
int rc;
const struct peer *peer = peer_find(conn_handle);
if (peer == NULL) {
MODLOG_DFLT(ERROR, "Peer not found for conn_handle=%d\n", conn_handle);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
if (error->status != 0) {
MODLOG_DFLT(ERROR, "Subscribe to temp measurement failed; status=%d\n", error->status);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
dsc = peer_dsc_find_uuid(peer,
BLE_UUID16_DECLARE(BLE_SVC_HTP_UUID16),
@@ -86,9 +95,7 @@ ble_htp_cent_on_subscribe(uint16_t conn_handle,
return 0;
err:
/* Terminate the connection. */
return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return 0;
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
/**
@@ -113,6 +120,15 @@ ble_htp_cent_on_write(uint16_t conn_handle,
uint8_t value[2];
int rc;
const struct peer *peer = peer_find(conn_handle);
if (peer == NULL) {
MODLOG_DFLT(ERROR, "Peer not found for conn_handle=%d\n", conn_handle);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
if (error->status != 0) {
MODLOG_DFLT(ERROR, "Write to measurement interval failed; status=%d\n", error->status);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
dsc = peer_dsc_find_uuid(peer,
BLE_UUID16_DECLARE(BLE_SVC_HTP_UUID16),
@@ -137,7 +153,7 @@ ble_htp_cent_on_write(uint16_t conn_handle,
return 0;
err:
/* Terminate the connection. */
return ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
/**
@@ -155,6 +171,9 @@ ble_htp_cent_on_read(uint16_t conn_handle,
if (error->status == 0) {
MODLOG_DFLT(INFO, " attr_handle=%d value=", attr->handle);
print_mbuf(attr->om);
} else {
MODLOG_DFLT(ERROR, "Read temperature type failed; status=%d\n", error->status);
return ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
}
MODLOG_DFLT(INFO, "\n");
@@ -319,25 +338,15 @@ ext_ble_htp_cent_should_connect(const struct ble_gap_ext_disc_desc *disc)
{
int offset = 0;
int ad_struct_len = 0;
uint8_t test_addr[6];
uint32_t peer_addr[6];
memset(peer_addr, 0x0, sizeof peer_addr);
if (disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
uint8_t test_addr[6] = {0};
if (!(disc->props & BLE_HCI_ADV_CONN_MASK)) {
return 0;
}
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen ("ADDR_ANY")) != 0)) {
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
/* Conversion */
for (int i=0; i<6; i++) {
test_addr[i] = (uint8_t )peer_addr[5 - i];
if (peer_addr_parse(CONFIG_EXAMPLE_PEER_ADDR, test_addr) != 6) {
return 0;
}
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
@@ -356,9 +365,9 @@ ext_ble_htp_cent_should_connect(const struct ble_gap_ext_disc_desc *disc)
break;
}
/* Search if HTP UUID is advertised */
/* Search if HTP UUID is advertised (little-endian: 0x09 0x18 = 0x1809) */
if (disc->data[offset] == 0x03 && disc->data[offset + 1] == 0x03) {
if ( disc->data[offset + 2] == 0x18 && disc->data[offset + 3] == 0x09 ) {
if ( disc->data[offset + 2] == 0x09 && disc->data[offset + 3] == 0x18 ) {
return 1;
}
}
@@ -376,11 +385,7 @@ ble_htp_cent_should_connect(const struct ble_gap_disc_desc *disc)
struct ble_hs_adv_fields fields;
int rc;
int i;
uint8_t test_addr[6];
uint32_t peer_addr[6];
memset(peer_addr, 0x0, sizeof peer_addr);
uint8_t test_addr[6] = {0};
/* The device has to be advertising connectability. */
if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
@@ -396,15 +401,9 @@ ble_htp_cent_should_connect(const struct ble_gap_disc_desc *disc)
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) {
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
/* Conversion */
for (int i=0; i<6; i++) {
test_addr[i] = (uint8_t )peer_addr[i];
if (peer_addr_parse(CONFIG_EXAMPLE_PEER_ADDR, test_addr) != 6) {
return 0;
}
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0;
}
@@ -459,6 +458,9 @@ ble_htp_cent_connect_if_interesting(void *disc)
rc = ble_hs_id_infer_auto(0, &own_addr_type);
if (rc != 0) {
MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc);
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
ble_htp_cent_scan();
#endif
return;
}
@@ -476,6 +478,9 @@ ble_htp_cent_connect_if_interesting(void *disc)
MODLOG_DFLT(ERROR, "Error: Failed to connect to device; addr_type=%d "
"addr=%s; rc=%d\n",
addr->type, addr_str(addr->val), rc);
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
ble_htp_cent_scan();
#endif
return;
}
}
@@ -498,11 +503,13 @@ static int
ble_htp_cent_gap_event(struct ble_gap_event *event, void *arg)
{
struct ble_gap_conn_desc desc;
struct ble_hs_adv_fields fields;
int rc;
switch (event->type) {
case BLE_GAP_EVENT_DISC:
#if !CONFIG_EXAMPLE_EXTENDED_ADV
{
struct ble_hs_adv_fields fields;
rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
event->disc.length_data);
if (rc != 0) {
@@ -514,6 +521,8 @@ ble_htp_cent_gap_event(struct ble_gap_event *event, void *arg)
/* Try to connect to the advertiser if it looks interesting. */
ble_htp_cent_connect_if_interesting(&event->disc);
}
#endif
return 0;
case BLE_GAP_EVENT_CONNECT:
@@ -746,11 +755,14 @@ app_main(void)
/* Initialize data structures to track connected peers. */
#if MYNEWT_VAL(BLE_INCL_SVC_DISCOVERY) || MYNEWT_VAL(BLE_GATT_CACHING_INCLUDE_SERVICES)
rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64, 64);
assert(rc == 0);
#else
rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64);
assert(rc == 0);
#endif
if (rc != 0) {
ESP_LOGE(tag, "Failed to init peer tracking; rc=%d", rc);
nimble_port_deinit();
return;
}
#if CONFIG_BT_NIMBLE_GAP_SERVICE
/* Set the default device name. */
rc = ble_svc_gap_device_name_set("nimble-htp-cent");
@@ -5,8 +5,5 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
@@ -68,7 +65,6 @@ CONFIG_ESP_WIFI_ENABLED=n
# Application
CONFIG_APP_COMPILE_TIME_DATE=n
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=n
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
@@ -82,7 +78,6 @@ CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=n
#Uncomment below, if security needs to be disabled
#CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
#Uncomment below, if logging needs to be disabled
#CONFIG_LOG_DEFAULT_LEVEL_NONE=y
#CONFIG_LOG_DEFAULT_LEVEL=0
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -15,7 +15,7 @@
static const char *manuf_name = "ESP32 devkitC";
static const char *model_num = "HTP Sensor demo";
static const char *system_id = "HTP1";
static const uint8_t system_id[8] = { 'H', 'T', 'P', '1' };
static int
gatt_svr_chr_access_device_info(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg);
@@ -72,7 +72,7 @@ gatt_svr_chr_access_device_info(uint16_t conn_handle, uint16_t attr_handle,
}
if (uuid == GATT_DIS_CHR_UUID16_SYS_ID) {
rc = os_mbuf_append(ctxt->om, system_id, strlen(system_id));
rc = os_mbuf_append(ctxt->om, system_id, sizeof(system_id));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
@@ -123,7 +123,7 @@ gatt_svr_init(void)
#if MYNEWT_VAL(BLE_GATTS)
ble_svc_gatt_init();
#endif
#if CONFIG_BT_NIMBLE_ANS_SERVICE
#if CONFIG_BT_NIMBLE_HTP_SERVICE
ble_svc_htp_init();
#endif
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -20,7 +20,7 @@
static uint8_t ext_adv_pattern_1[] = {
0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06,
0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd,
0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x09,
0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x09, 0x18,
0x12, BLE_HS_ADV_TYPE_COMP_NAME, 'n', 'i', 'm', 'b', 'l', 'e', '-', 'h', 't', 'p', '-', 'p', 'r', 'p', 'h', '-', 'e',
};
#endif
@@ -81,8 +81,8 @@ ext_ble_htp_prph_advertise(void)
/* enable connectable advertising */
params.connectable = 1;
/* advertise using random addr */
params.own_addr_type = BLE_OWN_ADDR_PUBLIC;
/* advertise using configured addr */
params.own_addr_type = ble_htp_prph_addr_type;
params.primary_phy = BLE_HCI_LE_PHY_1M;
params.secondary_phy = BLE_HCI_LE_PHY_2M;
@@ -150,9 +150,10 @@ ble_htp_prph_advertise(void)
fields.name_len = strlen(device_name);
fields.name_is_complete = 1;
fields.uuids16 = (ble_uuid16_t[]) {
static const ble_uuid16_t adv_uuids16[] = {
BLE_UUID16_INIT(BLE_SVC_HTP_UUID16)
};
fields.uuids16 = adv_uuids16;
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
@@ -178,23 +179,16 @@ ble_htp_prph_advertise(void)
static void
ble_htp_prph_tx_htp_stop(void)
{
xTimerStop( ble_htp_prph_tx_timer, 1000 / portTICK_PERIOD_MS );
xTimerStop( ble_htp_prph_tx_timer, 0 );
}
/* Reset temperature measurement */
static void
ble_htp_prph_tx_htp_reset(void)
{
int rc;
if (xTimerReset(ble_htp_prph_tx_timer, 1000 / portTICK_PERIOD_MS ) == pdPASS) {
rc = 0;
} else {
rc = 1;
if (xTimerReset(ble_htp_prph_tx_timer, 0) != pdPASS) {
MODLOG_DFLT(ERROR, "Failed to reset HTP timer\n");
}
assert(rc == 0);
}
/* This function notifies intermediate temperature to the client */
@@ -372,6 +366,11 @@ void app_main(void)
/* name, period/time, auto reload, timer ID, callback */
ble_htp_prph_tx_timer = xTimerCreate("ble_htp_prph_tx_timer", pdMS_TO_TICKS(1000), pdTRUE,
(void *)0, ble_htp_prph_tx);
if (ble_htp_prph_tx_timer == NULL) {
MODLOG_DFLT(ERROR, "Failed to create HTP TX timer\n");
nimble_port_deinit();
return;
}
#if MYNEWT_VAL(BLE_GATTS)
int rc;
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4000
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4000
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=1
@@ -36,7 +33,6 @@ CONFIG_BT_NIMBLE_SPS_SERVICE=n
CONFIG_BT_NIMBLE_HR_SERVICE=n
CONFIG_BT_NIMBLE_DIS_SERVICE=n
CONFIG_BT_ALARM_MAX_NUM=15
CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU=23
@@ -80,7 +76,6 @@ CONFIG_ESP_WIFI_ENABLED=n
# Application
CONFIG_APP_COMPILE_TIME_DATE=n
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=n
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
@@ -94,7 +89,6 @@ CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=n
#Uncomment below, if security needs to be disabled
#CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
#Uncomment below, if logging needs to be disabled
#CONFIG_LOG_DEFAULT_LEVEL_NONE=y
#CONFIG_LOG_DEFAULT_LEVEL=0
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -68,16 +68,9 @@ blecent_l2cap_coc_send_data(struct ble_l2cap_chan *chan)
rc = ble_l2cap_send(chan, sdu_rx_data);
retry = 0;
while (rc == BLE_HS_ESTALLED && retry < max_retry) {
MODLOG_DFLT(INFO, "Send stalled, waiting for credits (retry=%d)", retry);
vTaskDelay(100 / portTICK_PERIOD_MS);
rc = ble_l2cap_send(chan, sdu_rx_data);
retry++;
}
if (rc == BLE_HS_ESTALLED) {
MODLOG_DFLT(INFO, "Send still stalled after %d retries, returning", retry);
/* Stack took ownership of sdu_rx_data; wait for BLE_L2CAP_EVENT_COC_TX_UNSTALLED */
MODLOG_DFLT(INFO, "Send stalled, waiting for credits");
return;
}
@@ -115,7 +108,7 @@ blecent_l2cap_coc_on_disc_complete(const struct peer *peer, int status, void *ar
rc = ble_l2cap_connect(conn_handle_coc, psm, MTU, sdu_rx, blecent_l2cap_coc_event_cb, NULL);
if (rc != 0) {
MODLOG_DFLT(ERROR, "L2CAP COC connect failed, rc=%d", rc);
os_mbuf_free_chain(sdu_rx);
/* sdu_rx is freed by the stack on all failure paths; do not free here */
}
}
@@ -163,6 +156,7 @@ blecent_l2cap_coc_event_cb(struct ble_l2cap_event *event, void *arg)
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
console_printf("LE CoC disconnected, chan: %p\n",
event->disconnect.chan);
coc_chan = NULL;
return 0;
default:
@@ -266,27 +260,14 @@ ext_blecent_should_connect(const struct ble_gap_ext_disc_desc *disc)
int offset = 0;
int ad_struct_len = 0;
uint8_t test_addr[6];
uint32_t peer_addr[6];
memset(peer_addr, 0x0, sizeof peer_addr);
if (disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
if (!(disc->props & BLE_HCI_ADV_CONN_MASK)) {
return 0;
}
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) &&
(strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) {
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
/* Conversion */
for (int i=0; i<6; i++) {
test_addr[i] = (uint8_t )peer_addr[i];
}
peer_addr_parse(CONFIG_EXAMPLE_PEER_ADDR, test_addr);
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0;
}
@@ -308,11 +289,11 @@ ext_blecent_should_connect(const struct ble_gap_ext_disc_desc *disc)
break;
}
/* AD Type (1) + UUID16 (2) requires at least 4 bytes total */
/* AD Type (1) + UUID16 (2) requires at least 4 bytes total; UUID 0x1812 is LE [0x12, 0x18] */
if (ad_struct_len >= 3 &&
disc->data[offset + 1] == 0x03 &&
disc->data[offset + 2] == 0x18 &&
disc->data[offset + 3] == 0x12) {
disc->data[offset + 2] == 0x12 &&
disc->data[offset + 3] == 0x18) {
return 1;
}
@@ -329,10 +310,6 @@ blecent_should_connect(const struct ble_gap_disc_desc *disc)
int rc;
int i;
uint8_t test_addr[6];
uint32_t peer_addr[6];
memset(peer_addr, 0x0, sizeof peer_addr);
/* The device has to be advertising connectability. */
if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
@@ -349,15 +326,7 @@ blecent_should_connect(const struct ble_gap_disc_desc *disc)
(strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen("ADDR_ANY")) != 0)) {
MODLOG_DFLT(INFO, "Peer address from menuconfig:%s", CONFIG_EXAMPLE_PEER_ADDR);
/* Convert string to address */
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%lx:%lx:%lx:%lx:%lx:%lx",
&peer_addr[5], &peer_addr[4], &peer_addr[3],
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
/* Conversion */
for (int i=0; i<6; i++) {
test_addr[i] = (uint8_t )peer_addr[i];
}
peer_addr_parse(CONFIG_EXAMPLE_PEER_ADDR, test_addr);
if (memcmp(test_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
return 0;
}
@@ -410,6 +379,9 @@ blecent_connect_if_interesting(void *disc)
rc = ble_hs_id_infer_auto(0, &own_addr_type);
if (rc != 0) {
MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc);
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
blecent_scan();
#endif
return;
}
@@ -428,6 +400,9 @@ blecent_connect_if_interesting(void *disc)
MODLOG_DFLT(ERROR, "Error: Failed to connect to device; addr_type=%d "
"addr=%s; rc=%d\n",
addr->type, addr_str(addr->val), rc);
#if !(MYNEWT_VAL(BLE_HOST_ALLOW_CONNECT_WITH_SCAN))
blecent_scan();
#endif
return;
}
}
@@ -515,6 +490,10 @@ blecent_gap_event(struct ble_gap_event *event, void *arg)
print_conn_desc(&event->disconnect.conn);
MODLOG_DFLT(INFO, "\n");
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) >= 1
coc_chan = NULL;
#endif
/* Forget about peer. */
peer_delete(event->disconnect.conn.conn_handle);
@@ -560,6 +539,9 @@ static void
blecent_on_reset(int reason)
{
MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) >= 1
coc_chan = NULL;
#endif
}
static void
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=1
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=1
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=1
@@ -70,7 +67,6 @@ CONFIG_ESP_WIFI_ENABLED=n
# Application
CONFIG_APP_COMPILE_TIME_DATE=n
CONFIG_ESP_COEX_SW_COEXIST_ENABLE=n
CONFIG_ESP_ERR_TO_NAME_LOOKUP=n
CONFIG_SPI_MASTER_ISR_IN_IRAM=n
@@ -84,7 +80,6 @@ CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE=n
#Uncomment below, if security needs to be disabled
#CONFIG_BT_NIMBLE_SECURITY_ENABLE=n
#Uncomment below, if logging needs to be disabled
#CONFIG_LOG_DEFAULT_LEVEL_NONE=y
#CONFIG_LOG_DEFAULT_LEVEL=0
@@ -0,0 +1,4 @@
# ESP32-only BTDM controller mode (classic BT + BLE SoC)
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
@@ -18,7 +18,7 @@
static uint8_t ext_adv_pattern_1[] = {
0x02, BLE_HS_ADV_TYPE_FLAGS, 0x06,
0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0xab, 0xcd,
0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x18, 0x12,
0x03, BLE_HS_ADV_TYPE_COMP_UUIDS16, 0x12, 0x18, /* UUID 0x1812 in little-endian */
0x12, BLE_HS_ADV_TYPE_COMP_NAME, 'e', 'x', 't', '-', 'b', 'l', 'e', 'p', 'r', 'p', 'h', '-', 'l', '2', 'c', 'o', 'c',
};
#endif
@@ -164,9 +164,10 @@ bleprph_advertise(void)
fields.name_len = strlen(name);
fields.name_is_complete = 1;
fields.uuids16 = (ble_uuid16_t[]) {
static const ble_uuid16_t adv_uuids16[] = {
BLE_UUID16_INIT(L2CAP_COC_UUID)
};
fields.uuids16 = adv_uuids16;
fields.num_uuids16 = 1;
fields.uuids16_is_complete = 1;
@@ -196,8 +197,8 @@ bleprph_l2cap_coc_accept(uint16_t conn_handle, uint16_t peer_mtu,
{
struct os_mbuf *sdu_rx;
console_printf("LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n",
(uint32_t) chan, peer_mtu);
console_printf("LE CoC accepting, chan: 0x%08x, peer_mtu %d\n",
(unsigned) (uint32_t) chan, peer_mtu);
sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
if (!sdu_rx) {
@@ -259,7 +260,7 @@ bleprph_l2cap_coc_event_cb(struct ble_l2cap_event *event, void *arg)
for (int i = 0; i < event->receive.sdu_rx->om_len; i++) {
console_printf("%d ", event->receive.sdu_rx->om_data[i]);
}
os_mbuf_free(event->receive.sdu_rx);
os_mbuf_free_chain(event->receive.sdu_rx);
}
fflush(stdout);
bleprph_l2cap_coc_accept(event->receive.conn_handle,
@@ -5,9 +5,6 @@
# BT config
#
CONFIG_BT_ENABLED=y
CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y
CONFIG_BTDM_CTRL_MODE_BR_EDR_ONLY=n
CONFIG_BTDM_CTRL_MODE_BTDM=n
CONFIG_BT_BLUEDROID_ENABLED=n
CONFIG_BT_NIMBLE_ENABLED=y
CONFIG_BT_NIMBLE_L2CAP_COC_MAX_NUM=1

Some files were not shown because too many files have changed in this diff Show More