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
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "wifi_comm/wifi_comm_lib.h"
00038
00039 wifi_comm::WiFiComm::WiFiComm(void(*fp)(char * ip)) : n_()
00040 {
00041 ROS_ERROR("Using the constructor wifi_comm::WiFiComm::WiFiComm(void(*)(char*)) is deprecated. Please change to wifi_comm::WiFiComm::WiFiComm(boost::function<void(char*)>)");
00042
00043 neighbours_sub_ = n_.subscribe("wifi_neighbours_list", 10, &WiFiComm::neighboursListUpdated, this);
00044
00045 c_callback_ = fp;
00046 using_boost_ = false;
00047 }
00048
00049 wifi_comm::WiFiComm::WiFiComm(boost::function<void(char * ip)> f) : n_()
00050 {
00051 neighbours_sub_ = n_.subscribe("wifi_neighbours_list", 10, &WiFiComm::neighboursListUpdated, this);
00052
00053 boost_callback_ = f;
00054 using_boost_ = true;
00055 }
00056
00057 wifi_comm::WiFiComm::~WiFiComm()
00058 {
00059 ROS_INFO("Killing all active foreign relays before exiting...");
00060 for(int i=0 ; i<foreign_relays_.size() ; i++)
00061 {
00062 closeForeignRelay((char*)foreign_relays_[i].ip.c_str());
00063 }
00064 }
00065
00066 char * wifi_comm::WiFiComm::concatTopicAndIp(char * final_topic, char * topic, const char * ip)
00067 {
00068 sprintf(final_topic, "%s_%s", topic, ip);
00069
00070 for(int i=0 ; i<strlen(final_topic) ; i++)
00071 {
00072 if(final_topic[i]=='.') final_topic[i]='_';
00073 }
00074 return final_topic;
00075 }
00076
00077 std::string * wifi_comm::WiFiComm::openForeignRelay(char * ip, char * topic, bool public_publish, bool append_my_ip)
00078 {
00079 ROS_ERROR("Using wifi_comm::WiFiComm::openForeignRelay(char * ip, char * topic, bool public_publish, bool append_my_ip) is deprecated. Please change to wifi_comm::WiFiComm::openForeignRelay(char * ip, char * local_topic, char * foreign_topic).");
00080
00081 ForeignRelay newRelay;
00082
00083 int pid = fork();
00084 if(pid==0)
00085 {
00086 char foreign_topic[STR_SIZE];
00087 char local_topic[STR_SIZE];
00088
00089 if(public_publish) strcpy(local_topic, topic);
00090 else concatTopicAndIp(local_topic, topic, ip);
00091
00092 char ros_master_uri[STR_SIZE];
00093 sprintf(ros_master_uri, "http://%s:11311", ip);
00094 execlp("rosrun", "rosrun", "foreign_relay", "foreign_relay", "adv", ros_master_uri, append_my_ip ? concatTopicAndIp(foreign_topic, topic, (char*)neighbours_list_.self_ip.c_str()) : topic, local_topic, (char*)0);
00095
00096 ROS_WARN("Reached the end of foreign_relay to %s on the topic %s with pid %d", ip, topic, getpid());
00097 exit(0);
00098 }
00099 else if(pid<0)
00100 {
00101 ROS_ERROR("Failed to open foreign_relay to %s on the topic %s", ip, topic);
00102 return NULL;
00103 }
00104 else
00105 {
00106 newRelay.pid = pid;
00107 newRelay.ip = ip;
00108 foreign_relays_.push_back(newRelay);
00109 ROS_INFO("Successfully opened foreign_relay to %s on the topic %s with pid %d", ip, topic, pid);
00110 return &newRelay.ip;
00111 }
00112 return NULL;
00113 }
00114
00115 std::string * wifi_comm::WiFiComm::openForeignRelay(char * ip, char * local_topic, char * foreign_topic)
00116 {
00117 ForeignRelay newRelay;
00118
00119 int pid = fork();
00120 if(pid==0)
00121 {
00122 char ros_master_uri[STR_SIZE];
00123 sprintf(ros_master_uri, "http://%s:11311", ip);
00124 execlp("rosrun", "rosrun", "foreign_relay", "foreign_relay", "adv", ros_master_uri, foreign_topic, local_topic, (char*)0);
00125
00126 ROS_WARN("Reached the end of foreign_relay to %s on the topic %s with pid %d", ip, foreign_topic, getpid());
00127 exit(0);
00128 }
00129 else if(pid<0)
00130 {
00131 ROS_ERROR("Failed to open foreign_relay to %s on the topic %s", ip, foreign_topic);
00132 return NULL;
00133 }
00134 else
00135 {
00136 newRelay.pid = pid;
00137 newRelay.ip = ip;
00138 foreign_relays_.push_back(newRelay);
00139 ROS_INFO("Successfully opened foreign_relay to %s on the topic %s with pid %d", ip, foreign_topic, pid);
00140 return &newRelay.ip;
00141 }
00142 return NULL;
00143 }
00144
00145 void wifi_comm::WiFiComm::closeForeignRelay(char * ip)
00146 {
00147 unsigned int i;
00148
00149 for(i=0 ; i<foreign_relays_.size() ; i++)
00150 {
00151 if(foreign_relays_[i].ip.compare(ip)==0)
00152 {
00153
00154 char cmd[STR_SIZE];
00155 sprintf(cmd, "ps -o pid= --ppid %d", foreign_relays_[i].pid);
00156
00157 char buf[STR_SIZE];
00158 int child_pid;
00159 FILE * ptr;
00160 if((ptr = popen(cmd, "r")) != NULL)
00161 {
00162 fscanf(ptr, "%d", &child_pid);
00163 if(kill(child_pid, SIGTERM)!=0) ROS_WARN("Unable to kill foreign_relay child to %s with pid %d", ip, child_pid);
00164 if(kill(foreign_relays_[i].pid, SIGTERM)!=0) ROS_WARN("Unable to kill foreign_relay to %s with pid %d", ip, foreign_relays_[i].pid);
00165 }
00166 else
00167 {
00168 ROS_WARN("Unable to kill foreign_relay child to %s with ppid %d", ip, foreign_relays_[i].pid);
00169 }
00170 pclose(ptr);
00171
00172 ROS_INFO("Closed foreign_relay to %s with pid %d", ip, foreign_relays_[i].pid);
00173
00174 foreign_relays_.erase(foreign_relays_.begin()+i);
00175 }
00176 }
00177 return;
00178 }
00179
00180 void wifi_comm::WiFiComm::neighboursListUpdated(const wifi_comm::WiFiNeighboursListConstPtr& msg)
00181 {
00182 unsigned int i, j, ind;
00183 bool found;
00184
00185
00186 neighbours_list_.self_ip.assign(msg->self_ip);
00187 neighbours_list_.neighbours.clear();
00188 for(i=0 ; i<msg->neighbours.size() ; i++) neighbours_list_.neighbours.push_back(msg->neighbours[i]);
00189
00190
00191 for(i=0 ; i<msg->neighbours.size() ; i++)
00192 {
00193 found = false;
00194 for(j=0 ; j<foreign_relays_.size() ; j++)
00195 {
00196 if(msg->neighbours[i].ip.compare(foreign_relays_[j].ip)==0)
00197 {
00198 found = true;
00199 break;
00200 }
00201 }
00202
00203 if(!found)
00204 if(using_boost_) boost_callback_((char*)msg->neighbours[i].ip.c_str());
00205 else (c_callback_)((char*)msg->neighbours[i].ip.c_str());
00206 }
00207
00208 for(i=0 ; i<foreign_relays_.size() ; i++)
00209 {
00210 found = false;
00211 for(j=0 ; j<msg->neighbours.size() ; j++)
00212 {
00213 if(foreign_relays_[i].ip.compare(msg->neighbours[j].ip)==0)
00214 {
00215 found = true;
00216 break;
00217 }
00218 }
00219 if(!found) closeForeignRelay((char*)foreign_relays_[i].ip.c_str());
00220 }
00221 }
00222
00223
00224