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 #include "ros/service_client.h"
00029 #include "ros/service_server_link.h"
00030 #include "ros/connection.h"
00031 #include "ros/service_manager.h"
00032 #include "ros/service.h"
00033
00034 namespace ros
00035 {
00036
00037 ServiceClient::Impl::Impl()
00038 : is_shutdown_(false), constructed_(WallTime::now().toSec())
00039 {
00040 }
00041
00042 ServiceClient::Impl::~Impl()
00043 {
00044 shutdown();
00045 }
00046
00047 void ServiceClient::Impl::shutdown()
00048 {
00049 if (!is_shutdown_)
00050 {
00051 if (!persistent_)
00052 {
00053 is_shutdown_ = true;
00054 }
00055
00056 if (server_link_)
00057 {
00058 server_link_->getConnection()->drop(Connection::Destructing);
00059 server_link_.reset();
00060 }
00061 }
00062 }
00063
00064 bool ServiceClient::Impl::isValid() const
00065 {
00066
00067 if (!persistent_)
00068 {
00069 return true;
00070 }
00071
00072 if (is_shutdown_)
00073 {
00074 return false;
00075 }
00076
00077 if (!server_link_)
00078 {
00079 return false;
00080 }
00081
00082 return server_link_->isValid();
00083 }
00084
00085 ServiceClient::ServiceClient(const std::string& service_name, bool persistent, const M_string& header_values, const std::string& service_md5sum)
00086 : impl_(new Impl)
00087 {
00088 impl_->name_ = service_name;
00089 impl_->persistent_ = persistent;
00090 impl_->header_values_ = header_values;
00091 impl_->service_md5sum_ = service_md5sum;
00092
00093 if (persistent)
00094 {
00095 impl_->server_link_ = ServiceManager::instance()->createServiceServerLink(impl_->name_, impl_->persistent_, impl_->service_md5sum_, impl_->service_md5sum_, impl_->header_values_);
00096 }
00097 }
00098
00099 ServiceClient::ServiceClient(const ServiceClient& rhs)
00100 {
00101 impl_ = rhs.impl_;
00102 }
00103
00104 ServiceClient::~ServiceClient()
00105 {
00106
00107 }
00108
00109 bool ServiceClient::call(const SerializedMessage& req, SerializedMessage& resp, const std::string& service_md5sum)
00110 {
00111 if (service_md5sum != impl_->service_md5sum_)
00112 {
00113 ROS_ERROR("Call to service [%s] with md5sum [%s] does not match md5sum when the handle was created ([%s])", impl_->name_.c_str(), service_md5sum.c_str(), impl_->service_md5sum_.c_str());
00114
00115 return false;
00116 }
00117
00118 ServiceServerLinkPtr link;
00119
00120 if (impl_->persistent_)
00121 {
00122 if (!impl_->server_link_)
00123 {
00124 impl_->server_link_ = ServiceManager::instance()->createServiceServerLink(impl_->name_, impl_->persistent_, service_md5sum, service_md5sum, impl_->header_values_);
00125
00126 if (!impl_->server_link_)
00127 {
00128 return false;
00129 }
00130 }
00131
00132 link = impl_->server_link_;
00133 }
00134 else
00135 {
00136 link = ServiceManager::instance()->createServiceServerLink(impl_->name_, impl_->persistent_, service_md5sum, service_md5sum, impl_->header_values_);
00137
00138 if (!link)
00139 {
00140 return false;
00141 }
00142 }
00143
00144 bool ret = link->call(req, resp);
00145 link.reset();
00146
00147
00148 while (ros::isShuttingDown() && ros::ok())
00149 {
00150 ros::WallDuration(0.001).sleep();
00151 }
00152
00153 return ret;
00154 }
00155
00156 bool ServiceClient::isValid() const
00157 {
00158 if (!impl_)
00159 {
00160 return false;
00161 }
00162
00163 return impl_->isValid();
00164 }
00165
00166 void ServiceClient::shutdown()
00167 {
00168 if (impl_)
00169 {
00170 impl_->shutdown();
00171 }
00172 }
00173
00174 bool ServiceClient::waitForExistence(ros::Duration timeout)
00175 {
00176 if (impl_)
00177 {
00178 return service::waitForService(impl_->name_, timeout);
00179 }
00180
00181 return false;
00182 }
00183
00184 bool ServiceClient::exists()
00185 {
00186 if (impl_)
00187 {
00188 return service::exists(impl_->name_, false);
00189 }
00190
00191 return false;
00192 }
00193
00194 std::string ServiceClient::getService()
00195 {
00196 if (impl_)
00197 {
00198 return impl_->name_;
00199 }
00200
00201 return "";
00202 }
00203
00204 }