utils.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/license/LICENSE
00005 #
00006 ##############################################################################
00007 # Imports
00008 ##############################################################################
00009 
00010 #import collections
00011 import copy
00012 import cPickle as pickle
00013 #import simplejson as json
00014 import os
00015 
00016 from Crypto.PublicKey import RSA
00017 import Crypto.Util.number as CUN
00018 
00019 from gateway_msgs.msg import Rule, ConnectionType
00020 
00021 ##############################################################################
00022 # Constants
00023 ##############################################################################
00024 
00025 # for help in iterating over the set of connection constants
00026 connection_types = frozenset([ConnectionType.PUBLISHER, ConnectionType.SUBSCRIBER,
00027                              ConnectionType.SERVICE, ConnectionType.ACTION_CLIENT, ConnectionType.ACTION_SERVER])
00028 connection_types_list = [ConnectionType.PUBLISHER, ConnectionType.SUBSCRIBER,
00029                          ConnectionType.SERVICE, ConnectionType.ACTION_CLIENT, ConnectionType.ACTION_SERVER]
00030 connection_type_strings_list = ["publisher", "subscriber", "service", "action_client", "action_server"]
00031 action_types = ['/goal', '/cancel', '/status', '/feedback', '/result']
00032 
00033 ##############################################################################
00034 # Rule
00035 ##############################################################################
00036 
00037 
00038 class Connection():
00039 
00040     '''
00041       An object that represents a connection containing all the gory details
00042       about a connection, allowing a connection to be passed through to a
00043       foreign gateway
00044 
00045        - rule (gateway_msgs.msg.Rule) (containing type,name,node)
00046        - type_info              (msg type for pubsub or service api for services)
00047        - xmlrpc_uri             (the xmlrpc node uri for the connection)
00048     '''
00049 
00050     def __init__(self, rule, type_info, xmlrpc_uri):
00051         '''
00052           @param type_info : either topic_type (pubsub), service api (service) or ??? (action)
00053           @type string
00054         '''
00055         self.rule = rule
00056         self.type_info = type_info
00057         self.xmlrpc_uri = xmlrpc_uri
00058 
00059     def __eq__(self, other):
00060         if isinstance(other, self.__class__):
00061             return self.__dict__ == other.__dict__
00062         else:
00063             return False
00064 
00065     def __ne__(self, other):
00066         return not self.__eq__(other)
00067 
00068     def __str__(self):
00069         if self.rule.type == ConnectionType.SERVICE:
00070             return '{type: %s, name: %s, node: %s, uri: %s, service_api: %s}' % (
00071                 self.rule.type, self.rule.name, self.rule.node, self.xmlrpc_uri, self.type_info)
00072         else:
00073             return '{type: %s, name: %s, node: %s, uri: %s, topic_type: %s}' % (
00074                 self.rule.type, self.rule.name, self.rule.node, self.xmlrpc_uri, self.type_info)
00075 
00076     def __repr__(self):
00077         return self.__str__()
00078 
00079     def inConnectionList(self, connection_list):
00080         '''
00081           Checks to see if this connection has the same rule
00082           as an item in the given connection_list
00083 
00084           @param connection_list : connection list to trawl.
00085           @type utils.Connection[]
00086           @return true if this connection rule matches a connection rule in the list
00087           @rtype Bool
00088         '''
00089         for connection in connection_list:
00090             if self.hasSameRule(connection):
00091                 return True
00092         return False
00093 
00094     def hasSameRule(self, connection):
00095         '''
00096           Checks for equivalency regardless of type_info and xmlrpc_uri.
00097 
00098           @param connection : connection to compare with
00099           @type utils.Connection
00100           @return true if equivalent, false otherwise
00101           @rtype Bool
00102         '''
00103         return (self.rule.name == connection.rule.name and
00104                 self.rule.type == connection.rule.type and
00105                 self.rule.node == connection.rule.node)
00106 
00107 ##############################################################################
00108 # Registration
00109 ##############################################################################
00110 
00111 
00112 class Registration():
00113 
00114     '''
00115       An object that represents a connection registered with the local
00116       master (or about to be registered). This has all the gory detail
00117       for the connection. It includes the gateway name it originated
00118       from as well as master registration information.
00119 
00120        - connection             (the remote connection information)
00121        - remote_gateway         (the remote gateway from where this connection originated)
00122        - local_node             (the local anonymously generated node name)
00123     '''
00124 
00125     def __init__(self, connection, remote_gateway, local_node=None):
00126         '''
00127           @param connection : string identifier storing the remote connection details (type, name, node)
00128           @type gateway_msgs.msg.RemoteRule
00129 
00130           @param remote_gateway : string identifier for where this registration game from
00131           @type string
00132 
00133           @param local_node : the local node that this registration is created under
00134           @type string
00135         '''
00136         self.connection = connection
00137         self.remote_gateway = remote_gateway
00138         self.local_node = local_node
00139 
00140     def __eq__(self, other):
00141         if isinstance(other, self.__class__):
00142             return self.__dict__ == other.__dict__
00143         else:
00144             return False
00145 
00146     def __ne__(self, other):
00147         return not self.__eq__(other)
00148 
00149     def __str__(self):
00150         return '[%s]%s' % (self.remote_gateway, format_rule(self.connection.rule))
00151 
00152     def __repr__(self):
00153         return self.__str__()
00154 
00155 ##########################################################################
00156 # serialization/deserialization Functions
00157 ##########################################################################
00158 
00159 
00160 # def convert(data):
00161 #     '''
00162 #       Convert unicode to standard string (Not sure how necessary this is)
00163 #       http://stackoverflow.com/questions/1254454/fastest-way-to-convert-a-dicts-keys-values-from-unicode-to-str
00164 #     '''
00165 #     if isinstance(data, unicode):
00166 #         return str(data)
00167 #     elif isinstance(data, collections.Mapping):
00168 #         return dict(map(convert, data.iteritems()))
00169 #     elif isinstance(data, collections.Iterable):
00170 #         return type(data)(map(convert, data))
00171 #     else:
00172 #         return data
00173 #
00174 
00175 def serialize(data):
00176     # return json.dumps(data)
00177     return pickle.dumps(data)
00178 
00179 
00180 def deserialize(str_msg):
00181     # return convert(json.loads(str_msg))
00182     try:
00183         deserialized_data = pickle.loads(str_msg)
00184     except ValueError as e:
00185         rospy.logwarn("Gateway : Error while deserialization[%s]"%e)
00186         import traceback
00187         print(traceback.format_exc())
00188         print("Data : %s"%str_msg)
00189     return deserialized_data
00190 
00191 
00192 def serialize_connection(connection):
00193     return serialize([connection.rule.type,
00194                       connection.rule.name,
00195                       connection.rule.node,
00196                       connection.type_info,
00197                       connection.xmlrpc_uri]
00198                      )
00199 
00200 
00201 def deserialize_connection(connection_str):
00202     deserialized_list = deserialize(connection_str)
00203     rule = Rule(deserialized_list[0],
00204                 deserialized_list[1],
00205                 deserialized_list[2]
00206                 )
00207     return Connection(rule, deserialized_list[3], deserialized_list[4])
00208 
00209 
00210 def serialize_connection_request(command, source, connection):
00211     return serialize([command, source,
00212                       connection.rule.type,
00213                       connection.rule.name,
00214                       connection.rule.node,
00215                       connection.type_info,
00216                       connection.xmlrpc_uri]
00217                      )
00218 
00219 
00220 def serialize_rule_request(command, source, rule):
00221     return serialize([command, source, rule.type, rule.name, rule.node])
00222 
00223 
00224 def deserialize_request(request_str):
00225     deserialized_list = deserialize(request_str)
00226     return deserialized_list[0], deserialized_list[1], deserialized_list[2:]
00227 
00228 
00229 def get_connection_from_list(connection_argument_list):
00230     rule = Rule(connection_argument_list[0], connection_argument_list[1], connection_argument_list[2])
00231     return Connection(rule, connection_argument_list[3], connection_argument_list[4])
00232 
00233 
00234 def get_rule_from_list(rule_argument_list):
00235     return Rule(rule_argument_list[0], rule_argument_list[1], rule_argument_list[2])
00236 
00237 ##########################################################################
00238 # Encryption/Decryption
00239 ##########################################################################
00240 
00241 MAX_PLAINTEXT_LENGTH = 256
00242 
00243 
00244 def generate_private_public_key():
00245     key = RSA.generate(8 * MAX_PLAINTEXT_LENGTH)
00246     public_key = key.publickey()
00247     return key, public_key
00248 
00249 
00250 def deserialize_key(serialized_key):
00251     return RSA.importKey(serialized_key)
00252 
00253 
00254 def serialize_key(key):
00255     return key.exportKey()
00256 
00257 
00258 def encrypt(plaintext, public_key):
00259     if len(plaintext) > MAX_PLAINTEXT_LENGTH:
00260         # TODO need to have arbitrary lengths
00261         raise ValueError('Trying to encrypt text longer than ' + MAX_PLAINTEXT_LENGTH + ' bytes!')
00262     K = CUN.getRandomNumber(128, os.urandom)  # Not used, legacy compatibility
00263     ciphertext = public_key.encrypt(plaintext, K)
00264     return ciphertext[0]
00265     # return plaintext
00266 
00267 
00268 def decrypt(ciphertext, key):
00269     return key.decrypt(ciphertext)
00270     # return ciphertext
00271 
00272 
00273 def decrypt_connection(connection, key):
00274     decrypted_connection = copy.deepcopy(connection)
00275     decrypted_connection.type_info = decrypt(connection.type_info, key)
00276     decrypted_connection.xmlrpc_uri = decrypt(connection.xmlrpc_uri, key)
00277     return decrypted_connection
00278 
00279 
00280 def encrypt_connection(connection, key):
00281     encrypted_connection = copy.deepcopy(connection)
00282     encrypted_connection.type_info = encrypt(connection.type_info, key)
00283     encrypted_connection.xmlrpc_uri = encrypt(connection.xmlrpc_uri, key)
00284     return encrypted_connection
00285 
00286 ##########################################################################
00287 # Regex
00288 ##########################################################################
00289 
00290 
00291 def is_all_pattern(pattern):
00292     '''
00293       Convenience function for detecting the 'all' pattern.
00294 
00295       @param pattern : the name rule string for the flip all concept
00296       @type str
00297       @return true if matching, false otherwise
00298       @rtype Bool
00299     '''
00300     if pattern == ".*":
00301         return True
00302     else:
00303         return False
00304 
00305 
00306 ##########################################################################
00307 # Formatters
00308 ##########################################################################
00309 
00310 def format_rule(rule):
00311     return '[%s][%s][%s]' % (rule.type, rule.name, rule.node)
00312 
00313 ##########################################################################
00314 # Factories
00315 ##########################################################################
00316 
00317 
00318 def create_empty_connection_type_dictionary():
00319     '''
00320       Used to initialise a dictionary with rule type keys
00321       and empty lists.
00322     '''
00323     dic = {}
00324     for connection_type in connection_types:
00325         dic[connection_type] = []
00326     return dic
00327 
00328 difflist = lambda l1, l2: [x for x in l1 if x not in l2]  # diff of lists


rocon_gateway
Author(s): Daniel Stonier , Jihoon Lee , Piyush Khandelwal
autogenerated on Sat Jun 8 2019 18:48:44