service_client.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2009, Willow Garage, Inc.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *   * Redistributions of source code must retain the above copyright notice,
00007  *     this list of conditions and the following disclaimer.
00008  *   * Redistributions in binary form must reproduce the above copyright
00009  *     notice, this list of conditions and the following disclaimer in the
00010  *     documentation and/or other materials provided with the distribution.
00011  *   * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
00012  *     contributors may be used to endorse or promote products derived from
00013  *     this software without specific prior written permission.
00014  *
00015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00025  * POSSIBILITY OF SUCH DAMAGE.
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   // Non-persistent connections are always valid
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   // If we're shutting down but the node haven't finished yet, wait until we do
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 bool ServiceClient::isPersistent() const
00166 {
00167   if (impl_)
00168   {
00169     return impl_->persistent_;
00170   }
00171 
00172   return false;
00173 }
00174 
00175 void ServiceClient::shutdown()
00176 {
00177   if (impl_)
00178   {
00179     impl_->shutdown();
00180   }
00181 }
00182 
00183 bool ServiceClient::waitForExistence(ros::Duration timeout)
00184 {
00185   if (impl_)
00186   {
00187     return service::waitForService(impl_->name_, timeout);
00188   }
00189 
00190   return false;
00191 }
00192 
00193 bool ServiceClient::exists()
00194 {
00195   if (impl_)
00196   {
00197     return service::exists(impl_->name_, false);
00198   }
00199 
00200   return false;
00201 }
00202 
00203 std::string ServiceClient::getService()
00204 {
00205   if (impl_)
00206   {
00207     return impl_->name_;
00208   }
00209 
00210   return "";
00211 }
00212 
00213 }


roscpp
Author(s): Morgan Quigley, Josh Faust, Brian Gerkey, Troy Straszheim
autogenerated on Tue Mar 7 2017 04:01:03