def _onServiceChanged(self, zeroconf, service_type, name, state_change):
        if state_change == ServiceStateChange.Added:
            Logger.log("d", "Bonjour service added: %s" % name)

            # First try getting info from zeroconf cache
            info = ServiceInfo(service_type, name, properties = {})
            for record in zeroconf.cache.entries_with_name(name.lower()):
                info.update_record(zeroconf, time.time(), record)

            for record in zeroconf.cache.entries_with_name(info.server):
                info.update_record(zeroconf, time.time(), record)
                if info.address:
                    break

            # Request more data if info is not complete
            if not info.address:
                Logger.log("d", "Trying to get address of %s", name)
                info = zeroconf.get_service_info(service_type, name)

            if info:
                type_of_device = info.properties.get(b"type", None).decode("utf-8")
                if type_of_device == "printer":
                    address = '.'.join(map(lambda n: str(n), info.address))
                    self.addPrinterSignal.emit(str(name), address, info.properties)
                else:
                    Logger.log("w", "The type of the found device is '%s', not 'printer'! Ignoring.." %type_of_device )
            else:
                Logger.log("w", "Could not get information about %s" % name)

        elif state_change == ServiceStateChange.Removed:
            Logger.log("d", "Bonjour service removed: %s" % name)
            self.removePrinterSignal.emit(str(name))
def test_multiple_addresses():
    type_ = "_http._tcp.local."
    registration_name = "xxxyyy.%s" % type_
    desc = {'path': '/~paulsm/'}
    address = socket.inet_aton("10.0.1.2")

    # Old way
    info = ServiceInfo(type_, registration_name, address, 80, 0, 0, desc, "ash-2.local.")

    assert info.address == address
    assert info.addresses == [address]

    # Updating works
    address2 = socket.inet_aton("10.0.1.3")
    info.address = address2

    assert info.address == address2
    assert info.addresses == [address2]

    info.address = None

    assert info.address is None
    assert info.addresses == []

    # Compatibility way
    info = ServiceInfo(type_, registration_name, [address, address], 80, 0, 0, desc, "ash-2.local.")

    assert info.addresses == [address, address]

    # New kwarg way
    info = ServiceInfo(
        type_, registration_name, None, 80, 0, 0, desc, "ash-2.local.", addresses=[address, address]
    )

    assert info.addresses == [address, address]
    def test_service_info_text_properties_not_given(self):
        type_ = "_test-srvc-type._tcp.local."
        name = "xxxyyy"
        registration_name = "%s.%s" % (name, type_)
        info = ServiceInfo(
            type_=type_,
            name=registration_name,
            address=socket.inet_aton("10.0.1.2"),
            port=80,
            server="ash-2.local.",
        )

        assert isinstance(info.text, bytes)
        repr(info)
Example #4
0
 def __init__(self, announce_address, announce_port, desc=None):
     if type(desc) is 'dict':
         del self.desc
         self.desc = desc
     logging.debug(
         "Requested announce server at address {}".format(announce_address))
     self.zeroconf = Zeroconf()
     self.info = ServiceInfo(
         "_midiband-hub._tcp.local.",
         socket.gethostname() + "._midiband-hub._tcp.local.",
         socket.inet_aton(announce_address), announce_port, 0, 0, self.desc,
         socket.gethostname() + ".local.")
     logging.info("Announcing server")
     self.zeroconf.register_service(self.info)
