Go to the documentation of this file.00001
00011
00012
00013
00014
00015 #include <boost/function.hpp>
00016
00017 #include <ros/ros.h>
00018 #include <zeroconf_msgs/AddListener.h>
00019 #include <zeroconf_msgs/RemoveListener.h>
00020 #include <zeroconf_msgs/AddService.h>
00021 #include <zeroconf_msgs/ListDiscoveredServices.h>
00022 #include <zeroconf_msgs/ListPublishedServices.h>
00023
00024 #include "../../include/zeroconf_avahi/zeroconf.hpp"
00025
00026
00027
00028
00029
00030 using namespace zeroconf_avahi;
00031 using namespace zeroconf_msgs;
00032
00033
00034
00035
00036
00043 class ZeroconfNode
00044 {
00045
00046 private:
00047 typedef boost::function<void(zeroconf_msgs::DiscoveredService)> connection_signal_cb;
00048
00049 public:
00050 void init(ros::NodeHandle &nh)
00051 {
00052
00053
00054
00055 server_add_listener = nh.advertiseService("add_listener", &ZeroconfNode::add_listener, this);
00056 server_remove_listener = nh.advertiseService("remove_listener", &ZeroconfNode::remove_listener, this);
00057 server_add_service = nh.advertiseService("add_service", &ZeroconfNode::add_service, this);
00058 server_remove_service = nh.advertiseService("remove_service", &ZeroconfNode::remove_service, this);
00059 server_list_discovered_services = nh.advertiseService("list_discovered_services",
00060 &ZeroconfNode::list_discovered_services, this);
00061 server_list_published_services = nh.advertiseService("list_published_services",
00062 &ZeroconfNode::list_published_services, this);
00063 pub_new_connections = nh.advertise<DiscoveredService>("new_connections", 10);
00064 pub_lost_connections = nh.advertise<DiscoveredService>("lost_connections", 10);
00065
00066
00067
00068
00069
00070 connection_signal_cb new_connection_signal = std::bind1st(std::mem_fun(&ZeroconfNode::new_connections), this);
00071 connection_signal_cb old_connection_signal = std::bind1st(std::mem_fun(&ZeroconfNode::lost_connections), this);
00072 zeroconf.connect_signal_callbacks(new_connection_signal, old_connection_signal);
00073
00074
00075
00076
00077 ros::NodeHandle local_nh("~");
00078
00079 XmlRpc::XmlRpcValue value;
00080 XmlRpc::XmlRpcValue::iterator iter;
00081 if (local_nh.getParam("listeners", value))
00082 {
00083 if (value.getType() != XmlRpc::XmlRpcValue::TypeArray)
00084 {
00085 ROS_ERROR_STREAM("Zeroconf: param variable 'listeners' has malformed type, should be of type array");
00086 }
00087 else
00088 {
00089 for (int i = 0; i < value.size(); ++i)
00090 {
00091 zeroconf.add_listener(value[i]);
00092 }
00093 }
00094 }
00095
00096 XmlRpc::XmlRpcValue value_services;
00097 if (local_nh.getParam("services", value_services))
00098 {
00099 if (value_services.getType() != XmlRpc::XmlRpcValue::TypeArray)
00100 {
00101 ROS_ERROR_STREAM("Zeroconf: param variable 'services' has malformed type, should be of type array");
00102 }
00103 else
00104 {
00105 for (int i = 0; i < value_services.size(); ++i)
00106 {
00107 XmlRpc::XmlRpcValue value_service = value_services[i];
00108 if (value_service.getType() != XmlRpc::XmlRpcValue::TypeStruct)
00109 {
00110 ROS_ERROR_STREAM(
00111 "Zeroconf: " << i << "th element of param variable 'services' has malformed type, should be of type struct");
00112 break;
00113 }
00114 zeroconf_msgs::PublishedService service;
00115 XmlRpc::XmlRpcValue value_name = value_service["name"];
00116 if (value_name.getType() != XmlRpc::XmlRpcValue::TypeString)
00117 {
00118 ROS_ERROR_STREAM("Zeroconf: services[" << i << "]['name'] has malformed type, should be of type string");
00119 break;
00120 }
00121 service.name = std::string(value_name);
00122 if (service.name == "Ros Master")
00123 {
00124
00125 service.name = service.name + " (" + ros::master::getHost() + ")";
00126 }
00127 XmlRpc::XmlRpcValue value_type = value_service["type"];
00128 if (value_type.getType() != XmlRpc::XmlRpcValue::TypeString)
00129 {
00130 ROS_ERROR_STREAM("Zeroconf: services[" << i << "]['type'] has malformed type, should be of type string");
00131 break;
00132 }
00133 service.type = std::string(value_type);
00134 XmlRpc::XmlRpcValue value_domain = value_service["domain"];
00135 if (value_domain.getType() != XmlRpc::XmlRpcValue::TypeString)
00136 {
00137 ROS_ERROR_STREAM("Zeroconf: services[" << i << "]['domain'] has malformed type, should be of type string");
00138 break;
00139 }
00140 service.domain = std::string(value_domain);
00141 XmlRpc::XmlRpcValue value_port = value_service["port"];
00142 if (value_port.getType() == XmlRpc::XmlRpcValue::TypeInvalid)
00143 {
00144 service.port = ros::master::getPort();
00145
00146 ROS_WARN_STREAM(
00147 "Zeroconf: services[" << service.name << "]['port'] wasn't set, default to ros master's port [" << service.port << "]");
00148 }
00149 else if (value_port.getType() != XmlRpc::XmlRpcValue::TypeInt)
00150 {
00151 ROS_ERROR_STREAM(
00152 "Zeroconf: services[" << service.name << "]['port'] has malformed type, should be of type int");
00153 break;
00154 }
00155 else
00156 {
00157 service.port = value_port;
00158 }
00159 XmlRpc::XmlRpcValue value_description = value_service["description"];
00160 if (value_description.getType() != XmlRpc::XmlRpcValue::TypeString)
00161 {
00162 service.description = "";
00163 }
00164 else
00165 {
00166 service.description = std::string(value_description);
00167 }
00168 zeroconf.add_service(service);
00169 }
00170 }
00171 }
00172 }
00173
00174 private:
00175 bool add_listener(AddListener::Request &request, AddListener::Response &response)
00176 {
00177 ROS_DEBUG_STREAM("Zeroconf: serving an add_listener call... [" << request.service_type << "]");
00178 response.result = zeroconf.add_listener(request.service_type);
00179 return true;
00180 }
00181 bool remove_listener(RemoveListener::Request &request, RemoveListener::Response &response)
00182 {
00183 ROS_DEBUG_STREAM("Zeroconf: serving a remove_listener call... [" << request.service_type << "]");
00184 response.result = zeroconf.remove_listener(request.service_type);
00185 return true;
00186 }
00187 bool add_service(AddService::Request &request, AddService::Response &response)
00188 {
00189 response.result = zeroconf.add_service(request.service);
00190 return true;
00191 }
00192 bool remove_service(AddService::Request &request, AddService::Response &response)
00193 {
00194 response.result = zeroconf.remove_service(request.service);
00195 return true;
00196 }
00197 bool list_discovered_services(ListDiscoveredServices::Request &request, ListDiscoveredServices::Response &response)
00198 {
00199 ROS_DEBUG_STREAM("Zeroconf: serving a list_discovered_services call... [" << request.service_type << "]");
00200 zeroconf.list_discovered_services(request.service_type, response.services);
00201 return true;
00202 }
00203 bool list_published_services(ListPublishedServices::Request &request, ListPublishedServices::Response &response)
00204 {
00205 zeroconf.list_published_services(request.service_type, response.services);
00206 return true;
00207 }
00208 void new_connections(DiscoveredService service)
00209 {
00210 pub_new_connections.publish(service);
00211 }
00212 void lost_connections(DiscoveredService service)
00213 {
00214 pub_lost_connections.publish(service);
00215 }
00216
00217 Zeroconf zeroconf;
00218 ros::ServiceServer server_add_listener, server_remove_listener, server_add_service, server_remove_service;
00219 ros::ServiceServer server_list_discovered_services, server_list_published_services;
00220 ros::Publisher pub_new_connections, pub_lost_connections;
00221 };
00222
00223
00224
00225
00226
00227 int main(int argc, char **argv)
00228 {
00229
00230 ros::init(argc, argv, "zeroconf");
00231 ros::NodeHandle nh;
00232 ZeroconfNode zeroconf_node;
00233 zeroconf_node.init(nh);
00234 ros::spin();
00235 return 0;
00236 }