Improve improv BLE error handling (#129902)

pull/129970/head
Erik Montnemery 2024-11-05 17:12:05 +01:00 committed by Franck Nijhof
parent eb3371beef
commit 734ebc1adb
No known key found for this signature in database
GPG Key ID: D62583BA8AB11CA3
3 changed files with 51 additions and 4 deletions

View File

@ -120,12 +120,22 @@ class ImprovBLEConfigFlow(ConfigFlow, domain=DOMAIN):
assert self._discovery_info is not None
service_data = self._discovery_info.service_data
improv_service_data = ImprovServiceData.from_bytes(
service_data[SERVICE_DATA_UUID]
)
try:
improv_service_data = ImprovServiceData.from_bytes(
service_data[SERVICE_DATA_UUID]
)
except improv_ble_errors.InvalidCommand as err:
_LOGGER.warning(
"Aborting improv flow, device %s sent invalid improv data: '%s'",
self._discovery_info.address,
service_data[SERVICE_DATA_UUID].hex(),
)
raise AbortFlow("invalid_improv_data") from err
if improv_service_data.state in (State.PROVISIONING, State.PROVISIONED):
_LOGGER.debug(
"Aborting improv flow, device is already provisioned: %s",
"Aborting improv flow, device %s is already provisioned: %s",
self._discovery_info.address,
improv_service_data.state,
)
raise AbortFlow("already_provisioned")

View File

@ -25,6 +25,25 @@ IMPROV_BLE_DISCOVERY_INFO = BluetoothServiceInfoBleak(
)
BAD_IMPROV_BLE_DISCOVERY_INFO = BluetoothServiceInfoBleak(
name="00123456",
address="AA:BB:CC:DD:EE:F0",
rssi=-60,
manufacturer_data={},
service_uuids=[SERVICE_UUID],
service_data={SERVICE_DATA_UUID: b"\x00\x00\x00\x00\x00\x00"},
source="local",
device=generate_ble_device(address="AA:BB:CC:DD:EE:F0", name="00123456"),
advertisement=generate_advertisement_data(
service_uuids=[SERVICE_UUID],
service_data={SERVICE_DATA_UUID: b"\x00\x00\x00\x00\x00\x00"},
),
time=0,
connectable=True,
tx_power=-127,
)
PROVISIONED_IMPROV_BLE_DISCOVERY_INFO = BluetoothServiceInfoBleak(
name="00123456",
address="AA:BB:CC:DD:EE:F0",

View File

@ -15,6 +15,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResult, FlowResultType
from . import (
BAD_IMPROV_BLE_DISCOVERY_INFO,
IMPROV_BLE_DISCOVERY_INFO,
NOT_IMPROV_BLE_DISCOVERY_INFO,
PROVISIONED_IMPROV_BLE_DISCOVERY_INFO,
@ -649,3 +650,20 @@ async def test_provision_retry(hass: HomeAssistant, exc, error) -> None:
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "provision"
assert result["errors"] == {"base": error}
async def test_provision_fails_invalid_data(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test bluetooth flow with error due to invalid data."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_BLUETOOTH},
data=BAD_IMPROV_BLE_DISCOVERY_INFO,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "invalid_improv_data"
assert (
"Aborting improv flow, device AA:BB:CC:DD:EE:F0 sent invalid improv data: '000000000000'"
in caplog.text
)