Example #5
0
    def run(self):
        # wait until zeroconf is available (tinypilot booting)
        while True:
            try:
                # register zeroconf service
                from zeroconf import IPVersion, ServiceInfo, Zeroconf

            except:
                time.sleep(10)
                continue  # try again
            break

        addresses = []
        zeroconf = {}
        info = {}

        #ip_version = IPVersion.All
        #ip_version = IPVersion.V6Only
        ip_version = IPVersion.V4Only

        while True:
            t = time.time()
            i = get_local_addresses()
            #print("t", time.time()-t)
            if i != addresses:
                print('zeroconf addresses', i, len(i))
                # close addresses
                for address in zeroconf:
                    zeroconf[address].unregister_service(info[address])
                    zeroconf[address].close()
                zeroconf = {}
                info = {}

                addresses = i

                # register addresses
                for address in addresses:
                    #print('zeroconf registering address', address)
                    info[address] = ServiceInfo(
                        "_pypilot._tcp.local.",
                        "pypilot._pypilot._tcp.local.",
                        addresses=[socket.inet_aton(address)],
                        port=DEFAULT_PORT,
                        properties={'version': strversion})

                    zeroconf[address] = Zeroconf(ip_version=ip_version,
                                                 interfaces=[address])
                    zeroconf[address].register_service(info[address])

            time.sleep(60)
    def test_find_with_device(self):
        zeroconf = Zeroconf()
        desc = {'id': '00:00:02:00:00:02'}
        info = ServiceInfo('_hap._tcp.local.', 'foo1._hap._tcp.local.', address=socket.inet_aton('127.0.0.1'),
                           port=1234, properties=desc, weight=0, priority=0)
        zeroconf.unregister_all_services()
        zeroconf.register_service(info, allow_name_change=True)

        result = find_device_ip_and_port('00:00:02:00:00:02', 10)

        zeroconf.unregister_all_services()

        self.assertIsNotNone(result)
        self.assertEqual(result['ip'], '127.0.0.1')
Example #7
0
    def verify_name_change(self, zc, type_, name, number_hosts):
        desc = {'path': '/~paulsm/'}
        info_service = ServiceInfo(
            type_, '%s.%s' % (name, type_), socket.inet_aton("10.0.1.2"),
            80, 0, 0, desc, "ash-2.local.")

        # verify name conflict
        self.assertRaises(
            r.NonUniqueNameException,
            zc.register_service, info_service)

        zc.register_service(info_service, allow_name_change=True)
        assert info_service.name.split('.')[0] == '%s-%d' % (
            name, number_hosts + 1)
    def test_discover_homekit_devices_missing_md(self):
        zeroconf = Zeroconf()
        desc = {'c#': '1', 'id': '00:00:01:00:00:04', 's#': '1', 'ci': '5'}
        info = ServiceInfo('_hap._tcp.local.', 'foo4._hap._tcp.local.', address=socket.inet_aton('127.0.0.1'),
                           port=1234, properties=desc, weight=0, priority=0)
        zeroconf.unregister_all_services()
        zeroconf.register_service(info, allow_name_change=True)

        result = discover_homekit_devices()
        test_device = self.find_device(desc, result)

        zeroconf.unregister_all_services()

        self.assertIsNone(test_device)
Example #9
0
 def get_service_info(self, type_, name, timeout=3000):
     id = _id_from_name(name)
     info = ServiceInfo(
         SERVICE_TYPE,
         name=".".join([id, SERVICE_TYPE]),
         server=".".join([id, LOCAL_DOMAIN, ""]),
         address=socket.inet_aton(MOCK_INTERFACE_IP),
         port=MOCK_PORT,
         properties={
             "facilities": "[]",
             "channels": "[]"
         },
     )
     return info
def main():
    logging.basicConfig(level=logging.DEBUG)

    parser = argparse.ArgumentParser()
    parser.add_argument('--debug', action='store_true')
    parser.add_argument("--name", dest="name", default=None,
                        help="mdns service name")
    version_group = parser.add_mutually_exclusive_group()
    version_group.add_argument('--v6', action='store_true')
    version_group.add_argument('--v6-only', action='store_true')
    args = parser.parse_args()

    if args.debug:
        logging.getLogger('zeroconf').setLevel(logging.DEBUG)
    if args.v6:
        ip_version = IPVersion.All
    elif args.v6_only:
        ip_version = IPVersion.V6Only
    else:
        ip_version = IPVersion.V4Only

    properties = {'who': 'codelab'}  # 详细信息

    name = args.name if args.name else uuid.uuid4().hex[:8]

    service_type = "_http._tcp.local."
    service_name = f"{name}._http._tcp.local."
    server = f"{name}.local." 
    port = 12358
    info = ServiceInfo(
        service_type,
        service_name,
        addresses=[socket.inet_aton(get_local_ip())],
        port=port,
        properties=properties,
        server=server,
    )
    print(info)
    zeroconf = Zeroconf(ip_version=ip_version)
    print("Registration of a service, press Ctrl-C to exit...")
    zeroconf.register_service(info)
    try:
        while True:
            sleep(0.1)
    except KeyboardInterrupt:
        pass
    finally:
        print("Unregistering...")
        zeroconf.unregister_service(info)
        zeroconf.close()
