YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
NetworkProfilerBasic.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
7
8#include <yarp/os/Network.h>
9#include <yarp/os/LogStream.h>
11#include <yarp/os/Port.h>
13#include <yarp/os/Carrier.h>
14#include <yarp/companion/impl/Companion.h>
15#include <algorithm>
16
17using namespace yarp::os;
18using namespace yarp::profiler;
19
21{
22 l.clear();
23 for (auto it = ports.begin(); it != ports.end(); it++)
24 {
25 std::string ip = it->owner_process.owner_machine.ip;
26 if (std::find(l.begin(), l.end(), ip) == l.end())
27 {
28 l.push_back(ip);
29 }
30 }
31 return true;
32}
33
35{
36 l.clear();
37 for (auto it = ports.begin(); it != ports.end(); it++)
38 {
39 //int pid = it->owner.pid;
40 std::string pid = it->owner_process.process_fullname;
41 if (std::find(l.begin(), l.end(), pid) == l.end())
42 {
43 l.push_back(pid);
44 }
45 }
46 return true;
47}
48
50{
52 bool r = getPortsList(port_names, complete);
53 if (!r) return false;
54
56 for (auto it = port_names.begin(); it != port_names.end(); it++)
57 {
58 PortDetails details;
59 r = getPortDetails(it->name, details);
60 if (!r) { yError() << "getPortDetails of `" << it->name << "`failed"; }
61 ports.push_back(details);
62 }
63 return r;
64}
65
67{
68 filtered_out.clear();
69 for (auto it = in.begin(); it != in.end(); it++)
70 {
71 if (ip != "*") {
72 if (it->owner_process.owner_machine.hostname == ip) { filtered_out.push_back(*it); }
73 }
74 }
75}
76
78{
79 filtered_out.clear();
80 for (auto it = in.begin(); it != in.end(); it++)
81 {
82 if (process_fullname != "*") {
83 if (it->owner_process.process_fullname == process_fullname) { filtered_out.push_back(*it); }
84 }
85 }
86}
87
89{
90 filtered_out.clear();
91 for (auto it = in.begin(); it != in.end(); it++)
92 {
93 if (src_name!="*" && dst_name != "*") {
94 if (it->src.name == src_name && it->src.name == dst_name) { filtered_out.push_back(*it);}
95 }
96 else if (src_name == "*") {
97 if (it->dst.name == dst_name) { filtered_out.push_back(*it); }
98 }
99 else if (dst_name == "*") {
100 if (it->src.name == src_name) {filtered_out.push_back(*it); }
101 }
102 }
103}
104
106{
107 filtered_out.clear();
108 for (auto it = in.begin(); it != in.end(); it++)
109 {
110 if (src_portnumber != "*" && dst_portnumber != "*") {
111 if (it->src.ip == src_portnumber && it->src.ip == dst_portnumber) { filtered_out.push_back(*it); }
112 }
113 else if (src_portnumber == "*") {
114 if (it->dst.ip == dst_portnumber) { filtered_out.push_back(*it); }
115 }
116 else if (dst_portnumber == "*") {
117 if (it->src.ip == src_portnumber) { filtered_out.push_back(*it); }
118 }
119 }
120}
121
123{
124 filtered_out.clear();
125 for (auto it = in.begin(); it != in.end(); it++)
126 {
127 if (src_ip != "*" && dst_ip != "*") {
128 if (it->src.port_number == src_ip && it->src.port_number == dst_ip) { filtered_out.push_back(*it); }
129 }
130 else if (src_ip == "*") {
131 if (it->dst.port_number == dst_ip) { filtered_out.push_back(*it); }
132 }
133 else if (dst_ip == "*") {
134 if (it->src.port_number == src_ip) { filtered_out.push_back(*it); }
135 }
136 }
137}
138
139bool NetworkProfilerBasic::getPortInfo (const std::string& name, const ports_name_set& ports, PortInfo& p)
140{
141 for (auto it = ports.begin(); it != ports.end(); it++)
142 {
143 if (name == it->name)
144 {
145 p.name = it->name;
146 p.ip = it->ip;
147 p.port_number = it->port_number;
148 return true;
149 }
150 }
151 return false;
152}
153
155{
156 //get the list of all the ports
159
160 //for each port, get the list of its connections...
161 for (auto it = ports.begin(); it != ports.end(); it++)
162 {
164 getPortDetails(it->name, info);
166 /*
167 //I will not process incoming connections since probably everything in the system
168 //is determined just looking at the outgoing connections
169 for (auto it2 = info.inputs.begin(); it2 != info.inputs.end(); it2++)
170 {
171 PortInfo p; getPortInfo(it2->name, ports, p);
172 conn.src.name = it2->name;
173 conn.src.ip = p.ip;
174 conn.src.port_number = p.port_number;
175 conn.dst.name = it->name;
176 conn.dst.ip = it->ip;
177 conn.dst.port_number = it->port_number;
178 conn.carrier = it2->carrier;
179 }*/
180 //process all the outgoing connections and put them into a vector
181 for (auto it2 = info.outputs.begin(); it2 != info.outputs.end(); it2++)
182 {
183 PortInfo p; getPortInfo(it2->port_name, ports, p);
184 conn.src.name = it->name;
185 conn.src.ip = it->ip;
186 conn.src.port_number= it->port_number;
187 conn.dst.name = it2->port_name;
188 conn.dst.ip = p.ip;
189 conn.dst.port_number = p.port_number;
190 conn.carrier = it2->carrier;
191
192 //add the connection to the list if it is valid and it is unique
193 //(no other connections with same src/dst/protocol)
194 if (conn.isValid() &&
195 std::find(connections.begin(), connections.end(), conn) == connections.end())
196 {
197 connections.push_back(conn);
198 }
199 }
200 }
201 return true;
202}
203
205 ports.clear();
206
207 ContactStyle style;
208 style.quiet = true;
209 style.timeout = 3.0;
211 Bottle msg, reply;
212 msg.addString("bot");
213 msg.addString("list");
214 if(!NetworkBase::write(Contact(nameserver), msg, reply, style)) {
215 yError() << "Cannot write to yarp name server";
216 return false;
217 }
218
219 if(reply.size() == 0) {
220 yError() << "Empty reply from yarp name server";
221 return false;
222 }
223
224 for (size_t i=1; i<reply.size(); i++) {
225 Bottle *entry = reply.get(i).asList();
226 if(entry != nullptr) {
227 bool shouldTake = false;
228 std::string portname = entry->check("name", Value("")).asString();
229 if(complete)
230 {
231 shouldTake = portname != "";
232 }
233 else
234 {
235 shouldTake = portname != "" && portname != "fallback" && portname != nameserver;
236 }
237 if (shouldTake) {
239 if (c.getCarrier() != "mcast")
240 {
242 portd.name = entry->find("name").asString();
243 portd.ip = entry->find("ip").asString();
244 portd.port_number = std::to_string(entry->find("port_number").asInt32());
245 ports.push_back(portd);
246 }
247 }
248 }
249 }
250
251 return true;
252}
253
254bool NetworkProfilerBasic::getPortDetails(const std::string& portName, PortDetails& details) {
255
256 details.info.name = portName;
257 Port ping;
258 ping.open("...");
259 ping.setAdminMode(true);
260 ping.setTimeout(1.0);
261 if(!NetworkBase::connect(ping.getName(), portName)) {
262 yWarning()<<"Cannot connect to"<<portName;
263 ping.close();
264 return false;
265 }
266
267 // Getting output connections list
268 Bottle cmd, reply;
269 cmd.addString("list"); cmd.addString("out");
270 if(!ping.write(cmd, reply)) {
271 yError()<<"Cannot write (list out) to"<<portName;
272 ping.close();
273 return false;
274 }
275 for(size_t i=0; i<reply.size(); i++) {
277 cnn.port_name = reply.get(i).asString();
279 cmd.clear();
280 cmd.addString("list"); cmd.addString("out"); cmd.addString(cnn.port_name);
281 if (!ping.write(cmd, reply2)) {
282 yWarning()<<"Cannot write (list out"<<cnn.port_name <<") to"<<portName;
283 } else {
284 cnn.carrier = reply2.find("carrier").asString();
285 }
286 details.outputs.push_back(cnn);
287 }
288
289 // Getting input connections list
290 cmd.clear(); reply.clear();
291 cmd.addString("list"); cmd.addString("in");
292 if(!ping.write(cmd, reply)) {
293 yError()<<"Cannot write (list in) to"<<portName;
294 ping.close();
295 return false;
296 }
297 for(size_t i=0; i<reply.size(); i++) {
299 cnn.port_name = reply.get(i).asString();
300 if (cnn.port_name != ping.getName()) {
301 details.inputs.push_back(cnn);
302 }
303 }
304
305 // Getting owner info
306 cmd.clear(); reply.clear();
307 cmd.addString("prop"); cmd.addString("get"); cmd.addString(portName);
308 if(!ping.write(cmd, reply)) {
309 yError()<<"Cannot write (prop get"<<portName<<") to"<<portName;
310 ping.close();
311 return false;
312 }
313
314 Property* process = reply.find("process").asDict();
315 if (!process) {
316 yWarning()<<"Cannot find 'process' property of port "<<portName;
317 } else {
318 std::string process_str = process->toString();
319 details.owner_process.process_name = process->find("name").asString();
320 details.owner_process.arguments = process->find("arguments").asString();
321 details.owner_process.pid = process->find("pid").asInt32();
322 details.owner_process.priority = process->find("priority").asInt32();
323 details.owner_process.policy = process->find("policy").asInt32();
324 details.owner_process.process_fullname = details.owner_process.process_name + "(" + std::to_string(details.owner_process.pid) + ")";
325 }
326
327 Property* platform = reply.find("platform").asDict();
328 if (!platform) {
329 yWarning()<<"Cannot find 'platform' property of port "<<portName;
330 } else {
331 std::string platform_str = platform->toString();
332 details.owner_process.owner_machine.os = platform->find("os").asString();
333 details.owner_process.owner_machine.hostname = platform->find("hostname").asString();
334 details.owner_process.owner_machine.ip = platform->find("hostname").asString();
335 }
336
337 ping.close();
338 return true;
339}
340
342
343 if (timeout <= 0) {
344 timeout = -1;
345 }
346
347 std::stringstream sstream;
348 sstream<<timeout;
349 char* argv[2];
350 argv[0] = (char*) "--timeout";
351 argv[1] = (char*) sstream.str().c_str();
352 yarp::companion::impl::Companion::getInstance().cmdClean(2,argv);
353 return true;
354}
355
357{
358 std::ostringstream str;
359 str << "port name: " << info.name << std::endl;
360 str << "port ip: " << info.ip << std::endl;
361 str << "port port number: " << info.port_number << std::endl;
362 str << "outputs:" << std::endl;
363 std::vector<ConnectedPortInfo>::const_iterator itr;
364 for (itr = outputs.begin(); itr != outputs.end(); itr++) {
365 str << " + " << (*itr).port_name << " (" << (*itr).carrier << ")" << std::endl;
366 }
367 str << "inputs:" << std::endl;
368 for (itr = inputs.begin(); itr != inputs.end(); itr++) {
369 str << " + " << (*itr).port_name << " (" << (*itr).carrier << ")" << std::endl;
370 }
371 str << "owner:" << std::endl;
372 str << " + name: " << owner_process.process_name << std::endl;
373 str << " + arguments: " << owner_process.arguments << std::endl;
374 str << " + hostname: " << owner_process.owner_machine.hostname << std::endl;
375 str << " + priority: " << owner_process.priority << std::endl;
376 str << " + policy: " << owner_process.policy << std::endl;
377 str << " + os: " << owner_process.owner_machine.os << std::endl;
378 str << " + pid: " << owner_process.pid << std::endl;
379 return str.str();
380}
#define yError(...)
Definition Log.h:361
#define yWarning(...)
Definition Log.h:340
A simple collection of objects that can be described and transmitted in a portable way.
Definition Bottle.h:64
size_type size() const
Gets the number of elements in the bottle.
Definition Bottle.cpp:251
Value & get(size_type index) const
Reads a Value v from a certain part of the list.
Definition Bottle.cpp:246
void clear()
Empties the bottle of any objects it contains.
Definition Bottle.cpp:121
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition Bottle.cpp:170
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
Definition Bottle.cpp:287
A mini-server for performing network communication in the background.
std::string getName() const override
Get name of port.
void close() override
Stop port activity.
bool open(const std::string &name) override
Start port operation, with a specific name, with automatically-chosen network parameters.
void write(bool forceStrict=false)
Write the current object being returned by BufferedPort::prepare.
Preferences for how to communicate with a contact.
double timeout
Set a timeout for communication (in units of seconds, fractional seconds allowed).
bool quiet
Suppress all outputs and warnings.
Represents how to reach a part of a YARP network.
Definition Contact.h:33
static Contact fromConfig(const Searchable &config)
Factory method.
Definition Contact.cpp:129
static std::string getNameServerName()
Get the name of the port associated with the nameserver (usually "/root", but this can be overwritten...
Definition Network.cpp:1345
static bool connect(const std::string &src, const std::string &dest, const std::string &carrier="", bool quiet=true)
Request that an output port connect to an input port.
Definition Network.cpp:682
static bool write(const Contact &contact, PortWriter &cmd, PortReader &reply, bool admin=false, bool quiet=false, double timeout=-1)
Send a single command to a port and await a single response.
Definition Network.cpp:1219
A mini-server for network communication.
Definition Port.h:46
A class for storing options and configuration information.
Definition Property.h:33
Value & find(const std::string &key) const override
Gets a value corresponding to a given keyword.
std::string toString() const override
Return a standard text representation of the content of the object.
A single value (typically within a Bottle).
Definition Value.h:43
virtual std::int32_t asInt32() const
Get 32-bit integer value.
Definition Value.cpp:204
virtual Bottle * asList() const
Get list value.
Definition Value.cpp:240
virtual Property * asDict() const
Get dictionary (hash table) value.
Definition Value.cpp:246
virtual std::string asString() const
Get string value.
Definition Value.cpp:234
std::vector< ConnectionDetails > connections_set
static bool getProcessesList(const ports_detail_set &ports, processes_list &l)
static void filterConnectionListByName(const connections_set &in, connections_set &filtered_out, std::string src_name="*", std::string dst_name="*")
static bool getPortsList(ports_name_set &ports, bool complete=false)
static void filterConnectionListByPortNumber(const connections_set &in, connections_set &filtered_out, std::string src_name="*", std::string dst_name="*")
static void filterPortsListByProcess(const ports_detail_set &in, ports_detail_set &filtered_out, std::string fullprocess="*")
std::vector< PortDetails > ports_detail_set
std::vector< std::string > processes_list
static bool getPortDetails(const std::string &portName, PortDetails &info)
static bool yarpClean(float timeout=0.1)
static void filterConnectionListByIp(const connections_set &in, connections_set &filtered_out, std::string src_name="*", std::string dst_name="*")
static bool getConnectionsList(connections_set &connections)
static bool getMachinesList(const ports_detail_set &ports, machines_list &l)
static void filterPortsListByIp(const ports_detail_set &in, ports_detail_set &filtered_out, std::string ip="*")
static bool getPortsDetailedList(ports_detail_set &ports, bool complete=false)
static bool getPortInfo(const std::string &name, const ports_name_set &ports, PortInfo &p)
std::vector< std::string > machines_list
An interface to the operating system, including Port based communication.