YARP
Yet Another Robot Platform
TcpRosCarrier.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2020 Istituto Italiano di Tecnologia (IIT)
3  * All rights reserved.
4  *
5  * This software may be modified and distributed under the terms of the
6  * BSD-3-Clause license. See the accompanying LICENSE file for details.
7  */
8 
9 #include "TcpRosCarrier.h"
10 #include "RosSlave.h"
11 #include "TcpRosLogComponent.h"
12 
13 #include <string>
14 #include <map>
15 
16 #include <yarp/os/Bytes.h>
18 #include <yarp/os/NetType.h>
19 #include <yarp/os/Name.h>
20 #include <yarp/os/Route.h>
22 
23 using namespace yarp::os;
24 using namespace yarp::sig;
25 using namespace yarp::wire_rep_utils;
26 using namespace std;
27 
28 void TcpRosCarrier::setParameters(const Bytes& header) {
29  if (header.length()!=8) {
30  return;
31  }
32  headerLen1 = *reinterpret_cast<const NetInt32*>(header.get());
33  headerLen2 = *reinterpret_cast<const NetInt32*>(header.get() + 4);
34 }
35 
36 bool TcpRosCarrier::checkHeader(const Bytes& header) {
37  if (header.length()!=8) {
38  return false;
39  }
40  setParameters(header);
41  if (!(headerLen1<60000&&headerLen1>0 &&
42  headerLen2<60000&&headerLen2>0)) {
43  // not tcpros
44  return false;
45  }
46  // plausibly tcpros.
47  yCTrace(TCPROSCARRIER, "tcpros! %d %d", headerLen1,headerLen2);
48  return true;
49 }
50 
51 
52 std::string TcpRosCarrier::getRosType(ConnectionState& proto) {
53  std::string typ;
54  std::string rtyp;
55  if (proto.getContactable()) {
56  Type t = proto.getContactable()->getType();
57  typ = t.getName();
58  md5sum = t.readProperties().find("md5sum").asString();
59  message_definition = t.readProperties().find("message_definition").asString();
60  user_type = typ;
61  if (typ=="yarp/image") {
62  wire_type = "sensor_msgs/Image";
63  rtyp = "";
64  } else if (typ=="yarp/bottle") {
65  rtyp = proto.getContactable()->getType().getNameOnWire();
66  if (rtyp=="yarp/image") rtyp = "sensor_msgs/Image";
67  wire_type = rtyp;
68  } else if (typ!="") {
69  rtyp = typ;
70  wire_type = typ;
71  }
72  }
73  Name n(proto.getRoute().getCarrierName() + "://test");
74  std::string mode = "topic";
75  std::string modeValue = n.getCarrierModifier("topic");
76  if (modeValue=="") {
77  mode = "service";
78  modeValue = n.getCarrierModifier("service");
79  }
80  if (modeValue!="") {
81  std::string package = n.getCarrierModifier("package");
82  if (package!="") {
83  rtyp = package + "/" + modeValue;
84  }
85  }
86 
87  yCTrace(TCPROSCARRIER, "USER TYPE %s", user_type.c_str());
88  yCTrace(TCPROSCARRIER, "WIRE TYPE %s", wire_type.c_str());
89 
90  return rtyp;
91 }
92 
94  yCTrace(TCPROSCARRIER, "Route is %s", proto.getRoute().toString().c_str());
95  Name n(proto.getRoute().getCarrierName() + "://test");
96  std::string mode = "topic";
97  std::string modeValue = n.getCarrierModifier("topic");
98  if (modeValue=="") {
99  mode = "service";
100  modeValue = n.getCarrierModifier("service");
101  isService = true;
102  }
103  if (modeValue=="") {
104  yCInfo(TCPROSCARRIER, "*** no topic or service specified!");
105  mode = "topic";
106  modeValue = "notopic";
107  isService = false;
108  }
109  std::string rawValue = n.getCarrierModifier("raw");
110  if (rawValue=="2") {
111  raw = 2;
112  yCTrace(TCPROSCARRIER, "ROS-native mode requested");
113  } else if (rawValue=="1") {
114  raw = 1;
115  yCTrace(TCPROSCARRIER, "Raw mode requested");
116  } else if (rawValue=="0") {
117  raw = 0;
118  yCTrace(TCPROSCARRIER, "Cooked mode requested");
119  }
120 
121  RosHeader header;
122  yCTrace(TCPROSCARRIER, "Writing to %s", proto.getStreams().getRemoteAddress().toString().c_str());
123  yCTrace(TCPROSCARRIER, "Writing from %s", proto.getStreams().getLocalAddress().toString().c_str());
124 
125  std::string rtyp = getRosType(proto);
126  if (rtyp!="") {
127  header.data["type"] = rtyp;
128  }
129  header.data[mode] = modeValue;
130  header.data["md5sum"] = (md5sum!="")?md5sum:"*";
131  if (message_definition!="") {
132  header.data["message_definition"] = message_definition;
133  }
134  NestedContact nc(proto.getRoute().getFromName());
135  header.data["callerid"] = nc.getNodeName();
136  header.data["persistent"] = "1";
137  string header_serial = header.writeHeader();
138  string header_len(4,'\0');
139  char *at = (char*)header_len.c_str();
140  RosHeader::appendInt32(at,header_serial.length());
141  yCTrace(TCPROSCARRIER, "Writing %s -- %d bytes",
142  RosHeader::showMessage(header_len).c_str(),
143  (int)header_len.length());
144 
145  Bytes b1((char*)header_len.c_str(),header_len.length());
146  proto.os().write(b1);
147  yCTrace(TCPROSCARRIER, "Writing %s -- %d bytes",
148  RosHeader::showMessage(header_serial).c_str(),
149  (int)header_serial.length());
150  Bytes b2((char*)header_serial.c_str(),header_serial.length());
151  proto.os().write(b2);
152 
153  return proto.os().isOk();
154 }
155 
156 
158  RosHeader header;
159 
160  char mlen[4];
161  Bytes mlen_buf(mlen,4);
162 
163  int res = proto.is().readFull(mlen_buf);
164  if (res<4) {
165  yCWarning(TCPROSCARRIER, "Fail %s %d", __FILE__, __LINE__);
166  return false;
167  }
168  int len = NetType::netInt(mlen_buf);
169  yCTrace(TCPROSCARRIER, "Len %d", len);
170  if (len>10000) {
171  yCWarning(TCPROSCARRIER, "not ready for serious messages");
172  return false;
173  }
174  ManagedBytes m(len);
175  res = proto.is().readFull(m.bytes());
176  if (res!=len) {
177  yCWarning(TCPROSCARRIER, "Fail %s %d", __FILE__, __LINE__);
178  return false;
179  }
180  header.readHeader(string(m.get(),m.length()));
181  yCTrace(TCPROSCARRIER, "Message header: %s", header.toString().c_str());
182  std::string rosname;
183  if (header.data.find("type")!=header.data.end()) {
184  rosname = header.data["type"];
185  }
186  yCTrace(TCPROSCARRIER, "<incoming> Type of data is [%s]s", rosname.c_str());
187  if (header.data.find("callerid")!=header.data.end()) {
188  string name = header.data["callerid"];
189  yCTrace(TCPROSCARRIER, "<incoming> callerid is %s", name.c_str());
190  yCTrace(TCPROSCARRIER, "Route was %s", proto.getRoute().toString().c_str());
191  Route route = proto.getRoute();
192  route.setToName(name);
193  proto.setRoute(route);
194  yCTrace(TCPROSCARRIER, "Route is now %s", proto.getRoute().toString().c_str());
195  }
196 
197  if (!isService) {
198  isService = (header.data.find("request_type")!=header.data.end());
199  }
200  if (rosname!="" && (user_type != wire_type || user_type == "")) {
201  kind = TcpRosStream::rosToKind(rosname.c_str());
202  TcpRosStream::configureTwiddler(twiddler,kind.c_str(),rosname.c_str(),false,false);
203  translate = TCPROS_TRANSLATE_TWIDDLER;
204  } else {
205  rosname = "";
206  }
207  yCTrace(TCPROSCARRIER, "tcpros %s mode", isService?"service":"topic");
208 
209  // we may be a pull stream
210  sender = isService;
211 
212  processRosHeader(header);
213 
214  auto* stream = new TcpRosStream(proto.giveStreams(),
215  sender,
216  sender,
217  isService,
218  raw,
219  rosname.c_str());
220 
221  if (stream==nullptr) { return false; }
222 
223  yCTrace(TCPROSCARRIER, "Getting ready to hand off streams...");
224 
225  proto.takeStreams(stream);
226 
227  return proto.is().isOk();
228 }
229 
231  Route route = proto.getRoute();
232  route.setFromName("tcpros");
233  proto.setRoute(route);
234  yCTrace(TCPROSCARRIER, "Trying for tcpros header");
235  ManagedBytes m(headerLen1);
236  Bytes mrem(m.get()+4,m.length()-4);
237  NetInt32 ni = headerLen2;
238  memcpy(m.get(),(char*)(&ni), 4);
239  yCTrace(TCPROSCARRIER, "reading %d bytes", (int)mrem.length());
240  int res = proto.is().readFull(mrem);
241  yCTrace(TCPROSCARRIER, "read %d bytes", res);
242  if (res!=(int)mrem.length()) {
243  if (res>=0) {
244  yCError(TCPROSCARRIER, "TCPROS header failure, expected %d bytes, got %d bytes",
245  (int)mrem.length(),res);
246  } else {
247  yCError(TCPROSCARRIER, "TCPROS connection has gone terribly wrong");
248  }
249  return false;
250  }
251  RosHeader header;
252  header.readHeader(string(m.get(),m.length()));
253  yCTrace(TCPROSCARRIER, "Got header %s", header.toString().c_str());
254 
255  std::string rosname;
256  if (header.data.find("type")!=header.data.end()) {
257  rosname = header.data["type"];
258  }
259  std::string rtyp = getRosType(proto);
260  if (rtyp!="") {
261  rosname = rtyp;
262  header.data["type"] = rosname;
263  header.data["md5sum"] = (md5sum!="")?md5sum:"*";
264  if (message_definition!="") {
265  header.data["message_definition"] = message_definition;
266  }
267  }
268  yCTrace(TCPROSCARRIER, "<outgoing> Type of data is %s", rosname.c_str());
269 
270  route = proto.getRoute();
271  if (header.data.find("callerid")!=header.data.end()) {
272  route.setFromName(header.data["callerid"]);
273  } else {
274  route.setFromName("tcpros");
275  }
276  proto.setRoute(route);
277 
278  // Let's just ignore everything that is sane and holy, and
279  // send the same header right back.
280  // **UPDATE** Oh, ok, let's modify the callerid. Begrudgingly.
281  NestedContact nc(proto.getRoute().getToName());
282  header.data["callerid"] = nc.getNodeName();
283 
284  string header_serial = header.writeHeader();
285  string header_len(4,'\0');
286  char *at = (char*)header_len.c_str();
287  RosHeader::appendInt32(at,header_serial.length());
288  yCTrace(TCPROSCARRIER, "Writing %s -- %d bytes",
289  RosHeader::showMessage(header_len).c_str(),
290  (int)header_len.length());
291 
292  Bytes b1((char*)header_len.c_str(),header_len.length());
293  proto.os().write(b1);
294  yCTrace(TCPROSCARRIER, "Writing %s -- %d bytes",
295  RosHeader::showMessage(header_serial).c_str(),
296  (int)header_serial.length());
297  Bytes b2((char*)header_serial.c_str(),header_serial.length());
298  proto.os().write(b2);
299 
300  if (header.data.find("probe")!=header.data.end()) {
301  yCTrace(TCPROSCARRIER, "================PROBE===============");
302  return false;
303  }
304 
305 
306  if (!isService) {
307  isService = (header.data.find("service")!=header.data.end());
308  }
309  if (rosname!="" && (user_type != wire_type || user_type == "")) {
310  if (wire_type!="sensor_msgs/Image") { // currently using a custom method for images
311  kind = TcpRosStream::rosToKind(rosname.c_str());
312  TcpRosStream::configureTwiddler(twiddler,kind.c_str(),rosname.c_str(),true,true);
313  translate = TCPROS_TRANSLATE_TWIDDLER;
314  }
315  } else {
316  rosname = "";
317  }
318  sender = isService;
319 
320  processRosHeader(header);
321 
322  if (isService) {
323  auto* stream = new TcpRosStream(proto.giveStreams(),
324  sender,
325  false,
326  isService,
327  raw,
328  rosname.c_str());
329  if (stream==nullptr) { return false; }
330  proto.takeStreams(stream);
331  return proto.is().isOk();
332  }
333 
334  return true;
335 }
336 
338  SizedWriter *flex_writer = &writer;
339 
340  if (raw!=2) {
341  // At startup, we check for what kind of messages are going
342  // through, and prepare an appropriate byte-rejiggering if
343  // needed.
344  if (translate==TCPROS_TRANSLATE_UNKNOWN) {
345  yCTrace(TCPROSCARRIER, "* TCPROS_TRANSLATE_UNKNOWN");
346  FlexImage *img = nullptr;
347  if (user_type=="yarp/image"||user_type=="yarp/bottle") {
348  img = wi.checkForImage(writer);
349  }
350  if (img) {
351  translate = TCPROS_TRANSLATE_IMAGE;
352  std::string frame = "/frame";
353  ri.init(*img,frame);
354  } else {
355  if (WireBottle::extractBlobFromBottle(writer,wt)) {
356  translate = TCPROS_TRANSLATE_BOTTLE_BLOB;
357  } else {
358  translate = TCPROS_TRANSLATE_INHIBIT;
359  }
360  }
361  }
362  } else {
363  translate = TCPROS_TRANSLATE_INHIBIT;
364  }
365 
366  // Apply byte-rejiggering if needed.
367  switch (translate) {
369  {
370  yCTrace(TCPROSCARRIER, "* TCPROS_TRANSLATE_IMAGE");
371  FlexImage *img = wi.checkForImage(writer);
372  if (img==nullptr) {
373  yCError(TCPROSCARRIER, "TCPROS Expected an image, but did not get one.");
374  return false;
375  }
376  ri.update(img,seq,Time::now()); // Time here is the timestamp of the ROS message, so Time::now(), the mutable one is correct.
377  seq++;
378  flex_writer = &ri;
379  }
380  break;
382  {
383  yCTrace(TCPROSCARRIER, "* TCPROS_TRANSLATE_BOTTLE_BLOB");
384  if (!WireBottle::extractBlobFromBottle(writer,wt)) {
385  yCError(TCPROSCARRIER, "TCPROS Expected a bottle blob, but did not get one.");
386  return false;
387  }
388  flex_writer = &wt;
389  }
390  break;
392  {
393  yCTrace(TCPROSCARRIER, "* TCPROS_TRANSLATE_TWIDDLER");
394  twiddler_output.attach(writer,twiddler);
395  if (twiddler_output.update()) {
396  flex_writer = &twiddler_output;
397  } else {
398  flex_writer = nullptr;
399  }
400  }
401  break;
403  yCTrace(TCPROSCARRIER, "* TCPROS_TRANSLATE_INHIBIT");
404  break;
405  default:
406  yCTrace(TCPROSCARRIER, "* TCPROS_TRANSLATE_OTHER");
407  break;
408  }
409 
410  if (flex_writer == nullptr) {
411  return false;
412  }
413 
414  int len = 0;
415  for (size_t i=0; i<flex_writer->length(); i++) {
416  len += (int)flex_writer->length(i);
417  }
418  yCTrace(TCPROSCARRIER, "Prepping to write %d blocks (%d bytes)",
419  (int)flex_writer->length(),
420  len);
421 
422  string header_len(4,'\0');
423  char *at = (char*)header_len.c_str();
424  RosHeader::appendInt32(at,len);
425  Bytes b1((char*)header_len.c_str(),header_len.length());
426  proto.os().write(b1);
427  flex_writer->write(proto.os());
428 
429  yCTrace(TCPROSCARRIER, "done sending");
430 
431  if (isService) {
432  if (!sender) {
433  if (!persistent) {
434  proto.os().close();
435  }
436  }
437  }
438 
439  return proto.getStreams().isOk();
440 }
441 
443  char twiddle[1];
444  twiddle[0] = 1;
445  Bytes twiddle_buf(twiddle,1);
446  proto.os().write(twiddle_buf);
447  return write(proto,writer);
448 }
449 
450 
452  const yarp::os::Contact& dest,
453  const yarp::os::ContactStyle& style,
454  int mode,
455  bool reversed) {
456  switch (mode) {
458  yCInfo(TCPROSCARRIER, "tcpros disconnect not implemented yet in this direction ");
459  return -1;
460  break;
461  case YARP_ENACT_EXISTS:
462  yCInfo(TCPROSCARRIER, "tcpros connection check not implemented yet in this direction ");
463  return -1;
464  break;
465  }
466 
467  if (!reversed) return -1;
468 
469  Contact fullDest = dest;
470  if (fullDest.getPort()<=0) {
471  fullDest = NetworkBase::queryName(fullDest.getName());
472  }
473 
474  Contact fullSrc = src;
475  if (fullSrc.getPort()<=0) {
476  fullSrc = NetworkBase::queryName(fullSrc.getName());
477  }
478 
479  Name n(style.carrier + "://test");
480  std::string topic = n.getCarrierModifier("topic");
481  if (topic=="") {
482  yCInfo(TCPROSCARRIER, "Warning, no topic!");
483  topic = "notopic";
484  }
485 
486  RosSlave slave;
487  yCTrace(TCPROSCARRIER, "Starting temporary slave");
488  slave.start(fullDest.getHost().c_str(),fullDest.getPort());
489  Contact addr_slave = slave.where();
490  Bottle cmd, reply;
491  cmd.addString("publisherUpdate");
492  cmd.addString("dummy_id");
493  cmd.addString(topic);
494  Bottle& lst = cmd.addList();
495  char buf[1000];
496  sprintf(buf,"http://%s:%d/", addr_slave.getHost().c_str(),
497  addr_slave.getPort());
498  lst.addString(buf);
499  ContactStyle req;
500  req.carrier = "xmlrpc";
501  req.timeout = 4;
502  req.quiet = false;
503  bool ok = NetworkBase::write(fullSrc,cmd,reply,req);
504  yCTrace(TCPROSCARRIER, "%s",reply.toString().c_str());
505  if (!ok) {
506  yCError(TCPROSCARRIER, "error talking to %s", fullSrc.toString().c_str());
507  }
508  slave.stop();
509  if (!slave.isOk()) {
510  yCError(TCPROSCARRIER, "Problem: did not get a callback from ROS - can happen if connection already exists.");
511  ok = false;
512  }
513 
514  return ok?0:1;
515 }
516 
517 
518 void TcpRosCarrier::processRosHeader(RosHeader& header) {
519  if (header.data.find("persistent")!=header.data.end()) {
520  persistent = (header.data["persistent"]=="1");
521  } else {
522  persistent = false;
523  }
524 }
yarp::os::Route::toString
std::string toString() const
Render a text form of the route, "source->carrier->dest".
Definition: Route.cpp:141
yarp::os::TwoWayStream::getLocalAddress
virtual const Contact & getLocalAddress() const =0
Get the address of the local side of the stream.
TcpRosCarrier.h
TCPROS_TRANSLATE_IMAGE
#define TCPROS_TRANSLATE_IMAGE
Definition: TcpRosCarrier.h:23
yarp::os::Bottle
A simple collection of objects that can be described and transmitted in a portable way.
Definition: Bottle.h:73
yarp::os::SizedWriter::length
virtual size_t length() const =0
yarp::os::Bottle::toString
std::string toString() const override
Gives a human-readable textual representation of the bottle.
Definition: Bottle.cpp:214
yarp::os::Route::getCarrierName
const std::string & getCarrierName() const
Get the carrier type of the route.
Definition: Route.cpp:126
yarp::os::ContactStyle
Preferences for how to communicate with a contact.
Definition: ContactStyle.h:27
yarp::os::NestedContact
A placeholder for rich contact information.
Definition: NestedContact.h:27
yarp::os::OutputStream::close
virtual void close()=0
Terminate the stream.
yarp::sig
Signal processing.
Definition: Image.h:25
t
float t
Definition: FfmpegWriter.cpp:74
yCWarning
#define yCWarning(component,...)
Definition: LogComponent.h:146
yarp::os::ConnectionState::giveStreams
virtual TwoWayStream * giveStreams()=0
Take ownership of the streams associated with the connection.
yarp::os::Type
Definition: Type.h:24
yarp::os::OutputStream::write
virtual void write(char ch)
Write a single byte to the stream.
Definition: OutputStream.cpp:17
TcpRosStream::rosToKind
static std::map< std::string, std::string > rosToKind()
yarp::os::Contact::getName
std::string getName() const
Get the name associated with this Contact.
Definition: Contact.cpp:208
yarp::os::NetworkBase::write
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:1229
RosHeader::appendInt32
static void appendInt32(char *&buf, int x)
Definition: RosHeader.cpp:20
TCPROS_TRANSLATE_INHIBIT
#define TCPROS_TRANSLATE_INHIBIT
Definition: TcpRosCarrier.h:21
TCPROS_TRANSLATE_BOTTLE_BLOB
#define TCPROS_TRANSLATE_BOTTLE_BLOB
Definition: TcpRosCarrier.h:24
yarp::os::NestedContact::getNodeName
std::string getNodeName() const
Definition: NestedContact.cpp:184
TcpRosCarrier::expectReplyToHeader
bool expectReplyToHeader(yarp::os::ConnectionState &proto) override
Process reply to header, if one is expected for this carrier.
Definition: TcpRosCarrier.cpp:157
yarp::os::SizedWriter::write
virtual void write(OutputStream &os)
Definition: SizedWriter.cpp:19
yarp::os::Route
Information about a connection between two ports.
Definition: Route.h:32
TcpRosStream::configureTwiddler
static bool configureTwiddler(yarp::wire_rep_utils::WireTwiddler &twiddler, const char *txt, const char *prompt, bool sender, bool reply)
RosSlave::isOk
bool isOk()
Definition: RosSlave.h:64
RosHeader::readHeader
bool readHeader(const std::string &bin)
Definition: RosHeader.cpp:63
RosHeader::showMessage
static std::string showMessage(std::string s)
Definition: RosHeader.cpp:32
yarp::os::Time::now
double now()
Return the current time in seconds, relative to an arbitrary starting point.
Definition: Time.cpp:124
Name.h
yarp::os::Contact::toString
std::string toString() const
Get a textual representation of the Contact.
Definition: Contact.cpp:306
NetType.h
RosSlave.h
yarp::os::ManagedBytes::bytes
const Bytes & bytes() const
Definition: ManagedBytes.cpp:177
TcpRosStream
Definition: TcpRosStream.h:27
yarp::os::NetworkBase::queryName
static Contact queryName(const std::string &name)
Find out information about a registered name.
Definition: Network.cpp:998
yarp::os::ConnectionState::takeStreams
virtual void takeStreams(TwoWayStream *streams)=0
Provide streams to be used with the connection.
yarp::os::Type::getNameOnWire
std::string getNameOnWire() const
Definition: Type.cpp:147
yarp::os::ConnectionState::os
OutputStream & os()
Shorthand for getOutputStream()
Definition: ConnectionState.h:117
yarp::os::ConnectionState::getRoute
virtual const Route & getRoute() const =0
Get the route associated with this connection.
yarp::os::ManagedBytes
An abstraction for a block of bytes, with optional responsibility for allocating/destroying that bloc...
Definition: ManagedBytes.h:25
Route.h
ConnectionState.h
yarp::os::ContactStyle::quiet
bool quiet
Suppress all outputs and warnings.
Definition: ContactStyle.h:39
yarp::os::Bottle::addList
Bottle & addList()
Places an empty nested list in the bottle, at the end of the list.
Definition: Bottle.cpp:185
yarp::os::Contact::getPort
int getPort() const
Get the port number associated with this Contact for socket communication.
Definition: Contact.cpp:242
yarp::sig::FlexImage
Image class with user control of representation details.
Definition: Image.h:403
RosHeader::writeHeader
std::string writeHeader()
Definition: RosHeader.cpp:42
yarp::os::Bytes::get
const char * get() const
Definition: Bytes.cpp:30
yarp::os::ConnectionState::setRoute
virtual void setRoute(const Route &route)=0
Set the route associated with this connection.
yarp::os::Bytes::length
size_t length() const
Definition: Bytes.cpp:25
TcpRosCarrier::expectSenderSpecifier
bool expectSenderSpecifier(yarp::os::ConnectionState &proto) override
Expect the name of the sending port.
Definition: TcpRosCarrier.cpp:230
TcpRosCarrier::checkHeader
bool checkHeader(const yarp::os::Bytes &header) override
Given the first 8 bytes received on a connection, decide if this is the right carrier type to use for...
Definition: TcpRosCarrier.cpp:36
RosSlave::start
void start(const char *hostname, int portnum)
Definition: RosSlave.h:36
RosHeader::data
std::map< std::string, std::string > data
Definition: RosHeader.h:18
yarp::os::Name::getCarrierModifier
std::string getCarrierModifier(const char *mod, bool *hasModifier=nullptr)
Definition: Name.cpp:47
YARP_ENACT_DISCONNECT
#define YARP_ENACT_DISCONNECT
Definition: Carrier.h:16
yarp::os::TwoWayStream::getRemoteAddress
virtual const Contact & getRemoteAddress() const =0
Get the address of the remote side of the stream.
yarp::os::Name
Simple abstraction for a YARP port name.
Definition: Name.h:22
TcpRosCarrier::sendHeader
bool sendHeader(yarp::os::ConnectionState &proto) override
Write a header appropriate to the carrier to the connection, followed by any carrier-specific data.
Definition: TcpRosCarrier.cpp:93
yarp::os::ConnectionState::getStreams
virtual TwoWayStream & getStreams()=0
Access the streams associated with the connection.
yarp::os::InputStream::isOk
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
yarp::os::Bottle::addString
void addString(const char *str)
Places a string in the bottle, at the end of the list.
Definition: Bottle.cpp:173
yarp::os::Bytes
A simple abstraction for a block of bytes.
Definition: Bytes.h:28
RosHeader::toString
std::string toString() const
Definition: RosHeader.cpp:90
TcpRosCarrier::write
bool write(yarp::os::ConnectionState &proto, yarp::os::SizedWriter &writer) override
Write a message.
Definition: TcpRosCarrier.cpp:337
RosSlave
Definition: RosSlave.h:22
RosSlave::stop
void stop()
Definition: RosSlave.h:43
yarp::os::ConnectionState
The basic state of a connection - route, streams in use, etc.
Definition: ConnectionState.h:31
yCError
#define yCError(component,...)
Definition: LogComponent.h:157
yarp::os::OutputStream::isOk
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
TcpRosCarrier::connect
virtual int connect(const yarp::os::Contact &src, const yarp::os::Contact &dest, const yarp::os::ContactStyle &style, int mode, bool reversed) override
Some carrier types may require special connection logic.
Definition: TcpRosCarrier.cpp:451
yarp::os::InputStream::readFull
yarp::conf::ssize_t readFull(Bytes &b)
Keep reading until buffer is full.
Definition: InputStream.cpp:99
yarp::os::ContactStyle::carrier
std::string carrier
Request that communication be made using a particular carrier.
Definition: ContactStyle.h:56
yCInfo
#define yCInfo(component,...)
Definition: LogComponent.h:135
yarp::os
An interface to the operating system, including Port based communication.
Definition: AbstractCarrier.h:17
TCPROS_TRANSLATE_TWIDDLER
#define TCPROS_TRANSLATE_TWIDDLER
Definition: TcpRosCarrier.h:25
TcpRosLogComponent.h
TCPROS_TRANSLATE_UNKNOWN
#define TCPROS_TRANSLATE_UNKNOWN
Definition: TcpRosCarrier.h:22
yarp::os::Route::setFromName
void setFromName(const std::string &fromName)
Set the source of the route.
Definition: Route.cpp:101
Bytes.h
yarp::os::Contact::getHost
std::string getHost() const
Get the host name associated with this Contact for socket communication.
Definition: Contact.cpp:231
yarp::os::ConnectionState::is
InputStream & is()
Shorthand for getInputStream()
Definition: ConnectionState.h:125
yarp::os::Route::setToName
void setToName(const std::string &toName)
Set the destination of the route.
Definition: Route.cpp:111
RosHeader
Definition: RosHeader.h:16
yarp::os::Contact
Represents how to reach a part of a YARP network.
Definition: Contact.h:39
yarp::os::Route::getToName
const std::string & getToName() const
Get the destination of the route.
Definition: Route.cpp:106
yarp::os::ManagedBytes::get
const char * get() const
Definition: ManagedBytes.cpp:154
yarp::os::TwoWayStream::isOk
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
TcpRosCarrier::reply
bool reply(yarp::os::ConnectionState &proto, yarp::os::SizedWriter &writer) override
Definition: TcpRosCarrier.cpp:442
yarp::os::ContactStyle::timeout
double timeout
Set a timeout for communication (in units of seconds, fractional seconds allowed).
Definition: ContactStyle.h:50
yarp::os::Contactable::getType
virtual Type getType()=0
Get the type of data the port has committed to send/receive.
yarp::os::ManagedBytes::length
size_t length() const
Definition: ManagedBytes.cpp:144
yCTrace
#define yCTrace(component,...)
Definition: LogComponent.h:88
TcpRosCarrier::setParameters
void setParameters(const yarp::os::Bytes &header) override
Configure this carrier based on the first 8 bytes of the connection.
Definition: TcpRosCarrier.cpp:28
yarp::wire_rep_utils
Definition: BlobNetworkHeader.h:18
yarp::os::ConnectionState::getContactable
virtual Contactable * getContactable() const =0
Get the port associated with the connection.
yarp::sig::file::write
bool write(const ImageOf< PixelRgb > &src, const std::string &dest, image_fileformat format=FORMAT_PPM)
Definition: ImageFile.cpp:971
yarp::os::Route::getFromName
const std::string & getFromName() const
Get the source of the route.
Definition: Route.cpp:96
WireImage.h
yarp::os::NetType::netInt
static int netInt(const yarp::os::Bytes &code)
Definition: NetType.cpp:96
YARP_ENACT_EXISTS
#define YARP_ENACT_EXISTS
Definition: Carrier.h:17
yarp::os::SizedWriter
Minimal requirements for an efficient Writer.
Definition: SizedWriter.h:36
TCPROSCARRIER
const yarp::os::LogComponent & TCPROSCARRIER()
Definition: TcpRosLogComponent.cpp:16
RosSlave::where
yarp::os::Contact where()
Definition: RosSlave.h:60
yarp::os::NetInt32
std::int32_t NetInt32
Definition of the NetInt32 type.
Definition: NetInt32.h:33