示例#1
0
def service_connection_handler(sock, client_addr, header):
    """
    Process incoming service connection. For use with
    TCPROSServer. Reads in service name from handshake and creates the
    appropriate service handler for the connection.
    @param sock: socket connection
    @type  sock: socket
    @param client_addr: client address
    @type  client_addr: (str, int)
    @param header: key/value pairs from handshake header
    @type  header: dict
    @return: error string or None 
    @rtype: str
    """
    for required in ['service', 'md5sum', 'callerid']:
        if not required in header:
            return "Missing required '%s' field" % required
    else:
        logger.debug("connection from %s:%s", client_addr[0], client_addr[1])
        service_name = header['service']
        """ check again if the client request is authorized """
        auth_logger.info(
            "received service connection for %s from %s (%s:%s)" %
            (service_name, header["callerid"], client_addr[0], client_addr[1]))
        client_ip_address = client_addr[0]
        if not is_requester_authorized(service_name, client_ip_address):
            auth_logger.warn(
                "service connection for %s from %s (%s) not authorized" %
                (service_name, header["callerid"], client_ip_address))
            return "Client [%s] wants service connection for %s, but %s is not authorized" % (
                header['callerid'], service_name, client_ip_address)

        auth_logger.info("service connection for %s from %s (%s) OK" %
                         (service_name, header["callerid"], client_ip_address))
        #TODO: make service manager configurable. I think the right
        #thing to do is to make these singletons private members of a
        #Node instance and enable rospy to have multiple node
        #instances.

        sm = get_service_manager()
        md5sum = header['md5sum']
        service = sm.get_service(service_name)
        if not service:
            return "[%s] is not a provider of  [%s]" % (
                rospy.names.get_caller_id(), service_name)
        elif md5sum != rospy.names.SERVICE_ANYTYPE and md5sum != service.service_class._md5sum:
            return "request from [%s]: md5sums do not match: [%s] vs. [%s]" % (
                header['callerid'], md5sum, service.service_class._md5sum)
        else:
            transport = TCPROSTransport(service.protocol,
                                        service_name,
                                        header=header)
            transport.set_socket(sock, header['callerid'])
            transport.write_header()
            # using threadpool reduced performance by an order of
            # magnitude, need to investigate better
            t = threading.Thread(target=service.handle,
                                 args=(transport, header))
            t.setDaemon(True)
            t.start()
    def test_TCPROSTransport(self):
        import rospy.impl.tcpros_base
        from rospy.impl.tcpros_base import TCPROSTransport, TCPROSTransportProtocol
        from rospy.impl.transport import OUTBOUND
        p = TCPROSTransportProtocol('Bob', rospy.AnyMsg)
        p.direction = OUTBOUND

        try:
            TCPROSTransport(p, '')
            self.fail("TCPROSTransport should not accept bad name")
        except rospy.impl.tcpros_base.TransportInitError: pass
        
        t = TCPROSTransport(p, 'transport-name')
        self.assert_(t.socket is None)
        self.assert_(t.md5sum is None)
        self.assert_(t.type is None)         
        self.assertEquals(p, t.protocol)
        self.assertEquals('TCPROS', t.transport_type)        
        self.assertEquals(OUTBOUND, t.direction)        
        self.assertEquals('unknown', t.endpoint_id)        
        self.assertEquals('', t.read_buff.getvalue())
        self.assertEquals('', t.write_buff.getvalue())

        s = MockSock('12345')
        t.set_socket(s, 'new_endpoint_id')
        self.assertEquals('new_endpoint_id', t.endpoint_id)
        self.assertEquals(s, t.socket)

        t.close()
        self.assert_(t.socket is None)
        self.assert_(t.read_buff is None)
        self.assert_(t.write_buff is None)
        self.assert_(t.protocol is None)
    def test_TCPROSTransport(self):
        import rospy.impl.tcpros_base
        from rospy.impl.tcpros_base import TCPROSTransport, TCPROSTransportProtocol
        from rospy.impl.transport import OUTBOUND
        p = TCPROSTransportProtocol('Bob', rospy.AnyMsg)
        p.direction = OUTBOUND

        try:
            TCPROSTransport(p, '')
            self.fail("TCPROSTransport should not accept bad name")
        except rospy.impl.tcpros_base.TransportInitError: pass
        
        t = TCPROSTransport(p, 'transport-name')
        self.assert_(t.socket is None)
        self.assert_(t.md5sum is None)
        self.assert_(t.type is None)         
        self.assertEquals(p, t.protocol)
        self.assertEquals('TCPROS', t.transport_type)        
        self.assertEquals(OUTBOUND, t.direction)        
        self.assertEquals('unknown', t.endpoint_id)        
        self.assertEquals('', t.read_buff.getvalue())
        self.assertEquals('', t.write_buff.getvalue())

        s = MockSock('12345')
        t.set_socket(s, 'new_endpoint_id')
        self.assertEquals('new_endpoint_id', t.endpoint_id)
        self.assertEquals(s, t.socket)

        t.close()
        self.assert_(t.socket is None)
        self.assert_(t.read_buff is None)
        self.assert_(t.write_buff is None)
        self.assert_(t.protocol is None)
示例#4
0
def inbound_handler(sock, addr):
  print "%s connected." % (str(addr))

  t = TCPROSTransport(TestServerProtocol(), "testservice")
  t.set_socket(sock, "client")
  t.write_header()	
  t.read_header()

  inputs.append(sock)
