zigpy-zboss 2.0.0__tar.gz → 2.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {zigpy_zboss-2.0.0/zigpy_zboss.egg-info → zigpy_zboss-2.0.2}/PKG-INFO +1 -1
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/__init__.py +1 -1
- zigpy_zboss-2.0.2/zigpy_zboss/tools/get_nwk_keys.py +87 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/zigbee/application.py +35 -34
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2/zigpy_zboss.egg-info}/PKG-INFO +1 -1
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss.egg-info/SOURCES.txt +1 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/COPYING +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/LICENSE +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/README.md +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/pyproject.toml +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/setup.cfg +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/setup.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/tests/test_commands.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/tests/test_config.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/tests/test_frame.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/tests/test_nvids.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/tests/test_types_basic.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/tests/test_types_cstruct.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/tests/test_types_named.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/tests/test_uart.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/tests/test_utils.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/api.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/checksum.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/commands/__init__.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/commands/af.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/commands/aps.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/commands/ncp_config.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/commands/nwk_mgmt.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/commands/security.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/commands/zdo.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/config.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/debug.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/exceptions.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/frames.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/logger.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/nvram.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/tools/__init__.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/tools/config.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/tools/factory_reset_ncp.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/tools/get_ncp_version.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/tools/log2pcap.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/types/__init__.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/types/basic.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/types/commands.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/types/cstruct.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/types/named.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/types/nvids.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/types/structs.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/uart.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/utils.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/zigbee/__init__.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss/zigbee/device.py +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss.egg-info/dependency_links.txt +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss.egg-info/requires.txt +0 -0
- {zigpy_zboss-2.0.0 → zigpy_zboss-2.0.2}/zigpy_zboss.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Probe the NCP's network keys.
|
|
2
|
+
|
|
3
|
+
Reads the active network key(s) from the live stack via GetNwkKeys and, for
|
|
4
|
+
contrast, attempts to read the ZB_NVRAM_COMMON_DATA dataset directly. Use this
|
|
5
|
+
to confirm GetNwkKeys returns a usable key on your hardware - the COMMON_DATA
|
|
6
|
+
NVRAM read is the one that intermittently fails with GENERIC/ERROR and leaves
|
|
7
|
+
zigpy with a blank network key.
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
python -m zigpy_zboss.tools.get_nwk_keys [/dev/ttyACM0]
|
|
11
|
+
"""
|
|
12
|
+
import asyncio
|
|
13
|
+
import sys
|
|
14
|
+
|
|
15
|
+
import serialx
|
|
16
|
+
|
|
17
|
+
from zigpy_zboss import commands as c
|
|
18
|
+
from zigpy_zboss import types as t
|
|
19
|
+
from zigpy_zboss.api import ZBOSS
|
|
20
|
+
from zigpy_zboss.tools.config import get_config
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _is_blank(key) -> bool:
|
|
24
|
+
"""Return True if the key is unset (all 0x00 or all 0xFF) or missing."""
|
|
25
|
+
return key is None or key.serialize() in (b"\xff" * 16, b"\x00" * 16)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
async def get_nwk_keys(config):
|
|
29
|
+
"""Print the NCP network keys and contrast with the NVRAM read."""
|
|
30
|
+
zboss = ZBOSS(config)
|
|
31
|
+
await zboss.connect()
|
|
32
|
+
try:
|
|
33
|
+
rsp = await zboss.request(c.NcpConfig.GetNwkKeys.Req(TSN=1))
|
|
34
|
+
print(f"GetNwkKeys status: {rsp.StatusCat} {rsp.StatusCode}")
|
|
35
|
+
for idx, (key, num) in enumerate(
|
|
36
|
+
(
|
|
37
|
+
(rsp.NwkKey1, rsp.KeyNumber1),
|
|
38
|
+
(rsp.NwkKey2, rsp.KeyNumber2),
|
|
39
|
+
(rsp.NwkKey3, rsp.KeyNumber3),
|
|
40
|
+
),
|
|
41
|
+
start=1,
|
|
42
|
+
):
|
|
43
|
+
tag = "blank" if _is_blank(key) else "REAL"
|
|
44
|
+
print(f" NwkKey{idx} (seq {num}): {key} [{tag}]")
|
|
45
|
+
|
|
46
|
+
usable = not _is_blank(rsp.NwkKey1)
|
|
47
|
+
print(
|
|
48
|
+
"\nVerdict: GetNwkKeys "
|
|
49
|
+
+ (
|
|
50
|
+
"returns a usable network key - the fix will work."
|
|
51
|
+
if usable
|
|
52
|
+
else "did NOT return a usable key on this firmware."
|
|
53
|
+
)
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Contrast: the COMMON_DATA NVRAM read that intermittently fails.
|
|
57
|
+
nv = await zboss.request(
|
|
58
|
+
c.NcpConfig.ReadNVRAM.Req(
|
|
59
|
+
TSN=2, DatasetId=t.DatasetId.ZB_NVRAM_COMMON_DATA
|
|
60
|
+
)
|
|
61
|
+
)
|
|
62
|
+
print(
|
|
63
|
+
f"\nZB_NVRAM_COMMON_DATA read status: {nv.StatusCat} "
|
|
64
|
+
f"{nv.StatusCode}"
|
|
65
|
+
+ (" (OK)" if nv.StatusCode == 0 else " (this is the failure)")
|
|
66
|
+
)
|
|
67
|
+
finally:
|
|
68
|
+
zboss.close()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
async def main(argv):
|
|
72
|
+
"""Get config and print the NCP network keys."""
|
|
73
|
+
config = get_config(argv)
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
await get_nwk_keys(config)
|
|
77
|
+
except serialx.SerialException as exc:
|
|
78
|
+
print(f"Failed to read NCP network keys! {exc}")
|
|
79
|
+
except RuntimeError as exc2:
|
|
80
|
+
print(
|
|
81
|
+
f"Failed to read NCP network keys! {exc2}\n"
|
|
82
|
+
"Power cycle the module and try again."
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
if __name__ == "__main__":
|
|
87
|
+
asyncio.run(main(sys.argv[1:]))
|
|
@@ -87,7 +87,10 @@ class ControllerApplication(zigpy.application.ControllerApplication):
|
|
|
87
87
|
|
|
88
88
|
async def start_network(self):
|
|
89
89
|
"""Start the network."""
|
|
90
|
-
if
|
|
90
|
+
if (
|
|
91
|
+
self.state.node_info.nwk in (None, t.NWK(0xFFFE))
|
|
92
|
+
or self.state.node_info.ieee in (None, t.EUI64.UNKNOWN)
|
|
93
|
+
):
|
|
91
94
|
await self.load_network_info()
|
|
92
95
|
|
|
93
96
|
await self.start_without_formation()
|
|
@@ -447,10 +450,6 @@ class ControllerApplication(zigpy.application.ControllerApplication):
|
|
|
447
450
|
|
|
448
451
|
self.state.network_info.security_level = 0x05
|
|
449
452
|
|
|
450
|
-
common = await self._api.nvram.read(
|
|
451
|
-
t_zboss.DatasetId.ZB_NVRAM_COMMON_DATA,
|
|
452
|
-
t_zboss.DSCommonData
|
|
453
|
-
)
|
|
454
453
|
counters = await self._api.nvram.read(
|
|
455
454
|
t_zboss.DatasetId.ZB_IB_COUNTERS,
|
|
456
455
|
t_zboss.DSIbCounters
|
|
@@ -461,37 +460,39 @@ class ControllerApplication(zigpy.application.ControllerApplication):
|
|
|
461
460
|
if counters is not None:
|
|
462
461
|
tx_counter = counters.nib_counter
|
|
463
462
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
463
|
+
nwk_keys = await self._api.request(
|
|
464
|
+
c.NcpConfig.GetNwkKeys.Req(TSN=self.get_sequence()))
|
|
465
|
+
nwk_key = nwk_keys.NwkKey1
|
|
466
|
+
if (
|
|
467
|
+
nwk_keys.StatusCode != 0
|
|
468
|
+
or nwk_key is None
|
|
469
|
+
or nwk_key.serialize() in (b"\xff" * 16, b"\x00" * 16)
|
|
470
|
+
):
|
|
471
|
+
raise zigpy.exceptions.ControllerException(
|
|
472
|
+
"NCP reports joined but GetNwkKeys returned no usable network "
|
|
473
|
+
f"key (status={nwk_keys.StatusCode}, NwkKey1={nwk_key}); "
|
|
474
|
+
"refusing to load a blank key."
|
|
471
475
|
)
|
|
476
|
+
self.state.network_info.network_key = zigpy.state.Key(
|
|
477
|
+
key=nwk_key,
|
|
478
|
+
tx_counter=tx_counter,
|
|
479
|
+
rx_counter=0,
|
|
480
|
+
seq=nwk_keys.KeyNumber1,
|
|
481
|
+
partner_ieee=self.state.node_info.ieee,
|
|
482
|
+
)
|
|
472
483
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
TSN=self.get_sequence()))
|
|
486
|
-
self.state.network_info.tc_link_key = (
|
|
487
|
-
zigpy.state.Key(
|
|
488
|
-
key=None,
|
|
489
|
-
tx_counter=0,
|
|
490
|
-
rx_counter=0,
|
|
491
|
-
seq=0,
|
|
492
|
-
partner_ieee=res.TCIEEE,
|
|
493
|
-
),
|
|
494
|
-
)
|
|
484
|
+
# The coordinator is the trust centre, and ZBOSS always uses the
|
|
485
|
+
# standard global TC link key (ZigBeeAlliance09) - we never push a
|
|
486
|
+
# custom one. Set it explicitly rather than reading the flaky
|
|
487
|
+
# ZB_NVRAM_COMMON_DATA dataset (its only extra contribution was
|
|
488
|
+
# partner_ieee, which nothing compares against).
|
|
489
|
+
self.state.network_info.tc_link_key = zigpy.state.Key(
|
|
490
|
+
key=t.KeyData(zigpy.config.CONF_NWK_TC_LINK_KEY_DEFAULT),
|
|
491
|
+
tx_counter=0,
|
|
492
|
+
rx_counter=0,
|
|
493
|
+
seq=0,
|
|
494
|
+
partner_ieee=self.state.node_info.ieee,
|
|
495
|
+
)
|
|
495
496
|
|
|
496
497
|
res = await self._api.request(
|
|
497
498
|
c.NcpConfig.GetRxOnWhenIdle.Req(TSN=self.get_sequence()))
|
|
@@ -39,6 +39,7 @@ zigpy_zboss/tools/__init__.py
|
|
|
39
39
|
zigpy_zboss/tools/config.py
|
|
40
40
|
zigpy_zboss/tools/factory_reset_ncp.py
|
|
41
41
|
zigpy_zboss/tools/get_ncp_version.py
|
|
42
|
+
zigpy_zboss/tools/get_nwk_keys.py
|
|
42
43
|
zigpy_zboss/tools/log2pcap.py
|
|
43
44
|
zigpy_zboss/types/__init__.py
|
|
44
45
|
zigpy_zboss/types/basic.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|