Exemplo n.º 1
0
def get_service_headers(service_name, service_uri):
    """
    Utility for connecting to a service and retrieving the TCPROS
    headers. Services currently do not declare their type with the
    master, so instead we probe the service for its headers.
    @param service_name: name of service
    @type  service_name: str
    @param service_uri: ROSRPC URI of service
    @type  service_uri: str
    @return: map of header fields
    @rtype: dict
    @raise ROSServiceException: if service has invalid information
    @raise ROSServiceIOException: if unable to communicate with service
    """
    try:
        dest_addr, dest_port = rospy.parse_rosrpc_uri(service_uri)
    except:
        raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service_name, service_uri))
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        try:
            # connect to service and probe it to get the headers
            s.settimeout(5.0)
            s.connect((dest_addr, dest_port))
            header = { 'probe':'1', 'md5sum':'*',
                       'callerid':'/rosservice', 'service':service_name}
            rosgraph.network.write_ros_handshake_header(s, header)
            return rosgraph.network.read_ros_handshake_header(s, StringIO(), 2048)
        except socket.error:
            raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service_name, service_uri))
    finally:
        if s is not None:
            s.close()
Exemplo n.º 2
0
def get_service_class(service_name):
    master = roslib.scriptutil.get_master()
    code, msg, service_uri = master.lookupService(CALLER_ID, service_name)

    dest_addr, dest_port = rospy.parse_rosrpc_uri(service_uri)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        try:
            # connect to service and probe it to get the headers
            s.settimeout(5.0)
            s.connect((dest_addr, dest_port))
            header = {
                'probe': '1',
                'md5sum': '*',
                'callerid': '/rosservice',
                'service': service_name
            }
            roslib.network.write_ros_handshake_header(s, header)
            return roslib.network.read_ros_handshake_header(
                s, cStringIO.StringIO(), 2048).get('type', None)
        except socket.error:
            raise ROSServiceIOException(
                "Unable to communicate with service [%s], address [%s]" %
                (service_name, service_uri))
    finally:
        if s is not None:
            s.close()
Exemplo n.º 3
0
    def _getServiceInfo(self, services):
        '''
        Gets service info through the RPC interface of the service.
        This method blocks until the info is retrieved or socket timeout is reached (0.5 seconds).

        :param service: the name of the service

        :type service: str

        :param uri: the uri of the service

        :type uri: str
        '''
        for (service, uri) in services.items():
            with self._lock:
                if service in self.__cached_services:
                    if time.time() - self.__cached_services[service][2] < self.MAX_PING_SEC:
                        return
            if uri is not None:
                dest_addr = dest_port = None
                try:
                    dest_addr, dest_port = rospy.parse_rosrpc_uri(uri)
                except:
                    continue
        #      raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri))
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                try:
                    # connect to service and probe it to get the headers
                    s.settimeout(0.5)
                    s.connect((dest_addr, dest_port))
                    header = {'probe': '1', 'md5sum': '*',
                              'callerid': self.ros_node_name, 'service': service}
                    roslib.network.write_ros_handshake_header(s, header)
                    buf = io.StringIO() if sys.version_info < (3, 0) else io.BytesIO()
                    stype = roslib.network.read_ros_handshake_header(s, buf, 2048)
                    with self._lock:
                        self.__new_master_state.getService(service).type = stype['type']
                        self.__cached_services[service] = (uri, stype['type'], time.time())
                except socket.error:
                    with self._lock:
                        try:
                            del self.__cached_services[service]
                        except:
                            pass
        #      raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri))
                except:
                    with self._lock:
                        self._limited_log(service, "can't get service type: %s" % traceback.format_exc(), level=rospy.DEBUG)
                    with self._lock:
                        try:
                            del self.__cached_services[service]
                        except:
                            pass
                    pass
                finally:
                    if s is not None:
                        s.close()
    def _getServiceInfo(self, services):
        '''
        Gets service info through the RPC interface of the service.
        This method blocks until the info is retrieved or socket timeout is reached (0.5 seconds).

        :param service: the name of the service

        :type service: str

        :param uri: the uri of the service

        :type uri: str
        '''
        for (service, uri) in services.items():
            with self._lock:
                if service in self.__cached_services:
                    if time.time() - self.__cached_services[service][2] < self.MAX_PING_SEC:
                        return
            if uri is not None:
                dest_addr = dest_port = None
                try:
                    dest_addr, dest_port = rospy.parse_rosrpc_uri(uri)
                except:
                    continue
        #      raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri))
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                try:
                    # connect to service and probe it to get the headers
                    s.settimeout(0.5)
                    s.connect((dest_addr, dest_port))
                    header = {'probe': '1', 'md5sum': '*',
                              'callerid': self.ros_node_name, 'service': service}
                    roslib.network.write_ros_handshake_header(s, header)
                    stype = roslib.network.read_ros_handshake_header(s, cStringIO.StringIO(), 2048)
                    with self._lock:
                        self.__new_master_state.getService(service).type = stype['type']
                        self.__cached_services[service] = (uri, stype['type'], time.time())
                except socket.error:
                    with self._lock:
                        try:
                            del self.__cached_services[service]
                        except:
                            pass
        #      raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri))
                except:
                    with self._lock:
                        self._limited_log(service, "can't get service type: %s" % traceback.format_exc(), level=rospy.DEBUG)
                    with self._lock:
                        try:
                            del self.__cached_services[service]
                        except:
                            pass
                    pass
                finally:
                    if s is not None:
                        s.close()