Example #11
0
 def __init__(self,
              zconf,
              type,
              name,
              address,
              port,
              weight=0,
              priority=0,
              properties=None):
     self.zconf = zconf
     self.info = ServiceInfo(type, "{}.{}".format(name, type),
                             socket.inet_aton(address), int(port), weight,
                             priority, properties)
     self.zconf.register_service(self.info)
Example #12
0
    def __start_advertising(self):
        self.service = ServiceInfo("{}._tcp.local.".format(self.type),
                                   "{}.{}._tcp.local.".format(self.name, self.type),
                                   socket.inet_aton(self.address), self.port, 0, 0,
                                   self.properties, "{}.local.".format(self.server))

        zeroconf = Zeroconf()
        zeroconf.register_service(self.service)

        while self.alive:
            time.sleep(.1)

        zeroconf.unregister_service(self.service)
        zeroconf.close()
Example #13
0
 def mock_homekit_info(service_type, name):
     return ServiceInfo(
         service_type,
         name,
         addresses=[b"\n\x00\x00\x14"],
         port=80,
         weight=0,
         priority=0,
         server="name.local.",
         properties={
             b"md": model.encode(),
             b"sf": pairing_status
         },
     )
Example #14
0
    def zeroConf(self):
        print("starting zeroconf")
        logging.basicConfig(level=logging.DEBUG)

        desc = {}

        info = ServiceInfo("_printer._tcp.local.",
                           "e-Paper._printer._tcp.local.",
                           socket.inet_aton(self.PRINTER_IP),
                           self.PRINTER_PORT, 0, 0, desc, "ash-2.local.")

        zeroconf = Zeroconf()
        zeroconf.register_service(info)
        print("zeroconf registered device")
Example #15
0
        def test_mdns_services_register_unregister_multiple(self):
            """Ensure that `adb mdns services` correctly adds and removes multiple services
            """
            from zeroconf import IPVersion, ServiceInfo

            with adb_server() as server_port:
                output = subprocess.check_output(
                    ["adb", "-P",
                     str(server_port), "mdns", "services"]).strip()
                self.assertTrue(
                    output.startswith(b"List of discovered mdns services"))
                """TODO(joshuaduong): Add ipv6 tests once we have it working in adb"""
                """Register/Unregister a service"""
                with zeroconf_context(IPVersion.V4Only) as zc:
                    srvs = {
                        'mdns_name':
                        ["testservice0", "testservice1", "testservice2"],
                        'mdns_type':
                        "_" + self.service_name + "._tcp.",
                        'ipaddr': [
                            socket.inet_aton("192.168.0.1"),
                            socket.inet_aton("10.0.0.255"),
                            socket.inet_aton("172.16.1.100")
                        ],
                        'port': [10000, 20000, 65535]
                    }
                    srv_infos = []
                    for i in range(len(srvs['mdns_name'])):
                        srv_infos.append(
                            ServiceInfo(srvs['mdns_type'] + "local.",
                                        name=srvs['mdns_name'][i] + "." +
                                        srvs['mdns_type'] + "local.",
                                        addresses=[srvs['ipaddr'][i]],
                                        port=srvs['port'][i]))
                    """ Register all devices, then unregister"""
                    with zeroconf_register_services(zc, srv_infos) as infos:
                        """Give adb some time to register the service"""
                        time.sleep(1)
                        for i in range(len(srvs['mdns_name'])):
                            self.assertTrue(
                                any((srvs['mdns_name'][i] in line
                                     and srvs['mdns_type'] in line) for line in
                                    MdnsTest._mdns_services(server_port)))
                    """Give adb some time to unregister the service"""
                    time.sleep(1)
                    for i in range(len(srvs['mdns_name'])):
                        self.assertFalse(
                            any((srvs['mdns_name'][i] in line
                                 and srvs['mdns_type'] in line) for line in
                                MdnsTest._mdns_services(server_port)))
