Skip to content

Commit

Permalink
Implement many_to_one_rri handler. (#34)
Browse files Browse the repository at this point in the history
* Swallow exceptions for non existent handlers.
* Handler for 'many_to_one_rri' frames.
* NWK class with default hex representation.
  • Loading branch information
Adminiuga authored Mar 28, 2019
1 parent 03fe973 commit c53be77
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 7 deletions.
25 changes: 25 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,25 @@ def test_frame_received(api, monkeypatch):
my_handler.reset_mock()


def test_frame_received_no_handler(api, monkeypatch):
monkeypatch.setattr(t, 'deserialize', mock.MagicMock(
return_value=(b'deserialized data', b'')))
my_handler = mock.MagicMock()
cmd = 'no_handler'
cmd_id = 0x00
xbee_api.COMMANDS[cmd] = (cmd_id, (), None)
api._commands_by_id[cmd_id] = cmd

cmd_opts = xbee_api.COMMANDS[cmd]
cmd_id = cmd_opts[0]
payload = b'\x01\x02\x03\x04'
data = cmd_id.to_bytes(1, 'big') + payload
api.frame_received(data)
assert t.deserialize.call_count == 1
assert t.deserialize.call_args[0][0] == payload
assert my_handler.call_count == 0


def _handle_at_response(api, tsn, status, at_response=b''):
data = (tsn, 'AI'.encode('ascii'), status, at_response)
response = asyncio.Future()
Expand Down Expand Up @@ -346,3 +365,9 @@ def test_set_application(api):

def test_handle_route_record_indicator(api):
api._handle_route_record_indicator(mock.sentinel.ri)


def test_handle_many_to_one_rri(api):
ieee = t.EUI64([t.uint8_t(a) for a in range(0, 8)])
nwk = 0x1234
api._handle_many_to_one_rri([ieee, nwk, 0])
7 changes: 7 additions & 0 deletions tests/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,10 @@ class undEnum(t.uint8_t, t.UndefinedEnum):

with pytest.raises(ValueError):
undEnum(0xEE)


def test_nwk():
nwk = t.NWK(0x1234)

assert str(nwk) == '0x1234'
assert repr(nwk) == '0x1234'
22 changes: 15 additions & 7 deletions zigpy_xbee/api.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import binascii
import enum
import logging

Expand Down Expand Up @@ -32,21 +33,21 @@ class ModemStatus(t.uint8_t, t.UndefinedEnum):
'queued_at': (0x09, (t.uint8_t, t.ATCommand, t.Bytes), 0x88),
'remote_at': (0x17, (), None),
'tx': (0x10, (), None),
'tx_explicit': (0x11, (t.uint8_t, t.EUI64, t.uint16_t, t.uint8_t, t.uint8_t, t.uint16_t, t.uint16_t, t.uint8_t, t.uint8_t, t.Bytes), None),
'create_source_route': (0x21, (), None),
'tx_explicit': (0x11, (t.uint8_t, t.EUI64, t.NWK, t.uint8_t, t.uint8_t, t.uint16_t, t.uint16_t, t.uint8_t, t.uint8_t, t.Bytes), None),
'create_source_route': (0x21, (t.uint8_t, t.EUI64, t.NWK, t.uint8_t, LVList(t.NWK)), None),
'register_joining_device': (0x24, (), None),

'at_response': (0x88, (t.uint8_t, t.ATCommand, t.uint8_t, t.Bytes), None),
'modem_status': (0x8A, (ModemStatus, ), None),
'tx_status': (0x8B, (t.uint8_t, t.uint16_t, t.uint8_t, t.uint8_t, t.uint8_t), None),
'tx_status': (0x8B, (t.uint8_t, t.NWK, t.uint8_t, t.uint8_t, t.uint8_t), None),
'route_information': (0x8D, (), None),
'rx': (0x90, (), None),
'explicit_rx_indicator': (0x91, (t.EUI64, t.uint16_t, t.uint8_t, t.uint8_t, t.uint16_t, t.uint16_t, t.uint8_t, t.Bytes), None),
'explicit_rx_indicator': (0x91, (t.EUI64, t.NWK, t.uint8_t, t.uint8_t, t.uint16_t, t.uint16_t, t.uint8_t, t.Bytes), None),
'rx_io_data_long_addr': (0x92, (), None),
'remote_at_response': (0x97, (), None),
'extended_status': (0x98, (), None),
'route_record_indicator': (0xA1, (t.EUI64, t.uint16_t, t.uint8_t, LVList(t.uint16_t)), None),
'many_to_one_rri': (0xA3, (), None),
'route_record_indicator': (0xA1, (t.EUI64, t.NWK, t.uint8_t, LVList(t.NWK)), None),
'many_to_one_rri': (0xA3, (t.EUI64, t.NWK, t.uint8_t), None),
'node_id_indicator': (0x95, (), None),

}
Expand Down Expand Up @@ -261,7 +262,11 @@ def frame_received(self, data):
command = self._commands_by_id[data[0]]
LOGGER.debug("Frame received: %s", command)
data, rest = t.deserialize(data[1:], COMMANDS[command][1])
getattr(self, '_handle_%s' % (command, ))(data)
try:
getattr(self, '_handle_%s' % (command, ))(data)
except AttributeError:
LOGGER.error("No '%s' handler. Data: %s", command,
binascii.hexlify(data))

def _handle_at_response(self, data):
fut, = self._awaiting.pop(data[0])
Expand All @@ -283,6 +288,9 @@ def _handle_at_response(self, data):
response, remains = response_type.deserialize(data[3])
fut.set_result(response)

def _handle_many_to_one_rri(self, data):
LOGGER.debug("_handle_many_to_one_rri: %s", data)

def _handle_modem_status(self, data):
LOGGER.debug("Handle modem status frame: %s", data)
status = data[0]
Expand Down
8 changes: 8 additions & 0 deletions zigpy_xbee/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,11 @@ def __call__(cls, value=None, *args, **kwargs):

class UndefinedEnum(enum.Enum, metaclass=UndefinedEnumMeta):
pass


class NWK(uint16_t):
def __repr__(self):
return '0x{:04x}'.format(self)

def __str__(self):
return '0x{:04x}'.format(self)

0 comments on commit c53be77

Please sign in to comment.