Improve improv BLE error handling (#129902)

This commit is contained in:
Erik Montnemery 2024-11-05 17:12:05 +01:00 committed by GitHub
parent ed56e5d631
commit 05e76105ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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 assert self._discovery_info is not None
service_data = self._discovery_info.service_data service_data = self._discovery_info.service_data
improv_service_data = ImprovServiceData.from_bytes( try:
service_data[SERVICE_DATA_UUID] 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): if improv_service_data.state in (State.PROVISIONING, State.PROVISIONED):
_LOGGER.debug( _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, improv_service_data.state,
) )
raise AbortFlow("already_provisioned") 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( PROVISIONED_IMPROV_BLE_DISCOVERY_INFO = BluetoothServiceInfoBleak(
name="00123456", name="00123456",
address="AA:BB:CC:DD:EE:F0", 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 homeassistant.data_entry_flow import FlowResult, FlowResultType
from . import ( from . import (
BAD_IMPROV_BLE_DISCOVERY_INFO,
IMPROV_BLE_DISCOVERY_INFO, IMPROV_BLE_DISCOVERY_INFO,
NOT_IMPROV_BLE_DISCOVERY_INFO, NOT_IMPROV_BLE_DISCOVERY_INFO,
PROVISIONED_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["type"] is FlowResultType.FORM
assert result["step_id"] == "provision" assert result["step_id"] == "provision"
assert result["errors"] == {"base": error} 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
)