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