Exemplo n.º 5
0
    def getServiceInfo(self, services):
        '''
    Gets service info through the RPC interface of the service.
    @param service: the name of the service
    @type service: C{str}
    @param uri: the uri of the service
    @type uri: C{str}
    '''
        for (service, uri) in services.items():
            if not uri is None:
                type = dest_addr = dest_port = None
                try:
                    dest_addr, dest_port = rospy.parse_rosrpc_uri(uri)
                except:
                    #      print "ERROR while get service info"
                    continue
#          return
#      raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri))
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                try:
                    # connect to service and probe it to get the headers
                    s.settimeout(0.5)
                    s.connect((dest_addr, dest_port))
                    header = {
                        'probe': '1',
                        'md5sum': '*',
                        'callerid': rospy.get_name(),
                        'service': service
                    }
                    roslib.network.write_ros_handshake_header(s, header)
                    type = roslib.network.read_ros_handshake_header(
                        s, cStringIO.StringIO(), 2048)
                except socket.error:
                    pass
        #      raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri))
                except:
                    pass
                finally:
                    if s is not None:
                        s.close()

        self._lock.acquire(True)
        try:
            self.new_master_state.getService(service).type = type['type']
        except:
            pass
#      print "ignored:"
#      import traceback
#      traceback.print_exc()
#      print "type field in service header not available, type:", type
        self._lock.release()
Exemplo n.º 6
0
  def getServiceInfo(self, services):
    '''
    Gets service info through the RPC interface of the service.
    @param service: the name of the service
    @type service: C{str}
    @param uri: the uri of the service
    @type uri: C{str}
    '''
    for (service, uri) in services.items():
      if not uri is None:
        type = dest_addr = dest_port = None
        try:
          dest_addr, dest_port = rospy.parse_rosrpc_uri(uri)
        except:
    #      print "ERROR while get service info"
          continue
#          return
    #      raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri))
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
          # connect to service and probe it to get the headers
          s.settimeout(0.5)
          s.connect((dest_addr, dest_port))
          header = { 'probe':'1', 'md5sum':'*',
                    'callerid':rospy.get_name(), 'service':service}
          roslib.network.write_ros_handshake_header(s, header)
          type = roslib.network.read_ros_handshake_header(s, cStringIO.StringIO(), 2048)
        except socket.error:
          pass
    #      raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri))
        except:
          pass
        finally:
          if s is not None:
            s.close()

    self._lock.acquire(True)
    try:
      self.new_master_state.getService(service).type = type['type']
    except:
      pass
#      print "ignored:"
#      import traceback
#      traceback.print_exc()
#      print "type field in service header not available, type:", type 
    self._lock.release()
