mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
[bluetooth_proxy] Make the GATT dispatch platform neutral (#18130)
This commit is contained in:
@@ -5,12 +5,14 @@ advertisement-only arm applies its own defaults."""
|
||||
import pytest
|
||||
|
||||
from esphome import config_validation as cv
|
||||
from esphome.components import bluetooth_connection, bluetooth_proxy
|
||||
from esphome.components import ble_device_base, bluetooth_connection, bluetooth_proxy
|
||||
from esphome.const import (
|
||||
CONF_ACTIVE,
|
||||
KEY_CORE,
|
||||
KEY_TARGET_FRAMEWORK,
|
||||
KEY_TARGET_PLATFORM,
|
||||
PLATFORM_LN882X,
|
||||
PLATFORM_RP2,
|
||||
PlatformFramework,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
@@ -22,12 +24,18 @@ HUB_PLATFORM_FRAMEWORKS = [
|
||||
PlatformFramework.RP2_ARDUINO,
|
||||
]
|
||||
|
||||
HUB_TRACKERS = {
|
||||
PLATFORM_LN882X: "ln882h_ble_tracker",
|
||||
PLATFORM_RP2: "rp2_ble_tracker",
|
||||
}
|
||||
|
||||
|
||||
def test_hub_platform_list_covers_every_hub_platform() -> None:
|
||||
# A platform added to _HUB_PLATFORMS (bk72xx is planned) would otherwise
|
||||
# get no gate coverage at all.
|
||||
covered = {pf.value[0] for pf in HUB_PLATFORM_FRAMEWORKS}
|
||||
assert covered == set(bluetooth_proxy._HUB_PLATFORMS)
|
||||
assert set(HUB_TRACKERS) == set(bluetooth_proxy._HUB_PLATFORMS)
|
||||
|
||||
|
||||
def _set_platform(platform: str | None) -> None:
|
||||
@@ -35,6 +43,14 @@ def _set_platform(platform: str | None) -> None:
|
||||
CORE.data.setdefault(KEY_CORE, {})[KEY_TARGET_PLATFORM] = platform
|
||||
|
||||
|
||||
def _register_tracker(platform: str) -> None:
|
||||
# The ble_hub_id guard needs a loaded tracker, normally registered as an
|
||||
# import side effect of the tracker module.
|
||||
tracker = HUB_TRACKERS[platform]
|
||||
ble_device_base.register_hub_provider(tracker)
|
||||
CORE.loaded_integrations.add(tracker)
|
||||
|
||||
|
||||
def test_ble_less_platform_gets_the_real_reason(
|
||||
set_core_config: SetCoreConfigCallable,
|
||||
) -> None:
|
||||
@@ -68,6 +84,7 @@ def test_hub_platform_rejects_active(
|
||||
platform_framework: PlatformFramework,
|
||||
) -> None:
|
||||
set_core_config(platform_framework)
|
||||
_register_tracker(platform_framework.value[0])
|
||||
with pytest.raises(cv.Invalid, match="Active connections are not supported"):
|
||||
bluetooth_proxy.CONFIG_SCHEMA({"active": True})
|
||||
|
||||
@@ -100,6 +117,7 @@ def test_hub_platform_accepts_the_advertisement_only_shape(
|
||||
platform_framework: PlatformFramework,
|
||||
) -> None:
|
||||
set_core_config(platform_framework)
|
||||
_register_tracker(platform_framework.value[0])
|
||||
validated = bluetooth_proxy.CONFIG_SCHEMA({})
|
||||
assert validated[CONF_ACTIVE] is False
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// Pins the shared UUID wire packing and the size-estimate budget the service
|
||||
// streamers rely on, in both efficient and legacy client modes.
|
||||
#include "esphome/components/bluetooth_connection/bluetooth_connection.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace esphome::bluetooth_connection::testing {
|
||||
|
||||
using ble_device_base::ESPBTUUID;
|
||||
|
||||
TEST(GattUuidPacking, ShortUuidUsedWhenClientSupportsIt) {
|
||||
std::array<uint64_t, 2> uuid128{};
|
||||
uint32_t short_uuid = 0;
|
||||
fill_gatt_uuid(uuid128, short_uuid, ESPBTUUID::from_uint16(0x180F), true);
|
||||
EXPECT_EQ(short_uuid, 0x180Fu);
|
||||
EXPECT_EQ(uuid128[0], 0u);
|
||||
EXPECT_EQ(uuid128[1], 0u);
|
||||
}
|
||||
|
||||
TEST(GattUuidPacking, LegacyClientGetsBaseUuidExpansion) {
|
||||
// 0000180F-0000-1000-8000-00805F9B34FB
|
||||
std::array<uint64_t, 2> uuid128{};
|
||||
uint32_t short_uuid = 0;
|
||||
fill_gatt_uuid(uuid128, short_uuid, ESPBTUUID::from_uint16(0x180F), false);
|
||||
EXPECT_EQ(short_uuid, 0u);
|
||||
EXPECT_EQ(uuid128[0], 0x0000180F00001000ULL);
|
||||
EXPECT_EQ(uuid128[1], 0x800000805F9B34FBULL);
|
||||
}
|
||||
|
||||
TEST(GattUuidPacking, FullUuidPassesThroughBigEndian) {
|
||||
// 12345678-90AB-CDEF-1122-334455667788, stored little-endian in ESPBTUUID.
|
||||
const uint8_t big_endian[16] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF,
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
|
||||
std::array<uint64_t, 2> uuid128{};
|
||||
uint32_t short_uuid = 0;
|
||||
// Efficient mode must still use the 128-bit form for 128-bit UUIDs.
|
||||
fill_gatt_uuid(uuid128, short_uuid, ESPBTUUID::from_raw_reversed(big_endian), true);
|
||||
EXPECT_EQ(short_uuid, 0u);
|
||||
EXPECT_EQ(uuid128[0], 0x1234567890ABCDEFULL);
|
||||
EXPECT_EQ(uuid128[1], 0x1122334455667788ULL);
|
||||
}
|
||||
|
||||
TEST(GattUuidPacking, EstimateGrowsWithCharacteristicsAndMode) {
|
||||
// The estimate only gates batching; pin its shape, not exact bytes.
|
||||
EXPECT_LT(estimate_service_size(0, true), estimate_service_size(0, false));
|
||||
EXPECT_LT(estimate_service_size(1, false), estimate_service_size(2, false));
|
||||
}
|
||||
|
||||
} // namespace esphome::bluetooth_connection::testing
|
||||
Reference in New Issue
Block a user