Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 import rospy
00012 import rocon_gateway
00013 import redis
00014
00015 import zeroconf_msgs.srv
00016 import gateway_msgs.msg as gateway_msgs
00017
00018
00019
00020
00021
00022
00023 class HubConnector(object):
00024 hub_service = "_ros-multimaster-hub._tcp"
00025 is_connected = False
00026
00027 def __init__(self, whitelist, blacklist, is_zeroconf, connectFunc):
00028
00029 self.param = {} if self.param == None else self.param
00030
00031 self.param['whitelist'] = whitelist
00032 self.param['blacklist'] = blacklist
00033 self.connectToHub = connectFunc
00034
00035 self._zeroconf_services = {}
00036 if is_zeroconf:
00037 self._zeroconf_services = rocon_gateway.zeroconf.setupRosServices()
00038
00039 def connect(self, hub_uri=None):
00040 if hub_uri:
00041 return self.direct_connect(hub_uri)
00042 else:
00043 return self.zeroconfConnect()
00044
00045 def direct_connect(self, hub_uri):
00046 '''
00047 If hub_uri is provided, attempt a direct connection
00048 '''
00049 (ip, port) = hub_uri.split(':')
00050
00051 if self._connect(ip, int(port)) == gateway_msgs.Result.SUCCESS:
00052 rospy.loginfo("HubConnector : made direct connection to the hub [%s]" % hub_uri)
00053 self.is_connected = True
00054 return True
00055 else:
00056 rospy.logwarn("HubConnector : failed direct connection attempt to hub [%s]" % hub_uri)
00057 return False
00058
00059 def zeroconf_connect(self):
00060 while not rospy.is_shutdown() and not self.is_connected:
00061 rospy.sleep(1.0)
00062 if self._zeroconf_services:
00063 found_hubs = self._scan_for_zeroconf_hubs()
00064 for (ip, port) in found_hubs:
00065 rospy.loginfo("HubConnector : discovered hub zeroconf service at " + str(ip) + ":" + str(port))
00066 if self._connect(ip, port) == gateway_msgs.Result.SUCCESS:
00067 self.is_connected = True
00068 break
00069 rospy.logdebug("HubConnector : waiting for hub uri input")
00070
00071 return self.is_connected
00072
00073 def _scan_for_zeroconf_hubs(self):
00074 '''
00075 Does a quick scan on zeroconf for gateway hubs. If new ones are
00076 found, and it is not on the blacklist, it attempts a connection.
00077
00078 This gets run in the pre-spin part of the spin loop.
00079
00080 @param previously_found_hubs: zeroconf names of previously scanned hubs
00081 @type previously_found_hubs: list of str
00082 '''
00083
00084 previously_found_hubs = []
00085 found_hubs = []
00086
00087 req = zeroconf_msgs.srv.ListDiscoveredServicesRequest()
00088 req.service_type = rocon_gateway.zeroconf.gateway_hub_service
00089 resp = self._zeroconf_services["list_discovered_services"](req)
00090 rospy.logdebug("HubConnector : checking for autodiscovered gateway hubs")
00091 new_services = lambda l1,l2: [x for x in l1 if x not in l2]
00092
00093 for service in new_services(resp.services,previously_found_hubs):
00094 (ip, port) = rocon_gateway.zeroconf.resolve_address(service)
00095 found_hubs.append((ip,port))
00096
00097 return found_hubs
00098
00099 def _connect(self,ip,port):
00100 if self.is_connected:
00101 rospy.logwarn("HubConnector : gateway is already connected, aborting connection attempt.")
00102 return gateway_msgs.Result.HUB_CONNECTION_ALREADY_EXISTS
00103 try:
00104 hub_name = rocon_gateway.resolve_hub(ip,port)
00105 rospy.loginfo("HubConnector : resolved hub name [%s].", hub_name)
00106 except redis.exceptions.ConnectionError:
00107 rospy.logerr("HubConnector : couldn't connect to the hub [%s:%s]", ip, port)
00108 return gateway_msgs.Result.HUB_CONNECTION_UNRESOLVABLE
00109 if ip in self.param['blacklist']:
00110 rospy.loginfo("HubConnector : ignoring blacklisted hub [%s]",ip)
00111 return gateway_msgs.Result.HUB_CONNECTION_BLACKLISTED
00112 elif hub_name in self.param['blacklist']:
00113 rospy.loginfo("HubConnector : ignoring blacklisted hub [%s]",hub_name)
00114 return gateway_msgs.Result.HUB_CONNECTION_BLACKLISTED
00115
00116 if (len(self.param['whitelist']) == 0) or (ip in self.param['whitelist']) or (hub_name in self.param['whitelist']):
00117 if self.connectToHub(ip,port):
00118 return gateway_msgs.Result.SUCCESS
00119 else:
00120 return gateway_msgs.Result.HUB_CONNECTION_FAILED
00121 else:
00122 rospy.loginfo("HubConnector : hub/ip not in non-empty whitelist [%s]",hub_name)
00123 return gateway_msgs.Result.HUB_CONNECTION_NOT_IN_NONEMPTY_WHITELIST