Package rospy :: Package impl :: Module transport

Source Code for Module rospy.impl.transport

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2008, Willow Garage, Inc. 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Willow Garage, Inc. nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32  # 
 33  # Revision $Id$ 
 34  """ 
 35  Base classes for rospy transports 
 36   
 37  These are the base underlying transport implementations, i.e. 
 38  TCP/IP connections, etc... 
 39   
 40  For topic implementations, see L{topics} 
 41  """ 
 42   
 43  import threading 
 44   
 45  # we need ids for the transports so we can send the IDs instead of 
 46  # full connection details 
 47  _transport_id = 0 
 48  _id_lock = threading.Lock() 
49 -def _nextId():
50 global _transport_id 51 try: 52 _id_lock.acquire() 53 _transport_id += 1 54 return _transport_id 55 finally: 56 _id_lock.release()
57 58 INBOUND = 'i' 59 OUTBOUND = 'o' 60 BIDIRECTIONAL = 'b' 61 62 ## Base API of Transport implementations
63 -class Transport(object):
64 transport_type = 'UNKNOWN' 65 66 ## @param self 67 ## @param direction str: INBOUND | OUTBOUND | BIDIRECTIONAL 68 ## @param name str
69 - def __init__(self, direction, name='unnamed'):
70 self.name = name 71 self.direction = direction 72 self.done = False 73 self.cleanup_cb = None 74 self.endpoint_id = '' 75 76 #STATS 77 self.id = _nextId() 78 self.stat_bytes = 0 79 # Number of messages that have passed through this transport 80 self.stat_num_msg = 0 81 82 # Endpoint Details (IP, Port) 83 self.local_endpoint = (0, 0) 84 self.remote_endpoint = (0, 0)
85
86 - def fileno(self):
87 """ 88 Get a file descriptor for select() if available 89 """ 90 return None
91 92 ## callback function to invoke when this connection is 93 ## closed. Function will be passed this transport as an argument. 94 ## @param self 95 ## @param cleanup_callback fn(Transport): callback for when connection is closed
96 - def set_cleanup_callback(self, cleanup_callback):
97 self.cleanup_cb = cleanup_callback
98 99 ## terminate i/o. Leaf subclasses should override and call this implementation 100 ## @param self
101 - def close(self):
102 self.done = True 103 if self.cleanup_cb: 104 self.cleanup_cb(self)
105 106 ## Write raw data to transport 107 ## @throws TransportInitialiationError could not be initialized 108 ## @throws TransportTerminated no longer open for publishing
109 - def write_data(self, data):
110 raise Exception("not implemented")
111 112 ## Implements the getTransportInfo() from roscpp 113 ## Similar to getTransportInfo() in 'libros/transport/transport_tcp.cpp'
114 - def get_transport_info(self):
115 raise NotImplementedError
116 117 ## Shell class to hold stats about transport that is being killed off. 118 ## This allows the information to stick around but the original Tranport to be gc'd
119 -class DeadTransport(Transport):
120 121 ## @param self 122 ## @param transport str: transport name
123 - def __init__(self, transport):
124 super(DeadTransport, self).__init__( 125 transport.direction, transport.name) 126 self.transport_type = transport.transport_type #class property 127 self.id = transport.id 128 self.stat_bytes = transport.stat_bytes 129 self.stat_num_msg = transport.stat_num_msg 130 self.done = True 131 self.endpoint_id = transport.endpoint_id 132 self.local_endpoint = transport.local_endpoint 133 self.remote_endpoint = transport.remote_endpoint
134 135 ## @param self
136 - def get_transport_info(self):
137 return "Closed %s connection on port %s to [%s:%s]" % (self.transport_type, self.local_endpoint[1], self.remote_endpoint[0], self.remote_endpoint[1])
138 139 ## ProtocolHandler interface: implements topic communication for a 140 ## particular protocol(s). In order to understand the methods of this 141 ## API, it is important to understand how topic communication is 142 ## established: 143 ## 144 ## When a subscriber is notified of a new topic publisher, it contacts 145 ## the publisher to establish a connection. The subscriber gathers a 146 ## list of supported protocols (e.g. [['TCPROS'], ['MEMMAP']]) from 147 ## its protocol handlers (L{get_supported}) and then passes these to 148 ## the publisher. Each of these protocols is actual a list, 149 ## e.g. ['MPI', LaneWidth, BusSpeed], since a protocol may have 150 ## associated parameters. This is considered the start of the 151 ## 'negotiation phase'. 152 ## 153 ## subscriber -> pub.requestTopic(protocols) 154 ## 155 ## The Publisher selects a protocol from the lists and tells the 156 ## appropriate protocol handler to prepare the outbound connection: 157 ## 158 ## pub.requestTopic() -> pub.protocol_handler.init_publisher(selected_protocol) 159 ## 160 ## The protocol handler will return a new set of parameters 161 ## representing connection parameters, e.g. [TCPROS, address, 162 ## port]. These new parameters are passed back to the subscriber, 163 ## which tells its protocol handler to establish the connection. 164 ## 165 ## subscriber -> subscriber.protocol_handler.create_transport(protocolParams)
166 -class ProtocolHandler(object): #interface
167 168 ## shutdown any resources associated with handling this protocol 169 ## @param self
170 - def shutdown(self):
171 pass
172 173 ## Create a new Transport using the specified \a protocol_params 174 ## returned from the Publisher \a pub_uri. 175 ## @param self 176 ## @param protocol_params [[str, val*]]: parameter list from Publisher. Actual 177 ## contents are protocol-specified. 178 ## @param pub_uri str: publisher API URI 179 ## @param topic str: topic name 180 ## @return int, str, int: code, message, debug
181 - def create_transport(self, topic, pub_uri, protocol_params):
182 raise Exception("interface impl")
183 184 ## @param self 185 ## @param protocol str: protocol name. Must match string identifier used in 186 ## negotiation. 187 ## @return bool: True if this handler supports the specified protocol"""
188 - def supports(self, protocol):
189 return False
190 191 ## This method is called on subscribers and returns the protocol list 192 ## @param self 193 ## @return [[str, val*]]: list of supported protocol params. Each set of protocol params is a 194 ## list where the first element is the string identifier for the protocol.
195 - def get_supported(self):
196 return []
197 198 ## Prepare a transport based on one of the supported protocols 199 ## declared by a Subscriber. Subscribers supply a list of 200 ## supported protocols, of which one is selected by the Publisher 201 ## and passed to init_publisher(). init_publisher is responsible 202 ## for initializing the publisher based on the selection. 203 ## @param self 204 ## @param topic str: name of topic 205 ## @param protocol: selected protocol parameters from the Subscriber. 206 ## @return (int, str, list): (code, statusMessage, params). params 207 ## is protocol specific. These params will be sent to the Subscriber 208 ## so that it can create_transport().
209 - def init_publisher(self, topic, protocol):
210 raise Exception("interface impl") 211