Example #16
0
 def get_service_info(service_type, name):
     dns_type = discovery.BREWBLOX_DNS_TYPE
     service_name = f'{name}.{dns_type}'
     if name == 'id0':
         return ServiceInfo(
             service_type,
             service_name,
             addresses=[inet_aton('0.0.0.0')],
             properties={
                 b'ID': b'id0',
                 b'HW': b'Spark 3',
             },
         )
     if name == 'id1':
         return ServiceInfo(
             service_type,
             service_name,
             server=f'{name}.local.',
             addresses=[inet_aton('1.2.3.4')],
             port=1234,
             properties={
                 b'ID': b'id1',
                 b'HW': b'Spark 3',
             },
         )
     if name == 'id2':
         return ServiceInfo(
             service_type,
             service_name,
             server=f'{name}.local.',
             addresses=[inet_aton('4.3.2.1')],
             port=4321,
             properties={
                 b'ID': b'id2',
                 b'HW': b'Spark 4',
             },
         )
Example #17
0
    def register_service(self,
                         port: Optional[int] = None,
                         name: Optional[str] = None,
                         udp: bool = False):
        """
        Initialize the Zeroconf service configuration for this backend.
        """
        try:
            from zeroconf import ServiceInfo, Zeroconf
            from platypush.plugins.zeroconf import ZeroconfListener
        except ImportError:
            self.logger.warning(
                'zeroconf package not available, service discovery will be disabled.'
            )
            return

        self.zeroconf = Zeroconf()
        srv_desc = {
            'name': 'Platypush',
            'vendor': 'Platypush',
            'version': __version__,
        }

        name = name or re.sub(r'Backend$', '', self.__class__.__name__).lower()
        srv_type = '_platypush-{name}._{proto}.local.'.format(
            name=name, proto='udp' if udp else 'tcp')
        srv_name = '{host}.{type}'.format(host=self.device_id, type=srv_type)

        if port:
            srv_port = port
        else:
            srv_port = self.port if hasattr(self, 'port') else None

        self.zeroconf_info = ServiceInfo(
            srv_type,
            srv_name,
            addresses=[socket.inet_aton(self._get_ip())],
            port=srv_port,
            weight=0,
            priority=0,
            properties=srv_desc)

        self.zeroconf.register_service(self.zeroconf_info)
        self.bus.post(
            ZeroconfServiceAddedEvent(
                service_type=srv_type,
                service_name=srv_name,
                service_info=ZeroconfListener.parse_service_info(
                    self.zeroconf_info)))
Example #18
0
async def test_find_with_device(mock_zeroconf):
    desc = {b"id": b"00:00:02:00:00:02"}
    info = ServiceInfo(
        "_hap._tcp.local.",
        "foo1._hap._tcp.local.",
        addresses=[socket.inet_aton("127.0.0.1")],
        port=1234,
        properties=desc,
        weight=0,
        priority=0,
    )
    mock_zeroconf.get_service_info.return_value = info

    result = await async_find_device_ip_and_port("00:00:02:00:00:02", 0)
    assert result == ("127.0.0.1", 1234)
Example #19
0
 def update_txt(self, txt):
     args = list(self.args)
     args[6] = self.txt_rec(txt)
     self.args = tuple(args)
     si = ServiceInfo(*self.args)
     try:
         self.zeroconf.update_service(si)
         self.service = si
     except KeyError as e:
         #probably a race condition with cleanup
         log("update_txt(%s)", txt, exc_info=True)
         log.warn("Warning: failed to update service")
         log.warn(" %s", e)
     except Exception:
         log.error("Error: failed to update service", exc_info=True)
