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')
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')
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)
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)
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.
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
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