def test_unresponsiveness(self): core_communicator = CoreCommunicator(controller_serial=Mock()) core_communicator.do_command = Mock() slave_communicator = SlaveCommunicator( master_communicator=core_communicator, verbose=True) slave_communicator._transparent_mode = True address = '000.000.000.000' command_spec = SlaveCommandSpec( instruction=Instruction(instruction='AB'), request_fields=[ByteField('foo')], response_fields=[ByteField('bar')]) with self.assertRaises(CommunicationTimedOutException): core_communicator.do_command.side_effect = lambda command, fields, timeout=None: time.sleep( 2) slave_communicator.do_command(address, command_spec, {'foo': 0}, timeout=1) # No slave response with self.assertRaises(CommunicationTimedOutException): core_communicator.do_command.side_effect = CommunicationTimedOutException( 'Master unresponsive') slave_communicator.do_command(address, command_spec, {'foo': 0}, timeout=1)
def test_transparent_mode(self): received_commands = [] def do_command(command, fields, timeout=None): received_commands.append(fields) return {'mode': fields['mode']} core_communicator = CoreCommunicator(controller_serial=Mock()) core_communicator.do_command = do_command slave_communicator = SlaveCommunicator(master_communicator=core_communicator, verbose=True) address = '000.000.000.000' command_spec = SlaveCommandSpec(instruction=Instruction(instruction='AB'), request_fields=[ByteField('foo')], response_fields=[ByteField('bar')]) with self.assertRaises(RuntimeError): # Transparent mode inactive slave_communicator.do_command(address, command_spec, {'foo': 0}, timeout=None) self.assertFalse(slave_communicator._transparent_mode) with slave_communicator: # SlaveCommunicator as ContextManager activates transparent mode self.assertEqual(1, len(received_commands)) self.assertEqual({'mode': CoreAPI.SlaveBusMode.TRANSPARENT}, received_commands[0]) self.assertTrue(slave_communicator._transparent_mode) self.assertEqual(2, len(received_commands)) self.assertEqual({'mode': CoreAPI.SlaveBusMode.LIVE}, received_commands[1]) self.assertFalse(slave_communicator._transparent_mode)
def write_firmware_block(): # type: () -> SlaveCommandSpec """ Writes a single 64-byte firmware block to a given address """ return SlaveCommandSpec(instruction=Instruction(instruction='FD'), request_fields=[ WordField('address'), ByteArrayField('payload', length=64) ], response_fields=[ByteField('return_code')])
def get_firmware_version(): # type: () -> SlaveCommandSpec """ Gets a slave firmware version """ return SlaveCommandSpec(instruction=Instruction(instruction='FV', padding=9), response_fields=[ ByteField('return_code'), ByteField('hardware_version'), VersionField('version'), ByteField('status') ])
def test_rxtx(self): received_commands = [] def do_command(command, fields, timeout=None): received_commands.append(fields) core_communicator = CoreCommunicator(controller_serial=Mock()) core_communicator.do_command = do_command slave_communicator = SlaveCommunicator(master_communicator=core_communicator, verbose=True) slave_communicator._transparent_mode = True address = '000.000.000.000' command_spec = SlaveCommandSpec(instruction=Instruction(instruction='AB'), request_fields=[ByteField('foo')], response_fields=[ByteField('bar')]) slave_communicator.do_command(address, command_spec, {'foo': 0}, timeout=None) self.assertEqual(1, len(received_commands)) self.assertTrue('payload' in received_commands[0]) payload = received_commands[0]['payload'] self.assertEqual(SlaveCommunicatorTest._build_request_message(b'\x00\x00\x00\x00AB\x00'), payload) consumer = slave_communicator._consumers[0] response_payload = SlaveCommunicatorTest._build_response_message(b'\x00\x00\x00\x00AC\x04') slave_communicator._process_transport_message({'payload': bytearray(b'FOO') + response_payload[:5]}) slave_communicator._process_transport_message({'payload': response_payload[5:]}) slave_communicator._process_transport_message({'payload': SlaveCommunicatorTest._build_response_message(b'\x00\x00\x00\x01AB\x03')}) slave_communicator._process_transport_message({'payload': SlaveCommunicatorTest._build_response_message(b'\x00\x00\x00\x00AB\x02', bad_crc=True)}) with self.assertRaises(CommunicationTimedOutException): self.assertEqual({'bar': 1}, consumer.get(1)) # Invalid CRC slave_communicator.do_command(address, command_spec, {'foo': 0}, timeout=None) consumer = slave_communicator._consumers[0] slave_communicator._process_transport_message({'payload': SlaveCommunicatorTest._build_response_message(b'\x00\x00\x00\x00AB\x01')}) self.assertEqual({'bar': 1}, consumer.get(1)) command_spec = SlaveCommandSpec(instruction=Instruction(instruction='AB'), request_fields=[ByteField('foo')]) slave_communicator.do_command(address, command_spec, {'foo': 0}, timeout=None) consumer = slave_communicator._consumers[0] with self.assertRaises(CommunicationTimedOutException): consumer.get(0)
def _build_response_message(payload, bad_crc=False): if bad_crc: crc = bytearray(b'\x00\x00') else: crc = SlaveCommandSpec.calculate_crc(bytearray(payload)) return bytearray(b'RC' + payload + b'C' + crc + b'\r\n')
def _build_request_message(payload): crc = SlaveCommandSpec.calculate_crc(bytearray(payload)) return bytearray(b'ST' + payload + b'C' + crc + b'\r\n\r\n')
def set_firmware_crc(): # type: () -> SlaveCommandSpec """ Sets the CRC of the loaded firmware """ return SlaveCommandSpec( instruction=Instruction(instruction='FC', padding=5), request_fields=[ByteArrayField('crc', length=4)], response_fields=[ByteField('return_code')])
def set_firmware_version(): # type: () -> SlaveCommandSpec """ Sets the version of the firmware version to flash """ return SlaveCommandSpec(instruction=Instruction(instruction='FN', padding=6), request_fields=[VersionField('version')], response_fields=[ByteField('return_code')])
def goto_application(): # type: () -> SlaveCommandSpec """ Instructs a slave to go to application """ return SlaveCommandSpec(instruction=Instruction(instruction='FG', padding=9), response_fields=[ByteField('return_code')])
def goto_bootloader(): # type: () -> SlaveCommandSpec """ Instructs a slave to go to bootloader """ return SlaveCommandSpec(instruction=Instruction(instruction='FR', padding=8), request_fields=[ByteField('timeout')], response_fields=[ByteField('return_code')])
def integrity_check(): # type: () -> SlaveCommandSpec """ Runs an integrity check for the firmware """ return SlaveCommandSpec(instruction=Instruction(instruction='FE', padding=9), response_fields=[ByteField('return_code')])