Randomize thread network names (#108302)
* Randomize thread network names * Use PAN ID as network name suffix * Apply suggestions from code review Co-authored-by: Stefan Agner <stefan@agner.ch> * Update tests * Format code * Change format of network name again --------- Co-authored-by: Stefan Agner <stefan@agner.ch>
This commit is contained in:
parent
d8f16c14ab
commit
823f268054
5 changed files with 47 additions and 9 deletions
|
@ -28,7 +28,11 @@ from homeassistant.exceptions import HomeAssistantError
|
|||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
from .const import DEFAULT_CHANNEL, DOMAIN
|
||||
from .util import get_allowed_channel
|
||||
from .util import (
|
||||
compose_default_network_name,
|
||||
generate_random_pan_id,
|
||||
get_allowed_channel,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
@ -85,10 +89,12 @@ class OTBRConfigFlow(ConfigFlow, domain=DOMAIN):
|
|||
_LOGGER.debug(
|
||||
"not importing TLV with channel %s", thread_dataset_channel
|
||||
)
|
||||
pan_id = generate_random_pan_id()
|
||||
await api.create_active_dataset(
|
||||
python_otbr_api.ActiveDataSet(
|
||||
channel=allowed_channel if allowed_channel else DEFAULT_CHANNEL,
|
||||
network_name="home-assistant",
|
||||
network_name=compose_default_network_name(pan_id),
|
||||
pan_id=pan_id,
|
||||
)
|
||||
)
|
||||
await api.set_enabled(True)
|
||||
|
|
|
@ -5,6 +5,7 @@ from collections.abc import Callable, Coroutine
|
|||
import dataclasses
|
||||
from functools import wraps
|
||||
import logging
|
||||
import random
|
||||
from typing import Any, Concatenate, ParamSpec, TypeVar, cast
|
||||
|
||||
import python_otbr_api
|
||||
|
@ -48,6 +49,17 @@ INSECURE_PASSPHRASES = (
|
|||
)
|
||||
|
||||
|
||||
def compose_default_network_name(pan_id: int) -> str:
|
||||
"""Generate a default network name."""
|
||||
return f"ha-thread-{pan_id:04x}"
|
||||
|
||||
|
||||
def generate_random_pan_id() -> int:
|
||||
"""Generate a random PAN ID."""
|
||||
# PAN ID is 2 bytes, 0xffff is reserved for broadcast
|
||||
return random.randint(0, 0xFFFE)
|
||||
|
||||
|
||||
def _handle_otbr_error(
|
||||
func: Callable[Concatenate[OTBRData, _P], Coroutine[Any, Any, _R]],
|
||||
) -> Callable[Concatenate[OTBRData, _P], Coroutine[Any, Any, _R]]:
|
||||
|
|
|
@ -16,7 +16,13 @@ from homeassistant.core import HomeAssistant, callback
|
|||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from .const import DEFAULT_CHANNEL, DOMAIN
|
||||
from .util import OTBRData, get_allowed_channel, update_issues
|
||||
from .util import (
|
||||
OTBRData,
|
||||
compose_default_network_name,
|
||||
generate_random_pan_id,
|
||||
get_allowed_channel,
|
||||
update_issues,
|
||||
)
|
||||
|
||||
|
||||
@callback
|
||||
|
@ -99,10 +105,13 @@ async def websocket_create_network(
|
|||
connection.send_error(msg["id"], "factory_reset_failed", str(exc))
|
||||
return
|
||||
|
||||
pan_id = generate_random_pan_id()
|
||||
try:
|
||||
await data.create_active_dataset(
|
||||
python_otbr_api.ActiveDataSet(
|
||||
channel=channel, network_name="home-assistant"
|
||||
channel=channel,
|
||||
network_name=compose_default_network_name(pan_id),
|
||||
pan_id=pan_id,
|
||||
)
|
||||
)
|
||||
except HomeAssistantError as exc:
|
||||
|
|
|
@ -121,9 +121,11 @@ async def test_user_flow_router_not_setup(
|
|||
# Check we create a dataset and enable the router
|
||||
assert aioclient_mock.mock_calls[-2][0] == "PUT"
|
||||
assert aioclient_mock.mock_calls[-2][1].path == "/node/dataset/active"
|
||||
pan_id = aioclient_mock.mock_calls[-2][2]["PanId"]
|
||||
assert aioclient_mock.mock_calls[-2][2] == {
|
||||
"Channel": 15,
|
||||
"NetworkName": "home-assistant",
|
||||
"NetworkName": f"ha-thread-{pan_id:04x}",
|
||||
"PanId": pan_id,
|
||||
}
|
||||
|
||||
assert aioclient_mock.mock_calls[-1][0] == "PUT"
|
||||
|
@ -425,9 +427,11 @@ async def test_hassio_discovery_flow_router_not_setup(
|
|||
# Check we create a dataset and enable the router
|
||||
assert aioclient_mock.mock_calls[-2][0] == "PUT"
|
||||
assert aioclient_mock.mock_calls[-2][1].path == "/node/dataset/active"
|
||||
pan_id = aioclient_mock.mock_calls[-2][2]["PanId"]
|
||||
assert aioclient_mock.mock_calls[-2][2] == {
|
||||
"Channel": 15,
|
||||
"NetworkName": "home-assistant",
|
||||
"NetworkName": f"ha-thread-{pan_id:04x}",
|
||||
"PanId": pan_id,
|
||||
}
|
||||
|
||||
assert aioclient_mock.mock_calls[-1][0] == "PUT"
|
||||
|
@ -532,9 +536,11 @@ async def test_hassio_discovery_flow_router_not_setup_has_preferred_2(
|
|||
# Check we create a dataset and enable the router
|
||||
assert aioclient_mock.mock_calls[-2][0] == "PUT"
|
||||
assert aioclient_mock.mock_calls[-2][1].path == "/node/dataset/active"
|
||||
pan_id = aioclient_mock.mock_calls[-2][2]["PanId"]
|
||||
assert aioclient_mock.mock_calls[-2][2] == {
|
||||
"Channel": 15,
|
||||
"NetworkName": "home-assistant",
|
||||
"NetworkName": f"ha-thread-{pan_id:04x}",
|
||||
"PanId": pan_id,
|
||||
}
|
||||
|
||||
assert aioclient_mock.mock_calls[-1][0] == "PUT"
|
||||
|
|
|
@ -105,7 +105,10 @@ async def test_create_network(
|
|||
"python_otbr_api.OTBR.get_active_dataset_tlvs", return_value=DATASET_CH16
|
||||
) as get_active_dataset_tlvs_mock, patch(
|
||||
"homeassistant.components.thread.dataset_store.DatasetStore.async_add"
|
||||
) as mock_add:
|
||||
) as mock_add, patch(
|
||||
"homeassistant.components.otbr.util.random.randint",
|
||||
return_value=0x1234,
|
||||
):
|
||||
await websocket_client.send_json_auto_id({"type": "otbr/create_network"})
|
||||
|
||||
msg = await websocket_client.receive_json()
|
||||
|
@ -113,7 +116,9 @@ async def test_create_network(
|
|||
assert msg["result"] is None
|
||||
|
||||
create_dataset_mock.assert_called_once_with(
|
||||
python_otbr_api.models.ActiveDataSet(channel=15, network_name="home-assistant")
|
||||
python_otbr_api.models.ActiveDataSet(
|
||||
channel=15, network_name="ha-thread-1234", pan_id=0x1234
|
||||
)
|
||||
)
|
||||
factory_reset_mock.assert_called_once_with()
|
||||
assert len(set_enabled_mock.mock_calls) == 2
|
||||
|
|
Loading…
Add table
Reference in a new issue