Example #20
0
    def start_zeroconf(self):
        self.zeroconf = Zeroconf()

        self.service_ident = auth.get_singleton().get_ident()
        self.service_name = "%s.%s" % (self.service_ident, SERVICE_TYPE)

        self.info = ServiceInfo(SERVICE_TYPE,
                                self.service_name,
                                socket.inet_aton(util.get_ip()),
                                prefs.get_port(),
                                properties={'hostname': util.get_hostname()})

        self.zeroconf.register_service(self.info)

        return False
Example #21
0
def get_service_info_mock(service_type, name):
    """Return service info for get_service_info."""
    return ServiceInfo(
        service_type,
        name,
        address=b"\n\x00\x00\x14",
        port=80,
        weight=0,
        priority=0,
        server="name.local.",
        properties={
            b"macaddress": b"ABCDEF012345",
            b"non-utf8-value": b"ABCDEF\x8a"
        },
    )
Example #22
0
        def setup_discovery():
            zeroconf_type = "_hue._tcp.local."

            info = ServiceInfo(
                zeroconf_type,
                name=
                f"Philips Hue - {self.config.bridge_id[-6:]}.{zeroconf_type}",
                addresses=[get_ip_pton()],
                port=80,
                properties={
                    "bridgeid": self.config.bridge_id,
                    "modelid": self.config.definitions["bridge"]["modelid"],
                },
            )
            zeroconf.register_service(info)
Example #23
0
def register_zeroconf_service() -> Tuple[Zeroconf, ServiceInfo]:
    ip = get_ip()

    if not ip:
        raise ValueError("Can't obtain IP address")

    info = ServiceInfo(
        "_grpc._tcp.local.",
        f"Input Server ({socket.gethostname()})._grpc._tcp.local.",
        addresses=[socket.inet_aton(ip)],
        port=17863)

    zeroconf = Zeroconf(ip_version=IPVersion.All)
    zeroconf.register_service(info)
    return zeroconf, info
Example #24
0
    def verify_name_change(self, zc, type_, name, number_hosts):
        desc = {'path': '/~paulsm/'}
        info_service = ServiceInfo(
            type_,
            '%s.%s' % (name, type_),
            80,
            0,
            0,
            desc,
            "ash-2.local.",
            addresses=[socket.inet_aton("10.0.1.2")],
        )

        # verify name conflict
        self.assertRaises(r.NonUniqueNameException, zc.register_service,
                          info_service)

        # verify no name conflict https://tools.ietf.org/html/rfc6762#section-6.6
        zc.register_service(info_service, cooperating_responders=True)

        # Create a new object since allow_name_change will mutate the
        # original object and then we will have the wrong service
        # in the registry
        info_service2 = ServiceInfo(
            type_,
            '%s.%s' % (name, type_),
            80,
            0,
            0,
            desc,
            "ash-2.local.",
            addresses=[socket.inet_aton("10.0.1.2")],
        )
        zc.register_service(info_service2, allow_name_change=True)
        assert info_service2.name.split('.')[0] == '%s-%d' % (name,
                                                              number_hosts + 1)
Example #25
0
    def __init__(self, name, address, port, description):
        self.zeroconf = Zeroconf()
        self.name = name
        self.description = description
        self.address = address
        self.port = port

        self.full_name = get_full_name(name)
        self.info = ServiceInfo(type_=TYPE,
                                name=self.full_name,
                                address=socket.inet_aton(self.address),
                                port=self.port,
                                weight=0,
                                priority=0,
                                properties=self.description)
Example #26
0
    def registerService(self, ip):
        info = ServiceInfo("_http._tcp.local.",
                           "Raspberry Pi Sleep Monitor._http._tcp.local.",
                           socket.inet_aton(ip), self.portNumber, 0, 0,
                           {}, "sleepmonitor.local.")

        zeroconf = Zeroconf()
        log("Registering zeroconf service...")
        zeroconf.register_service(info)

        def unregisterService():
            log("Unregistering zeroconf service...")
            zeroconf.unregister_service(info)

        reactor.addSystemEventTrigger('before', 'shutdown', unregisterService)
