def test_simple_received_return_file_data_command(self): cmd = Command( generate_tag_request_action=False, actions=[ RegularAction(operation=ReturnFileData( operand=Data(data=list(bytearray("Hello world")), offset=Offset(id=0x51)))), StatusAction( status_operand_extension=StatusActionOperandExtensions. INTERFACE_STATUS, operation=InterfaceStatus(operand=InterfaceStatusOperand( interface_id=0xD7, interface_status=D7ASpStatus(channel_header=0, channel_index=16, rx_level=70, link_budget=80, target_rx_level=80, nls=False, missed=False, retry=False, unicast=False, fifo_token=200, seq_nr=0, response_to=CT(mant=20), addressee=Addressee())))) ]) expected = [ 0x62, # Interface Status action 0xD7, # D7ASP interface 0, # channel header 16, 0, # channel_id 70, # rxlevel (- dBm) 80, # link budget 80, # target rx level 0, # status 200, # fifo token 0, # seq 20, # response timeout 16, # addressee ctrl (BCAST) 0x20, # action=32/ReturnFileData 0x51, # File ID 0x00, # offset 0x0b, # length 0x48, 0x65, 0x6c, 0x6c, 0x6f, # Hello 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64 # World ] bytes = bytearray(cmd) self.assertEqual(len(bytes), len(expected)) for i in xrange(len(expected)): self.assertEqual(bytes[i], expected[i])
def test_byte_generation(self): bytes = bytearray(Offset()) self.assertEqual(len(bytes), 2) self.assertEqual(bytes[0], int('00000000', 2)) self.assertEqual(bytes[1], int('00000000', 2)) bytes = bytearray(Offset(id=0xFF)) self.assertEqual(len(bytes), 2) self.assertEqual(bytes[0], int('11111111', 2)) self.assertEqual(bytes[1], int('00000000', 2)) bytes = bytearray(Offset(size=4)) self.assertEqual(len(bytes), 5) self.assertEqual(bytes[0], int('00000000', 2)) self.assertEqual(bytes[1], int('11000000', 2)) self.assertEqual(bytes[2], int('00000000', 2)) self.assertEqual(bytes[3], int('00000000', 2)) self.assertEqual(bytes[4], int('00000000', 2))
def create_with_return_file_data_action(file_id, data, interface_type=InterfaceType.HOST, interface_configuration=None): # default to host interface, when D7ASP interface is used prepend with Forward action cmd = Command() cmd.add_forward_action(interface_type, interface_configuration) cmd.add_action( RegularAction(operation=ReturnFileData( operand=Data(data=data, offset=Offset(id=file_id))))) return cmd
def create_with_write_file_action_system_file( file, interface_type=InterfaceType.HOST, interface_configuration=None): # default to host interface, when D7ASP interface is used prepend with Forward action cmd = Command() cmd.add_forward_action(interface_type, interface_configuration) cmd.add_action( RegularAction(operation=WriteFileData(operand=Data( offset=Offset(id=file.id, offset=0), # TODO offset size data=list(file))))) return cmd
def create_with_read_file_action_system_file( file, interface_type=InterfaceType.HOST, interface_configuration=None): # default to host interface, when D7ASP interface is used prepend with Forward action cmd = Command() cmd.add_forward_action(interface_type, interface_configuration) cmd.add_action( RegularAction(operation=ReadFileData(operand=DataRequest( offset=Offset(id=file.file_id(), offset=0), # TODO offset size length=file.length())))) return cmd
def _connect_serial_modem(self): self.dev = serial.Serial( port=self.config["device"], baudrate=self.config["baudrate"], timeout=0.5, ) read_modem_info_action = Command.create_with_read_file_action_system_file( UidFile()) read_modem_info_action.add_action( RegularAction(operation=ReadFileData(operand=DataRequest( offset=Offset(id=FirmwareVersionFile().id, offset=0), # TODO offset size length=FirmwareVersionFile().length)))) self.send_command(read_modem_info_action) # read thread not yet running here, read sync start_time = datetime.now() timeout = False while not timeout: commands, info = self.read() for command in commands: for action in command.actions: if type(action) is RegularAction and type( action.operation) is ReturnFileData: if action.operand.offset.id == SystemFileIds.UID.value: self.uid = '{:x}'.format( struct.unpack(">Q", bytearray( action.operand.data))[0]) if action.operand.offset.id == SystemFileIds.FIRMWARE_VERSION.value: self.firmware_version = FirmwareVersionFile.parse( ConstBitStream(bytearray(action.operand.data))) if self.uid and self.firmware_version: return True if (datetime.now() - start_time).total_seconds() > 2: timeout = True self.log("Timed out reading node information") return False
def _connect_serial_modem(self): self.dev = serial.Serial( port=self.config["device"], baudrate=self.config["baudrate"], timeout=None, ) self.dev.flush() # ignore possible buffered data self.start_reading() read_modem_info_action = Command.create_with_read_file_action_system_file( UidFile()) read_modem_info_action.add_action( RegularAction(operation=ReadFileData(operand=DataRequest( offset=Offset(id=FirmwareVersionFile().id, offset=0), # TODO offset size length=FirmwareVersionFile().length)))) resp_cmd = self.execute_command(read_modem_info_action, timeout_seconds=60) if len(resp_cmd) == 0: self.log.warning("Timed out reading node information") return False for action in resp_cmd[0].actions: if type(action) is RegularAction and type( action.operation) is ReturnFileData: if action.operand.offset.id == SystemFileIds.UID.value: self.uid = '{:x}'.format( struct.unpack(">Q", bytearray(action.operand.data))[0]) if action.operand.offset.id == SystemFileIds.FIRMWARE_VERSION.value: self.firmware_version = FirmwareVersionFile.parse( ConstBitStream(bytearray(action.operand.data))) if self.uid and self.firmware_version: return True return False
def bad(args, kwargs): Offset(**kwargs)
def test_offset_valid_boundaries(self): Offset(id=0x00) and Offset(id=0xFF) Offset(size=1) and Offset(size=4) Offset(offset=0x00) and Offset(offset=0xFF) Offset(size=2, offset=0x00) and Offset(size=2, offset=0xFFFF) Offset(size=3, offset=0x00) and Offset(size=3, offset=0xFFFFFF) Offset(size=4, offset=0x00) and Offset(size=4, offset=0xFFFFFFFF)
def test_default_offset_constructor(self): Offset()
def parse_offset(self, s): id = s.read("uint:8") size = s.read("uint:2") # + 1 = already read offset = s.read("uint:" + str(6 + (size * 8))) return Offset(id=id, size=size + 1, offset=offset)