async def process(self, timeout: int) -> None: """Start to process devices and services.""" zc_timeout = timeout * 1000 services_by_address, name_to_model = await self._lookup_services_and_models( zc_timeout) dev_services_by_address: Dict[str, List[mdns.Service]] = {} model_by_address: Dict[str, Optional[str]] = {} for address, service_infos in services_by_address.items(): if self.hosts and address not in self.hosts: continue dev_services = [] for service_info in service_infos: name = _extract_service_name(service_info) service_type = service_info.type[:-1] if address not in model_by_address: device_name = self._device_info_name[service_type](name) if device_name: model_by_address[address] = name_to_model.get( device_name) dev_services.append( mdns.Service( service_type, name, IPv4Address(address), service_info.port, CaseInsensitiveDict({ k.decode("ascii"): mdns.decode_value(v) for k, v in service_info.properties.items() }), )) dev_services_by_address[address] = dev_services self._process_responses(dev_services_by_address, model_by_address)
async def _start_relay(loop, args, zconf): _, protocol = await loop.create_connection(lambda: RemoteConnection(loop), args.remote_ip, args.remote_port) coro = loop.create_server(lambda: RelayConnection(loop, protocol), "0.0.0.0") server = await loop.create_task(coro) port = server.sockets[0].getsockname()[1] props = dict({(prop.split("=")[0], prop.split("=")[1]) for prop in args.properties}) unpublisher = await mdns.publish( asyncio.get_event_loop(), mdns.Service(args.service_type, args.name, IPv4Address(args.local_ip), port, props), zconf, ) print("Press ENTER to quit") await loop.run_in_executor(None, sys.stdin.readline) server.close() return unpublisher
async def publish_companion_service(zconf: Zeroconf, address: str, port: int): """Publish zeroconf service for ATV Companion proxy instance.""" properties = { "rpMac": "1", "rpHA": "9948cfb6da55", "rpHN": "88f979f04023", "rpVr": "230.1", "rpMd": "AppleTV6,2", "rpFl": "0x36782", "rpAD": "657c1b9d3484", "rpHI": "91756a18d8e5", "rpBA": "9D:19:F9:74:65:EA", } return await mdns.publish( asyncio.get_event_loop(), mdns.Service( "_companion-link._tcp.local", DEVICE_NAME, IPv4Address(address), port, properties, ), zconf, )
def test_airport_handler(): handler, _ = scan()[AIRPORT_SERVICE] mdns_service = mdns.Service(RAOP_SERVICE, "foo@bar", ip_address("127.0.0.1"), 1234, {"foo": "bar"}) mdns_response = mdns.Response([], False, None) assert not handler(mdns_service, mdns_response)
def test_airplay_handler_to_service(): handler, _ = scan()[AIRPLAY_SERVICE] mdns_service = mdns.Service(AIRPLAY_SERVICE, "foo", ip_address("127.0.0.1"), 1234, {"foo": "bar"}) mdns_response = mdns.Response([], False, None) name, service = handler(mdns_service, mdns_response) assert name == "foo" assert service.port == 1234 assert service.credentials is None assert not DeepDiff(service.properties, {"foo": "bar"})
def test_mrp_handler_to_service(): handler, _ = scan()[MRP_SERVICE] mdns_service = mdns.Service(MRP_SERVICE, "foo", ip_address("127.0.0.1"), 1234, {"Name": "test"}) mdns_response = mdns.Response([], False, None) name, service = handler(mdns_service, mdns_response) assert name == "test" assert service.port == 1234 assert service.credentials is None assert not DeepDiff(service.properties, {"Name": "test"})
def test_homesharing_handler_to_service(): handler, _ = scan()[HOMESHARING_SERVICE] mdns_service = mdns.Service( HOMESHARING_SERVICE, "foo", ip_address("127.0.0.1"), 1234, {"Name": "bar"} ) mdns_response = mdns.Response([], False, None) name, service = handler(mdns_service, mdns_response) assert name == "bar" assert service.port == 1234 assert service.credentials is None assert not DeepDiff(service.properties, {"Name": "bar"})
async def publish_airplay_zeroconf(loop, zconf, address, port): """Publish AirPlay Zeroconf service.""" props = { "deviceid": "00:01:02:03:04:05", "model": "AppleTV3,1", "pi": "4EE5AF58-7E5D-465A-935E-82E4DB74385D", "flags": "0x44", "vv": "2", "features": "0x5A7FFFF7,0xE", "pk": "3853c0e2ce3844727ca0cb1b86a3e3875e66924d2648d8f8caf71f8118793d98", # pylint: disable=line-too-long # noqa "srcvers": "220.68", } return await mdns.publish( loop, mdns.Service( "_airplay._tcp.local", DEVICE_NAME, IPv4Address(address), port, props ), zconf, )
async def publish_mrp_zeroconf(loop, zconf, address, port): """Publish MRP Zeroconf service.""" props = { "ModelName": "Apple TV", "AllowPairing": "YES", "macAddress": "40:cb:c0:12:34:56", "BluetoothAddress": False, "Name": DEVICE_NAME, "UniqueIdentifier": SERVER_IDENTIFIER, "SystemBuildVersion": "17K499", "LocalAirPlayReceiverPairingIdentity": AIRPLAY_IDENTIFIER, } return await mdns.publish( loop, mdns.Service( "_mediaremotetv._tcp.local", DEVICE_NAME, IPv4Address(address), port, props ), zconf, )
async def publish_companion_zeroconf(loop, zconf, address, port): """Publish Companion Zeroconf service.""" props = { "rpMac": "1", "rpHA": "9948cfb6da55", "rpHN": "88f979f04023", "rpVr": "230.1", "rpMd": "AppleTV6,2", "rpFl": "0x36782", "rpAD": "657c1b9d3484", "rpHI": "91756a18d8e5", "rpBA": "9D:19:F9:74:65:EA", } return await mdns.publish( loop, mdns.Service( "_companion-link._tcp.local", DEVICE_NAME, IPv4Address(address), port, props ), zconf, )
async def publish_mrp_service(zconf: Zeroconf, address: str, port: int, name: str): """Publish zeroconf service for ATV MRP proxy instance.""" properties = { "ModelName": "Apple TV", "AllowPairing": "YES", "macAddress": "40:cb:c0:12:34:56", "BluetoothAddress": "False", "Name": name, "UniqueIdentifier": SERVER_IDENTIFIER, "SystemBuildVersion": "17K499", "LocalAirPlayReceiverPairingIdentity": AIRPLAY_IDENTIFIER, } return await mdns.publish( asyncio.get_event_loop(), mdns.Service("_mediaremotetv._tcp.local", name, IPv4Address(address), port, properties), zconf, )
async def publish_dmap_zeroconf(loop, zconf, address, port): """Publish DMAP Zeroconf service.""" props = { "DFID": "2", "PrVs": "65538", "hG": HSGID, "Name": DEVICE_NAME, "txtvers": "1", "atSV": "65541", "MiTPV": "196611", "EiTS": "1", "fs": "2", "MniT": "167845888", } return await mdns.publish( loop, mdns.Service( "_appletv-v2._tcp.local", DEVICE_NAME, IPv4Address(address), port, props ), zconf, )
async def _publish_service(self, address: IPv4Address, port: int) -> None: props = { "DvNm": self._name, "RemV": "10000", "DvTy": "iPod", "RemN": "Remote", "txtvers": "1", "Pair": self._pairing_guid, } await mdns.publish( self._loop, mdns.Service( "_touch-remote._tcp.local", f"{int(address):040d}", address, port, props, ), self._zeroconf, )
async def publish_raop_zeroconf(loop, zconf, address, port): """Publish RAOP Zeroconf service.""" props = { "et": "0", "ss": "16", "am": "AppleTV6,2", "md": "0", "ch": "2", "sr": "44100", "cn": "1", } return await mdns.publish( loop, mdns.Service( "_raop._tcp.local", f"AA:BB:CC:DD:EE:FF@{DEVICE_NAME}", IPv4Address(address), port, props, ), zconf, )