Go to the documentation of this file.00001 from rosbridge_library.internal.ros_loader import get_service_class
00002 from rosbridge_library.internal import message_conversion
00003 from rosbridge_library.capability import Capability
00004 import fnmatch
00005 import rospy
00006 import time
00007
00008
00009 class AdvertisedServiceHandler():
00010
00011 id_counter = 1
00012 responses = {}
00013
00014 services_glob = None
00015
00016 def __init__(self, service_name, service_type, protocol):
00017 self.service_name = service_name
00018 self.service_type = service_type
00019 self.protocol = protocol
00020
00021 self.service_handle = rospy.Service(service_name, get_service_class(service_type), self.handle_request)
00022
00023 def next_id(self):
00024 id = self.id_counter
00025 self.id_counter += 1
00026 return id
00027
00028 def handle_request(self, req):
00029
00030 request_id = "service_request:" + self.service_name + ":" + str(self.next_id())
00031
00032
00033 request_message = {
00034 "op": "call_service",
00035 "id": request_id,
00036 "service": self.service_name,
00037 "args": message_conversion.extract_values(req)
00038 }
00039 self.protocol.send(request_message)
00040
00041
00042 while request_id not in self.responses.keys():
00043 time.sleep(0)
00044
00045 resp = self.responses[request_id]
00046 del self.responses[request_id]
00047 return resp
00048
00049
00050 class AdvertiseService(Capability):
00051
00052 advertise_service_msg_fields = [(True, "service", (str, unicode)), (True, "type", (str, unicode))]
00053
00054 def __init__(self, protocol):
00055
00056 Capability.__init__(self, protocol)
00057
00058
00059 protocol.register_operation("advertise_service", self.advertise_service)
00060
00061 def advertise_service(self, message):
00062
00063 service_name = message["service"]
00064
00065 if AdvertiseService.services_glob is not None and AdvertiseService.services_glob:
00066 self.protocol.log("debug", "Service security glob enabled, checking service: " + service_name)
00067 match = False
00068 for glob in AdvertiseService.services_glob:
00069 if (fnmatch.fnmatch(service_name, glob)):
00070 self.protocol.log("debug", "Found match with glob " + glob + ", continuing service advertisement...")
00071 match = True
00072 break
00073 if not match:
00074 self.protocol.log("warn", "No match found for service, cancelling service advertisement for: " + service_name)
00075 return
00076 else:
00077 self.protocol.log("debug", "No service security glob, not checking service advertisement.")
00078
00079
00080 if service_name in self.protocol.external_service_list.keys():
00081 self.protocol.log("warn", "Duplicate service advertised. Overwriting %s." % service_name)
00082 self.protocol.external_service_list[service_name].service_handle.shutdown("Duplicate advertiser.")
00083 del self.protocol.external_service_list[service_name]
00084
00085
00086 service_type = message["type"]
00087 service_handler = AdvertisedServiceHandler(service_name, service_type, self.protocol)
00088 self.protocol.external_service_list[service_name] = service_handler
00089 self.protocol.log("info", "Advertised service %s." % service_name)