async def start(self, skip_initial_messages=False): """Connect to device and listen to incoming messages.""" if self.connection.connected: return await self.connection.connect() # In case credentials have been given externally (i.e. not by pairing # with a device), then use that client id if self.service.credentials: self.srp.pairing_id = Credentials.parse( self.service.credentials).client_id # The first message must always be DEVICE_INFORMATION, otherwise the # device will not respond with anything msg = messages.device_information('pyatv', self.srp.pairing_id.decode()) await self.send_and_receive(msg) self._initial_message_sent = True # This is a hack to support re-use of a protocol object in # proxy (will be removed/refactored later) if skip_initial_messages: return await self._connect_and_encrypt() # This should be the first message sent after encryption has # been enabled await self.send(messages.set_connection_state()) # Subscribe to updates at this stage await self.send(messages.client_updates_config()) await self.send_and_receive(messages.get_keyboard_session())
def handle_send_hid_event(self, message, inner): # These corresponds to the bytes mapping to pressed key (see # send_hid_event in pyatv/mrp/messages.py) start = inner.hidEventData[43:49] use_page, usage, down_press = struct.unpack('>HHH', start) if down_press == 1: self.outstanding_keypresses.add((use_page, usage)) self.send(messages.create(0, identifier=message.identifier)) elif down_press == 0: if (use_page, usage) in self.outstanding_keypresses: if ( _convert_key_press(use_page, usage) == 'select' and self.last_button_pressed == 'home' ): msg = messages.device_information( 'pyatv', message.identifier, 0) self.send(msg) self.last_button_pressed = _convert_key_press(use_page, usage) self.outstanding_keypresses.remove((use_page, usage)) _LOGGER.debug('Pressed button: %s', self.last_button_pressed) self.send(messages.create(0, identifier=message.identifier)) else: _LOGGER.error('Missing key down for %d,%d', use_page, usage) else: _LOGGER.error('Invalid key press state: %d', down_press)
async def start(self, skip_initial_messages=False): """Connect to device and listen to incoming messages.""" if self._state != ProtocolState.NOT_CONNECTED: raise exceptions.InvalidStateError(self._state.name) self._state = ProtocolState.CONNECTING try: await self.connection.connect() self._state = ProtocolState.CONNECTED # In case credentials have been given externally (i.e. not by pairing # with a device), then use that client id if self.service.credentials: self.srp.pairing_id = HapCredentials.parse( self.service.credentials).client_id # The first message must always be DEVICE_INFORMATION, otherwise the # device will not respond with anything msg = messages.device_information("pyatv", self.srp.pairing_id.decode()) self.device_info = await self.send_and_receive(msg) # This is a hack to support re-use of a protocol object in # proxy (will be removed/refactored later) if skip_initial_messages: return await self._enable_encryption() # This should be the first message sent after encryption has # been enabled await self.send(messages.set_connection_state()) # Subscribe to updates at this stage await self.send_and_receive(messages.client_updates_config()) await self.send_and_receive(messages.get_keyboard_session()) self._heartbeat_task = asyncio.ensure_future(heartbeat_loop(self)) except Exception: # Something went wrong, let's do cleanup self.stop() raise else: # We're now ready self._state = ProtocolState.READY
async def start(self): """Connect to device and listen to incoming messages.""" if self.connection.connected: return await self.connection.connect() # In case credentials have been given externally (i.e. not by pairing # with a device), then use that client id if self.service.device_credentials: self.srp.pairing_id = Credentials.parse( self.service.device_credentials).client_id # The first message must always be DEVICE_INFORMATION, otherwise the # device will not respond with anything msg = messages.device_information( 'pyatv', self.srp.pairing_id.decode()) await self.send_and_receive(msg) self._initial_message_sent = True # This should be the first message sent after encryption has # been enabled await self.send(messages.set_ready_state()) async def _wait_for_updates(_, semaphore): # Use a counter here whenever more than one message is expected semaphore.release() # Wait for some stuff to arrive before returning semaphore = asyncio.Semaphore(value=0, loop=self.loop) self.add_listener(_wait_for_updates, protobuf.SET_STATE_MESSAGE, data=semaphore, one_shot=True) # Subscribe to updates at this stage await self.send(messages.client_updates_config()) await self.send(messages.wake_device()) try: await asyncio.wait_for( semaphore.acquire(), 1, loop=self.loop) except asyncio.TimeoutError: # This is not an issue itself, but I should do something better. # Basically this gives the device about one second to respond with # some metadata before continuing. pass
def _send_device_info(self, identifier=None, update=False): resp = messages.device_information(DEVICE_NAME, "1234", update=update) if identifier: resp.identifier = identifier resp.inner().logicalDeviceCount = 1 if self.state.powered_on else 0 self.send(resp)
def handle_device_info(self, message): _LOGGER.debug('Received device info message') resp = messages.device_information('Fake MRP ATV', '1234') resp.identifier = message.identifier self._send(resp)
def handle_wake_device(self, message, inner): msg = messages.device_information('pyatv', message.identifier, 1) self.send(msg) self.send(messages.command_result(message.identifier))
def handle_device_info(self, message, inner): resp = messages.device_information(DEVICE_NAME, '1234') resp.identifier = message.identifier self.send(resp)