Example #27
0
def register():
    global zeroconf
    desc = {'path': 'fire.properties'}

    info = ServiceInfo(
        "_http._tcp.local.",
        "fire._http._tcp.local.",
        addresses=[socket.inet_aton("127.0.0.1")],
        port=50052,
        properties=desc,
        server="fire.local.",
    )
    zeroconf = Zeroconf()
    zeroconf.register_service(info)
    print('registered...')
Example #28
0
def setup(hass, config):
    """Set up Zeroconf and make Home Assistant discoverable."""
    from zeroconf import Zeroconf, ServiceInfo

    zeroconf = Zeroconf()

    zeroconf_name = '{}.{}'.format(hass.config.location_name, ZEROCONF_TYPE)

    requires_api_password = hass.config.api.api_password is not None
    params = {
        'version': __version__,
        'base_url': hass.config.api.base_url,
        'requires_api_password': requires_api_password,
    }

    try:
        info = ServiceInfo(
            ZEROCONF_TYPE, zeroconf_name,
            socket.inet_pton(socket.AF_INET, hass.config.api.host),
            hass.config.api.port, 0, 0, params)
    except socket.error:
        info = ServiceInfo(
            ZEROCONF_TYPE, zeroconf_name,
            socket.inet_pton(socket.AF_INET6, hass.config.api.host),
            hass.config.api.port, 0, 0, params)

    zeroconf.register_service(info)

    def stop_zeroconf(event):
        """Stop Zeroconf."""
        zeroconf.unregister_service(info)
        zeroconf.close()

    hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_zeroconf)

    return True
Example #29
0
    def startBonjour(self):
        if len(sys.argv) > 1:
            assert sys.argv[1:] == ['--debug']
            self.logging.getLogger('zeroconf').setLevel(logging.DEBUG)

        #desc = {'path': '/~paulsm/'}

        self.info = ServiceInfo("_dartsconnect._tcp.local.",
                           "Dartboard._dartsconnect._tcp.local.",
                           socket.inet_aton(self.ip), self.port, 0, 0,
                           {}, None)

        self.zeroconf = Zeroconf()
        print("DartsConnectBonjour --> DartsConnect service registered")
        self.zeroconf.register_service(self.info)
Example #30
0
def mrp_service(service_name, atv_name, address):
    """Create a MediaRemote service simulating an Apple TV."""
    props = {
        b'ModelName': b'Mac',
        b'SystemBuildVersion': b'16G29',
        b'Name': atv_name,
        b'AllowPairing': b'YES',
        b'UniqueIdentifier': b'4EE5AF58-7E5D-465A-935E-82E4DB74385D'
    }

    return ServiceInfo('_mediaremotetv._tcp.local.',
                       service_name + '._mediaremotetv._tcp.local.',
                       address=address,
                       port=49152,
                       properties=props)
    def get_service_info(self):

        type_ = "_ewelink._tcp.local."
        registration_name = "eWeLink_%s.%s" % (self._name, type_)

        service_info = ServiceInfo(
            type_,
            registration_name,
            socket.inet_aton(self._ip),
            port=self._port,
            properties=self._properties,
            server="eWeLink_" + self._name + ".local.",
        )

        return service_info
Example #32
0
    def register_mdns(self):
        logging.info("registering MDNS")
        desc = {'path': '/'}
        self.zeroconf_info = \
            ServiceInfo("_http._tcp.local.",
                        "spotify-registration._http._tcp.local.",
                        socket.inet_aton(get_ip()),
                        MYSERVER_PORT_NUMBER,
                        0,
                        0,
                        desc, "spotify-registration.local.")

        self.zeroconf = Zeroconf()
        logging.info("Registration of spotify-registration.local. in mDNS")
        self.zeroconf.register_service(self.zeroconf_info)