Exemplo n.º 7
0
def get_service_headers(service_name, service_uri):
    """
    Utility for connecting to a service and retrieving the TCPROS
    headers. Services currently do not declare their type with the
    master, so instead we probe the service for its headers.
    @param service_name: name of service
    @type  service_name: str
    @param service_uri: ROSRPC URI of service
    @type  service_uri: str
    @return: map of header fields
    @rtype: dict
    @raise ROSServiceException: if service has invalid information
    @raise ROSServiceIOException: if unable to communicate with service
    """
    try:
        dest_addr, dest_port = rospy.parse_rosrpc_uri(service_uri)
    except:
        raise ROSServiceException("service [%s] has an invalid RPC URI [%s]" %
                                  (service_name, service_uri))
    if rosgraph.network.use_ipv6():
        s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
    else:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        try:
            # connect to service and probe it to get the headers
            s.settimeout(5.0)
            s.connect((dest_addr, dest_port))
            header = {
                'probe': '1',
                'md5sum': '*',
                'callerid': '/rosservice',
                'service': service_name
            }
            rosgraph.network.write_ros_handshake_header(s, header)
            return rosgraph.network.read_ros_handshake_header(
                s, StringIO(), 2048)
        except socket.error:
            raise ROSServiceIOException(
                "Unable to communicate with service [%s], address [%s]" %
                (service_name, service_uri))
    finally:
        if s is not None:
            s.close()
 def test_parse_rosrpc_uri(self):
     from rospy.core import parse_rosrpc_uri
     valid = [('rosrpc://localhost:1234/', 'localhost', 1234), 
              ('rosrpc://localhost2:1234', 'localhost2', 1234), 
              ('rosrpc://third:1234/path/bar', 'third', 1234), 
              ('rosrpc://foo.com:1/', 'foo.com', 1),
              ('rosrpc://foo.com:1/', 'foo.com', 1)]
     for t, addr, port in valid:
         paddr, pport = rospy.core.parse_rosrpc_uri(t)
         self.assertEquals(addr, paddr)
         self.assertEquals(port, pport)
         # validate that it's a top-level API method
         self.assertEquals(rospy.core.parse_rosrpc_uri(t), rospy.parse_rosrpc_uri(t))
     invalid = ['rosrpc://:1234/', 'rosrpc://localhost', 'http://localhost:1234/']
     for i in invalid:
         try:
             parse_rosrpc_uri(i)
             self.fail("%s was an invalid rosrpc uri"%i)
         except: pass
Exemplo n.º 9
0
 def test_parse_rosrpc_uri(self):
     from rospy.core import parse_rosrpc_uri
     valid = [('rosrpc://localhost:1234/', 'localhost', 1234), 
              ('rosrpc://localhost2:1234', 'localhost2', 1234), 
              ('rosrpc://third:1234/path/bar', 'third', 1234), 
              ('rosrpc://foo.com:1/', 'foo.com', 1),
              ('rosrpc://foo.com:1/', 'foo.com', 1)]
     for t, addr, port in valid:
         paddr, pport = rospy.core.parse_rosrpc_uri(t)
         self.assertEquals(addr, paddr)
         self.assertEquals(port, pport)
         # validate that it's a top-level API method
         self.assertEquals(rospy.core.parse_rosrpc_uri(t), rospy.parse_rosrpc_uri(t))
     invalid = ['rosrpc://:1234/', 'rosrpc://localhost', 'http://localhost:1234/']
     for i in invalid:
         try:
             parse_rosrpc_uri(i)
             self.fail("%s was an invalid rosrpc uri"%i)
         except: pass
Exemplo n.º 10
0
def getServiceType(serviceName, serviceUri):
    dest_addr, dest_port = rospy.parse_rosrpc_uri(serviceUri)
    if rosgraph.network.use_ipv6():
        s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
    else:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.settimeout(5.0)
        s.connect((dest_addr, dest_port))
        header = {
            'probe': '1',
            'md5sum': '*',
            'callerid': '/rosservice',
            'service': serviceName
        }
        rosgraph.network.write_ros_handshake_header(s, header)

        return rosgraph.network.read_ros_handshake_header(s, StringIO(),
                                                          2048).get(
                                                              'type', None)
    finally:
        if s is not None:
            s.close()
