def datagramReceived(self, message): cls = self.__class__ # check if we need to authenticate if cls.authenticate and not self.authenticated: try: msg = json.loads(message) if msg['op'] == 'auth': # check the authorization information auth_srv = rospy.ServiceProxy('authenticate', Authentication) resp = auth_srv(msg['mac'], msg['client'], msg['dest'], msg['rand'], rospy.Time(msg['t']), msg['level'], rospy.Time(msg['end'])) self.authenticated = resp.authenticated if self.authenticated: rospy.loginfo("Client %d has authenticated.", self.protocol.client_id) return # if we are here, no valid authentication was given rospy.logwarn("Client %d did not authenticate. Closing connection.", self.protocol.client_id) self.close() except: # proper error will be handled in the protocol class self.protocol.incoming(message) else: # no authentication required self.protocol.incoming(message)
def deserialize(self, msg, cid=None): """ Turns the wire-level representation into a dictionary of values Default behaviour assumes JSON. Override to use a different container. Keyword arguments: msg -- the wire-level message to deserialize cid -- (optional) an ID associated with this. Is logged on error Returns a dictionary of values """ try: return json.loads(msg) except Exception, e: # if we did try to deserialize whole buffer .. first try to let self.incoming check for multiple/partial json-decodes before logging error # .. this means, if buffer is not == msg --> we tried to decode part of buffer # TODO: implement a way to have a final Exception when nothing works out to decode (multiple/broken/partial JSON..) # supressed logging of exception on json-decode to keep rosbridge-logs "clean", otherwise console logs would get spammed for every failed json-decode try # if msg != self.buffer: # error_msg = "Unable to deserialize message from client: %s" % msg # error_msg += "\nException was: " +str(e) # # self.log("error", error_msg, cid) # re-raise Exception to allow handling outside of deserialize function instead of returning None raise
def on_message(self, message): global authenticate # check if we need to authenticate msg = None try: msg = json.loads(message) except: pass if authenticate and not self.authenticated: if msg and msg['op'] == 'auth': # check the authorization information auth_srv = rospy.ServiceProxy('authenticate', Authentication) resp = auth_srv(msg['mac'], msg['client'], msg['dest'], msg['rand'], rospy.Time(msg['t']), msg['level'], rospy.Time(msg['end'])) self.authenticated = resp.authenticated if self.authenticated: rospy.loginfo("Client %d has authenticated.", self.protocol.client_id) else: # if we are here, no valid authentication was given rospy.logwarn( "Client %d did not authenticate. Closing connection.", self.protocol.client_id) self.close() return if msg and msg['op'] == 'roscmd': self.commander.incoming(msg['msg']) else: self.protocol.incoming(message)
def calculate_service_response(request): request_object = json.loads(request) # parse string for service request args = request_object["args"] # get parameter field (args) count = int(args["count"] ) # get parameter(s) as described in corresponding ROS srv-file message = "" # calculate service response for i in range(0,count): #message += str(chr(randint(32,126))) message+= str(chr(randint(32,126))) if i% 100000 == 0: print count - i, "bytes left to generate" """ IMPORTANT! use base64 encoding to avoid JSON-parsing problems! --> use .decode("base64","strict") at client side """ message = message.encode('base64','strict') service_response_data = { "data": message} # service response (as defined in srv-file) response_object = { "op": "service_response", "id": request_object["id"], "data": service_response_data # put service response in "data"-field of response object (in this case it's twice "data", because response value is also named data (in srv-file) } response_message = json.dumps(response_object) return response_message
def calculate_service_response(request): request_object = json.loads(request) # parse string for service request args = request_object["args"] # get parameter field (args) count = int(args["count"]) # get parameter(s) as described in corresponding ROS srv-file message = "" # calculate service response for i in range(0, count): # message += str(chr(randint(32,126))) message += str(chr(randint(32, 126))) if i % 100000 == 0: print count - i, "bytes left to generate" """ IMPORTANT! use base64 encoding to avoid JSON-parsing problems! --> use .decode("base64","strict") at client side """ message = message.encode('base64', 'strict') service_response_data = {"data": message} # service response (as defined in srv-file) response_object = { "op": "service_response", "id": request_object["id"], "data": service_response_data } response_message = json.dumps(response_object) return response_message
def deserialize(self, msg, cid=None): """ Turns the wire-level representation into a dictionary of values Default behaviour assumes JSON. Override to use a different container. Keyword arguments: msg -- the wire-level message to deserialize cid -- (optional) an ID associated with this. Is logged on error Returns a dictionary of values """ try: if self.bson_only_mode: bson_message = bson.BSON(msg) return bson_message.decode() else: return json.loads(msg) except Exception, e: # if we did try to deserialize whole buffer .. first try to let self.incoming check for multiple/partial json-decodes before logging error # .. this means, if buffer is not == msg --> we tried to decode part of buffer # TODO: implement a way to have a final Exception when nothing works out to decode (multiple/broken/partial JSON..) # supressed logging of exception on json-decode to keep rosbridge-logs "clean", otherwise console logs would get spammed for every failed json-decode try # if msg != self.buffer: # error_msg = "Unable to deserialize message from client: %s" % msg # error_msg += "\nException was: " +str(e) # # self.log("error", error_msg, cid) # re-raise Exception to allow handling outside of deserialize function instead of returning None raise
def on_message(self, message): cls = self.__class__ # check if we need to authenticate if cls.authenticate and not self.authenticated: try: msg = json.loads(message) if msg["op"] == "auth": # check the authorization information auth_srv = rospy.ServiceProxy("authenticate", Authentication) resp = auth_srv( msg["mac"], msg["client"], msg["dest"], msg["rand"], rospy.Time(msg["t"]), msg["level"], rospy.Time(msg["end"]), ) self.authenticated = resp.authenticated if self.authenticated: rospy.loginfo("Client %d has authenticated.", self.protocol.client_id) return # if we are here, no valid authentication was given rospy.logwarn("Client %d did not authenticate. Closing connection.", self.protocol.client_id) self.close() except: # proper error will be handled in the protocol class self.protocol.incoming(message) else: # no authentication required self.protocol.incoming(message)
def calculate_service_response(request): request_object = json.loads(request) # parse string for service request args = request_object["args"] # get parameter field (args) # count = int(args["count"] ) # get parameter(s) as described in corresponding ROS srv-file # # message = "" # calculate service response # for i in range(0,count): # message += str(chr(randint(32,126))) # if i% 100000 == 0: # print count - i, "bytes left to generate" message = {"data": {"data": 42.0}} """ IMPORTANT! use base64 encoding to avoid JSON-parsing problems! --> use .decode("base64","strict") at client side """ #message = message.encode('base64','strict') service_response_data = message # service response (as defined in srv-file) response_object = { "op": "service_response", "id": request_object["id"], "data": service_response_data # put service response in "data"-field of response object (in this case it's twice "data", because response value is also named data (in srv-file) } response_message = json.dumps(response_object) return response_message
def on_message(self, message): cls = self.__class__ # check if we need to authenticate if cls.authenticate and not self.authenticated: try: if cls.bson_only_mode: msg = bson.BSON(message).decode() else: msg = json.loads(message) if msg['op'] == 'auth': # check the authorization information auth_srv = rospy.ServiceProxy('authenticate', Authentication) resp = auth_srv(msg['mac'], msg['client'], msg['dest'], msg['rand'], rospy.Time(msg['t']), msg['level'], rospy.Time(msg['end'])) self.authenticated = resp.authenticated if self.authenticated: rospy.loginfo("Client %d has authenticated.", self.protocol.client_id) return # if we are here, no valid authentication was given rospy.logwarn("Client %d did not authenticate. Closing connection.", self.protocol.client_id) self.close() except: # proper error will be handled in the protocol class self.protocol.incoming(message) else: # no authentication required self.protocol.incoming(message)
def on_message(self, message): cls = self.__class__ # check if we need to authenticate if cls.authenticate and not self.authenticated: try: if cls.bson_only_mode: msg = bson.BSON(message).decode() else: msg = json.loads(message) if msg['op'] == 'auth': # check the authorization information auth_srv_client = cls.node_handle.create_client( Authentication, 'authenticate') auth_srv_req = Authentication.Request() auth_srv_req.mac = msg['mac'] auth_srv_req.client = msg['client'] auth_srv_req.dest = msg['dest'] auth_srv_req.rand = msg['rand'] auth_srv_req.t = Time(seconds=msg['t']).to_msg() auth_srv_req.level = msg['level'] auth_srv_req.end = Time(seconds=msg['end']).to_msg() while not auth_srv_client.wait_for_service( timeout_sec=1.0): cls.node_handle.get_logger().info( 'Authenticate service not available, waiting again...' ) future = auth_srv_client.call_async(auth_srv_req) rclpy.spin_until_future_complete(cls.node_handle, future) # Log error if service could not be called. if future.result() is not None: self.authenticated = future.result().authenticated else: self.authenticated = False cls.node_handle.get_logger.error( 'Authenticate service call failed') if self.authenticated: cls.node_handle.get_logger().info( "Client {} has authenticated.".format( self.protocol.client_id)) return # if we are here, no valid authentication was given cls.node_handle.get_logger().warn( "Client {} did not authenticate. Closing connection.". format(self.protocol.client_id)) self.close() except: # proper error will be handled in the protocol class self.protocol.incoming(message) else: # no authentication required self.protocol.incoming(message)
def deserialize(self, msg, cid=None): """ Turns the wire-level representation into a dictionary of values Default behaviour assumes JSON. Override to use a different container. Keyword arguments: msg -- the wire-level message to deserialize cid -- (optional) an ID associated with this. Is logged on error Returns a dictionary of values """ try: return json.loads(msg) except Exception as e: raise
def calculate_service_response(request): request_object = json.loads(request) # parse string for service request args = request_object["args"] message = {"data": {"data": 42.0}} """ IMPORTANT! use base64 encoding to avoid JSON-parsing problems! --> use .decode("base64","strict") at client side """ # message = message.encode('base64','strict') service_response_data = message response_object = { "op": "service_response", "id": request_object["id"], "data": service_response_data } response_message = json.dumps(response_object) return response_message
reconstructed = None while not done: # should not need a loop (maximum wait can be set by client_socket_timeout), but since its for test/demonstration only .. leave it as it is for now try: incoming = sock.recv( max_msg_length) # receive service_response from rosbridge if buffer == "": buffer = incoming if incoming == "": print "closing socket" sock.close() break else: buffer = buffer + incoming #print "buffer-length:", len(buffer) try: # try to access service_request directly (not fragmented) data_object = json.loads(buffer) if data_object["op"] == "service_response": reconstructed = buffer done = True except Exception, e: #print "direct access to JSON failed.." #print e pass try: #print "defragmenting incoming messages" result_string = buffer.split( "}{" ) # split buffer into fragments and re-fill curly brackets result = [] for fragment in result_string: if fragment[0] != "{":
result = None reconstructed = None while not done: # should not need a loop (maximum wait can be set by client_socket_timeout), but since its for test/demonstration only .. leave it as it is for now try: incoming = sock.recv(max_msg_length) # receive service_response from rosbridge if buffer == "": buffer = incoming if incoming == "": print "closing socket" sock.close() break else: buffer = buffer + incoming #print "buffer-length:", len(buffer) try: # try to access service_request directly (not fragmented) data_object = json.loads(buffer) if data_object["op"] == "service_response": reconstructed = buffer done = True except Exception, e: #print "direct access to JSON failed.." #print e pass try: #print "defragmenting incoming messages" result_string = buffer.split("}{") # split buffer into fragments and re-fill curly brackets result = [] for fragment in result_string: if fragment[0] != "{": fragment = "{"+fragment if fragment[len(fragment)-1] != "}":
reconstructed = None while not done: try: incoming = sock.recv(max_msg_length) # receive service_response from rosbridge if buffer == "": buffer = incoming if incoming == "": print "closing socket" sock.close() break else: buffer = buffer + incoming # print "buffer-length:", len(buffer) try: data_object = json.loads(buffer) if data_object["op"] == "service_response": reconstructed = buffer done = True except Exception as e: # print "direct access to JSON failed.." # print e pass try: # print "defragmenting incoming messages" result_string = buffer.split("}{") # split buffer into fragments and # re-fill curly brackets result = [] for fragment in result_string: if fragment[0] != "{":
def wait_for_service_request(): # receive data from rosbridge data = None global buffer try: done = False global buffer while not done: incoming = tcp_socket.recv(max_msg_length) # get data from socket if incoming == '': print "connection closed by peer" sys.exit(1) buffer = buffer + incoming # append data to buffer try: # try to parse JSON from buffer data_object = json.loads(buffer) if data_object["op"] == "call_service": data = buffer done = True return data # if parsing was successful --> return data string except Exception, e: #print "direct_access error:" #print e pass #print "trying to defragment" try: # opcode was not "call_service" -> try to defragment result_string = buffer.split("}{") # split buffer into fragments and re-fill with curly brackets result = [] for fragment in result_string: if fragment[0] != "{": fragment = "{"+fragment if fragment[len(fragment)-1] != "}": fragment = fragment + "}" result.append(json.loads(fragment)) try: # try to defragment when received all fragments fragment_count = len(result) announced = int(result[0]["total"]) if fragment_count == announced: reconstructed = "" sorted_result = [None] * fragment_count # sort fragments.. unsorted_result = [] for fragment in result: unsorted_result.append(fragment) sorted_result[int(fragment["num"])] = fragment for fragment in sorted_result: # reconstruct from fragments reconstructed = reconstructed + fragment["data"] #print "reconstructed", reconstructed buffer = "" # empty buffer done = True print "reconstructed message from", len(result), "fragments" #print reconstructed return reconstructed except Exception, e: print "not possible to defragment:", buffer print e except Exception, e: print "defrag_error:", buffer print e pass
def wait_for_service_request(): data = None global buffer try: done = False global buffer while not done: incoming = tcp_socket.recv(max_msg_length) # get data from socket if incoming == '': print "connection closed by peer" sys.exit(1) buffer = buffer + \ incoming try: data_object = json.loads(buffer) if data_object["op"] == "call_service": data = buffer done = True return data except Exception as e: # print "direct_access error:" # print e pass # print "trying to defragment" try: result_string = buffer.split("}{") # split buffer into fragments and # re-fill with curly brackets result = [] for fragment in result_string: if fragment[0] != "{": fragment = "{" + fragment if fragment[len(fragment) - 1] != "}": fragment = fragment + "}" result.append(json.loads(fragment)) try: fragment_count = len(result) announced = int(result[0]["total"]) if fragment_count == announced: reconstructed = "" sorted_result = [None ] * fragment_count # sort fragments.. unsorted_result = [] for fragment in result: unsorted_result.append(fragment) sorted_result[int(fragment["num"])] = fragment for fragment in sorted_result: reconstructed = reconstructed + fragment["data"] # print "reconstructed", reconstructed buffer = "" done = True print "reconstructed message from", len( result), "fragments" # print reconstructed return reconstructed except Exception as e: print "not possible to defragment:", buffer print e except Exception as e: print "defrag_error:", buffer print e pass except Exception as e: # print "network-error(?):", e pass return data
def wait_for_service_request(): # receive data from rosbridge data = None global buffer try: done = False global buffer while not done: incoming = tcp_socket.recv(max_msg_length) # get data from socket if incoming == '': print "connection closed by peer" sys.exit(1) buffer = buffer + incoming # append data to buffer try: # try to parse JSON from buffer data_object = json.loads(buffer) if data_object["op"] == "call_service": data = buffer done = True return data # if parsing was successful --> return data string except Exception, e: #print "direct_access error:" #print e pass #print "trying to defragment" try: # opcode was not "call_service" -> try to defragment result_string = buffer.split( "}{" ) # split buffer into fragments and re-fill with curly brackets result = [] for fragment in result_string: if fragment[0] != "{": fragment = "{" + fragment if fragment[len(fragment) - 1] != "}": fragment = fragment + "}" result.append(json.loads(fragment)) try: # try to defragment when received all fragments fragment_count = len(result) announced = int(result[0]["total"]) if fragment_count == announced: reconstructed = "" sorted_result = [None ] * fragment_count # sort fragments.. unsorted_result = [] for fragment in result: unsorted_result.append(fragment) sorted_result[int(fragment["num"])] = fragment for fragment in sorted_result: # reconstruct from fragments reconstructed = reconstructed + fragment["data"] #print "reconstructed", reconstructed buffer = "" # empty buffer done = True print "reconstructed message from", len( result), "fragments" #print reconstructed return reconstructed except Exception, e: print "not possible to defragment:", buffer print e except Exception, e: print "defrag_error:", buffer print e pass