00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 from functools import partial
00034 from rosbridge_library.capability import Capability
00035 from rosbridge_library.internal.services import ServiceCaller
00036
00037
00038 class CallService(Capability):
00039
00040 call_service_msg_fields = [(True, "service", (str, unicode)),
00041 (False, "fragment_size", (int, type(None))), (False, "compression", (str, unicode))]
00042
00043 def __init__(self, protocol):
00044
00045 Capability.__init__(self, protocol)
00046
00047
00048 protocol.register_operation("call_service", self.call_service)
00049
00050 def call_service(self, message):
00051
00052 cid = message.get("id", None)
00053
00054
00055 self.basic_type_check(message, self.call_service_msg_fields)
00056
00057
00058 service = message["service"]
00059 fragment_size = message.get("fragment_size", None)
00060 compression = message.get("compression", "none")
00061 args = message.get("args", [])
00062
00063
00064 cid = extract_id(service, cid)
00065
00066
00067 s_cb = partial(self._success, cid, service, fragment_size, compression)
00068 e_cb = partial(self._failure, cid, service)
00069
00070
00071 ServiceCaller(trim_servicename(service), args, s_cb, e_cb).start()
00072
00073 def _success(self, cid, service, fragment_size, compression, message):
00074 outgoing_message = {
00075 "op": "service_response",
00076 "service": service,
00077 "values": message,
00078 "result": True
00079 }
00080 if cid is not None:
00081 outgoing_message["id"] = cid
00082
00083 self.protocol.send(outgoing_message)
00084
00085 def _failure(self, cid, service, exc):
00086 self.protocol.log("error", "call_service %s: %s" %
00087 (type(exc).__name__, str(exc)), cid)
00088
00089 outgoing_message = {
00090 "op": "service_response",
00091 "service": service,
00092 "values": str(exc),
00093 "result": False
00094 }
00095 if cid is not None:
00096 outgoing_message["id"] = cid
00097 self.protocol.send(outgoing_message)
00098
00099
00100 def trim_servicename(service):
00101 if '#' in service:
00102 return service[:service.find('#')]
00103 return service
00104
00105
00106 def extract_id(service, cid):
00107 if cid is not None:
00108 return cid
00109 elif '#' in service:
00110 return service[service.find('#') + 1:]