Exemplo n.º 11
0
  def get_service_class(self, allow_get_type=False):
    '''
    Get the service class using the type of the service. NOTE: this
    method is from `rosservice` and changed to avoid a probe call to the service.
    
    :param allow_get_type: allow to connect to service and get the type if the type is not valid (in case of other host)
    
    :type allow_get_type: bool
    
    :return: service class
    
    :rtype: ServiceDefinition: service class
    
    :raise: ``ROSServiceException``, if service class cannot be retrieved
    '''
    if not self.__service_class is None:
      return self.__service_class

    type = self.type
    # request the type if it is empty and allowed
    if not type and allow_get_type and self.uri:
      dest_addr = dest_port = None
      try:
        dest_addr, dest_port = rospy.parse_rosrpc_uri(self.uri)
      except:
        pass
      else:
        import socket
        import cStringIO
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
          # connect to service and probe it to get the headers
          s.settimeout(0.5)
          s.connect((dest_addr, dest_port))
          header = { 'probe':'1', 'md5sum':'*',
                    'callerid':rospy.get_name(), 'service':self.name}
          roslib.network.write_ros_handshake_header(s, header)
          type = roslib.network.read_ros_handshake_header(s, cStringIO.StringIO(), 2048)
          type = type['type']
        except socket.error:
          pass
        except:
          pass
        finally:
          if s is not None:
            s.close()

    import rosservice
    if not type:
      raise rosservice.ROSServiceException("Not valid type of service [%s]."%str(type))

    # get the Service class so we can populate the request
    service_class = roslib.message.get_service_class(type)

    # #1083: roscpp services are currently returning the wrong type
    if service_class and self.type.endswith('Request') and \
            not hasattr(service_class, "_request_class"):
        type = type[:-7]
        service_class = roslib.message.get_service_class(type)
        
    if service_class is None:
        pkg = roslib.names.resource_name_package(self.type)
        raise rosservice.ROSServiceException("Unable to load type [%s].\n"%self.type+
                                             "Have you typed 'make' in [%s]?"%pkg)
    self.__service_class = service_class
    return service_class
Exemplo n.º 12
0
    def get_service_class(self, allow_get_type=False):
        '''
        Get the service class using the type of the service. NOTE: this
        method is from `rosservice` and changed to avoid a probe call to the service.

        :param allow_get_type: allow to connect to service and get the type if the type is not valid (in case of other host)

        :type allow_get_type: bool

        :return: service class

        :rtype: ServiceDefinition: service class

        :raise: ``ROSServiceException``, if service class cannot be retrieved
        '''
        if self.__service_class is not None:
            return self.__service_class

        srv_type = self.type
        # request the type if it is empty and allowed
        if not srv_type and allow_get_type and self.uri:
            dest_addr = dest_port = None
            try:
                dest_addr, dest_port = rospy.parse_rosrpc_uri(self.uri)
            except:
                pass
            else:
                import socket
                import cStringIO
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                try:
                    # connect to service and probe it to get the headers
                    s.settimeout(0.5)
                    s.connect((dest_addr, dest_port))
                    header = {
                        'probe': '1',
                        'md5sum': '*',
                        'callerid': rospy.get_name(),
                        'service': self.name
                    }
                    roslib.network.write_ros_handshake_header(s, header)
                    srv_type = roslib.network.read_ros_handshake_header(
                        s, cStringIO.StringIO(), 2048)
                    srv_type = srv_type['type']
                except socket.error:
                    pass
                except:
                    pass
                finally:
                    if s is not None:
                        s.close()

        import rosservice
        if not srv_type:
            raise rosservice.ROSServiceException(
                "Not valid type of service [%s]." % str(srv_type))

        # get the Service class so we can populate the request
        service_class = roslib.message.get_service_class(srv_type)

        # #1083: roscpp services are currently returning the wrong type
        if service_class and self.type.endswith('Request') and \
                not hasattr(service_class, "_request_class"):
            srv_type = srv_type[:-7]
            service_class = roslib.message.get_service_class(srv_type)

        if service_class is None:
            pkg = roslib.names.resource_name_package(self.type)
            raise rosservice.ROSServiceException(
                "Unable to load type [%s].\n" % self.type +
                "Have you typed 'make' in [%s]?" % pkg)
        self.__service_class = service_class
        return service_class
Exemplo n.º 13
0
    def _getServiceInfo(self, services):
        '''
    Gets service info through the RPC interface of the service. 
    This method blocks until the info is retrieved or socket timeout is reached (0.5 seconds).
    
    :param service: the name of the service
    
    :type service: str
    
    :param uri: the uri of the service
    
    :type uri: str
    '''
        for (service, uri) in services.items():
            with self._lock:
                if self.__cached_services.has_key(service):
                    if time.time(
                    ) - self.__cached_services[service][2] < self.MAX_PING_SEC:
                        return
            if not uri is None:
                type = dest_addr = dest_port = None
                try:
                    dest_addr, dest_port = rospy.parse_rosrpc_uri(uri)
                except:
                    #      print "ERROR while get service info"
                    continue
