socket_node.cpp
Go to the documentation of this file.
00001 
00026 #include "ros/ros.h"
00027 #include "nmea_msgs/Sentence.h"
00028 
00029 #include "nmea_comms/rx.h"
00030 #include "nmea_comms/tx.h"
00031 
00032 #include <poll.h>
00033 #include <sys/socket.h>
00034 #include <netinet/in.h>
00035 
00036 
00037 void msg_callback(const nmea_msgs::SentenceConstPtr sentence_msg_ptr)
00038 {
00039   // noop
00040 }
00041 
00042 
00043 int main(int argc, char **argv)
00044 {
00045   ros::init(argc, argv, "nmea_socket_node");
00046   ros::NodeHandle n_local("~");
00047   ros::NodeHandle n;
00048 
00049   int listener_fd = socket(AF_INET, SOCK_STREAM, 0);
00050   if (listener_fd < 0)
00051   {
00052     ROS_FATAL("ERROR opening socket");
00053     ros::shutdown();
00054   }
00055 
00056   int port;
00057   n_local.param("port", port, 29500);
00058 
00059   std::string frame_id;
00060   n_local.param<std::string>("frame_id", frame_id, "navsat");
00061 
00062   /* Initialize socket structure */
00063   struct sockaddr_in serv_addr, cli_addr;
00064   bzero((char *) &serv_addr, sizeof(serv_addr));
00065   serv_addr.sin_family = AF_INET;
00066   serv_addr.sin_addr.s_addr = INADDR_ANY;
00067   serv_addr.sin_port = htons(port);
00068 
00069   /* Now bind the host address using bind() call.*/
00070   int previous_success = 1;
00071   while (1)
00072   {
00073     if (bind(listener_fd, (struct sockaddr *) &serv_addr,
00074              sizeof(serv_addr)) < 0)
00075     {
00076       if (previous_success)
00077       {
00078         ROS_ERROR("Unable to bind socket. Is port %d in use? Retrying every 1s.", port);
00079         previous_success = 0;
00080       }
00081       ros::Duration(1.0).sleep();
00082     }
00083     else
00084     {
00085       break;
00086     }
00087   }
00088 
00089   // Start ROS spinning in the background.
00090   ros::AsyncSpinner spinner(1);
00091   spinner.start();
00092 
00093   // Dummy publisher and subscriber.
00094   // These are here because rospy has some bugs related to setting up
00095   // and tearing down the same connection repeatly. So having these topics
00096   // persistently available avoids issues with external Python-based nodes.
00097   // See: https://github.com/ros/ros_comm/issues/129
00098   ros::Publisher dummy_pub = n.advertise<nmea_msgs::Sentence>("nmea_sentence", 5);
00099   ros::Subscriber dummy_sub = n.subscribe<nmea_msgs::Sentence>("nmea_sentence_out", 5, msg_callback);
00100 
00101   // Now start listening for the clients, here
00102   // process will go in sleep mode and will wait
00103   // for the incoming connection
00104   listen(listener_fd, 5);
00105 
00106   unsigned int clilen = sizeof(cli_addr);
00107 
00108   ROS_INFO("Now listening for connections on port %d.", port);
00109   struct pollfd pollfds[] = { { listener_fd, POLLIN, 0 } };
00110   while (ros::ok())
00111   {
00112     int retval = poll(pollfds, 1, 500);
00113     if (retval > 0)
00114     {
00115       int new_client_fd = accept(listener_fd, (struct sockaddr *) &cli_addr, &clilen);
00116       if (new_client_fd < 0)
00117       {
00118         // Error of some kind?
00119       }
00120       else
00121       {
00122         rx_thread_start(n, new_client_fd, frame_id);
00123       }
00124     }
00125     else
00126     {
00127       // just in case
00128       ros::Duration(0.2).sleep();
00129     }
00130   }
00131 
00132   rx_stop_all();
00133 
00134   close(listener_fd);
00135   return 0;
00136 }


nmea_comms
Author(s): Mike Purvis
autogenerated on Sat Jun 8 2019 19:15:21