From bffe41fbb6bc07cbf49b984b7b815eefdeaaeb44 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Wed, 28 Aug 2019 18:29:14 +1000 Subject: [PATCH] protocol: handle 0xb3 automatically 0xb3 is the generic error code (or success, where applicable). Let's handle those by default so that the rest of the messages only have to care about replies with message-specific opcodes. Signed-off-by: Peter Hutterer --- test/test_messages.py | 19 +++++++++++++++++++ tuhi/protocol.py | 23 ++++++++++++++--------- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/test/test_messages.py b/test/test_messages.py index 57ff54b..d3df561 100644 --- a/test/test_messages.py +++ b/test/test_messages.py @@ -379,6 +379,25 @@ class TestProtocolAny(unittest.TestCase): msg = p.execute(Interactions.REGISTER_PRESS_BUTTON, uuid=uuid) self.assertEqual(msg.uuid, uuid) + def test_error_invalid_state(self): + def _cb(request, requires_reply=True, userdata=None, timeout=5): + return NordicData([0xb3, 0x1, 0x1]) + + p = Protocol(self.protocol_version, callback=_cb) + + # a "random" collection of requests that we want to check for + with self.assertRaises(DeviceError) as cm: + p.execute(Interactions.CONNECT, uuid='abcdef123456') + self.assertEqual(cm.exception.errorcode, DeviceError.ErrorCode.GENERAL_ERROR) + + with self.assertRaises(DeviceError) as cm: + p.execute(Interactions.GET_STROKES) + self.assertEqual(cm.exception.errorcode, DeviceError.ErrorCode.GENERAL_ERROR) + + with self.assertRaises(DeviceError) as cm: + p.execute(Interactions.SET_MODE, Mode.PAPER) + self.assertEqual(cm.exception.errorcode, DeviceError.ErrorCode.GENERAL_ERROR) + class TestProtocolSpark(TestProtocolAny): protocol_version = ProtocolVersion.SPARK diff --git a/tuhi/protocol.py b/tuhi/protocol.py index 0485bd6..5c0d982 100644 --- a/tuhi/protocol.py +++ b/tuhi/protocol.py @@ -523,18 +523,16 @@ class Msg(object): self._args = args def _handle_reply(self, reply): - '''Override this in the subclass to handle the reply. + ''' + Override this in the subclass to handle the reply. Note that the + default 0xb3 message is handled automaticaly, this is only for + non-default replies. - This is the default reply handler that deals with the 0xb3 ACK/Error - messages and throws the respective exceptions. + No return value, just throw the appropriate exception on failure. :param reply: A :class:`NordicData` object ''' - if reply.opcode != 0xb3: - raise UnexpectedReply(self) - - if reply[0] != 0x00: - raise DeviceError(reply[0]) + raise NotImplementedError(f'{reply} needs customized handling') def execute(self): ''' @@ -554,7 +552,14 @@ class Msg(object): if self.reply is None: raise MissingReplyError(self.request) try: - self._handle_reply(self.reply) + # 0xb3 is always handled by us, anything else requires a + # custom reply handler + if self.reply.opcode == 0xb3: + if self.reply[0] != 0x00: + raise DeviceError(self.reply[0]) + else: + self._handle_reply(self.reply) + # no exception? we can assume success self.errorcode = DeviceError.ErrorCode.SUCCESS except DeviceError as e: