Skip to content

Commit 766a6d6

Browse files
puddlyagners
andauthored
Implement new zigpy network state (#445)
* [WIP] Implement new zigpy network state * [WIP] Implement writing network settings * Set NWK and APS frame counters * Change key table size only if the new keys don't fit * Style cleanup * Directly create `EZSPCoordinator` instead of using a quirk * Use zigpy types when creating network state objects * Allow `load_network_info` to be called before/after `start_network` * Allow `node_info.ieee` to be `None` * Use `t.EUI64.UNKNOWN` instead of `None` to represent an unset IEEE addr * Do not leak EZSP types into zigpy * Fix network formation when a hashed TCLK is generated * Joins were not being properly permitting after fcf0b49 * Use the new zigpy `add_endpoint` method * Call `register_endpoints` when connecting * Always leave the current network during formation * Get some unit tests passing * Add unit tests for `bellows.zigbee.util` * Increase `bellows.uart` test coverage to 100% * Ignore `.DS_Store` files * Use new `pytest-asyncio` behavior * Newer versions of EmberZNet use a different response for `getChildData` * Use zigpy data types when populating `state` * Correct the TCLK's `partner_ieee` to use the node's IEEE address * Unit test `load_network_info` Foo * Assume the TCLK is always the well-known key * Add a few more unknown bitfields * Refactor code dealing with keys and add some comments * Write initial unit tests for `write_network_info` * Remove ignored flake8 errors from unit tests * Only use one pair of `network_info` and `node_info` fixtures * Test new code in `bellows.zigbee.util` * Add unit test for when `getMfgToken` is missing * Unit test `_ensure_network_running` * Fix startup delay caused by slow coordinator initialization * Key table size can't be adjusted * Unit test `getChildData` for EZSP v6 * Unit test `leaveNetwork` failing with `INVALID_CALL` * Add the coordinator to the zigpy device dictionary before initialization * Do not back up the address tables on EZSPv4, it is unstable * Do not set frame counters when using EZSPv4 * Fix UART port close on RSTACK message during startup When a RSTACK message is processed right after the UART has been opened, it causes EZSP.enter_failed_state() getting called at a point where the application callbacks are not registered yet. In that case the UART will get closed and it won't get opened again. Bellows is stuck with a closed transport. Avoid this issue by not closing the port in case there is no application callback registered yet. Typically, it is unlikely that a RSTACK message arrives right when the port gets opened (the race window is very narrow). However, with hardware flow control opening the port leads to RTS signal to get asserted which causes the radio to send pending messages, e.g. resets caused by EmberZNet watchdog. Note: With hardware flow control this is only the case if the tty "hupcl" option is set. The option is set by default, but cleared by tools like GNU screen. This option makes sure that the RTS signal is deasserted while the port is closed. Pyserial/bellows does not change the state of that option. * Unit test EZSP v4 changes * Fix tests * Include radio library metadata in network info * Fix unit tests broken by new `metadata` key * Do not set the `HAVE_TRUST_CENTER_EUI64` bit when forming a network * Bump minimum required zigpy version to 0.47.0 * Fix unit tests for Python 3.7 Co-authored-by: Stefan Agner <[email protected]>
1 parent f7b074e commit 766a6d6

25 files changed

+1184
-250
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,8 @@ ENV/
7070
.*.swp
7171

7272
# Visual Studio Code
73-
.vscode
73+
.vscode
74+
75+
76+
# macOS
77+
.DS_Store

bellows/ezsp/v7/commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
"getChildData": (
138138
0x4A,
139139
(t.uint8_t,),
140-
(t.EmberStatus, t.EmberNodeId, t.EmberEUI64, t.EmberNodeType),
140+
(t.EmberStatus, t.EmberChildData),
141141
),
142142
"getSourceRouteTableTotalSize": (0xC3, (), (t.uint8_t,)),
143143
"getSourceRouteTableFilledSize": (0xC2, (), (t.uint8_t,)),

bellows/ezsp/v7/types/struct.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,25 @@ class EmberPerDeviceDutyCycle(EzspStruct):
189189
nodeId: named.EmberNodeId
190190
# Amount of overall duty cycle consumed (up to suspend limit).
191191
dutyCycleConsumed: named.EmberDutyCycleHectoPct
192+
193+
194+
class EmberChildData(EzspStruct):
195+
"""A structure containing a child node's data."""
196+
197+
# The EUI64 of the child
198+
eui64: named.EmberEUI64
199+
# The node type of the child
200+
type: named.EmberNodeType
201+
# The short address of the child
202+
id: named.EmberNodeId
203+
# The phy of the child
204+
phy: basic.uint8_t
205+
# The power of the child
206+
power: basic.uint8_t
207+
# The timeout of the child
208+
timeout: basic.uint8_t
209+
210+
# The GPD's EUI64.
211+
# gpdIeeeAddress: named.EmberEUI64
212+
# The GPD's source ID.
213+
# sourceId: basic.uint32_t

bellows/ezsp/v8/commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@
134134
"getChildData": (
135135
0x004A,
136136
(t.uint8_t,),
137-
(t.EmberStatus, t.EmberNodeId, t.EmberEUI64, t.EmberNodeType),
137+
(t.EmberStatus, t.EmberChildData),
138138
),
139139
"getSourceRouteTableTotalSize": (0x00C3, (), (t.uint8_t,)),
140140
"getSourceRouteTableFilledSize": (0x00C2, (), (t.uint8_t,)),

bellows/ezsp/v8/types/struct.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,25 @@ class EmberTransientKeyData(EzspStruct):
202202
# The number of seconds remaining before the key is automatically timed out of the
203203
# transient key table.
204204
remainingTimeSeconds: basic.uint16_t
205+
206+
207+
class EmberChildData(EzspStruct):
208+
"""A structure containing a child node's data."""
209+
210+
# The EUI64 of the child
211+
eui64: named.EmberEUI64
212+
# The node type of the child
213+
type: named.EmberNodeType
214+
# The short address of the child
215+
id: named.EmberNodeId
216+
# The phy of the child
217+
phy: basic.uint8_t
218+
# The power of the child
219+
power: basic.uint8_t
220+
# The timeout of the child
221+
timeout: basic.uint8_t
222+
223+
# The GPD's EUI64.
224+
# gpdIeeeAddress: named.EmberEUI64
225+
# The GPD's source ID.
226+
# sourceId: basic.uint32_t

bellows/types/named.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,9 @@ class EmberStatus(basic.enum8):
610610
# An index was passed into the function that was larger than the valid
611611
# range.
612612
INDEX_OUT_OF_RANGE = 0xB1
613+
# The passed key data is not valid. A key of all zeros or all F's are reserved
614+
# values and cannot be used.
615+
KEY_INVALID = 0xB2
613616
# There are no empty entries left in the table.
614617
TABLE_FULL = 0xB4
615618
# The requested table entry has been erased and contains no valid data.
@@ -970,6 +973,8 @@ class EmberCurrentSecurityBitmask(basic.bitmap16):
970973
GLOBAL_LINK_KEY = 0x0004
971974
# This denotes that the node has a Trust Center Link Key.
972975
HAVE_TRUST_CENTER_LINK_KEY = 0x0010
976+
# TODO: 0x0020 is unknown
977+
# TODO: 0x0040 is unknown
973978
# This denotes that the Trust Center is using a Hashed Link Key.
974979
TRUST_CENTER_USES_HASHED_LINK_KEY = 0x0084
975980

@@ -994,6 +999,12 @@ class EmberKeyStructBitmask(basic.bitmap16):
994999
# hears a device announce from the partner indicating it is not
9951000
# an 'RX on when idle' device.
9961001
KEY_PARTNER_IS_SLEEPY = 0x0020
1002+
# This indicates that the transient key which is being added is unconfirmed. This
1003+
# bit is set when we add a transient key while the EmberTcLinkKeyRequestPolicy is
1004+
# EMBER_ALLOW_TC_LINK_KEY_REQUEST_AND_GENERATE_NEW_KEY
1005+
UNCONFIRMED_TRANSIENT_KEY = 0x0040
1006+
1007+
# TODO: 0x0080 is unknown
9971008

9981009

9991010
class EmberKeyStatus(basic.enum8):
@@ -1757,3 +1768,22 @@ class sl_Status(basic.enum32):
17571768
SL_STATUS_WIFI_RETRY_EXCEEDED = 0x0B1F
17581769
# The request failed because the MSDU life time was exceeded
17591770
SL_STATUS_WIFI_TX_LIFETIME_EXCEEDED = 0x0B20
1771+
1772+
1773+
class EmberDistinguishedNodeId(basic.enum16):
1774+
"""A distinguished network ID that will never be assigned to any node"""
1775+
1776+
# This value is used when getting the remote node ID from the address or binding
1777+
# tables. It indicates that the address or binding table entry is currently in use
1778+
# and network address discovery is underway.
1779+
DISCOVERY_ACTIVE = 0xFFFC
1780+
1781+
# This value is used when getting the remote node ID from the address or binding
1782+
# tables. It indicates that the address or binding table entry is currently in use
1783+
# but the node ID corresponding to the EUI64 in the table is currently unknown.
1784+
UNKNOWN = 0xFFFD
1785+
1786+
# This value is used when setting or getting the remote node ID in the address table
1787+
# or getting the remote node ID from the binding table. It indicates that the
1788+
# address or binding table entry is not in use.
1789+
TABLE_ENTRY_UNUSED = 0xFFFF

bellows/types/struct.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
import inspect
33
import typing
44

5-
import zigpy.state as app_state
6-
75
from . import basic, named
86

97
NoneType = type(None)
@@ -282,19 +280,6 @@ class EmberNetworkParameters(EzspStruct):
282280
# method.
283281
channels: named.Channels
284282

285-
@property
286-
def zigpy_network_information(self) -> app_state.NetworkInformation:
287-
"""Convert to NetworkInformation."""
288-
r = app_state.NetworkInformation(
289-
self.extendedPanId,
290-
app_state.t.PanId(self.panId),
291-
self.nwkUpdateId,
292-
app_state.t.NWK(self.nwkManagerId),
293-
self.radioChannel,
294-
channel_mask=self.channels,
295-
)
296-
return r
297-
298283

299284
class EmberZigbeeNetwork(EzspStruct):
300285
# The parameters of a ZigBee network.

0 commit comments

Comments
 (0)