Skip to content

Commit 6d4c14b

Browse files
committed
Add Z-Stack 3.0.1 support to tools.nvram_read
1 parent 0e3bbb8 commit 6d4c14b

File tree

2 files changed

+68
-23
lines changed

2 files changed

+68
-23
lines changed

tests/test_tools_nvram.py

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -134,36 +134,45 @@ def close(self):
134134
return znp_server
135135

136136

137-
@pytest_mark_asyncio_timeout(seconds=5)
138-
async def test_nvram_read(openable_serial_znp_server, tmp_path):
139-
def osal_nv_read(req):
140-
nvid = NwkNvIds(req.Id).name
137+
def osal_nv_read(req):
138+
nvid = NwkNvIds(req.Id).name
139+
140+
if nvid not in REAL_BACKUP["nwk"]:
141+
return c.SYS.OSALNVRead.Rsp(Status=t.Status.INVALID_PARAMETER, Value=b"")
142+
143+
value = bytes.fromhex(REAL_BACKUP["nwk"][nvid])
144+
145+
return c.SYS.OSALNVRead.Rsp(Status=t.Status.SUCCESS, Value=value[req.Offset :])
146+
147+
148+
def nv_length(req):
149+
nvid = OsalExNvIds(req.ItemId).name
141150

142-
if nvid not in REAL_BACKUP["nwk"]:
143-
return c.SYS.OSALNVRead.Rsp(Status=t.Status.INVALID_PARAMETER, Value=b"")
151+
if nvid not in REAL_BACKUP["osal"]:
152+
return c.SYS.NVLength.Rsp(Length=0)
144153

145-
value = bytes.fromhex(REAL_BACKUP["nwk"][nvid])
154+
value = bytes.fromhex(REAL_BACKUP["osal"][nvid])
146155

147-
return c.SYS.OSALNVRead.Rsp(Status=t.Status.SUCCESS, Value=value[req.Offset :])
156+
return c.SYS.NVLength.Rsp(Length=len(value))
148157

149-
def nv_length(req):
150-
nvid = OsalExNvIds(req.ItemId).name
151158

152-
if nvid not in REAL_BACKUP["osal"]:
153-
return c.SYS.NVLength.Rsp(Length=0)
159+
def nv_read(req):
160+
nvid = OsalExNvIds(req.ItemId).name
161+
value = bytes.fromhex(REAL_BACKUP["osal"][nvid])
154162

155-
value = bytes.fromhex(REAL_BACKUP["osal"][nvid])
163+
return c.SYS.NVRead.Rsp(
164+
Status=t.Status.SUCCESS, Value=value[req.Offset :][: req.Length]
165+
)
156166

157-
return c.SYS.NVLength.Rsp(Length=len(value))
158167

159-
def nv_read(req):
160-
nvid = OsalExNvIds(req.ItemId).name
161-
value = bytes.fromhex(REAL_BACKUP["osal"][nvid])
168+
def not_recognized(req):
169+
return c.RPCError.CommandNotRecognized.Rsp(
170+
ErrorCode=c.rpc_error.ErrorCode.InvalidCommandId, RequestHeader=req.header
171+
)
162172

163-
return c.SYS.NVRead.Rsp(
164-
Status=t.Status.SUCCESS, Value=value[req.Offset :][: req.Length]
165-
)
166173

174+
@pytest_mark_asyncio_timeout(seconds=5)
175+
async def test_nvram_read(openable_serial_znp_server, tmp_path):
167176
openable_serial_znp_server.reply_to(
168177
request=c.SYS.OSALNVRead.Req(partial=True), responses=[osal_nv_read],
169178
)
@@ -184,6 +193,34 @@ def nv_read(req):
184193
assert json.loads(backup_file.read_text()) == REAL_BACKUP
185194

186195

196+
@pytest_mark_asyncio_timeout(seconds=5)
197+
async def test_nvram_read_old_zstack(openable_serial_znp_server, tmp_path):
198+
openable_serial_znp_server.reply_to(
199+
request=c.SYS.OSALNVRead.Req(partial=True), responses=[osal_nv_read],
200+
)
201+
202+
# SYS.NVLength doesn't exist
203+
openable_serial_znp_server.reply_to(
204+
request=c.SYS.NVLength.Req(partial=True), responses=[not_recognized],
205+
)
206+
207+
# Nor does SYS.NVRead
208+
openable_serial_znp_server.reply_to(
209+
request=c.SYS.NVRead.Req(SysId=1, SubId=0, partial=True),
210+
responses=[not_recognized],
211+
)
212+
213+
backup_file = tmp_path / "backup.json"
214+
await nvram_read([openable_serial_znp_server._port_path, "-o", str(backup_file)])
215+
216+
backup_without_osal = REAL_BACKUP.copy()
217+
backup_without_osal["osal"] = {}
218+
219+
# The backup JSON written to disk should be an exact copy of our fake NVRAM,
220+
# without the OSAL NVIDs
221+
assert json.loads(backup_file.read_text()) == backup_without_osal
222+
223+
187224
@pytest_mark_asyncio_timeout(seconds=5)
188225
async def test_nvram_write(openable_serial_znp_server, tmp_path):
189226
simulated_nvram = {"osal": {}, "nwk": {}}

zigpy_znp/tools/nvram_read.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010

1111
from zigpy_znp.api import ZNP
1212
from zigpy_znp.config import CONFIG_SCHEMA
13-
from zigpy_znp.exceptions import InvalidCommandResponse
13+
from zigpy_znp.exceptions import InvalidCommandResponse, CommandNotRecognized
1414
from zigpy_znp.types.nvids import NwkNvIds, OsalExNvIds
1515

16-
coloredlogs.install(level=logging.DEBUG - 5)
17-
logging.getLogger("zigpy_znp").setLevel(logging.DEBUG - 5)
16+
coloredlogs.install(level=logging.DEBUG)
17+
logging.getLogger("zigpy_znp").setLevel(logging.DEBUG)
1818

1919
LOGGER = logging.getLogger(__name__)
2020

@@ -39,6 +39,14 @@ async def backup(radio_path):
3939
LOGGER.warning("Read failed for %s", nwk_nvid)
4040
continue
4141

42+
try:
43+
# Old versions of Z-Stack do not have the OSAL NVIDs
44+
await znp.request(
45+
c.SYS.NVLength.Req(SysId=1, ItemId=OsalExNvIds.DEVICE_LIST, SubId=0)
46+
)
47+
except CommandNotRecognized:
48+
return data
49+
4250
for osal_nvid in OsalExNvIds:
4351
length_rsp = await znp.request(
4452
c.SYS.NVLength.Req(SysId=1, ItemId=osal_nvid, SubId=0)

0 commit comments

Comments
 (0)