def service_connection_handler(sock, client_addr, header):
    """
    Process incoming service connection. For use with
    TCPROSServer. Reads in service name from handshake and creates the
    appropriate service handler for the connection.
    @param sock: socket connection
    @type  sock: socket
    @param client_addr: client address
    @type  client_addr: (str, int)
    @param header: key/value pairs from handshake header
    @type  header: dict
    @return: error string or None 
    @rtype: str
    """
    for required in ['service', 'md5sum', 'callerid']:
        if not required in header:
            return "Missing required '%s' field"%required
    else:
        logger.debug("connection from %s:%s", client_addr[0], client_addr[1])
        service_name = header['service']
        
        #TODO: make service manager configurable. I think the right
        #thing to do is to make these singletons private members of a
        #Node instance and enable rospy to have multiple node
        #instances.
        
        sm = get_service_manager()
        md5sum = header['md5sum']
        service = sm.get_service(service_name)
        if not service:
            return "[%s] is not a provider of  [%s]"%(rospy.names.get_caller_id(), service_name)
        elif md5sum != rospy.names.SERVICE_ANYTYPE and md5sum != service.service_class._md5sum:
            return "request from [%s]: md5sums do not match: [%s] vs. [%s]"%(header['callerid'], md5sum, service.service_class._md5sum)
        else:
            transport = TCPROSTransport(service.protocol, service_name, header=header)
            transport.set_socket(sock, header['callerid'])
            transport.write_header()
            # using threadpool reduced performance by an order of
            # magnitude, need to investigate better
            t = threading.Thread(target=service.handle, args=(transport, header))
            t.setDaemon(True)
            t.start()
    def service_connection_handler(self, sock, client_addr, header):
        """
        @param sock: socket connection
        @type  sock: socket
        @param client_addr: client address
        @type  client_addr: (str, int)
        @param header: key/value pairs from handshake header
        @type  header: dict
        @return: error string or None 
        @rtype: str
        """

        # This is a cturtle hack. rospy's service_connection_handler
        # is wired to the ServiceManager singleton. If we replace the
        # singleton with something more configurable, then we simply
        # have to run our own ServiceManager to handle the forwarding
        # behavior.

        for required in ['service', 'md5sum', 'callerid']:
            if not required in header:
                return "Missing required '%s' field" % required
        else:
            #logger.debug("connection from %s:%s", client_addr[0], client_addr[1])
            service_name = header['service']

            sm = self.service_manager
            md5sum = header['md5sum']
            service = sm.get_service(service_name)
            if not service:
                return "[%s] is not a provider of  [%s]" % (
                    rospy.names.get_caller_id(), service_name)
            elif md5sum != rospy.names.SERVICE_ANYTYPE and md5sum != service.service_class._md5sum:
                return "request from [%s]: md5sums do not match: [%s] vs. [%s]" % (
                    header['callerid'], md5sum, service.service_class._md5sum)
            else:
                transport = TCPROSTransport(service.protocol,
                                            service_name,
                                            header=header)
                transport.set_socket(sock, header['callerid'])
                transport.write_header()
                thread.start_new_thread(service.handle, (transport, header))
    def service_connection_handler(self, sock, client_addr, header):
        """
        @param sock: socket connection
        @type  sock: socket
        @param client_addr: client address
        @type  client_addr: (str, int)
        @param header: key/value pairs from handshake header
        @type  header: dict
        @return: error string or None 
        @rtype: str
        """

        # This is a cturtle hack. rospy's service_connection_handler
        # is wired to the ServiceManager singleton. If we replace the
        # singleton with something more configurable, then we simply
        # have to run our own ServiceManager to handle the forwarding
        # behavior.

        for required in ['service', 'md5sum', 'callerid']:
            if not required in header:
                return "Missing required '%s' field"%required
        else:
            #logger.debug("connection from %s:%s", client_addr[0], client_addr[1])
            service_name = header['service']

            sm = self.service_manager
            md5sum = header['md5sum']
            service = sm.get_service(service_name)
            if not service:
                return "[%s] is not a provider of  [%s]"%(rospy.names.get_caller_id(), service_name)
            elif md5sum != rospy.names.SERVICE_ANYTYPE and md5sum != service.service_class._md5sum:
                return "request from [%s]: md5sums do not match: [%s] vs. [%s]"%(header['callerid'], md5sum, service.service_class._md5sum)
            else:
                transport = TCPROSTransport(service.protocol, service_name, header=header)
                transport.set_socket(sock, header['callerid'])
                transport.write_header()
                thread.start_new_thread(service.handle, (transport, header))
示例#8
0
  t.write_header()	
  t.read_header()

  inputs.append(sock)

if __name__ == '__main__':
  s = TCPServer(inbound_handler, PORT)	
  s.start()

  while True:
    inputready,outputready,exceptready = select.select(inputs, [], [], 1)
    for s in inputready:
      # s is really just a python socket, but let's use
      # ROS to parse the message and write a response
      t = TCPROSTransport(TestServerProtocol(), "testservice")
      t.set_socket(s, "client")
      try:
        data = t.receive_once()

        # Echo all messages
        seq = 0
        for msg in data:
          msg.data = "This is a reply of the message '%s'." % (msg.data)
          t.send_message(msg, seq)
          seq += 1

        print "Echoed data"
      except rospy.exceptions.TransportTerminated:
        print "Closing connection"
        s.close()
        inputs.remove(s)