Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion bellows/multicast.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ async def unsubscribe(self, group_id) -> t.sl_Status:
try:
entry, idx = self._multicast[group_id]
except KeyError:
LOGGER.error(
LOGGER.debug(
"Couldn't find MulticastTableEntry for %s multicast_id", group_id
)
return t.sl_Status.INVALID_INDEX
Expand Down
14 changes: 14 additions & 0 deletions bellows/zigbee/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,20 @@ async def permit_with_link_key(

return await super().permit(time_s)

async def _subscribe_to_multicast_group(self, group_id: t.Group) -> None:
"""Ask the coordinator firmware to subscribe to a group, if needed."""
if self._multicast is None:
return None

await self._multicast.subscribe(group_id)

async def _unsubscribe_from_multicast_group(self, group_id: t.Group) -> None:
"""Ask the coordinator firmware to unsubscribe from a group, if needed."""
if self._multicast is None:
return None

await self._multicast.unsubscribe(group_id)

def _handle_id_conflict(self, nwk: t.EmberNodeId) -> None:
LOGGER.warning("NWK conflict is reported for 0x%04x", nwk)
self.state.counters[COUNTERS_CTRL][COUNTER_NWK_CONFLICTS].increment()
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dependencies = [
"click",
"click-log>=0.2.1",
"voluptuous",
"zigpy>=0.87.0",
"zigpy>=2.1.0",
]

[tool.setuptools.packages.find]
Expand Down
40 changes: 40 additions & 0 deletions tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
GetRouteTableEntryRsp,
GetTxPowerInfoRsp,
)
from bellows.multicast import Multicast
import bellows.types
import bellows.types as t
import bellows.types.struct
Expand Down Expand Up @@ -2683,3 +2684,42 @@ async def test_set_tx_power(app: ControllerApplication) -> None:
assert result == 12.0
assert app._ezsp.setRadioPower.mock_calls == [call(power=12)]
assert mock_update.mock_calls == [call(app._ezsp, tx_power=12)]


async def test_multicast_group_subscription(app: ControllerApplication) -> None:
"""Test multicast group subscription APIs when there are no XNCP extensions."""
app._ezsp._xncp_features = FirmwareFeatures.NONE
Comment thread
puddly marked this conversation as resolved.

app._multicast = Multicast(app._ezsp)
await app._multicast._initialize()

# Subscribe to a group
await app.subscribe_to_multicast_group(0x1234)
assert app._ezsp._protocol.setMulticastTableEntry.mock_calls == [
call(
0,
t.EmberMulticastTableEntry(multicastId=0x1234, endpoint=1, networkIndex=0),
)
]

app._ezsp._protocol.setMulticastTableEntry.reset_mock()

# Unsubscribe from a group
await app.unsubscribe_from_multicast_group(0x1234)
assert app._ezsp._protocol.setMulticastTableEntry.mock_calls == [
call(
0,
t.EmberMulticastTableEntry(multicastId=0x1234, endpoint=0, networkIndex=0),
)
]


async def test_multicast_group_subscription_xncp(app: ControllerApplication) -> None:
"""Test multicast group subscription APIs when XNCP extensions are available."""
app._ezsp._xncp_features |= FirmwareFeatures.MEMBER_OF_ALL_GROUPS
Comment thread
puddly marked this conversation as resolved.

# Subscribe to a group (no-op)
await app.subscribe_to_multicast_group(0x1234)

# Unsubscribe from a group (no-op)
await app.unsubscribe_from_multicast_group(0x1234)
Comment thread
puddly marked this conversation as resolved.
Loading