Пример #1
0
    async def report_received(self, data: Union[bytes, Text],
                              addr: Tuple[str, int]) -> None:
        self.sig_data_received.set()

        try:
            report = OutputReport(list(data))
        except ValueError as v_err:
            logger.warning(f'Report parsing error "{v_err}" - IGNORE')
            return

        try:
            output_report_id = report.get_output_report_id()
        except NotImplementedError as err:
            logger.warning(err)
            return

        if output_report_id == OutputReportID.SUB_COMMAND:
            await self._reply_to_sub_command(report)
        elif output_report_id == OutputReportID.RUMBLE_ONLY:
            # TODO Rumble
            pass
        elif output_report_id == OutputReportID.REQUEST_IR_NFC_MCU:
            self._mcu.received_11(report.data[11],
                                  report.get_sub_command_data())
            pass
        else:
            logger.warning(
                f'Output report {output_report_id} not implemented - ignoring')
Пример #2
0
    async def report_received(self, data: Union[bytes, Text],
                              addr: Tuple[str, int]) -> None:
        if not data:
            # disconnect happened
            logger.error('No data received (most likely due to a disconnect).')
            return

        self._data_received.set()

        try:
            report = OutputReport(list(data))
        except ValueError as v_err:
            logger.warning(f'Report parsing error "{v_err}" - IGNORE')
            return

        try:
            output_report_id = report.get_output_report_id()
        except NotImplementedError as err:
            logger.warning(err)
            return

        if output_report_id == OutputReportID.SUB_COMMAND:
            await self._reply_to_sub_command(report)
        #elif output_report_id == OutputReportID.RUMBLE_ONLY:
        #    pass
        else:
            logger.warning(
                f'Output report {output_report_id} not implemented - ignoring')
Пример #3
0
    async def input_report_mode_0x30(self):
        """
        Continuously sends 0x30 input reports containing the controller state.
        """
        if self.transport.is_reading():
            raise ValueError(
                'Transport must be paused in 0x30 input report mode')

        self._in_0x30_input_report_mode = True

        input_report = InputReport()
        input_report.set_input_report_id(0x30)
        input_report.set_vibrator_input()
        input_report.set_misc()

        reader = asyncio.ensure_future(self.transport.read())

        while True:
            await self.sig_unpause_input_report_mode_0x30.wait()

            if self.controller == Controller.PRO_CONTROLLER:
                # send state at 120Hz
                await asyncio.sleep(1 / 120)
            else:
                # send state at 60Hz
                await asyncio.sleep(1 / 60)

            reply_send = False
            if reader.done():
                data = await reader
                if not data:
                    # disconnect happened
                    logger.error(
                        'No data received (most likely due to a disconnect).')
                    break

                reader = asyncio.ensure_future(self.transport.read())

                try:
                    report = OutputReport(list(data))
                    output_report_id = report.get_output_report_id()

                    if output_report_id == OutputReportID.RUMBLE_ONLY:
                        # TODO
                        pass
                    elif output_report_id == OutputReportID.SUB_COMMAND:
                        reply_send = await self._reply_to_sub_command(report)
                except ValueError as v_err:
                    logger.warning(f'Report parsing error "{v_err}" - IGNORE')
                except NotImplementedError as err:
                    logger.warning(err)

            if reply_send:
                # Hack: Adding a delay here to avoid flooding during pairing
                await asyncio.sleep(0.3)
            else:
                # write 0x30 input report. TODO: set some sensor data
                input_report.set_6axis_data()
                await self.write(input_report)
Пример #4
0
    async def input_report_mode_0x30(self):
        if self.transport.is_reading():
            raise ValueError('Transport must be paused in 0x30 input report mode')

        input_report = InputReport()
        input_report.set_input_report_id(0x30)
        input_report.set_misc()

        reader = asyncio.ensure_future(self.transport.read())

        while True:
            if self.controller == Controller.PRO_CONTROLLER:
                # send state at 120Hz
                await asyncio.sleep(1 / 120)
            else:
                # send state at 60Hz
                await asyncio.sleep(1 / 60)

            reply_send = False
            if reader.done():
                data = await reader
                reader = asyncio.ensure_future(self.transport.read())

                try:
                    report = OutputReport(list(data))
                    output_report_id = report.get_output_report_id()

                    if output_report_id == OutputReportID.SUB_COMMAND:
                        reply_send = await self._reply_to_sub_command(report)
                except ValueError as v_err:
                    logger.warning(f'Report parsing error "{v_err}" - IGNORE')
                except NotImplementedError as err:
                    logger.warning(err)

            if reply_send:
                # Hack: Adding a delay here to avoid flooding
                await asyncio.sleep(0.3)
            else:
                # write 0x30 input report. TODO: set some sensor data
                input_report.set_6axis_data()
                await self.write(input_report)
