示例#1
0
    def __init__(self, config: Config, request_transmitter: 'Queue[Request]'):
        threading.Thread.__init__(self)
        self._config = config

        if not config.rfcomm_enabled:
            self._logger.fatal('RFCC is disabled but is trying to create')
            raise Exception('RFCC is disabled but is trying to create')

        self._count_connected = 0
        self._request_transmitter = request_transmitter
        self._protocol_parser = ProtocolParser(self)
示例#2
0
    def __init__(self, config: Config, request_transmitter: 'Queue[Request]'):
        threading.Thread.__init__(self)
        self._config = config

        if not config.mqtt_enabled:
            self._logger.fatal('Mqtt is disabled but is trying to create')
            raise Exception('Mqtt is disabled but is trying to create')

        self._request_transmitter = request_transmitter
        self._mqtt_address = config.mqtt_address
        self._is_mqtt_connected = False
        self._protocol_parser = ProtocolParser(self)
示例#3
0
    def test_serialize_with_empty_payload(self):
        # Given
        command = CommandType.GetSettings
        payload = None

        expected_bytes = bytes(b'\xfd\xba\xdc\x01\x50\xb4\x11\xff\x04\x00\x00\xab')

        parser = ProtocolParser(MagicMock())

        # When
        package = ProtocolParser.create_package(command, payload)
        ser_package = parser.serialize_package(package)

        # Then
        assert expected_bytes == ser_package
示例#4
0
    def test_serialize(self):
        # Given
        command = CommandType.GetGestures
        payload = bytes(b'\xba\x05')

        expected_bytes = bytes(b'\xfd\xba\xdc\x01\x50\xb4\x11\xff\x06\x02\x00\xba\x05\xb1')

        parser = ProtocolParser(MagicMock())

        # When
        package = ProtocolParser.create_package(command, payload)
        ser_package = parser.serialize_package(package)

        # Then
        assert expected_bytes == ser_package
示例#5
0
    def test_create_package_with_empty_payload(self):
        # Given
        command = CommandType.GetGestures

        # When
        package = ProtocolParser.create_package(command, None)

        # Then
        assert command == package.command_type
        assert package.payload is None
        assert 0 == package.payload_size
示例#6
0
    def test_create_package(self):
        # Given
        command = CommandType.GetGestures
        payload = bytes(b'\xba\x05')

        # When
        package = ProtocolParser.create_package(command, payload)

        # Then
        assert command == package.command_type
        assert payload == package.payload
        assert len(payload) == package.payload_size
示例#7
0
    def test_receive_sequence_package(self):
        # Given

        parser = ProtocolParser(MagicMock())
        package1_received = bytes(b'\xfd\xba\xdc\x01\x50\xb4\x11\xff\x09\x05\x00\xff\xff\xff\xff\xff\xb6')
        package2_received = bytes(b'\xfd\xba\xdc\x01\x50\xb4\x11\xff\x05\x02\x00\xab\xcd\x8a')

        # When & Then
        parser.update(package1_received)

        assert parser.state == ProtocolState.SFD
        assert parser.current_request.payload_size == 5
        assert parser.current_request.payload == bytes(b'\xff\xff\xff\xff\xff')
        assert parser.current_request.command_type == CommandType.PerformGestureId
        assert parser.current_request.received_crc8 == b'\xb6'
        assert parser.current_request.real_crc8 == b'\xc6'

        parser.update(package2_received)

        assert parser.state == ProtocolState.SFD
        assert parser.current_request.payload_size == 2
        assert parser.current_request.payload == bytes(b'\xab\xcd')
        assert parser.current_request.command_type == CommandType.SetSettings
        assert parser.current_request.received_crc8 == b'\x8a'
        assert parser.current_request.real_crc8 == b'\x23'
示例#8
0
    def test_receive_incorrect_sfd(self):
        # Given
        parser = ProtocolParser(MagicMock())
        first_received = bytes(b'\x03\x5B\xD5\xD4')
        second_received = bytes(b'\xff\xfa\xb4')
        third_received = bytes(b'\x01\x50\xb4\x11\xff')

        # When
        parser.update(first_received)
        parser.update(second_received)
        parser.update(third_received)

        # Then
        assert parser.state == ProtocolState.SFD
示例#9
0
    def test_receive_type(self):
        # Given
        parser = ProtocolParser(MagicMock())
        sfd_received = bytes(b'\xfd\xba\xdc\x01\x50\xb4\x11\xff')
        type_received = bytes(b'\x09')

        # When
        parser.update(sfd_received)
        parser.update(type_received)

        # Then
        assert parser.state == ProtocolState.SIZE
        assert parser.current_request.command_type == CommandType.PerformGestureId
