$search
00001 /* 00002 * Copyright (C) 2008, Morgan Quigley and 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.h" 00029 #include "ros/connection.h" 00030 #include "ros/service_server_link.h" 00031 #include "ros/service_manager.h" 00032 #include "ros/transport/transport_tcp.h" 00033 #include "ros/poll_manager.h" 00034 #include "ros/init.h" 00035 #include "ros/names.h" 00036 #include "ros/this_node.h" 00037 #include "ros/header.h" 00038 00039 using namespace ros; 00040 00041 bool service::exists(const std::string& service_name, bool print_failure_reason) 00042 { 00043 std::string mapped_name = names::resolve(service_name); 00044 00045 std::string host; 00046 uint32_t port; 00047 00048 if (ServiceManager::instance()->lookupService(mapped_name, host, port)) 00049 { 00050 TransportTCPPtr transport(new TransportTCP(0, TransportTCP::SYNCHRONOUS)); 00051 00052 if (transport->connect(host, port)) 00053 { 00054 M_string m; 00055 m["probe"] = "1"; 00056 m["md5sum"] = "*"; 00057 m["callerid"] = this_node::getName(); 00058 m["service"] = mapped_name; 00059 boost::shared_array<uint8_t> buffer; 00060 uint32_t size = 0;; 00061 Header::write(m, buffer, size); 00062 transport->write((uint8_t*)&size, sizeof(size)); 00063 transport->write(buffer.get(), size); 00064 transport->close(); 00065 00066 return true; 00067 } 00068 else 00069 { 00070 if (print_failure_reason) 00071 { 00072 ROS_INFO("waitForService: Service [%s] could not connect to host [%s:%d], waiting...", mapped_name.c_str(), host.c_str(), port); 00073 } 00074 } 00075 } 00076 else 00077 { 00078 if (print_failure_reason) 00079 { 00080 ROS_INFO("waitForService: Service [%s] has not been advertised, waiting...", mapped_name.c_str()); 00081 } 00082 } 00083 00084 return false; 00085 } 00086 00087 bool service::waitForService(const std::string& service_name, ros::Duration timeout) 00088 { 00089 std::string mapped_name = names::resolve(service_name); 00090 00091 Time start_time = Time::now(); 00092 00093 bool printed = false; 00094 bool result = false; 00095 while (ros::ok()) 00096 { 00097 if (exists(service_name, !printed)) 00098 { 00099 result = true; 00100 break; 00101 } 00102 else 00103 { 00104 printed = true; 00105 00106 if (timeout >= Duration(0)) 00107 { 00108 Time current_time = Time::now(); 00109 00110 if ((current_time - start_time) >= timeout) 00111 { 00112 return false; 00113 } 00114 } 00115 00116 Duration(0.02).sleep(); 00117 } 00118 } 00119 00120 if (printed && ros::ok()) 00121 { 00122 ROS_INFO("waitForService: Service [%s] is now available.", mapped_name.c_str()); 00123 } 00124 00125 return result; 00126 } 00127 00128 bool service::waitForService(const std::string& service_name, int32_t timeout) 00129 { 00130 return waitForService(service_name, ros::Duration(timeout / 1000.0)); 00131 }