Skip to content
Merged
Changes from all 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
25 changes: 25 additions & 0 deletions bellows/cli/dump.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import logging
import time

import click
Expand All @@ -7,6 +8,8 @@
from . import util
from .main import main

LOGGER = logging.getLogger(__name__)


@main.command()
@click.option(
Expand Down Expand Up @@ -39,6 +42,20 @@ def dump(ctx, channel, outfile):
ctx.obj["ezsp"].close()


def ieee_15_4_fcs(data: bytes) -> bytes:
# Modified from the implementation in `scapy.layers.dot15d4:Dot15d4FCS.compute_fcs`
crc = 0x0000

for c in data:
q = (crc ^ c) & 15 # Do low-order 4 bits
crc = (crc // 16) ^ (q * 0x1081)

q = (crc ^ (c // 16)) & 15 # And high 4 bits
crc = (crc // 16) ^ (q * 0x1081)

return crc.to_bytes(2, "little")


async def _dump(ctx, channel, outfile):
s = await util.setup(ctx.obj["device"], ctx.obj["baudrate"])
ctx.obj["ezsp"] = s
Expand All @@ -60,6 +77,14 @@ async def _dump(ctx, channel, outfile):
def cb(frame_name, response):
if frame_name == "mfglibRxHandler":
data = response[2]

# Later releases of EmberZNet incorrectly use a static FCS
fcs = data[-2:]
if s.ezsp_version == 8 and fcs == b"\x0F\x00":
computed_fcs = ieee_15_4_fcs(data[0:-2])
LOGGER.debug("Fixing FCS (expected %s, got %s)", computed_fcs, fcs)
data = data[0:-2] + computed_fcs

ts = time.time()
ts_sec = int(ts)
ts_usec = int((ts - ts_sec) * 1000000)
Expand Down