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.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 }