示例#10
0
    def test_receive_package(self):
        # Given
        receiver_mock = MagicMock()
        parser = ProtocolParser(receiver_mock)
        sfd_part1_received = bytes(b'\xfd\xba\xdc')
        sfd_part2_third_received = bytes(b'\x01\x50\xb4\x11\xff')
        type_info_payload_crc8_received = bytes(b'\x09\x05\x00\xff\xff\xff\xff\xff\xb6')

        # When
        parser.update(sfd_part1_received)
        parser.update(sfd_part2_third_received)
        parser.update(type_info_payload_crc8_received)

        # Then
        assert parser.state == ProtocolState.SFD
        assert parser.current_request.payload_size == 5
        assert parser.current_request.payload == bytes(b'\xff\xff\xff\xff\xff')
        assert parser.current_request.command_type == CommandType.PerformGestureId
        assert parser.current_request.received_crc8 == b'\xb6'
        assert parser.current_request.real_crc8 == b'\xc6'
        assert receiver_mock.receive_package.call_count == 1
示例#11
0
    def test_receive_size(self):
        # Given
        parser = ProtocolParser(MagicMock())
        sfd_received = bytes(b'\xfd\xba\xdc\x01\x50\xb4\x11\xff')
        type_received = bytes(b'\x09')
        size_received = bytes(b'\x3b\x01')

        # When
        parser.update(sfd_received)
        parser.update(type_received)
        parser.update(size_received)

        # Then
        assert parser.state == ProtocolState.PAYLOAD
        assert parser.current_request.payload_size == 315
示例#12
0
    def test_sfd_receive_correct(self):
        # Given
        self._package_receiver_mock = MagicMock()
        parser = ProtocolParser(self._package_receiver_mock)
        incorrect_received = bytes(b'\x03\x5B\xD5\xD4')
        sfd_part1_received = bytes(b'\xfd\xba\xdc')
        sfd_part2_received = bytes(b'\x01\x50\xb4\x11\xff')

        # When
        parser.update(incorrect_received)
        parser.update(sfd_part1_received)
        parser.update(sfd_part2_received)

        # Then
        assert parser.state == ProtocolState.TYPE
示例#13
0
    def test_timeout(self):
        # Given
        receiver_mock = MagicMock()
        parser = ProtocolParser(receiver_mock)
        sfd_received = bytes(b'\xfd\xba\xdc\x01\x50\xb4\x11\xff')
        before_timeout_received = bytes(b'\x09\x05\x00\xff')

        package_after_timeout_received = bytes(b'\xfd\xba\xdc\x01\x50\xb4\x11\xff\x09\x05\x00\xff\xff\xff\xff\xff\xb6')

        # When & Then
        parser.update(sfd_received)
        parser.update(before_timeout_received)

        assert parser.state == ProtocolState.PAYLOAD
        time.sleep(6)

        parser.update(package_after_timeout_received)

        assert parser.state == ProtocolState.SFD
        assert parser.current_request.payload_size == 5
        assert parser.current_request.payload == bytes(b'\xff\xff\xff\xff\xff')
        assert parser.current_request.command_type == CommandType.PerformGestureId
        assert parser.current_request.received_crc8 == b'\xb6'
        assert parser.current_request.real_crc8 == b'\xc6'
