hub_connector.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # License: BSD
00004 #   https://raw.github.com/robotics-in-concert/rocon_multimaster/master/rocon_hub_client/LICENSE
00005 #
00006 
00007 ##############################################################################
00008 # Imports
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 # HubConnector
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         # Get discovered redis server list from zeroconf
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         # Handle whitelist (ip or hub name)
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


rocon_hub_client
Author(s): Jihoon
autogenerated on Tue Jan 15 2013 17:44:00