mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 18:57:19 +02:00
feat(ble): added pytest for ble power save example
This commit is contained in:
@ -243,14 +243,19 @@ examples/bluetooth/nimble/ble_spp:
|
|||||||
reason: The runner doesn't support yet
|
reason: The runner doesn't support yet
|
||||||
|
|
||||||
examples/bluetooth/nimble/blecent:
|
examples/bluetooth/nimble/blecent:
|
||||||
enable:
|
disable:
|
||||||
- if: IDF_TARGET in ["esp32", "esp32c2", "esp32c3", "esp32c6" , "esp32s3", "esp32h2" ]
|
- if: SOC_BLE_SUPPORTED != 1
|
||||||
temporary: true
|
depends_components:
|
||||||
reason: the other targets are not tested yet
|
- bt
|
||||||
disable_test:
|
- esp_phy
|
||||||
- if: IDF_TARGET in ["esp32c2", "esp32c3", "esp32h2", "esp32s3", "esp32c6"]
|
- esp_event
|
||||||
temporary: true
|
- esp_coex
|
||||||
reason: The runner doesn't support yet
|
- esp_pm
|
||||||
|
depends_filepatterns:
|
||||||
|
- examples/bluetooth/nimble/common/**/*
|
||||||
|
- examples/bluetooth/nimble/blecent/**/*
|
||||||
|
- examples/bluetooth/nimble/power_save/**/*
|
||||||
|
- examples/bluetooth/nimble/pytest_nimble_test.py
|
||||||
|
|
||||||
examples/bluetooth/nimble/blehr:
|
examples/bluetooth/nimble/blehr:
|
||||||
enable:
|
enable:
|
||||||
@ -303,7 +308,16 @@ examples/bluetooth/nimble/hci:
|
|||||||
reason: The runner doesn't support yet
|
reason: The runner doesn't support yet
|
||||||
|
|
||||||
examples/bluetooth/nimble/power_save:
|
examples/bluetooth/nimble/power_save:
|
||||||
enable:
|
disable:
|
||||||
- if: IDF_TARGET in ["esp32", "esp32c3", "esp32s3", "esp32c6", "esp32h2"]
|
- if: SOC_BLE_SUPPORTED != 1
|
||||||
temporary: true
|
depends_components:
|
||||||
reason: the other targets are not tested yet
|
- bt
|
||||||
|
- esp_phy
|
||||||
|
- esp_event
|
||||||
|
- esp_coex
|
||||||
|
- esp_pm
|
||||||
|
depends_filepatterns:
|
||||||
|
- examples/bluetooth/nimble/common/**/*
|
||||||
|
- examples/bluetooth/nimble/blecent/**/*
|
||||||
|
- examples/bluetooth/nimble/power_save/**/*
|
||||||
|
- examples/bluetooth/nimble/pytest_nimble_test.py
|
||||||
|
@ -28,4 +28,12 @@ menu "Example Configuration"
|
|||||||
prompt "Enable Link Encryption"
|
prompt "Enable Link Encryption"
|
||||||
help
|
help
|
||||||
This enables bonding and encryption after connection has been established.
|
This enables bonding and encryption after connection has been established.
|
||||||
|
|
||||||
|
config EXAMPLE_USE_CI_ADDRESS
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
prompt "Advertise using Test address(Internal Test ONLY)"
|
||||||
|
help
|
||||||
|
Used for internal test ONLY.
|
||||||
|
Use this option to advertise in a specific random address.
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -455,17 +455,26 @@ ext_blecent_should_connect(const struct ble_gap_ext_disc_desc *disc)
|
|||||||
{
|
{
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int ad_struct_len = 0;
|
int ad_struct_len = 0;
|
||||||
|
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
|
uint32_t *addr_offset;
|
||||||
|
#endif // CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
|
|
||||||
if (disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
|
if (disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
|
||||||
disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
|
disc->legacy_event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen ("ADDR_ANY")) != 0)) {
|
if (strlen(CONFIG_EXAMPLE_PEER_ADDR) && (strncmp(CONFIG_EXAMPLE_PEER_ADDR, "ADDR_ANY", strlen ("ADDR_ANY")) != 0)) {
|
||||||
|
#if !CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
|
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
|
||||||
/* Convert string to address */
|
/* Convert string to address */
|
||||||
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||||
&peer_addr[5], &peer_addr[4], &peer_addr[3],
|
&peer_addr[5], &peer_addr[4], &peer_addr[3],
|
||||||
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
|
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
|
||||||
|
#else
|
||||||
|
addr_offset = (uint32_t *)&peer_addr[1];
|
||||||
|
*addr_offset = atoi(CONFIG_EXAMPLE_PEER_ADDR);
|
||||||
|
peer_addr[5] = 0xC3;
|
||||||
|
#endif // !CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
|
if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -501,6 +510,9 @@ blecent_should_connect(const struct ble_gap_disc_desc *disc)
|
|||||||
struct ble_hs_adv_fields fields;
|
struct ble_hs_adv_fields fields;
|
||||||
int rc;
|
int rc;
|
||||||
int i;
|
int i;
|
||||||
|
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
|
uint32_t *addr_offset;
|
||||||
|
#endif // CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
|
|
||||||
/* The device has to be advertising connectability. */
|
/* The device has to be advertising connectability. */
|
||||||
if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
|
if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
|
||||||
@ -516,10 +528,16 @@ blecent_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)) {
|
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);
|
ESP_LOGI(tag, "Peer address from menuconfig: %s", CONFIG_EXAMPLE_PEER_ADDR);
|
||||||
|
#if !CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
/* Convert string to address */
|
/* Convert string to address */
|
||||||
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
sscanf(CONFIG_EXAMPLE_PEER_ADDR, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
|
||||||
&peer_addr[5], &peer_addr[4], &peer_addr[3],
|
&peer_addr[5], &peer_addr[4], &peer_addr[3],
|
||||||
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
|
&peer_addr[2], &peer_addr[1], &peer_addr[0]);
|
||||||
|
#else
|
||||||
|
addr_offset = (uint32_t *)&peer_addr[1];
|
||||||
|
*addr_offset = atoi(CONFIG_EXAMPLE_PEER_ADDR);
|
||||||
|
peer_addr[5] = 0xC3;
|
||||||
|
#endif // !CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
|
if (memcmp(peer_addr, disc->addr.val, sizeof(disc->addr.val)) != 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
2
examples/bluetooth/nimble/blecent/sdkconfig.ci
Normal file
2
examples/bluetooth/nimble/blecent/sdkconfig.ci
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
|
||||||
|
CONFIG_EXAMPLE_PEER_ADDR="${CI_JOB_ID}"
|
@ -0,0 +1,4 @@
|
|||||||
|
CONFIG_IDF_TARGET="esp32c2"
|
||||||
|
CONFIG_XTAL_FREQ_26=y
|
||||||
|
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
|
||||||
|
CONFIG_EXAMPLE_PEER_ADDR="${CI_JOB_ID}"
|
@ -1,5 +1,5 @@
|
|||||||
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
|
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
|
||||||
| ----------------- | ----- | -------- | -------- | -------- | -------- |
|
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
|
||||||
|
|
||||||
Bluetooth Power Save Example
|
Bluetooth Power Save Example
|
||||||
=================================
|
=================================
|
||||||
|
@ -156,4 +156,19 @@ menu "Example Configuration"
|
|||||||
help
|
help
|
||||||
Use this option to enable resolving peer's address.
|
Use this option to enable resolving peer's address.
|
||||||
|
|
||||||
|
config EXAMPLE_USE_CI_ADDRESS
|
||||||
|
bool
|
||||||
|
default n
|
||||||
|
prompt "Advertise using Test address(Internal Test ONLY)"
|
||||||
|
help
|
||||||
|
Used for internal test ONLY.
|
||||||
|
Use this option to advertise in a specific random address.
|
||||||
|
|
||||||
|
config EXAMPLE_CI_ADDRESS_OFFSET
|
||||||
|
string
|
||||||
|
prompt "Advertise using Test address(Internal Test ONLY)"
|
||||||
|
depends on EXAMPLE_USE_CI_ADDRESS
|
||||||
|
help
|
||||||
|
Used for internal test ONLY.
|
||||||
|
Use this option to advertise in a specific random address.
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -28,7 +28,7 @@ static uint8_t ext_adv_pattern_1[] = {
|
|||||||
|
|
||||||
static const char *tag = "NimBLE_BLE_PRPH";
|
static const char *tag = "NimBLE_BLE_PRPH";
|
||||||
static int bleprph_gap_event(struct ble_gap_event *event, void *arg);
|
static int bleprph_gap_event(struct ble_gap_event *event, void *arg);
|
||||||
#if CONFIG_EXAMPLE_RANDOM_ADDR
|
#if CONFIG_EXAMPLE_RANDOM_ADDR || CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
static uint8_t own_addr_type = BLE_OWN_ADDR_RANDOM;
|
static uint8_t own_addr_type = BLE_OWN_ADDR_RANDOM;
|
||||||
#else
|
#else
|
||||||
static uint8_t own_addr_type;
|
static uint8_t own_addr_type;
|
||||||
@ -93,7 +93,7 @@ ext_bleprph_advertise(void)
|
|||||||
params.connectable = 1;
|
params.connectable = 1;
|
||||||
|
|
||||||
/* advertise using random addr */
|
/* advertise using random 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.primary_phy = BLE_HCI_LE_PHY_1M;
|
||||||
params.secondary_phy = BLE_HCI_LE_PHY_2M;
|
params.secondary_phy = BLE_HCI_LE_PHY_2M;
|
||||||
@ -462,14 +462,26 @@ bleprph_on_sync(void)
|
|||||||
ble_app_set_addr();
|
ble_app_set_addr();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
|
if (strlen(CONFIG_EXAMPLE_CI_ADDRESS_OFFSET)) {
|
||||||
|
uint8_t addr[6] = {0};
|
||||||
|
uint32_t *offset = (uint32_t *)&addr[1];
|
||||||
|
*offset = atoi(CONFIG_EXAMPLE_CI_ADDRESS_OFFSET);
|
||||||
|
addr[5] = 0xC3;
|
||||||
|
rc = ble_hs_id_set_rnd(addr);
|
||||||
|
assert(rc == 0);
|
||||||
|
}
|
||||||
|
#endif // CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
|
|
||||||
/* Make sure we have proper identity address set (public preferred) */
|
/* Make sure we have proper identity address set (public preferred) */
|
||||||
#if CONFIG_EXAMPLE_RANDOM_ADDR
|
#if CONFIG_EXAMPLE_RANDOM_ADDR || CONFIG_EXAMPLE_USE_CI_ADDRESS
|
||||||
rc = ble_hs_util_ensure_addr(1);
|
rc = ble_hs_util_ensure_addr(1);
|
||||||
#else
|
#else
|
||||||
rc = ble_hs_util_ensure_addr(0);
|
rc = ble_hs_util_ensure_addr(0);
|
||||||
#endif
|
#endif
|
||||||
assert(rc == 0);
|
assert(rc == 0);
|
||||||
|
|
||||||
|
|
||||||
/* Figure out address to use while advertising (no privacy for now) */
|
/* Figure out address to use while advertising (no privacy for now) */
|
||||||
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
rc = ble_hs_id_infer_auto(0, &own_addr_type);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
|
5
examples/bluetooth/nimble/power_save/sdkconfig.ci
Normal file
5
examples/bluetooth/nimble/power_save/sdkconfig.ci
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
#
|
||||||
|
# Test Config
|
||||||
|
#
|
||||||
|
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
|
||||||
|
CONFIG_EXAMPLE_CI_ADDRESS_OFFSET="${CI_JOB_ID}"
|
@ -0,0 +1,7 @@
|
|||||||
|
CONFIG_IDF_TARGET="esp32c2"
|
||||||
|
CONFIG_XTAL_FREQ_26=y
|
||||||
|
#
|
||||||
|
# Test Config
|
||||||
|
#
|
||||||
|
CONFIG_EXAMPLE_USE_CI_ADDRESS=y
|
||||||
|
CONFIG_EXAMPLE_CI_ADDRESS_OFFSET="${CI_JOB_ID}"
|
63
examples/bluetooth/nimble/pytest_nimble_test.py
Normal file
63
examples/bluetooth/nimble/pytest_nimble_test.py
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
|
||||||
|
import os.path
|
||||||
|
from typing import Tuple
|
||||||
|
|
||||||
|
import pexpect
|
||||||
|
import pytest
|
||||||
|
from pytest_embedded_idf.dut import IdfDut
|
||||||
|
|
||||||
|
|
||||||
|
# Case 1: BLE power save test
|
||||||
|
@pytest.mark.esp32c6
|
||||||
|
@pytest.mark.esp32h2
|
||||||
|
@pytest.mark.esp32c3
|
||||||
|
@pytest.mark.esp32s3
|
||||||
|
@pytest.mark.esp32
|
||||||
|
@pytest.mark.wifi_two_dut
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'count, app_path', [
|
||||||
|
(2,
|
||||||
|
f'{os.path.join(os.path.dirname(__file__), "power_save")}|{os.path.join(os.path.dirname(__file__), "blecent")}'),
|
||||||
|
],
|
||||||
|
indirect=True,
|
||||||
|
)
|
||||||
|
def test_power_save_conn(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None:
|
||||||
|
peripheral = dut[0]
|
||||||
|
central = dut[1]
|
||||||
|
|
||||||
|
peripheral.expect('NimBLE_BLE_PRPH: BLE Host Task Started', timeout=30)
|
||||||
|
central.expect('NimBLE_BLE_CENT: BLE Host Task Started', timeout=30)
|
||||||
|
peripheral.expect('Returned from app_main()', timeout=30)
|
||||||
|
central.expect('Returned from app_main()', timeout=30)
|
||||||
|
central.expect('Connection established', timeout=30)
|
||||||
|
peripheral.expect('connection established; status=0', timeout=30)
|
||||||
|
output = peripheral.expect(pexpect.TIMEOUT, timeout=30)
|
||||||
|
assert 'rst:' not in str(output) and 'boot:' not in str(output)
|
||||||
|
|
||||||
|
|
||||||
|
# Case 2: BLE power save test for ESP32C2
|
||||||
|
@pytest.mark.esp32c2
|
||||||
|
@pytest.mark.wifi_two_dut
|
||||||
|
@pytest.mark.xtal_26mhz
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
'config, count, app_path, baud', [
|
||||||
|
('esp32c2_xtal26m', 2,
|
||||||
|
f'{os.path.join(os.path.dirname(__file__), "power_save")}|{os.path.join(os.path.dirname(__file__), "blecent")}',
|
||||||
|
'74880'),
|
||||||
|
],
|
||||||
|
indirect=True,
|
||||||
|
)
|
||||||
|
def test_power_save_conn_esp32c2_26mhz(dut: Tuple[IdfDut, IdfDut]) -> None:
|
||||||
|
peripheral = dut[0]
|
||||||
|
central = dut[1]
|
||||||
|
|
||||||
|
peripheral.expect('NimBLE_BLE_PRPH: BLE Host Task Started', timeout=5)
|
||||||
|
central.expect('NimBLE_BLE_CENT: BLE Host Task Started', timeout=5)
|
||||||
|
peripheral.expect('Returned from app_main()', timeout=5)
|
||||||
|
central.expect('Returned from app_main()', timeout=5)
|
||||||
|
central.expect('Connection established', timeout=30)
|
||||||
|
peripheral.expect('connection established; status=0', timeout=30)
|
||||||
|
output = peripheral.expect(pexpect.TIMEOUT, timeout=30)
|
||||||
|
assert 'rst:' not in str(output) and 'boot:' not in str(output)
|
Reference in New Issue
Block a user