Skip to content

Commit

Permalink
Support both tuples and dicts, for testing
Browse files Browse the repository at this point in the history
  • Loading branch information
puddly committed Jul 22, 2024
1 parent 8a2fa21 commit f2c9fbd
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 13 deletions.
31 changes: 23 additions & 8 deletions bellows/ezsp/protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,19 @@ def __init__(self, cb_handler: Callable, gateway: Gateway) -> None:
}
self.tc_policy = 0

def _ezsp_frame(self, name: str, *args: tuple[Any, ...]) -> bytes:
def _ezsp_frame(self, name: str, *args: Any, **kwargs: Any) -> bytes:
"""Serialize the named frame and data."""
c = self.COMMANDS[name]
c, tx_schema, rx_schema = self.COMMANDS[name]
frame = self._ezsp_frame_tx(name)
data = t.serialize(args, c[1])

if isinstance(tx_schema, dict):
assert not kwargs
data = t.serialize_dict(args, tx_schema)
elif isinstance(tx_schema, tuple):
assert not kwargs
data = t.serialize(args, tx_schema)
else:
data = tx_schema(*args, **kwargs).serialize()
return frame + data

@abc.abstractmethod
Expand All @@ -58,10 +66,10 @@ def _ezsp_frame_rx(self, data: bytes) -> tuple[int, int, bytes]:
def _ezsp_frame_tx(self, name: str) -> bytes:
"""Serialize the named frame."""

async def command(self, name, *args) -> Any:
async def command(self, name, *args, **kwargs) -> Any:
"""Serialize command and send it."""
LOGGER.debug("Sending command %s: %s", name, args)
data = self._ezsp_frame(name, *args)
data = self._ezsp_frame(name, *args, **kwargs)
cmd_id, _, rx_schema = self.COMMANDS[name]
future = asyncio.get_running_loop().create_future()
self._awaiting[self._seq] = (cmd_id, rx_schema, future)
Expand Down Expand Up @@ -102,16 +110,23 @@ def __call__(self, data: bytes) -> None:
try:
if isinstance(rx_schema, tuple):
result, data = t.deserialize(data, rx_schema)
LOGGER.debug("Received command %s: %s", frame_name, result)
elif isinstance(rx_schema, dict):
result, data = t.deserialize_dict(data, rx_schema)
LOGGER.debug("Received command %s: %s", frame_name, result)
result = tuple(result.values())
else:
result, data = rx_schema.deserialize(data)
LOGGER.debug("Received command %s: %s", frame_name, result)
except Exception:
LOGGER.warning(
"Failed to parse frame %s: %s", frame_name, binascii.hexlify(data)
"Failed to parse frame %s: %s",
frame_name,
binascii.hexlify(data),
exc_info=True,
)
raise

LOGGER.debug("Received command %s: %s", frame_name, result)

if data:
LOGGER.debug("Frame contains trailing data: %s", data)

Expand Down
4 changes: 2 additions & 2 deletions bellows/ezsp/v14/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ class GetTokenDataRsp(Struct):
else:
tx_schema = [_REPLACEMENTS.get(v, v) for v in tx_schema]

if not isinstance(tx_schema, Struct):
if isinstance(tx_schema, dict):
if not isinstance(rx_schema, Struct):
if isinstance(rx_schema, dict):
rx_schema = {k: _REPLACEMENTS.get(v, v) for k, v in rx_schema.items()}
else:
rx_schema = [_REPLACEMENTS.get(v, v) for v in rx_schema]
Expand Down
12 changes: 12 additions & 0 deletions bellows/types/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,15 @@ def deserialize(data, schema):

def serialize(data, schema):
return b"".join(t(v).serialize() for t, v in zip(schema, data))


def deserialize_dict(data, schema):
result = {}
for key, type_ in schema.items():
value, data = type_.deserialize(data)
result[key] = value
return result, data


def serialize_dict(data, schema):
return b"".join(t(v).serialize() for v, (n, t) in zip(data, schema.items()))
6 changes: 3 additions & 3 deletions bellows/types/struct.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,6 @@ class SecurityManagerNetworkKeyInfo(EzspStruct):
class EmberMultiPhyRadioParameters(EzspStruct):
"""Holds radio parameters."""

radioTxPower: named.int8s
radioPage: named.uint8_t
radioChannel: named.uint8_t
radioTxPower: basic.int8s
radioPage: basic.uint8_t
radioChannel: basic.uint8_t

0 comments on commit f2c9fbd

Please sign in to comment.