Пример #5
0
    async def send_spi_read_request(self, hid_device, offset, size):
        report = OutputReport()
        report.sub_0x10_spi_flash_read(offset, size)

        # event shall be set if data received
        reply_event = asyncio.Event()
        self.pending_request = (offset, size, reply_event)

        # send spi flash read request
        while True:
            report.set_timer(self.timer)
            self.timer += 1

            # remove 0xA2 output report padding byte since it's not needed for communication over hid library
            data = report.data[1:]
            await hid_device.write(bytes(data))

            # wait for data received, send again if time out occurs (1 sec)
            try:
                await asyncio.wait_for(reply_event.wait(), 1)
                self.pending_request = None
                break
            except asyncio.TimeoutError:
                continue
                time = struct.unpack('d', _eof_read(capture, 8))[0]

                if start_time is None:
                    start_time = time

                # parse data size
                size = struct.unpack('i', _eof_read(capture, 4))[0]
                # parse data
                data = list(_eof_read(capture, size))

                if data[0] == 0xA1:
                    report = InputReport(data)
                    # normalise time
                    input_reports.append((time, report))
                elif data[0] == 0xA2:
                    report = OutputReport(data)
                    # normalise time
                    output_reports.append((time, report))
                else:
                    raise ValueError(f'Unexpected data.')
        except EOFError:
            pass

    dir_input_list = get_dir_inputs()
    rumble_timestamps = get_rumble_timestamps()
    print(dir_input_list)
    print(rumble_timestamps)

    tailcnt = cursor = 0
    seeds = []
    # The last direction of before snake scoring a point can be found by the timestamp when the rumble packet was sent.
Пример #7
0
    async def input_report_mode_full(self):
        """
        Continuously sends:
            0x30 input reports containing the controller state OR
            0x31 input reports containing the controller state and nfc data
        """
        if self.transport.is_reading():
            raise ValueError('Transport must be paused in full input report mode')

        # send state at 66Hz
        send_delay = 0.015
        await asyncio.sleep(send_delay)
        last_send_time = time.time()

        input_report = InputReport()
        input_report.set_vibrator_input()
        input_report.set_misc()
        if self._input_report_mode is None:
            raise ValueError('Input report mode is not set.')
        input_report.set_input_report_id(self._input_report_mode)

        reader = asyncio.ensure_future(self.transport.read())

        try:
            while True:
                reply_send = False
                if reader.done():
                    data = await reader

                    reader = asyncio.ensure_future(self.transport.read())

                    try:
                        report = OutputReport(list(data))
                        output_report_id = report.get_output_report_id()

                        if output_report_id == OutputReportID.RUMBLE_ONLY:
                            # TODO
                            pass
                        elif output_report_id == OutputReportID.SUB_COMMAND:
                            reply_send = await self._reply_to_sub_command(report)
                        elif output_report_id == OutputReportID.REQUEST_IR_NFC_MCU:
                            # TODO NFC
                            raise NotImplementedError('NFC communictation is not implemented.')                            
                        else:
                            logger.warning(f'Report unknown output report "{output_report_id}" - IGNORE')
                    except ValueError as v_err:
                        logger.warning(f'Report parsing error "{v_err}" - IGNORE')
                    except NotImplementedError as err:
                        logger.warning(err)

                if reply_send:
                    # Hack: Adding a delay here to avoid flooding during pairing
                    await asyncio.sleep(0.3)
                else:
                    # write 0x30 input report.
                    input_report.set_6axis_data(*self._controller_state.axis_state.get_6axis())
                    # TODO NFC - set nfc data
                    if input_report.get_input_report_id() == 0x31:
                        pass

                    await self.write(input_report)

                # calculate delay
                current_time = time.time()
                time_delta = time.time() - last_send_time
                sleep_time = send_delay - time_delta
                last_send_time = current_time

                if sleep_time < 0:
                    # logger.warning(f'Code is running {abs(sleep_time)} s too slow!')
                    sleep_time = 0

                await asyncio.sleep(sleep_time)

        except NotConnectedError as err:
            # Stop 0x30 input report mode if disconnected.
            logger.error(err)
        finally:
            # cleanup
            self._input_report_mode = None
            # cancel the reader
            with suppress(asyncio.CancelledError, NotConnectedError):
                if reader.cancel():
                    await reader
Пример #8
0
    async def input_report_mode_0x30(self):
        """
        Continuously sends 0x30 input reports containing the controller state.
        """
        if self.transport.is_reading():
            raise ValueError(
                'Transport must be paused in 0x30 input report mode')

        input_report = InputReport()
        input_report.set_input_report_id(0x30)
        input_report.set_vibrator_input()
        input_report.set_misc()

        reader = asyncio.ensure_future(self.transport.read())

        try:
            while True:
                # TODO: improve timing
                if self.controller == Controller.PRO_CONTROLLER:
                    # send state at 120Hz
                    await asyncio.sleep(1 / 120)
                else:
                    # send state at 60Hz
                    await asyncio.sleep(1 / 60)

                reply_send = False
                if reader.done():
                    data = await reader

                    reader = asyncio.ensure_future(self.transport.read())

                    try:
                        report = OutputReport(list(data))
                        output_report_id = report.get_output_report_id()

                        if output_report_id == OutputReportID.RUMBLE_ONLY:
                            # TODO
                            pass
                        elif output_report_id == OutputReportID.SUB_COMMAND:
                            reply_send = await self._reply_to_sub_command(
                                report)
                    except ValueError as v_err:
                        logger.warning(
                            f'Report parsing error "{v_err}" - IGNORE')
                    except NotImplementedError as err:
                        logger.warning(err)

                if reply_send:
                    # Hack: Adding a delay here to avoid flooding during pairing
                    await asyncio.sleep(0.3)
                else:
                    # write 0x30 input report.
                    # TODO: set some sensor data
                    input_report.set_6axis_data()

                    await self.write(input_report)

        except NotConnectedError as err:
            # Stop 0x30 input report mode if disconnected.
            print(' [-] Probably disconnected from console.')
            quit()
        finally:
            # cleanup
            self._input_report_mode = None
            # cancel the reader
            with suppress(asyncio.CancelledError, NotConnectedError):
                if reader.cancel():
                    await reader