def test_parsing(self): length_bytes = [0x01] length = Length.parse(ConstBitStream(bytes=length_bytes)) self.assertEqual(length.value, 1) length_bytes = [0x40, 0x41] length = Length.parse(ConstBitStream(bytes=length_bytes)) self.assertEqual(length.value, 65) length_bytes = [0xC0, 0x41, 0x10, 0x00] length = Length.parse(ConstBitStream(bytes=length_bytes)) self.assertEqual(length.value, 4263936)
def test_byte_generation(self): bytes = bytearray(Length()) self.assertEqual(len(bytes), 1) self.assertEqual(bytes[0], int('00000000', 2)) bytes = bytearray(Length(value=4)) self.assertEqual(len(bytes), 1) self.assertEqual(bytes[0], int('00000100', 2)) bytes = bytearray(Length(value=65120)) self.assertEqual(len(bytes), 3) self.assertEqual(bytes[0], int('10000000', 2)) self.assertEqual(bytes[1], int('11111110', 2)) self.assertEqual(bytes[2], int('01100000', 2))
def create_with_read_file_action(file_id, length, offset=0, 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_id, offset=Length( offset)), # TODO offset size length=Length(length))))) return cmd
def test_arith_comp_with_value_byte_generation(self): query = QueryOperand(type=QueryType.ARITH_COMP_WITH_VALUE, mask_present=False, params=ArithQueryParams( signed_data_type=False, comp_type=ArithComparisonType.GREATER_THAN), compare_length=Length(1), compare_value=[25], file_a_offset=Offset(id=32, offset=Length(1))) bytes = bytearray(query) self.assertEqual(len(bytes), 5) self.assertEqual(bytes[0], 0x44) self.assertEqual(bytes[1], 0x01) self.assertEqual(bytes[2], 25) self.assertEqual(bytes[3], 0x20) self.assertEqual(bytes[4], 0x01)
def connect(self): if self.connected: return 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=Length( 0)), # TODO offset size length=FirmwareVersionFile().length)))) if self.skip_alp_parsing: self.log.info( "Running in skip_alp_parsing mode, not checking if we can receive the modem's UID" ) self.connected = True self.execute_command_async(read_modem_info_action) return True resp_cmd = self.execute_command(read_modem_info_action, timeout_seconds=10) 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", str(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: self.connected = True if self.connected: self.log.info( "connected to {}, node UID {} running D7AP v{}, application \"{}\" with git sha1 {}" .format(self.config["device"], self.uid, self.firmware_version.d7ap_version, self.firmware_version.application_name, self.firmware_version.git_sha1)) return True else: return False
def parse(s): type = QueryType(s.read("uint:3")) assert (type == QueryType.ARITH_COMP_WITH_VALUE ) # TODO implement other types mask_present = s.read("bool") assert (mask_present is False) # TODO implement this params = ArithQueryParams.parse(s) compare_length = Length.parse(s) compare_value = map(ord, s.read("bytes:" + str(compare_length.value))) file_a_offset = Offset.parse(s) return QueryOperand(type=type, mask_present=mask_present, params=params, compare_length=compare_length, compare_value=compare_value, file_a_offset=file_a_offset)
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(offset=Length(65120))) self.assertEqual(len(bytes), 4) self.assertEqual(bytes[0], int('00000000', 2)) self.assertEqual(bytes[1], int('10000000', 2)) self.assertEqual(bytes[2], int('11111110', 2)) self.assertEqual(bytes[3], int('01100000', 2))
def _connect_serial_modem(self): self.dev = serial.Serial( port=self.config["device"], baudrate=self.config["baudrate"], timeout=None, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS, xonxoff=False, rtscts=False, dsrdtr=False, exclusive=True, ) 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=Length( 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 __init__(self, id=0, offset=Length()): self.id = id self.offset = offset super(Offset, self).__init__()
def parse_alp_return_file_data_operand(self, s): offset = self.parse_offset(s) length = Length.parse(s) data = s.read("bytes:" + str(length.value)) return Data(offset=offset, data=map(ord, data))
def parse_alp_file_data_request_operand(self, s): offset = self.parse_offset(s) length = Length.parse(s) return DataRequest(length=length.value, offset=offset)
def __init__(self, id, length): self.id = id self.length = Length(value=length)
def __init__(self, data=[], offset=Offset()): self.offset = offset self.data = data self.length = Length(len(data)) super(Data, self).__init__()
configure_default_logger(config.verbose) modem = Modem(config.device, config.rate, unsolicited_response_received_callback=received_command_callback) modem.connect() # command to be executed as an action: first do an arithmetic comparison of the sensor value with the supplied value... query_sensor_file_cmd = Command(generate_tag_request_action=False) query_sensor_file_cmd.add_action( RegularAction(operation=BreakQuery(operand=QueryOperand( type=QueryType.ARITH_COMP_WITH_VALUE, mask_present=False, params=ArithQueryParams(signed_data_type=False, comp_type=ArithComparisonType.GREATER_THAN), compare_length=Length(2), compare_value=[ ord(b) for b in struct.pack(">H", int(config.temperature * 10)) ], file_a_offset=Offset(id=0x40, offset=Length(0)))))) # ...if the query succeeds, read the file query_sensor_file_cmd.add_action( RegularAction(operation=ReadFileData( operand=DataRequest(offset=Offset(id=0x40), length=Length(2))))) # the interface config to send the result of above action to interface_config = InterfaceConfiguration( InterfaceType.D7ASP, Configuration(qos=QoS(resp_mod=ResponseMode.RESP_MODE_NO, retry_mod=RetryMode.RETRY_MODE_NO,
def parse(s): id = s.read("uint:8") offset = Length.parse(s) return Offset(id=id, offset=offset)
def __init__(self, length, offset=Offset()): self.offset = offset self.length = Length(length) super(DataRequest, self).__init__()
cmd = Command.create_with_write_file_action(file_id=199, data=data) answ = modem.execute_command(cmd) cmd = Command() f = open(config.file, "rb") total_length = os.path.getsize(config.file) amount_of_bytes = 239 length = 0 try: bytes = list(bytearray(f.read(amount_of_bytes))) while len(bytes) != 0: cmd.add_action( RegularAction(operation=WriteFileData(operand=Data( offset=Offset(id=200, offset=Length(length)), data=bytes)))) length += amount_of_bytes answ = modem.execute_command(cmd) worked = False for answer in answ: if answer.execution_completed and not answer.completed_with_error: worked = True if not worked: print("write failed") break cmd = Command() print( chr(27) + "[2J\n" + str(length) + "/" + str(total_length) + ": " + str(length * 100 / total_length) + "%")