Example #1
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')
Example #2
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')
Example #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)
Example #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)
Example #5
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
Example #6
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