Go to the documentation of this file.00001 #include <netinet/ip.h>
00002 #include <sys/ioctl.h>
00003 #include <net/if.h>
00004 #include <errno.h>
00005
00006 #include <string>
00007
00008 #include "ros/ros.h"
00009 #include "std_msgs/Bool.h"
00010
00011 static int socket_fd = -1;
00012
00013 bool initSocket()
00014 {
00015 socket_fd = socket( AF_INET, SOCK_DGRAM, 0 );
00016 if( socket_fd != -1 )
00017 return true;
00018 else
00019 return false;
00020 }
00021
00022 bool interfaceIsRunning( std::string interface_name )
00023 {
00024 struct ifreq ifr;
00025
00026 strcpy( ifr.ifr_name, interface_name.c_str() );
00027 if( ioctl( socket_fd, SIOCGIFFLAGS, &ifr ) < 0 )
00028 {
00029 static std::string last_warning;
00030 std::string warning = "Query of interface '" + interface_name + "' failed: '" + strerror( errno ) + "' Presuming down.";
00031 if( warning != last_warning )
00032 {
00033 ROS_WARN("%s", warning.c_str() );
00034 }
00035 last_warning = warning;
00036 return false;
00037 }
00038 bool running = (ifr.ifr_flags & IFF_RUNNING);
00039 bool up = (ifr.ifr_flags & IFF_UP);
00040
00041 return up && running;
00042 }
00043
00044 int main( int argc, char **argv )
00045 {
00046 ros::init( argc, argv, "network_detector" );
00047 ros::NodeHandle node;
00048 std::string interface_name;
00049 if( !ros::param::get( "~interface_name", interface_name ))
00050 {
00051 ROS_FATAL( "No parameter 'interface_name' specified. Don't know which interface to watch. Exiting." );
00052 exit(1);
00053 }
00054 ros::Publisher running_pub = node.advertise<std_msgs::Bool>( "network/connected", 0, true );
00055 int loop_count;
00056 bool first_time = true;
00057 bool was_running = false;
00058 float inner_loop_hertz = 4;
00059 ros::Rate loop_rate( inner_loop_hertz );
00060 if( !initSocket() )
00061 {
00062 ROS_FATAL( "Failed to open socket for network ioctl: '%s'. Exiting.",
00063 strerror( errno ));
00064 exit(1);
00065 }
00066 while( ros::ok() )
00067 {
00068 bool is_running = interfaceIsRunning( interface_name );
00069 if( is_running != was_running || first_time || loop_count > inner_loop_hertz * 5 )
00070 {
00071 if( is_running != was_running )
00072 {
00073 ROS_INFO( "Interface '%s' %s.", interface_name.c_str(), (is_running ? "connected" : "disconnected") );
00074 }
00075
00076 std_msgs::Bool msg;
00077 msg.data = is_running;
00078 running_pub.publish( msg );
00079
00080 loop_count = 0;
00081 first_time = false;
00082 }
00083 ros::spinOnce();
00084 loop_rate.sleep();
00085 loop_count++;
00086 was_running = is_running;
00087 }
00088 }