#          return
#      raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri))
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                try:
                    # connect to service and probe it to get the headers
                    s.settimeout(0.5)
                    s.connect((dest_addr, dest_port))
                    header = {
                        'probe': '1',
                        'md5sum': '*',
                        'callerid': self.ros_node_name,
                        'service': service
                    }
                    roslib.network.write_ros_handshake_header(s, header)
                    stype = roslib.network.read_ros_handshake_header(
                        s, cStringIO.StringIO(), 2048)
                    #          print "_getServiceInfo _lock try..", threading.current_thread()
                    with self._lock:
                        #            print "get info about service", service, uri
                        self.__new_master_state.getService(
                            service).type = stype['type']
                        self.__cached_services[service] = (uri, stype['type'],
                                                           time.time())
#          print "_getServiceInfo _lock RET", threading.current_thread()
                except socket.error:
                    #          print "_getServiceInfo _lock try..", threading.current_thread()
                    with self._lock:
                        try:
                            #              print "delete socket service", service, uri
                            del self.__cached_services[service]
                        except:
                            pass
        #      raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri))
#          print "_getServiceInfo _lock RET", threading.current_thread()
                except:
                    import traceback
                    with self._lock:
                        self._limited_log(
                            service, "can't get service type: %s" %
                            traceback.format_exc())
#          print traceback.format_exc()
#          print "_getServiceInfo _lock try..", threading.current_thread()
                    with self._lock:
                        try:
                            #              print "delete service", service, uri
                            del self.__cached_services[service]
                        except:
                            pass
#          print "_getServiceInfo _lock RET", threading.current_thread()
                    pass
                finally:
                    if s is not None:
                        s.close()
  def _getServiceInfo(self, services):
    '''
    Gets service info through the RPC interface of the service. 
    This method blocks until the info is retrieved or socket timeout is reached (0.5 seconds).
    
    :param service: the name of the service
    
    :type service: str
    
    :param uri: the uri of the service
    
    :type uri: str
    '''
    for (service, uri) in services.items():
      with self._lock:
        if self.__cached_services.has_key(service):
          if time.time() - self.__cached_services[service][2] < self.MAX_PING_SEC:
            return
      if not uri is None:
        type = dest_addr = dest_port = None
        try:
          dest_addr, dest_port = rospy.parse_rosrpc_uri(uri)
        except:
    #      print "ERROR while get service info"
          continue
#          return
    #      raise ROSServiceException("service [%s] has an invalid RPC URI [%s]"%(service, uri))
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
          # connect to service and probe it to get the headers
          s.settimeout(0.5)
          s.connect((dest_addr, dest_port))
          header = { 'probe':'1', 'md5sum':'*',
                    'callerid':self.ros_node_name, 'service':service}
          roslib.network.write_ros_handshake_header(s, header)
          type = roslib.network.read_ros_handshake_header(s, cStringIO.StringIO(), 2048)
#          print "_getServiceInfo _lock try..", threading.current_thread()
          with self._lock:
#            print "get info about service", service, uri
            self.__new_master_state.getService(service).type = type['type']
            self.__cached_services[service] = (uri, type['type'], time.time())
#          print "_getServiceInfo _lock RET", threading.current_thread()
        except socket.error:
#          print "_getServiceInfo _lock try..", threading.current_thread()
          with self._lock:
            try:
#              print "delete socket service", service, uri
              del self.__cached_services[service]
            except:
              pass
    #      raise ROSServiceIOException("Unable to communicate with service [%s], address [%s]"%(service, uri))
#          print "_getServiceInfo _lock RET", threading.current_thread()
        except:
#          import traceback
#          print traceback.format_exc()
#          print "_getServiceInfo _lock try..", threading.current_thread()
          with self._lock:
            try:
#              print "delete service", service, uri
              del self.__cached_services[service]
            except:
              pass
#          print "_getServiceInfo _lock RET", threading.current_thread()
          pass
        finally:
          if s is not None:
            s.close()