Rework PS owner service handling to use avahi flags for local services
This commit is contained in:
parent
4ae80802ce
commit
f205e8c67b
@ -287,9 +287,9 @@ class Buddy(object):
|
|||||||
class Owner(Buddy):
|
class Owner(Buddy):
|
||||||
"""Class representing the owner of the machine. This is the client
|
"""Class representing the owner of the machine. This is the client
|
||||||
portion of the Owner, paired with the server portion in Owner.py."""
|
portion of the Owner, paired with the server portion in Owner.py."""
|
||||||
def __init__(self, ps, bus_name, object_id, nick):
|
def __init__(self, ps, bus_name, object_id):
|
||||||
Buddy.__init__(self, bus_name, object_id, None)
|
Buddy.__init__(self, bus_name, object_id, None)
|
||||||
self._nick_name = nick
|
self._nick_name = env.get_nick_name()
|
||||||
self._color = env.get_color()
|
self._color = env.get_color()
|
||||||
self._ps = ps
|
self._ps = ps
|
||||||
|
|
||||||
@ -303,9 +303,12 @@ class Owner(Buddy):
|
|||||||
# service added to the Owner determines the owner's address
|
# service added to the Owner determines the owner's address
|
||||||
source_addr = service.get_source_address()
|
source_addr = service.get_source_address()
|
||||||
if self._address is None:
|
if self._address is None:
|
||||||
if self._ps.is_local_ip_address(source_addr):
|
if service.is_local():
|
||||||
self._address = source_addr
|
self._address = source_addr
|
||||||
self._dbus_helper.PropertyChanged(['ip4_address'])
|
self._dbus_helper.PropertyChanged(['ip4_address'])
|
||||||
|
logging.debug("Adding owner service %s.%s at %s:%d." % (service.get_name(),
|
||||||
|
service.get_type(), service.get_source_address(),
|
||||||
|
service.get_port()))
|
||||||
return Buddy.add_service(self, service)
|
return Buddy.add_service(self, service)
|
||||||
|
|
||||||
def is_owner(self):
|
def is_owner(self):
|
||||||
|
@ -4,32 +4,15 @@ import Service
|
|||||||
import Activity
|
import Activity
|
||||||
import random
|
import random
|
||||||
import logging
|
import logging
|
||||||
from sugar import env
|
|
||||||
from sugar import util
|
from sugar import util
|
||||||
|
|
||||||
|
|
||||||
def _get_local_ip_address(ifname):
|
_SA_UNRESOLVED = 0
|
||||||
"""Call Linux specific bits to retrieve our own IP address."""
|
_SA_RESOLVE_PENDING = 1
|
||||||
import socket
|
_SA_RESOLVED = 2
|
||||||
import sys
|
|
||||||
import fcntl
|
|
||||||
|
|
||||||
addr = None
|
|
||||||
SIOCGIFADDR = 0x8915
|
|
||||||
sockfd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
try:
|
|
||||||
ifreq = (ifname + '\0'*32)[:32]
|
|
||||||
result = fcntl.ioctl(sockfd.fileno(), SIOCGIFADDR, ifreq)
|
|
||||||
addr = socket.inet_ntoa(result[20:24])
|
|
||||||
except IOError, exc:
|
|
||||||
print "Error getting IP address: %s" % exc
|
|
||||||
sockfd.close()
|
|
||||||
return addr
|
|
||||||
|
|
||||||
|
|
||||||
class ServiceAdv(object):
|
class ServiceAdv(object):
|
||||||
"""Wrapper class to track services from Avahi."""
|
"""Wrapper class to track services from Avahi."""
|
||||||
def __init__(self, interface, protocol, name, stype, domain):
|
def __init__(self, interface, protocol, name, stype, domain, local):
|
||||||
self._interface = interface
|
self._interface = interface
|
||||||
self._protocol = protocol
|
self._protocol = protocol
|
||||||
if type(name) != type(u""):
|
if type(name) != type(u""):
|
||||||
@ -42,7 +25,10 @@ class ServiceAdv(object):
|
|||||||
raise ValueError("service advertisement domain must be unicode.")
|
raise ValueError("service advertisement domain must be unicode.")
|
||||||
self._domain = domain
|
self._domain = domain
|
||||||
self._service = None
|
self._service = None
|
||||||
self._resolved = False
|
if type(local) != type(False):
|
||||||
|
raise ValueError("local must be a boolean.")
|
||||||
|
self._local = local
|
||||||
|
self._state = _SA_UNRESOLVED
|
||||||
|
|
||||||
def interface(self):
|
def interface(self):
|
||||||
return self._interface
|
return self._interface
|
||||||
@ -54,16 +40,21 @@ class ServiceAdv(object):
|
|||||||
return self._stype
|
return self._stype
|
||||||
def domain(self):
|
def domain(self):
|
||||||
return self._domain
|
return self._domain
|
||||||
|
def is_local(self):
|
||||||
|
return self._local
|
||||||
def service(self):
|
def service(self):
|
||||||
return self._service
|
return self._service
|
||||||
def set_service(self, service):
|
def set_service(self, service):
|
||||||
if not isinstance(service, Service.Service):
|
if not isinstance(service, Service.Service):
|
||||||
raise ValueError("must be a valid service.")
|
raise ValueError("must be a valid service.")
|
||||||
self._service = service
|
self._service = service
|
||||||
def resolved(self):
|
def state(self):
|
||||||
return self._resolved
|
return self._state
|
||||||
def set_resolved(self, resolved):
|
def set_state(self, state):
|
||||||
self._resolved = resolved
|
if state == _SA_RESOLVE_PENDING:
|
||||||
|
if self._state == _SA_RESOLVED:
|
||||||
|
raise ValueError("Can't reset to resolve pending from resolved.")
|
||||||
|
self._state = state
|
||||||
|
|
||||||
|
|
||||||
_PRESENCE_SERVICE = "org.laptop.Presence"
|
_PRESENCE_SERVICE = "org.laptop.Presence"
|
||||||
@ -246,10 +237,9 @@ class PresenceService(object):
|
|||||||
self._services = {} # (name, type) -> Service
|
self._services = {} # (name, type) -> Service
|
||||||
self._activities = {} # activity id -> Activity
|
self._activities = {} # activity id -> Activity
|
||||||
|
|
||||||
# Keep track of stuff we're already browsing with ZC
|
# Keep track of stuff we're already browsing
|
||||||
self._service_type_browsers = {}
|
self._service_type_browsers = {}
|
||||||
self._service_browsers = {}
|
self._service_browsers = {}
|
||||||
self._resolve_queue = [] # Track resolve requests
|
|
||||||
|
|
||||||
# Resolved service list
|
# Resolved service list
|
||||||
self._service_advs = []
|
self._service_advs = []
|
||||||
@ -263,10 +253,9 @@ class PresenceService(object):
|
|||||||
self._dbus_helper = PresenceServiceDBusHelper(self, self._bus_name)
|
self._dbus_helper = PresenceServiceDBusHelper(self, self._bus_name)
|
||||||
|
|
||||||
# Our owner object
|
# Our owner object
|
||||||
owner_nick = env.get_nick_name()
|
|
||||||
objid = self._get_next_object_id()
|
objid = self._get_next_object_id()
|
||||||
self._owner = Buddy.Owner(self, self._bus_name, objid, owner_nick)
|
self._owner = Buddy.Owner(self, self._bus_name, objid)
|
||||||
self._buddies[owner_nick] = self._owner
|
self._buddies[self._owner.get_name()] = self._owner
|
||||||
|
|
||||||
self._started = False
|
self._started = False
|
||||||
|
|
||||||
@ -341,13 +330,10 @@ class PresenceService(object):
|
|||||||
def get_owner(self):
|
def get_owner(self):
|
||||||
return self._owner
|
return self._owner
|
||||||
|
|
||||||
def is_local_ip_address(self, address):
|
def _find_service_adv(self, interface=None, protocol=None, name=None,
|
||||||
if address in self._local_addrs.values():
|
stype=None, domain=None, local=None):
|
||||||
return True
|
"""Search a list of service advertisements for ones matching
|
||||||
return False
|
certain criteria."""
|
||||||
|
|
||||||
def _find_service_adv(self, interface=None, protocol=None, name=None, stype=None, domain=None):
|
|
||||||
"""Search a list of service advertisements for ones matching certain criteria."""
|
|
||||||
adv_list = []
|
adv_list = []
|
||||||
for adv in self._service_advs:
|
for adv in self._service_advs:
|
||||||
if interface and adv.interface() != interface:
|
if interface and adv.interface() != interface:
|
||||||
@ -360,10 +346,12 @@ class PresenceService(object):
|
|||||||
continue
|
continue
|
||||||
if domain and adv.domain() != domain:
|
if domain and adv.domain() != domain:
|
||||||
continue
|
continue
|
||||||
|
if local is not None and adv.is_local() != local:
|
||||||
|
continue
|
||||||
adv_list.append(adv)
|
adv_list.append(adv)
|
||||||
return adv_list
|
return adv_list
|
||||||
|
|
||||||
def _handle_new_service_for_buddy(self, service):
|
def _handle_new_service_for_buddy(self, service, local):
|
||||||
"""Deal with a new discovered service object."""
|
"""Deal with a new discovered service object."""
|
||||||
# Once a service is resolved, we match it up to an existing buddy,
|
# Once a service is resolved, we match it up to an existing buddy,
|
||||||
# or create a new Buddy if this is the first service known about the buddy
|
# or create a new Buddy if this is the first service known about the buddy
|
||||||
@ -420,21 +408,17 @@ class PresenceService(object):
|
|||||||
self._dbus_helper.ActivityDisappeared(activity.object_path())
|
self._dbus_helper.ActivityDisappeared(activity.object_path())
|
||||||
del self._activities[actid]
|
del self._activities[actid]
|
||||||
|
|
||||||
def _resolve_service_reply_cb(self, interface, protocol, full_name, stype, domain, host, aprotocol, address, port, txt, flags):
|
def _resolve_service_reply_cb(self, adv, interface, protocol, full_name,
|
||||||
"""When the service discovery finally gets here, we've got enough information about the
|
stype, domain, host, aprotocol, address, port, txt, flags):
|
||||||
service to assign it to a buddy."""
|
"""When the service discovery finally gets here, we've got enough
|
||||||
logging.debug("resolved service '%s' type '%s' domain '%s' to %s:%s" % (full_name, stype, domain, address, port))
|
information about the service to assign it to a buddy."""
|
||||||
|
logging.debug("Resolved service '%s' type '%s' domain '%s' to " \
|
||||||
|
" %s:%s" % (full_name, stype, domain, address, port))
|
||||||
|
|
||||||
# If this service was previously unresolved, remove it from the
|
if not adv in self._service_advs:
|
||||||
# unresolved list
|
return False
|
||||||
adv_list = self._find_service_adv(interface=interface, protocol=protocol,
|
if adv.state() != _SA_RESOLVED:
|
||||||
name=full_name, stype=stype, domain=domain)
|
|
||||||
if not adv_list:
|
|
||||||
return False
|
return False
|
||||||
adv = adv_list[0]
|
|
||||||
adv.set_resolved(True)
|
|
||||||
if adv in self._resolve_queue:
|
|
||||||
self._resolve_queue.remove(adv)
|
|
||||||
|
|
||||||
# See if we know about this service already
|
# See if we know about this service already
|
||||||
key = (full_name, stype)
|
key = (full_name, stype)
|
||||||
@ -442,12 +426,12 @@ class PresenceService(object):
|
|||||||
objid = self._get_next_object_id()
|
objid = self._get_next_object_id()
|
||||||
service = Service.Service(self._bus_name, objid, name=full_name,
|
service = Service.Service(self._bus_name, objid, name=full_name,
|
||||||
stype=stype, domain=domain, address=address, port=port,
|
stype=stype, domain=domain, address=address, port=port,
|
||||||
properties=txt, source_address=address)
|
properties=txt, source_address=address, local=adv.is_local())
|
||||||
self._services[key] = service
|
self._services[key] = service
|
||||||
else:
|
else:
|
||||||
# Already tracking this service; likely we were the one that shared it
|
# Already tracking this service; likely we were the one that shared it
|
||||||
# in the first place, and therefore the source address would have been
|
# in the first place, and therefore the source address would not have
|
||||||
# set yet
|
# been set yet
|
||||||
service = self._services[key]
|
service = self._services[key]
|
||||||
if not service.get_source_address():
|
if not service.get_source_address():
|
||||||
service.set_source_address(address)
|
service.set_source_address(address)
|
||||||
@ -456,51 +440,44 @@ class PresenceService(object):
|
|||||||
adv.set_service(service)
|
adv.set_service(service)
|
||||||
|
|
||||||
# Merge the service into our buddy and activity lists, if needed
|
# Merge the service into our buddy and activity lists, if needed
|
||||||
buddy = self._handle_new_service_for_buddy(service)
|
buddy = self._handle_new_service_for_buddy(service, adv.is_local())
|
||||||
if buddy and service.get_activity_id():
|
if buddy and service.get_activity_id():
|
||||||
self._handle_new_activity_service(service)
|
self._handle_new_activity_service(service)
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _resolve_service_reply_cb_glue(self, interface, protocol, name, stype, domain, host, aprotocol, address, port, txt, flags):
|
def _resolve_service_reply_cb_glue(self, adv, interface, protocol, name,
|
||||||
gobject.idle_add(self._resolve_service_reply_cb, interface, protocol,
|
stype, domain, host, aprotocol, address, port, txt, flags):
|
||||||
name, stype, domain, host, aprotocol, address, port, txt, flags)
|
adv.set_state(_SA_RESOLVED)
|
||||||
|
gobject.idle_add(self._resolve_service_reply_cb, adv, interface,
|
||||||
|
protocol, name, stype, domain, host, aprotocol, address,
|
||||||
|
port, txt, flags)
|
||||||
|
|
||||||
def _resolve_service_error_handler(self, err):
|
def _resolve_service_error_handler(self, adv, err):
|
||||||
logging.error("error resolving service: %s" % err)
|
adv.set_state(_SA_UNRESOLVED)
|
||||||
|
logging.error("Error resolving service %s.%s: %s" % (adv.name(), adv.stype(), err))
|
||||||
|
|
||||||
def _resolve_service(self, adv):
|
def _resolve_service(self, adv):
|
||||||
"""Resolve and lookup a ZeroConf service to obtain its address and TXT records."""
|
"""Resolve and lookup a ZeroConf service to obtain its address and TXT records."""
|
||||||
# Ask avahi to resolve this particular service
|
# Ask avahi to resolve this particular service
|
||||||
logging.debug('resolving service %s %s' % (adv.name(), adv.stype()))
|
|
||||||
self._mdns_service.ResolveService(int(adv.interface()), int(adv.protocol()), adv.name(),
|
self._mdns_service.ResolveService(int(adv.interface()), int(adv.protocol()), adv.name(),
|
||||||
adv.stype(), adv.domain(), avahi.PROTO_UNSPEC, dbus.UInt32(0),
|
adv.stype(), adv.domain(), avahi.PROTO_UNSPEC, dbus.UInt32(0),
|
||||||
reply_handler=self._resolve_service_reply_cb_glue,
|
reply_handler=lambda *args: self._resolve_service_reply_cb_glue(adv, *args),
|
||||||
error_handler=self._resolve_service_error_handler)
|
error_handler=lambda *args: self._resolve_service_error_handler(adv, *args))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _service_appeared_cb(self, interface, protocol, full_name, stype, domain, flags):
|
def _service_appeared_cb(self, interface, protocol, full_name, stype, domain, flags):
|
||||||
logging.debug("found service '%s' (%d) of type '%s' in domain '%s' on %i.%i." % (full_name, flags, stype, domain, interface, protocol))
|
local = flags & avahi.LOOKUP_RESULT_OUR_OWN > 0
|
||||||
|
|
||||||
# Add the service to our unresolved services list
|
|
||||||
adv_list = self._find_service_adv(interface=interface, protocol=protocol,
|
adv_list = self._find_service_adv(interface=interface, protocol=protocol,
|
||||||
name=full_name, stype=stype, domain=domain)
|
name=full_name, stype=stype, domain=domain, local=local)
|
||||||
adv = None
|
adv = None
|
||||||
if not adv_list:
|
if not adv_list:
|
||||||
adv = ServiceAdv(interface=interface, protocol=protocol, name=full_name,
|
adv = ServiceAdv(interface=interface, protocol=protocol, name=full_name,
|
||||||
stype=stype, domain=domain)
|
stype=stype, domain=domain, local=local)
|
||||||
self._service_advs.append(adv)
|
self._service_advs.append(adv)
|
||||||
else:
|
else:
|
||||||
adv = adv_list[0]
|
adv = adv_list[0]
|
||||||
|
|
||||||
# Find out the IP address of this interface, if we haven't already
|
|
||||||
if interface not in self._local_addrs.keys():
|
|
||||||
ifname = self._mdns_service.GetNetworkInterfaceNameByIndex(interface)
|
|
||||||
if ifname:
|
|
||||||
addr = _get_local_ip_address(ifname)
|
|
||||||
if addr:
|
|
||||||
self._local_addrs[interface] = addr
|
|
||||||
|
|
||||||
# Decompose service name if we can
|
# Decompose service name if we can
|
||||||
(actid, buddy_name) = Service.decompose_service_name(full_name)
|
(actid, buddy_name) = Service.decompose_service_name(full_name)
|
||||||
|
|
||||||
@ -508,11 +485,12 @@ class PresenceService(object):
|
|||||||
resolve = False
|
resolve = False
|
||||||
if actid is not None or stype in self._registered_service_types:
|
if actid is not None or stype in self._registered_service_types:
|
||||||
resolve = True
|
resolve = True
|
||||||
if resolve and not adv in self._resolve_queue:
|
if resolve and adv.state() == _SA_UNRESOLVED:
|
||||||
self._resolve_queue.append(adv)
|
logging.debug("Found '%s' (%d) of type '%s' in domain" \
|
||||||
|
" '%s' on %i.%i; will resolve." % (full_name, flags, stype,
|
||||||
|
domain, interface, protocol))
|
||||||
|
adv.set_state(_SA_RESOLVE_PENDING)
|
||||||
gobject.idle_add(self._resolve_service, adv)
|
gobject.idle_add(self._resolve_service, adv)
|
||||||
else:
|
|
||||||
logging.debug("Do not resolve service '%s' of type '%s', we don't care about it." % (full_name, stype))
|
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -520,22 +498,27 @@ class PresenceService(object):
|
|||||||
gobject.idle_add(self._service_appeared_cb, interface, protocol, name, stype, domain, flags)
|
gobject.idle_add(self._service_appeared_cb, interface, protocol, name, stype, domain, flags)
|
||||||
|
|
||||||
def _service_disappeared_cb(self, interface, protocol, full_name, stype, domain, flags):
|
def _service_disappeared_cb(self, interface, protocol, full_name, stype, domain, flags):
|
||||||
logging.debug("service '%s' of type '%s' in domain '%s' on %i.%i disappeared." % (full_name, stype, domain, interface, protocol))
|
local = flags & avahi.LOOKUP_RESULT_OUR_OWN > 0
|
||||||
|
|
||||||
# If it's an unresolved service, remove it from our unresolved list
|
# If it's an unresolved service, remove it from our unresolved list
|
||||||
adv_list = self._find_service_adv(interface=interface, protocol=protocol,
|
adv_list = self._find_service_adv(interface=interface, protocol=protocol,
|
||||||
name=full_name, stype=stype, domain=domain)
|
name=full_name, stype=stype, domain=domain, local=local)
|
||||||
if not adv_list:
|
if not adv_list:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Get the service object; if none, we have nothing left to do
|
# Get the service object; if none, we have nothing left to do
|
||||||
adv = adv_list[0]
|
adv = adv_list[0]
|
||||||
if adv in self._resolve_queue:
|
|
||||||
self._resolve_queue.remove(adv)
|
|
||||||
service = adv.service()
|
service = adv.service()
|
||||||
|
self._service_advs.remove(adv)
|
||||||
|
del adv
|
||||||
if not service:
|
if not service:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
logging.debug("Service %s.%s on %i.%i disappeared." % (full_name,
|
||||||
|
stype, domain, interface, protocol))
|
||||||
|
|
||||||
|
self._dbus_helper.ServiceDisappeared(service.object_path())
|
||||||
|
self._handle_remove_activity_service(service)
|
||||||
|
|
||||||
# Decompose service name if we can
|
# Decompose service name if we can
|
||||||
(actid, buddy_name) = Service.decompose_service_name(full_name)
|
(actid, buddy_name) = Service.decompose_service_name(full_name)
|
||||||
|
|
||||||
@ -546,8 +529,6 @@ class PresenceService(object):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
buddy.remove_service(service)
|
buddy.remove_service(service)
|
||||||
self._dbus_helper.ServiceDisappeared(service.object_path())
|
|
||||||
self._handle_remove_activity_service(service)
|
|
||||||
if not buddy.is_valid():
|
if not buddy.is_valid():
|
||||||
self._dbus_helper.BuddyDisappeared(buddy.object_path())
|
self._dbus_helper.BuddyDisappeared(buddy.object_path())
|
||||||
del self._buddies[buddy_name]
|
del self._buddies[buddy_name]
|
||||||
@ -567,7 +548,6 @@ class PresenceService(object):
|
|||||||
s_browser = self._mdns_service.ServiceBrowserNew(interface, protocol, stype, domain, dbus.UInt32(0))
|
s_browser = self._mdns_service.ServiceBrowserNew(interface, protocol, stype, domain, dbus.UInt32(0))
|
||||||
browser_obj = dbus.Interface(self._system_bus.get_object(avahi.DBUS_NAME, s_browser),
|
browser_obj = dbus.Interface(self._system_bus.get_object(avahi.DBUS_NAME, s_browser),
|
||||||
avahi.DBUS_INTERFACE_SERVICE_BROWSER)
|
avahi.DBUS_INTERFACE_SERVICE_BROWSER)
|
||||||
logging.debug("now browsing for services of type '%s' in domain '%s' on %i.%i ..." % (stype, domain, interface, protocol))
|
|
||||||
browser_obj.connect_to_signal('ItemNew', self._service_appeared_cb_glue)
|
browser_obj.connect_to_signal('ItemNew', self._service_appeared_cb_glue)
|
||||||
browser_obj.connect_to_signal('ItemRemove', self._service_disappeared_cb_glue)
|
browser_obj.connect_to_signal('ItemRemove', self._service_disappeared_cb_glue)
|
||||||
|
|
||||||
@ -600,7 +580,7 @@ class PresenceService(object):
|
|||||||
raise Exception("Avahi does not appear to be running. '%s'" % str_exc)
|
raise Exception("Avahi does not appear to be running. '%s'" % str_exc)
|
||||||
else:
|
else:
|
||||||
raise exc
|
raise exc
|
||||||
logging.debug("now browsing domain '%s' on %i.%i ..." % (domain, interface, protocol))
|
logging.debug("Browsing domain '%s' on %i.%i ..." % (domain, interface, protocol))
|
||||||
browser_obj.connect_to_signal('ItemNew', self._new_service_type_cb_glue)
|
browser_obj.connect_to_signal('ItemNew', self._new_service_type_cb_glue)
|
||||||
self._service_type_browsers[(interface, protocol, domain)] = browser_obj
|
self._service_type_browsers[(interface, protocol, domain)] = browser_obj
|
||||||
return False
|
return False
|
||||||
@ -667,7 +647,7 @@ class PresenceService(object):
|
|||||||
objid = self._get_next_object_id()
|
objid = self._get_next_object_id()
|
||||||
service = Service.Service(self._bus_name, objid, name=name,
|
service = Service.Service(self._bus_name, objid, name=name,
|
||||||
stype=stype, domain=domain, address=address, port=port,
|
stype=stype, domain=domain, address=address, port=port,
|
||||||
properties=properties, source_address=None)
|
properties=properties, source_address=None, local=True)
|
||||||
self._services[(name, stype)] = service
|
self._services[(name, stype)] = service
|
||||||
port = service.get_port()
|
port = service.get_port()
|
||||||
|
|
||||||
|
@ -104,7 +104,8 @@ class Service(object):
|
|||||||
"""Encapsulates information about a specific ZeroConf/mDNS
|
"""Encapsulates information about a specific ZeroConf/mDNS
|
||||||
service as advertised on the network."""
|
service as advertised on the network."""
|
||||||
def __init__(self, bus_name, object_id, name, stype, domain=u"local",
|
def __init__(self, bus_name, object_id, name, stype, domain=u"local",
|
||||||
address=None, port=-1, properties=None, source_address=None):
|
address=None, port=-1, properties=None, source_address=None,
|
||||||
|
local=False):
|
||||||
if not bus_name:
|
if not bus_name:
|
||||||
raise ValueError("DBus bus name must be valid")
|
raise ValueError("DBus bus name must be valid")
|
||||||
if not object_id or type(object_id) != type(1):
|
if not object_id or type(object_id) != type(1):
|
||||||
@ -138,6 +139,7 @@ class Service(object):
|
|||||||
self._properties = {}
|
self._properties = {}
|
||||||
self.set_properties(properties)
|
self.set_properties(properties)
|
||||||
self._avahi_entry_group = None
|
self._avahi_entry_group = None
|
||||||
|
self._local = local
|
||||||
|
|
||||||
# Source address is the unicast source IP
|
# Source address is the unicast source IP
|
||||||
self._source_address = None
|
self._source_address = None
|
||||||
@ -180,6 +182,9 @@ class Service(object):
|
|||||||
raise RuntimeError("Can only set a service's owner once")
|
raise RuntimeError("Can only set a service's owner once")
|
||||||
self._owner = owner
|
self._owner = owner
|
||||||
|
|
||||||
|
def is_local(self):
|
||||||
|
return self._local
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""Return the service's name, usually that of the
|
"""Return the service's name, usually that of the
|
||||||
buddy who provides it."""
|
buddy who provides it."""
|
||||||
|
Loading…
Reference in New Issue
Block a user