示例#14
0
class MqttConnector(threading.Thread, IResponseWriter, IPackageReceiver):
    _logger = logging.getLogger('Main')
    _mqtt_address: str
    _is_mqtt_connected: bool
    _bluetooth_client: BluetoothClient = None
    _response_mutex = threading.Lock()

    def __init__(self, config: Config, request_transmitter: 'Queue[Request]'):
        threading.Thread.__init__(self)
        self._config = config

        if not config.mqtt_enabled:
            self._logger.fatal('Mqtt is disabled but is trying to create')
            raise Exception('Mqtt is disabled but is trying to create')

        self._request_transmitter = request_transmitter
        self._mqtt_address = config.mqtt_address
        self._is_mqtt_connected = False
        self._protocol_parser = ProtocolParser(self)

    @property
    def connected(self) -> bool:
        if self._bluetooth_client is not None:
            return self._bluetooth_client.connected
        else:
            return False

    def run(self):
        self._logger.info('Mqtt running start')
        self._bluetooth_client = BluetoothClient(server=self._mqtt_address,
                                                 data_received_callback=self.data_received_handler,
                                                 auto_connect=False, power_up_device=True, encoding=None)
        self._logger.info('Mqtt client created')

        while True:
            self._logger.info('Mqtt client try to connect')
            try:
                self._bluetooth_client.connect()
            except OSError as e:
                self._logger.info(f'Mqtt client connection error: {e}')
                time.sleep(30)
                continue
            except Exception as e:
                self._logger.exception(e)
                raise e

            self._is_mqtt_connected = True
            self._logger.info('Mqtt client connected')

            while True:
                if not self._bluetooth_client.connected:
                    self._logger.info('Mqtt client disconnected')
                    self._is_mqtt_connected = False
                    break

                self._is_mqtt_connected = False

            time.sleep(10)

    def data_received_handler(self, data):
        self._logger.debug(f'MQTT receive {len(data)} bytes')
        self._protocol_parser.update(data)

    def write_response(self, response: Response):
        self._response_mutex.acquire()

        payload_length = 0
        if response.payload is not None:
            payload_length = {len(response.payload)}

        if response.command_type is not CommandType.Telemetry:
            self._logger.info(
                f'MQTT try to send response with type {response.command_type} and payload length {payload_length}')
        package = self._protocol_parser.create_package(response.command_type, response.payload)
        self.send(self._protocol_parser.serialize_package(package))

        self._response_mutex.release()

    def receive_package(self, package: PackageDto):
        self._logger.info(f'MQTT receive new package {package.command_type} with size {package.payload_size} bytes')
        new_request = Request(package.command_type, package.payload, self)
        self._request_transmitter.put(new_request)

    def send(self, payload: bytes):
        if self._bluetooth_client is None:
            self._logger.critical('MQTT not running, but send invoke')
            raise ConnectionError('MQTT not running, but send invoke')

        self._bluetooth_client.send(payload)
示例#15
0
class RFCCConnector(threading.Thread, IResponseWriter, IPackageReceiver):
    _logger = logging.getLogger('Main')
    _bluetooth_server: BluetoothServer = None
    _response_mutex = threading.Lock()
    _count_connected: int

    def __init__(self, config: Config, request_transmitter: 'Queue[Request]'):
        threading.Thread.__init__(self)
        self._config = config

        if not config.rfcomm_enabled:
            self._logger.fatal('RFCC is disabled but is trying to create')
            raise Exception('RFCC is disabled but is trying to create')

        self._count_connected = 0
        self._request_transmitter = request_transmitter
        self._protocol_parser = ProtocolParser(self)

    @property
    def connected(self) -> bool:
        if self._bluetooth_server is not None:
            return self._count_connected > 0
        else:
            return False

    def run(self):
        self._logger.info('RFCC running start')
        self._bluetooth_server = BluetoothServer(
            data_received_callback=self._data_received_handler,
            auto_start=False,
            power_up_device=True,
            encoding=None,
            when_client_connects=self._client_connect_handler,
            when_client_disconnects=self._client_disconnect_handler)
        self._logger.info('RFCC server created')

        while True:
            self._logger.info('RFCC server try to start')
            try:
                self._bluetooth_server.start()
            except OSError as e:
                self._logger.info(f'RFCC server start error: {e}')
                time.sleep(30)
                continue
            except Exception as e:
                self._logger.exception(e)
                raise e

            self._logger.info('RFCC started')
            break

    def _client_connect_handler(self):
        self._logger.info('New device connected')
        self._count_connected = self._count_connected + 1

    def _client_disconnect_handler(self):
        self._logger.info('Device disconnected')
        self._count_connected = self._count_connected - 1

        if self._count_connected < 0:
            self._count_connected = 0

    def _data_received_handler(self, data):
        self._logger.debug(f'RFCC receive {len(data)} bytes')
        self._protocol_parser.update(data)

    def write_response(self, response: Response):
        self._response_mutex.acquire()

        payload_length = 0
        if response.payload is not None:
            payload_length = {len(response.payload)}

        if response.command_type is not CommandType.Telemetry:
            self._logger.info(
                f'RFCC try to send response with type {response.command_type} and payload length {payload_length}'
            )
        package = self._protocol_parser.create_package(response.command_type,
                                                       response.payload)
        self.send(self._protocol_parser.serialize_package(package))

        self._response_mutex.release()

    def receive_package(self, package: PackageDto):
        self._logger.info(
            f'RFCC receive new package {package.command_type} with size {package.payload_size} bytes'
        )
        new_request = Request(package.command_type, package.payload, self)
        self._request_transmitter.put(new_request)

    def send(self, payload: bytes):
        if self._bluetooth_server is None:
            self._logger.critical('RFCC not running, but send invoke')
            raise ConnectionError('RFCC not running, but send invoke')

        self._bluetooth_server.send(payload)