async def _command_set_input_report_mode(self, sub_command_data): if sub_command_data[0] == 0x30: logger.info('Setting input report mode to 0x30...') input_report = InputReport() input_report.set_input_report_id(0x21) input_report.set_misc() input_report.set_ack(0x80) input_report.reply_to_subcommand_id(0x03) await self.write(input_report) # start sending 0x30 input reports if self._input_report_mode != 0x30: self._input_report_mode = 0x30 self.transport.pause_reading() new_reader = asyncio.ensure_future( self.input_report_mode_0x30()) # We need to swap the reader in the future because this function was probably called by it async def set_reader(): await self.transport.set_reader(new_reader) self.transport.resume_reading() asyncio.ensure_future(set_reader()).add_done_callback( utils.create_error_check_callback()) else: logger.error( f'input report mode {sub_command_data[0]} not implemented - ignoring request' )
def start_reader(self): """ Starts the transport reader which calls the protocols report_received function for every incoming message """ if self._read_thread is not None: raise ValueError('Reader is already running.') self._read_thread = asyncio.ensure_future(self._reader()) # Create callback in case the reader is failing callback = utils.create_error_check_callback( ignore=asyncio.CancelledError) self._read_thread.add_done_callback(callback)
async def _command_set_input_report_mode(self, sub_command_data): if self._input_report_mode == sub_command_data[0]: logger.warning( f'Already in input report mode {sub_command_data[0]} - ignoring request' ) # Start input report reader if sub_command_data[0] in (0x30, 0x31): new_reader = asyncio.ensure_future(self.input_report_mode_full()) else: logger.error( f'input report mode {sub_command_data[0]} not implemented - ignoring request' ) return # Replace the currently running reader with the input report mode sender, # which will also handle incoming requests in the future self.transport.pause_reading() # We need to replace the reader in the future because this function was probably called by it async def set_reader(): await self.transport.set_reader(new_reader) logger.info( f'Setting input report mode to {hex(sub_command_data[0])}...') self._input_report_mode = sub_command_data[0] self.transport.resume_reading() asyncio.ensure_future(set_reader()).add_done_callback( utils.create_error_check_callback()) # Send acknowledgement input_report = InputReport() input_report.set_input_report_id(0x21) input_report.set_misc() input_report.set_ack(0x80) input_report.reply_to_subcommand_id(0x03) await self.write(input_report)
async def set_reader(self, reader: asyncio.Future): """ Cancel the currently running reader and register the new one. A reader is a coroutine that calls this transports 'read' function. The 'read' function calls can be paused by calling pause_reading of this transport. :param reader: future reader """ if self._read_thread is not None: # cancel currently running reader if self._read_thread.cancel(): try: await self._read_thread except asyncio.CancelledError: pass # Create callback for debugging in case the reader is failing err_callback = utils.create_error_check_callback( ignore=asyncio.CancelledError) reader.add_done_callback(err_callback) self._read_thread = reader