YARP
Yet Another Robot Platform
MjpegCarrier.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 #ifndef MJPEGCARRIER_INC
8 #define MJPEGCARRIER_INC
9 
10 #include <yarp/os/Carrier.h>
11 #include <yarp/os/NetType.h>
13 #include "MjpegStream.h"
14 #include "MjpegLogComponent.h"
15 
16 #include <cstring>
17 
36 class MjpegCarrier :
37  public yarp::os::Carrier
38 {
39 private:
40  bool firstRound;
41  bool sender;
42  std::string envelope;
43 public:
45  firstRound = true;
46  sender = false;
47  }
48 
49  Carrier *create() const override {
50  return new MjpegCarrier();
51  }
52 
53  std::string getName() const override {
54  return "mjpeg";
55  }
56 
57  bool isConnectionless() const override {
58  return false;
59  }
60 
61  bool canAccept() const override {
62  return true;
63  }
64 
65  bool canOffer() const override {
66  return true;
67  }
68 
69  bool isTextMode() const override {
70  return false;
71  }
72 
73  bool canEscape() const override {
74  return false;
75  }
76 
77  void handleEnvelope(const std::string& envelope) override {
78  this->envelope = envelope;
79  }
80 
81  bool requireAck() const override {
82  return false;
83  }
84 
85  bool supportReply() const override {
86  return false;
87  }
88 
89  bool isLocal() const override {
90  return false;
91  }
92 
93  // this is important - flips expected flow of messages
94  bool isPush() const override {
95  return false;
96  }
97 
98  std::string toString() const override {
99  return "mjpeg_carrier";
100  }
101 
102  void getHeader(yarp::os::Bytes& header) const override {
103  // GET /?action=stream HTTP/1.1
104  const char *target = "GET /?ac";
105  for (size_t i=0; i<8 && i<header.length(); i++) {
106  header.get()[i] = target[i];
107  }
108  }
109 
110  bool checkHeader(const yarp::os::Bytes& header) override {
111  if (header.length()!=8) {
112  return false;
113  }
114  const char *target = "GET /?ac";
115  for (int i=0; i<8; i++) {
116  if (header.get()[i] != target[i]) {
117  return false;
118  }
119  }
120  yCTrace(MJPEGCARRIER, "Got header");
121  return true;
122  }
123 
124  void setParameters(const yarp::os::Bytes& header) override {
125  // no parameters - no carrier variants
126  }
127 
128 
129  // Now, the initial hand-shaking
130 
131  bool prepareSend(yarp::os::ConnectionState& proto) override {
132  // nothing special to do
133  return true;
134  }
135 
136  bool sendHeader(yarp::os::ConnectionState& proto) override;
137 
139  return true;
140  }
141 
143  std::string txt;
144  do {
145  txt = proto.is().readLine();
146  } while (txt!="");
147  return true;
148  }
149 
151  std::string target = "HTTP/1.0 200 OK\r\n\
152 Connection: close\r\n\
153 Server: yarp/mjpeg_carrier/0.1\r\n\
154 Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n\
155 Pragma: no-cache\r\n\
156 Expires: Mon, 3 Jan 2000 12:34:56 GMT\r\n\
157 Content-Type: multipart/x-mixed-replace;boundary=boundarydonotcross\r\n\
158 \r\n\
159 --boundarydonotcross\r\n";
160  yarp::os::Bytes b((char*)target.c_str(),strlen(target.c_str()));
161  proto.os().write(b);
162  sender = true; // this is a pull connection, not a push
163  //MjpegStream *stream = new MjpegStream(proto.giveStreams(),sender);
164  //if (stream==NULL) { return false; }
165  //proto.takeStreams(stream);
166  return true;
167  }
168 
170  std::string txt;
171  do {
172  txt = proto.is().readLine();
173  } while (txt!="");
174 
175  sender = false;
176  MjpegStream *stream = new MjpegStream(proto.giveStreams(),
177  autoCompression());
178  if (stream==NULL) { return false; }
179  proto.takeStreams(stream);
180  return true;
181  }
182 
183  bool isActive() const override {
184  return true;
185  }
186 
187 
188  // Payload time!
189 
190  bool write(yarp::os::ConnectionState& proto, yarp::os::SizedWriter& writer) override;
191 
192  bool reply(yarp::os::ConnectionState& proto, yarp::os::SizedWriter& writer) override;
193 
195  return true;
196  }
197 
198  bool expectIndex(yarp::os::ConnectionState& proto) override {
199  return true;
200  }
201 
202  bool sendAck(yarp::os::ConnectionState& proto) override {
203  return true;
204  }
205 
206  bool expectAck(yarp::os::ConnectionState& proto) override {
207  return true;
208  }
209 
210  std::string getBootstrapCarrierName() const override { return {}; }
211 
212  virtual bool autoCompression() const;
213 };
214 
215 #endif
const yarp::os::LogComponent & MJPEGCARRIER()
A carrier for sending/receiving images via mjpeg over http.
Definition: MjpegCarrier.h:38
virtual bool autoCompression() const
bool isActive() const override
Check if carrier is alive and error free.
Definition: MjpegCarrier.h:183
bool canEscape() const override
Check if carrier can encode administrative messages, as opposed to just user data.
Definition: MjpegCarrier.h:73
bool respondToHeader(yarp::os::ConnectionState &proto) override
Respond to the header.
Definition: MjpegCarrier.h:150
bool expectExtraHeader(yarp::os::ConnectionState &proto) override
Receive any carrier-specific header.
Definition: MjpegCarrier.h:142
void handleEnvelope(const std::string &envelope) override
Carriers that do not distinguish data from administrative headers (i.e.
Definition: MjpegCarrier.h:77
bool isLocal() const override
Check if carrier operates within a single process.
Definition: MjpegCarrier.h:89
bool reply(yarp::os::ConnectionState &proto, yarp::os::SizedWriter &writer) override
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: MjpegCarrier.h:110
Carrier * create() const override
Factory method.
Definition: MjpegCarrier.h:49
bool expectAck(yarp::os::ConnectionState &proto) override
Receive an acknowledgement, if expected for this carrier.
Definition: MjpegCarrier.h:206
void getHeader(yarp::os::Bytes &header) const override
Provide 8 bytes describing this connection sufficiently to allow the other side of a connection to se...
Definition: MjpegCarrier.h:102
bool supportReply() const override
This flag is used by YARP to determine whether the connection can carry RPC traffic,...
Definition: MjpegCarrier.h:85
bool isConnectionless() const override
Check if this carrier is connectionless (like udp, mcast) or connection based (like tcp).
Definition: MjpegCarrier.h:57
bool canAccept() const override
Check if reading is implemented for this carrier.
Definition: MjpegCarrier.h:61
void setParameters(const yarp::os::Bytes &header) override
Configure this carrier based on the first 8 bytes of the connection.
Definition: MjpegCarrier.h:124
std::string getName() const override
Get the name of this connection type ("tcp", "mcast", "shmem", ...)
Definition: MjpegCarrier.h:53
bool requireAck() const override
Check if carrier has flow control, requiring sent messages to be acknowledged by recipient.
Definition: MjpegCarrier.h:81
bool prepareSend(yarp::os::ConnectionState &proto) override
Perform any initialization needed before writing on a connection.
Definition: MjpegCarrier.h:131
bool isTextMode() const override
Check if carrier is textual in nature.
Definition: MjpegCarrier.h:69
bool sendAck(yarp::os::ConnectionState &proto) override
Send an acknowledgement, if needed for this carrier.
Definition: MjpegCarrier.h:202
bool isPush() const override
Check if carrier is "push" or "pull" style.
Definition: MjpegCarrier.h:94
std::string toString() const override
Get name of carrier.
Definition: MjpegCarrier.h:98
bool canOffer() const override
Check if writing is implemented for this carrier.
Definition: MjpegCarrier.h:65
bool expectSenderSpecifier(yarp::os::ConnectionState &proto) override
Expect the name of the sending port.
Definition: MjpegCarrier.h:138
bool write(yarp::os::ConnectionState &proto, yarp::os::SizedWriter &writer) override
Write a message.
bool sendHeader(yarp::os::ConnectionState &proto) override
Write a header appropriate to the carrier to the connection, followed by any carrier-specific data.
bool expectReplyToHeader(yarp::os::ConnectionState &proto) override
Process reply to header, if one is expected for this carrier.
Definition: MjpegCarrier.h:169
bool expectIndex(yarp::os::ConnectionState &proto) override
Expect a message header, if there is one for this carrier.
Definition: MjpegCarrier.h:198
std::string getBootstrapCarrierName() const override
Get the name of the carrier that should be used prior to handshaking, if a port is registered with th...
Definition: MjpegCarrier.h:210
virtual bool sendIndex(yarp::os::ConnectionState &proto, yarp::os::SizedWriter &writer)
Definition: MjpegCarrier.h:194
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 TwoWayStream * giveStreams()=0
Take ownership of the streams associated with the 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()
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 void write(char ch)
Write a single byte to the stream.
Minimal requirements for an efficient Writer.
Definition: SizedWriter.h:33
#define yCTrace(component,...)
Definition: LogComponent.h:85