YARP
Yet Another Robot Platform
HumanCarrier.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3  * SPDX-FileCopyrightText: 2006-2010 RobotCub Consortium
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <yarp/os/Carrier.h>
8 #include <yarp/os/Route.h>
9 #include <yarp/os/SizedWriter.h>
10 #include "HumanStream.h"
11 
12 class HumanCarrier : public Carrier {
13 public:
14 
15  // First, the easy bits...
16 
17  Carrier *create() const override {
18  return new HumanCarrier();
19  }
20 
21  std::string getName() const override {
22  return "human";
23  }
24 
25  bool isConnectionless() const override {
26  return true;
27  }
28 
29  bool canAccept() const override {
30  return true;
31  }
32 
33  bool canOffer() const override {
34  return true;
35  }
36 
37  bool isTextMode() const override {
38  // let's be text mode, for human-friendliness
39  return true;
40  }
41 
42  bool canEscape() const override {
43  return true;
44  }
45 
46  bool requireAck() const override {
47  return true;
48  }
49 
50  bool supportReply() const override {
51  return true;
52  }
53 
54  bool isLocal() const override {
55  return false;
56  }
57 
58  std::string toString() const override {
59  return "humans are handy";
60  }
61 
62  void getHeader(Bytes& header) const override {
63  const char *target = "HUMANITY";
64  for (size_t i=0; i<8 && i<header.length(); i++) {
65  header.get()[i] = target[i];
66  }
67  }
68 
69  bool checkHeader(const Bytes& header) override {
70  if (header.length()!=8) {
71  return false;
72  }
73  const char *target = "HUMANITY";
74  for (size_t i=0; i<8; i++) {
75  if (header.get()[i] != target[i]) {
76  return false;
77  }
78  }
79  return true;
80  }
81 
82  void setParameters(const Bytes& header) override {
83  // no parameters - no carrier variants
84  }
85 
86 
87  // Now, the initial hand-shaking
88 
89  bool prepareSend(ConnectionState& proto) override {
90  // nothing special to do
91  return true;
92  }
93 
94  bool sendHeader(ConnectionState& proto) override;
95 
96  bool expectSenderSpecifier(ConnectionState& proto) override {
97  // interpret everything that sendHeader wrote
98  Route route = proto.getRoute();
99  route.setFromName(proto.is().readLine());
100  proto.setRoute(route);
101  return proto.is().isOk();
102  }
103 
104  bool expectExtraHeader(ConnectionState& proto) override {
105  // interpret any extra header information sent - optional
106  return true;
107  }
108 
109  bool respondToHeader(ConnectionState& proto) override {
110  // SWITCH TO NEW STREAM TYPE
111  HumanStream *stream = new HumanStream();
112  if (stream==NULL) { return false; }
113  proto.takeStreams(stream);
114  return true;
115  }
116 
117  bool expectReplyToHeader(ConnectionState& proto) override {
118  // SWITCH TO NEW STREAM TYPE
119  HumanStream *stream = new HumanStream();
120  if (stream==NULL) { return false; }
121  proto.takeStreams(stream);
122  return true;
123  }
124 
125  bool isActive() const override {
126  return true;
127  }
128 
129 
130  // Payload time!
131 
132  bool write(ConnectionState& proto, SizedWriter& writer) override {
133  bool ok = sendIndex(proto,writer);
134  if (!ok) {
135  return false;
136  }
137  writer.write(proto.os());
138  return proto.os().isOk();
139  }
140 
141  virtual bool sendIndex(ConnectionState& proto,SizedWriter& writer) {
142  std::string prefix = "human says ";
143  Bytes b2((char*)prefix.c_str(),prefix.length());
144  proto.os().write(b2);
145  return true;
146  }
147 
148  bool expectIndex(ConnectionState& proto) override {
149  std::string prefix = "human says ";
150  std::string compare = prefix;
151  Bytes b2((char*)prefix.c_str(),prefix.length());
152  proto.is().read(b2);
153  bool ok = proto.is().isOk() && (prefix==compare);
154  if (!ok) {
155  std::cout << "YOU DID NOT SAY 'human says '" << std::endl;
156  }
157  return ok;
158  }
159 
160  // Acknowledgements, we don't do them
161 
162  bool sendAck(ConnectionState& proto) override {
163  std::string prefix = "computers rule!\r\n";
164  Bytes b2((char*)prefix.c_str(),prefix.length());
165  proto.os().write(b2);
166  return true;
167  }
168 
169  bool expectAck(ConnectionState& proto) override {
170  std::string prefix = "computers rule!\r\n";
171  std::string compare = prefix;
172  Bytes b2((char*)prefix.c_str(),prefix.length());
173  proto.is().read(b2);
174  bool ok = proto.is().isOk() && (prefix==compare);
175  if (!ok) {
176  std::cout << "YOU DID NOT SAY 'computers rule!'" << std::endl;
177  }
178  return ok;
179  }
180 
181 };
bool respondToHeader(ConnectionState &proto) override
Respond to the header.
Definition: HumanCarrier.h:109
std::string getName() const override
Get the name of this connection type ("tcp", "mcast", "shmem", ...)
Definition: HumanCarrier.h:21
bool canAccept() const override
Check if reading is implemented for this carrier.
Definition: HumanCarrier.h:29
bool expectIndex(ConnectionState &proto) override
Expect a message header, if there is one for this carrier.
Definition: HumanCarrier.h:148
bool canEscape() const override
Check if carrier can encode administrative messages, as opposed to just user data.
Definition: HumanCarrier.h:42
void setParameters(const Bytes &header) override
Configure this carrier based on the first 8 bytes of the connection.
Definition: HumanCarrier.h:82
Carrier * create() const override
Factory method.
Definition: HumanCarrier.h:17
bool checkHeader(const Bytes &header) override
Given the first 8 bytes received on a connection, decide if this is the right carrier type to use for...
Definition: HumanCarrier.h:69
bool expectAck(ConnectionState &proto) override
Receive an acknowledgement, if expected for this carrier.
Definition: HumanCarrier.h:169
bool isConnectionless() const override
Check if this carrier is connectionless (like udp, mcast) or connection based (like tcp).
Definition: HumanCarrier.h:25
void getHeader(Bytes &header) const override
Provide 8 bytes describing this connection sufficiently to allow the other side of a connection to se...
Definition: HumanCarrier.h:62
bool write(ConnectionState &proto, SizedWriter &writer) override
Write a message.
Definition: HumanCarrier.h:132
bool isLocal() const override
Check if carrier operates within a single process.
Definition: HumanCarrier.h:54
bool isActive() const override
Check if carrier is alive and error free.
Definition: HumanCarrier.h:125
bool sendHeader(ConnectionState &proto) override
Write a header appropriate to the carrier to the connection, followed by any carrier-specific data.
bool expectReplyToHeader(ConnectionState &proto) override
Process reply to header, if one is expected for this carrier.
Definition: HumanCarrier.h:117
bool expectSenderSpecifier(ConnectionState &proto) override
Expect the name of the sending port.
Definition: HumanCarrier.h:96
bool expectExtraHeader(ConnectionState &proto) override
Receive any carrier-specific header.
Definition: HumanCarrier.h:104
bool canOffer() const override
Check if writing is implemented for this carrier.
Definition: HumanCarrier.h:33
bool sendAck(ConnectionState &proto) override
Send an acknowledgement, if needed for this carrier.
Definition: HumanCarrier.h:162
bool isTextMode() const override
Check if carrier is textual in nature.
Definition: HumanCarrier.h:37
virtual bool sendIndex(ConnectionState &proto, SizedWriter &writer)
Definition: HumanCarrier.h:141
std::string toString() const override
Get name of carrier.
Definition: HumanCarrier.h:58
bool requireAck() const override
Check if carrier has flow control, requiring sent messages to be acknowledged by recipient.
Definition: HumanCarrier.h:46
bool supportReply() const override
This flag is used by YARP to determine whether the connection can carry RPC traffic,...
Definition: HumanCarrier.h:50
bool prepareSend(ConnectionState &proto) override
Perform any initialization needed before writing on a connection.
Definition: HumanCarrier.h:89
A simple abstraction for a block of bytes.
Definition: Bytes.h:25
size_t length() const
Definition: Bytes.cpp:22
const char * get() const
Definition: Bytes.cpp:27
A base class for connection types (tcp, mcast, shmem, ...) which are called carriers in YARP.
Definition: Carrier.h:45
The basic state of a connection - route, streams in use, etc.
virtual const Route & getRoute() const =0
Get the route associated with this connection.
virtual void takeStreams(TwoWayStream *streams)=0
Provide streams to be used with the connection.
InputStream & is()
Shorthand for getInputStream()
OutputStream & os()
Shorthand for getOutputStream()
virtual void setRoute(const Route &route)=0
Set the route associated with this connection.
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
virtual int read()
Read and return a single byte.
Definition: InputStream.cpp:20
std::string readLine(const char terminal='\n', bool *success=nullptr)
Read a block of text terminated with a specific marker (or EOF).
Definition: InputStream.cpp:54
virtual bool isOk() const =0
Check if the stream is ok or in an error state.
virtual void write(char ch)
Write a single byte to the stream.
Information about a connection between two ports.
Definition: Route.h:29
void setFromName(const std::string &fromName)
Set the source of the route.
Definition: Route.cpp:98
Minimal requirements for an efficient Writer.
Definition: SizedWriter.h:33
virtual void write(OutputStream &os)
Definition: SizedWriter.cpp:16